From 58249da5655dc288892769f2d67085b789c2c7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20D?= Date: Tue, 12 Oct 2021 20:49:18 +0200 Subject: [PATCH] * [MOD] Use static types. * [MOD] CORS headers. * [MOD] Improve Forwarded header lookup. * [ADD] Create interface for configuration data. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rubén D --- api.php | 4 +- .../api/Controllers/AccountController.php | 180 +- .../api/Controllers/CategoryController.php | 111 +- .../api/Controllers/ClientController.php | 111 +- .../api/Controllers/ConfigController.php | 60 +- .../api/Controllers/ControllerBase.php | 126 +- .../api/Controllers/Help/AccountHelp.php | 4 +- .../api/Controllers/Help/CategoryHelp.php | 4 +- .../api/Controllers/Help/ClientHelp.php | 4 +- .../api/Controllers/Help/ConfigHelp.php | 4 +- .../api/Controllers/Help/HelpInterface.php | 4 +- .../api/Controllers/Help/HelpTrait.php | 12 +- app/modules/api/Controllers/Help/TagHelp.php | 4 +- .../api/Controllers/Help/UserGroupHelp.php | 4 +- app/modules/api/Controllers/TagController.php | 108 +- .../api/Controllers/UserGroupController.php | 116 +- app/modules/api/Init.php | 37 +- app/modules/api/module.php | 8 +- app/modules/cli/Commands/BackupCommand.php | 25 +- app/modules/cli/Commands/CommandBase.php | 30 +- .../Crypt/UpdateMasterPasswordCommand.php | 44 +- app/modules/cli/Commands/InstallCommand.php | 54 +- app/modules/cli/Commands/Validators.php | 11 +- app/modules/cli/Init.php | 34 +- .../Controllers/AccessManagerController.php | 56 +- .../web/Controllers/AccountController.php | 436 +- .../Controllers/AccountFavoriteController.php | 51 +- .../web/Controllers/AccountFileController.php | 166 +- .../AccountHistoryManagerController.php | 113 +- .../Controllers/AccountManagerController.php | 122 +- .../web/Controllers/AuthTokenController.php | 267 +- .../web/Controllers/BootstrapController.php | 33 +- .../web/Controllers/CategoryController.php | 238 +- .../web/Controllers/ClientController.php | 250 +- .../Controllers/ConfigAccountController.php | 31 +- .../Controllers/ConfigBackupController.php | 225 +- .../Controllers/ConfigDokuWikiController.php | 49 +- .../ConfigEncryptionController.php | 119 +- .../Controllers/ConfigGeneralController.php | 117 +- .../Controllers/ConfigImportController.php | 40 +- .../web/Controllers/ConfigLdapController.php | 115 +- .../web/Controllers/ConfigMailController.php | 64 +- .../Controllers/ConfigManagerController.php | 203 +- .../web/Controllers/ConfigWikiController.php | 48 +- .../web/Controllers/ControllerBase.php | 134 +- .../web/Controllers/CustomFieldController.php | 260 +- .../web/Controllers/ErrorController.php | 68 +- .../web/Controllers/EventlogController.php | 60 +- .../Helpers/Account/AccountActionsDto.php | 35 +- .../Helpers/Account/AccountActionsHelper.php | 284 +- .../Helpers/Account/AccountHelper.php | 278 +- .../Helpers/Account/AccountHistoryHelper.php | 97 +- .../Helpers/Account/AccountPasswordHelper.php | 39 +- .../Helpers/Account/AccountSearchHelper.php | 167 +- .../Controllers/Helpers/Grid/AccountGrid.php | 29 +- .../Helpers/Grid/AccountHistoryGrid.php | 36 +- .../Helpers/Grid/AuthTokenGrid.php | 44 +- .../Controllers/Helpers/Grid/CategoryGrid.php | 29 +- .../Controllers/Helpers/Grid/ClientGrid.php | 39 +- .../Helpers/Grid/CustomFieldGrid.php | 44 +- .../Controllers/Helpers/Grid/EventlogGrid.php | 41 +- .../web/Controllers/Helpers/Grid/FileGrid.php | 47 +- .../web/Controllers/Helpers/Grid/GridBase.php | 38 +- .../Helpers/Grid/GridInterface.php | 4 +- .../Helpers/Grid/ItemPresetGrid.php | 24 +- .../Helpers/Grid/NotificationGrid.php | 92 +- .../Controllers/Helpers/Grid/PluginGrid.php | 68 +- .../Helpers/Grid/PublicLinkGrid.php | 47 +- .../web/Controllers/Helpers/Grid/TagGrid.php | 32 +- .../Controllers/Helpers/Grid/TrackGrid.php | 74 +- .../web/Controllers/Helpers/Grid/UserGrid.php | 126 +- .../Helpers/Grid/UserGroupGrid.php | 37 +- .../Helpers/Grid/UserProfileGrid.php | 37 +- .../web/Controllers/Helpers/HelperBase.php | 56 +- .../Controllers/Helpers/HelperException.php | 20 +- .../Controllers/Helpers/ItemPresetHelper.php | 132 +- .../web/Controllers/Helpers/LayoutHelper.php | 112 +- .../Controllers/Helpers/TabsGridHelper.php | 12 +- .../web/Controllers/Helpers/TabsHelper.php | 12 +- .../web/Controllers/IndexController.php | 11 +- .../web/Controllers/InstallController.php | 20 +- .../web/Controllers/ItemManagerController.php | 72 +- .../web/Controllers/ItemPresetController.php | 233 +- .../web/Controllers/ItemsController.php | 39 +- .../web/Controllers/LoginController.php | 65 +- .../Controllers/NotificationController.php | 277 +- .../web/Controllers/PluginController.php | 213 +- .../web/Controllers/PublicLinkController.php | 302 +- .../web/Controllers/ResourceController.php | 21 +- .../Controllers/SecurityManagerController.php | 41 +- .../web/Controllers/SimpleControllerBase.php | 52 +- .../web/Controllers/StatusController.php | 83 +- app/modules/web/Controllers/TagController.php | 244 +- .../web/Controllers/TaskController.php | 15 +- .../web/Controllers/TrackController.php | 82 +- .../web/Controllers/Traits/ConfigTrait.php | 38 +- .../web/Controllers/Traits/JsonTrait.php | 48 +- .../Controllers/Traits/WebControllerTrait.php | 80 +- .../web/Controllers/UpgradeController.php | 15 +- .../web/Controllers/UserController.php | 446 +- .../web/Controllers/UserGroupController.php | 310 +- .../Controllers/UserPassResetController.php | 90 +- .../web/Controllers/UserProfileController.php | 301 +- .../UserSettingsGeneralController.php | 24 +- .../UserSettingsManagerController.php | 30 +- app/modules/web/Forms/AccountForm.php | 40 +- app/modules/web/Forms/AuthTokenForm.php | 32 +- app/modules/web/Forms/CategoryForm.php | 27 +- app/modules/web/Forms/ClientForm.php | 18 +- app/modules/web/Forms/CustomFieldDefForm.php | 18 +- app/modules/web/Forms/FormBase.php | 39 +- app/modules/web/Forms/FormInterface.php | 4 +- app/modules/web/Forms/ItemsPresetForm.php | 44 +- app/modules/web/Forms/NotificationForm.php | 22 +- app/modules/web/Forms/PublicLinkForm.php | 18 +- app/modules/web/Forms/TagForm.php | 18 +- app/modules/web/Forms/UserForm.php | 39 +- app/modules/web/Forms/UserGroupForm.php | 18 +- app/modules/web/Forms/UserProfileForm.php | 18 +- app/modules/web/Init.php | 103 +- app/modules/web/module.php | 10 +- .../web/themes/material-blue/css/_base.scss | 8 +- .../themes/material-blue/css/_elements.scss | 15 + .../web/themes/material-blue/css/_login.scss | 11 + .../themes/material-blue/css/_noheader.scss | 16 + .../web/themes/material-blue/css/fonts.css | 3 + .../material-blue/css/search-card.css.map | 2 +- .../themes/material-blue/css/search-card.scss | 6 + .../material-blue/css/search-grid.css.map | 2 +- .../themes/material-blue/css/search-grid.scss | 4 + .../material-blue/css/selectize-custom.css | 8 +- .../css/selectize-custom.css.map | 2 +- .../css/selectize-custom.min.css | 2 +- .../material-blue/css/styles-wiki.css.map | 2 +- .../themes/material-blue/css/styles-wiki.scss | 2 + .../themes/material-blue/css/styles.css.map | 2 +- .../themes/material-blue/css/toastr.css.map | 2 +- .../web/themes/material-blue/css/toastr.scss | 4 + .../web/themes/material-blue/index.php | 10 +- .../web/themes/material-blue/js/app-theme.map | 179 +- .../js/bootstrap-material-datetimepicker.js | 1867 ++-- .../js/bootstrap-material-datetimepicker.map | 250 +- .../web/themes/material-blue/js/material.js | 7826 +++++++++-------- .../web/themes/material-blue/js/material.map | 725 +- .../js/mdl-jquery-modal-dialog.map | 62 +- .../views/account/account-editpass.inc | 11 +- .../views/account/account-history.inc | 11 +- .../views/account/account-link.inc | 11 +- .../views/account/account-permissions.inc | 13 +- .../views/account/account-request.inc | 11 +- .../material-blue/views/account/account.inc | 11 +- .../material-blue/views/account/actions.inc | 11 +- .../material-blue/views/account/details.inc | 11 +- .../views/account/files-list.inc | 9 +- .../material-blue/views/account/files.inc | 11 +- .../views/account/linkedAccounts.inc | 7 +- .../views/account/search-header.inc | 11 +- .../views/account/search-index.inc | 11 +- .../views/account/search-rows.inc | 17 +- .../views/account/search-searchbox.inc | 11 +- .../material-blue/views/account/viewpass.inc | 11 +- .../material-blue/views/config/accounts.inc | 9 +- .../material-blue/views/config/backup.inc | 11 +- .../material-blue/views/config/encryption.inc | 9 +- .../views/config/general-auth.inc | 9 +- .../views/config/general-events.inc | 9 +- .../views/config/general-proxy.inc | 9 +- .../views/config/general-site.inc | 9 +- .../material-blue/views/config/general.inc | 9 +- .../material-blue/views/config/import.inc | 9 +- .../material-blue/views/config/info.inc | 11 +- .../material-blue/views/config/ldap.inc | 9 +- .../material-blue/views/config/mail.inc | 9 +- .../views/config/wiki-dokuwiki.inc | 9 +- .../material-blue/views/config/wiki.inc | 9 +- .../views/eventlog/datagrid-rows.inc | 11 +- .../views/grid/datagrid-grid.inc | 3 +- .../views/grid/datatabs-grid.inc | 11 +- .../material-blue/views/install/index.inc | 9 +- .../views/itemshow/account_bulkedit.inc | 19 +- .../views/itemshow/auth_token.inc | 11 +- .../material-blue/views/itemshow/category.inc | 11 +- .../material-blue/views/itemshow/client.inc | 11 +- .../views/itemshow/custom_field.inc | 11 +- .../material-blue/views/itemshow/file.inc | 11 +- .../views/itemshow/item_preset-password.inc | 11 +- .../views/itemshow/item_preset-permission.inc | 9 +- .../views/itemshow/item_preset-private.inc | 11 +- .../itemshow/item_preset-session_timeout.inc | 11 +- .../views/itemshow/item_preset.inc | 11 +- .../views/itemshow/public_link.inc | 11 +- .../material-blue/views/itemshow/results.inc | 9 +- .../material-blue/views/itemshow/tag.inc | 11 +- .../material-blue/views/itemshow/user.inc | 11 +- .../views/itemshow/user_group.inc | 13 +- .../views/itemshow/user_pass.inc | 11 +- .../views/itemshow/user_profile.inc | 13 +- .../material-blue/views/login/index.inc | 9 +- .../material-blue/views/main/update.inc | 9 +- .../material-blue/views/main/upgrade.inc | 11 +- .../views/notification/notification.inc | 11 +- .../material-blue/views/plugin/plugin.inc | 13 +- .../views/userpassreset/reset.inc | 9 +- .../views/usersettings/general.inc | 11 +- .../material-blue/views/wiki/wikipage.inc | 9 +- cli.php | 10 +- index.php | 10 +- lib/Base.php | 26 +- lib/BaseFunctions.php | 146 +- lib/Definitions.php | 61 +- lib/SP/Adapters/AccountAdapter.php | 52 +- lib/SP/Adapters/AdapterBase.php | 18 +- lib/SP/Adapters/CategoryAdapter.php | 22 +- lib/SP/Adapters/ClientAdapter.php | 22 +- lib/SP/Adapters/CustomFieldAdapter.php | 9 +- lib/SP/Bootstrap.php | 121 +- lib/SP/Config/Config.php | 97 +- lib/SP/Config/ConfigCache.php | 94 - lib/SP/Config/ConfigData.php | 1012 +-- lib/SP/Config/ConfigDataInterface.php | 1190 +++ lib/SP/Config/ConfigInterface.php | 88 - lib/SP/Config/ConfigUtil.php | 45 +- .../Core/Acl/AccountPermissionException.php | 8 +- lib/SP/Core/Acl/Acl.php | 42 +- lib/SP/Core/Acl/ActionNotFoundException.php | 4 +- lib/SP/Core/Acl/Actions.php | 43 +- lib/SP/Core/Acl/ActionsInterface.php | 314 +- .../Core/Acl/UnauthorizedActionException.php | 4 +- lib/SP/Core/Acl/UnauthorizedPageException.php | 4 +- lib/SP/Core/AppInfoInterface.php | 22 +- lib/SP/Core/Context/ContextBase.php | 54 +- lib/SP/Core/Context/ContextCollection.php | 4 +- lib/SP/Core/Context/ContextException.php | 4 +- lib/SP/Core/Context/ContextInterface.php | 4 +- lib/SP/Core/Context/SessionContext.php | 46 +- lib/SP/Core/Context/StatelessContext.php | 26 +- lib/SP/Core/Crypt/CSRF.php | 40 +- lib/SP/Core/Crypt/Cookie.php | 41 +- lib/SP/Core/Crypt/Crypt.php | 61 +- lib/SP/Core/Crypt/CryptPKI.php | 56 +- lib/SP/Core/Crypt/CryptSessionHandler.php | 40 +- lib/SP/Core/Crypt/Hash.php | 34 +- lib/SP/Core/Crypt/OldCrypt.php | 8 +- lib/SP/Core/Crypt/SecureKeyCookie.php | 35 +- lib/SP/Core/Crypt/Session.php | 21 +- lib/SP/Core/Crypt/UUIDCookie.php | 19 +- lib/SP/Core/Crypt/Vault.php | 51 +- lib/SP/Core/DataCollection.php | 34 +- lib/SP/Core/Events/Event.php | 37 +- lib/SP/Core/Events/EventDispatcher.php | 4 +- lib/SP/Core/Events/EventDispatcherBase.php | 14 +- .../Core/Events/EventDispatcherInterface.php | 10 +- lib/SP/Core/Events/EventMessage.php | 107 +- lib/SP/Core/Events/EventReceiver.php | 6 +- lib/SP/Core/Exceptions/CheckException.php | 4 +- lib/SP/Core/Exceptions/ConfigException.php | 4 +- .../Core/Exceptions/ConstraintException.php | 4 +- .../Core/Exceptions/FileNotFoundException.php | 4 +- .../Exceptions/InitializationException.php | 4 +- lib/SP/Core/Exceptions/InstallError.php | 2 +- .../Exceptions/InvalidArgumentException.php | 4 +- .../Core/Exceptions/InvalidClassException.php | 4 +- .../Core/Exceptions/InvalidImageException.php | 4 +- lib/SP/Core/Exceptions/ItemException.php | 4 +- .../Exceptions/NoSuchPropertyException.php | 4 +- lib/SP/Core/Exceptions/QueryException.php | 4 +- lib/SP/Core/Exceptions/SPException.php | 4 +- lib/SP/Core/Exceptions/SessionTimeout.php | 4 +- .../Core/Exceptions/ValidationException.php | 4 +- lib/SP/Core/ItemsTypeInterface.php | 24 +- lib/SP/Core/Language.php | 72 +- lib/SP/Core/Messages/FormatterInterface.php | 16 +- lib/SP/Core/Messages/HtmlFormatter.php | 65 +- lib/SP/Core/Messages/LogMessage.php | 81 +- lib/SP/Core/Messages/MailMessage.php | 25 +- lib/SP/Core/Messages/MessageBase.php | 73 +- lib/SP/Core/Messages/MessageInterface.php | 4 +- lib/SP/Core/Messages/NotificationMessage.php | 29 +- lib/SP/Core/Messages/TaskMessage.php | 124 +- lib/SP/Core/Messages/TextFormatter.php | 50 +- lib/SP/Core/MimeTypes.php | 54 +- lib/SP/Core/ModuleBase.php | 46 +- lib/SP/Core/PhpExtensionChecker.php | 53 +- lib/SP/Core/SessionUtil.php | 6 +- lib/SP/Core/UI/Theme.php | 100 +- lib/SP/Core/UI/ThemeIcons.php | 15 +- lib/SP/Core/UI/ThemeIconsInterface.php | 4 +- lib/SP/Core/UI/ThemeInterface.php | 6 +- lib/SP/DataModel/AccountData.php | 6 +- lib/SP/DataModel/AccountExtData.php | 4 +- lib/SP/DataModel/AccountHistoryData.php | 4 +- lib/SP/DataModel/AccountPassData.php | 4 +- lib/SP/DataModel/AccountSearchVData.php | 4 +- lib/SP/DataModel/AccountToUserGroupData.php | 4 +- lib/SP/DataModel/AccountVData.php | 8 +- lib/SP/DataModel/ActionData.php | 4 +- lib/SP/DataModel/AuthTokenData.php | 4 +- lib/SP/DataModel/CategoryData.php | 4 +- lib/SP/DataModel/ClientData.php | 4 +- lib/SP/DataModel/ConfigData.php | 4 +- lib/SP/DataModel/CustomFieldBaseData.php | 4 +- lib/SP/DataModel/CustomFieldData.php | 4 +- lib/SP/DataModel/CustomFieldDefDataOld.php | 4 +- .../DataModel/CustomFieldDefinitionData.php | 4 +- lib/SP/DataModel/CustomFieldTypeData.php | 4 +- lib/SP/DataModel/DataModelBase.php | 4 +- lib/SP/DataModel/DataModelInterface.php | 10 +- lib/SP/DataModel/Dto/AccountAclDto.php | 4 +- lib/SP/DataModel/Dto/AccountCache.php | 4 +- .../DataModel/Dto/AccountDetailsResponse.php | 4 +- .../DataModel/Dto/AccountHistoryCreateDto.php | 4 +- .../DataModel/Dto/AccountSearchResponse.php | 4 +- lib/SP/DataModel/Dto/ConfigRequest.php | 4 +- lib/SP/DataModel/EncryptedModel.php | 4 +- lib/SP/DataModel/EventlogData.php | 4 +- lib/SP/DataModel/FileData.php | 4 +- lib/SP/DataModel/FileExtData.php | 4 +- lib/SP/DataModel/HydratableInterface.php | 4 +- lib/SP/DataModel/ItemData.php | 4 +- .../ItemPreset/AccountPermission.php | 4 +- .../DataModel/ItemPreset/AccountPrivate.php | 4 +- lib/SP/DataModel/ItemPreset/Password.php | 4 +- .../DataModel/ItemPreset/SessionTimeout.php | 4 +- lib/SP/DataModel/ItemPresetData.php | 4 +- lib/SP/DataModel/ItemSearchData.php | 64 +- lib/SP/DataModel/NotificationData.php | 4 +- lib/SP/DataModel/ProfileData.php | 4 +- lib/SP/DataModel/PublicLinkData.php | 4 +- lib/SP/DataModel/PublicLinkListData.php | 4 +- lib/SP/DataModel/PublickLinkOldData.php | 4 +- lib/SP/DataModel/SerializedModel.php | 4 +- lib/SP/DataModel/TagData.php | 20 +- lib/SP/DataModel/TrackData.php | 4 +- lib/SP/DataModel/UserData.php | 6 +- lib/SP/DataModel/UserGroupData.php | 36 +- lib/SP/DataModel/UserLoginData.php | 4 +- lib/SP/DataModel/UserPassData.php | 4 +- lib/SP/DataModel/UserPassRecoverData.php | 4 +- lib/SP/DataModel/UserPreferencesData.php | 6 +- lib/SP/DataModel/UserProfileData.php | 4 +- lib/SP/DataModel/UserToUserGroupData.php | 4 +- lib/SP/Html/Assets/FontIcon.php | 18 +- lib/SP/Html/Assets/IconBase.php | 68 +- lib/SP/Html/Assets/IconInterface.php | 32 +- lib/SP/Html/Assets/ImageIcon.php | 16 +- .../Html/DataGrid/Action/DataGridAction.php | 4 +- .../DataGrid/Action/DataGridActionBase.php | 74 +- .../DataGrid/Action/DataGridActionHelp.php | 6 +- .../Action/DataGridActionInterface.php | 4 +- .../DataGrid/Action/DataGridActionSearch.php | 24 +- .../DataGrid/Action/DataGridActionType.php | 18 +- lib/SP/Html/DataGrid/DataGrid.php | 6 +- lib/SP/Html/DataGrid/DataGridBase.php | 66 +- lib/SP/Html/DataGrid/DataGridData.php | 4 +- lib/SP/Html/DataGrid/DataGridDataBase.php | 34 +- .../Html/DataGrid/DataGridDataInterface.php | 22 +- lib/SP/Html/DataGrid/DataGridInterface.php | 9 +- lib/SP/Html/DataGrid/DataGridSort.php | 28 +- .../Html/DataGrid/DataGridSortInterface.php | 16 +- lib/SP/Html/DataGrid/DataGridTab.php | 6 +- .../Html/DataGrid/Layout/DataGridHeader.php | 4 +- .../DataGrid/Layout/DataGridHeaderBase.php | 12 +- .../Layout/DataGridHeaderInterface.php | 6 +- .../DataGrid/Layout/DataGridHeaderSort.php | 22 +- lib/SP/Html/DataGrid/Layout/DataGridPager.php | 4 +- .../DataGrid/Layout/DataGridPagerBase.php | 120 +- .../Layout/DataGridPagerInterface.php | 60 +- lib/SP/Html/Html.php | 40 +- lib/SP/Html/Minify.php | 110 +- lib/SP/Http/Address.php | 43 +- lib/SP/Http/Client.php | 16 +- lib/SP/Http/Json.php | 52 +- lib/SP/Http/JsonResponse.php | 119 +- lib/SP/Http/Message.php | 49 +- lib/SP/Http/Request.php | 150 +- lib/SP/Http/Uri.php | 44 +- lib/SP/Http/XMLRPCResponseParse.php | 14 +- lib/SP/Http/Xml.php | 19 +- lib/SP/Mvc/Controller/ControllerTrait.php | 39 +- .../Controller/CrudControllerInterface.php | 4 +- .../ExtensibleControllerInterface.php | 6 +- .../ExtensibleTabControllerInterface.php | 4 +- lib/SP/Mvc/Controller/ItemTrait.php | 111 +- .../Validators/PasswordValidator.php | 33 +- .../Mvc/Controller/Validators/Validator.php | 40 +- .../Validators/ValidatorInterface.php | 4 +- lib/SP/Mvc/Model/QueryAssignment.php | 60 +- lib/SP/Mvc/Model/QueryCondition.php | 49 +- lib/SP/Mvc/Model/QueryJoin.php | 48 +- lib/SP/Mvc/View/Components/DataTab.php | 39 +- .../View/Components/ItemAdapterInterface.php | 4 +- lib/SP/Mvc/View/Components/SelectItem.php | 78 +- .../Mvc/View/Components/SelectItemAdapter.php | 62 +- lib/SP/Mvc/View/Template.php | 131 +- lib/SP/Mvc/View/TemplateVarCollection.php | 4 +- lib/SP/Plugin/PluginBase.php | 52 +- lib/SP/Plugin/PluginEventReceiver.php | 4 +- lib/SP/Plugin/PluginInterface.php | 4 +- lib/SP/Plugin/PluginManager.php | 104 +- lib/SP/Plugin/PluginOperation.php | 33 +- lib/SP/Providers/Acl/AclHandler.php | 46 +- lib/SP/Providers/Auth/AuthDataBase.php | 30 +- lib/SP/Providers/Auth/AuthInterface.php | 8 +- lib/SP/Providers/Auth/AuthProvider.php | 27 +- lib/SP/Providers/Auth/AuthResult.php | 16 +- lib/SP/Providers/Auth/Browser/Browser.php | 25 +- .../Auth/Browser/BrowserAuthData.php | 4 +- lib/SP/Providers/Auth/Database/Database.php | 12 +- .../Auth/Database/DatabaseAuthData.php | 4 +- .../Auth/Ldap/AttributeCollection.php | 4 +- lib/SP/Providers/Auth/Ldap/Ldap.php | 26 +- lib/SP/Providers/Auth/Ldap/LdapActions.php | 53 +- lib/SP/Providers/Auth/Ldap/LdapAuth.php | 42 +- lib/SP/Providers/Auth/Ldap/LdapAuthData.php | 24 +- lib/SP/Providers/Auth/Ldap/LdapCode.php | 20 +- lib/SP/Providers/Auth/Ldap/LdapConnection.php | 75 +- .../Auth/Ldap/LdapConnectionInterface.php | 6 +- lib/SP/Providers/Auth/Ldap/LdapException.php | 4 +- lib/SP/Providers/Auth/Ldap/LdapInterface.php | 6 +- lib/SP/Providers/Auth/Ldap/LdapMsAds.php | 18 +- lib/SP/Providers/Auth/Ldap/LdapParams.php | 52 +- lib/SP/Providers/Auth/Ldap/LdapStd.php | 23 +- .../Providers/Auth/Ldap/LdapTypeInterface.php | 10 +- lib/SP/Providers/Auth/Ldap/LdapUtil.php | 26 +- lib/SP/Providers/EventsTrait.php | 8 +- lib/SP/Providers/Log/DatabaseLogHandler.php | 27 +- lib/SP/Providers/Log/FileLogHandler.php | 15 +- lib/SP/Providers/Log/LogInterface.php | 8 +- lib/SP/Providers/Log/LoggerBase.php | 38 +- lib/SP/Providers/Log/RemoteSyslogHandler.php | 19 +- lib/SP/Providers/Log/SyslogHandler.php | 17 +- lib/SP/Providers/Mail/MailHandler.php | 54 +- lib/SP/Providers/Mail/MailParams.php | 18 +- lib/SP/Providers/Mail/MailProvider.php | 26 +- .../Providers/Mail/MailProviderException.php | 4 +- .../Notification/NotificationHandler.php | 35 +- lib/SP/Providers/Provider.php | 6 +- .../Account/AccountFileRepository.php | 58 +- .../Account/AccountHistoryRepository.php | 46 +- .../Account/AccountRepository.php | 110 +- .../Account/AccountToFavoriteRepository.php | 10 +- .../Account/AccountToTagRepository.php | 12 +- .../Account/AccountToUserGroupRepository.php | 26 +- .../Account/AccountToUserRepository.php | 28 +- .../AuthToken/AuthTokenRepository.php | 74 +- .../Category/CategoryRepository.php | 44 +- .../Repositories/Client/ClientRepository.php | 56 +- .../Repositories/Config/ConfigRepository.php | 22 +- .../CustomField/CustomFieldDefCollection.php | 4 +- .../CustomField/CustomFieldDefRepository.php | 52 +- .../CustomField/CustomFieldRepository.php | 80 +- .../CustomField/CustomFieldTypeRepository.php | 42 +- .../Repositories/DuplicatedItemException.php | 4 +- .../EventLog/EventlogRepository.php | 12 +- .../ItemPreset/ItemPresetRepository.php | 47 +- lib/SP/Repositories/NoSuchItemException.php | 4 +- .../Notification/NotificationRepository.php | 108 +- .../Repositories/Plugin/PluginDataModel.php | 4 +- .../Plugin/PluginDataRepository.php | 91 +- lib/SP/Repositories/Plugin/PluginModel.php | 4 +- .../Repositories/Plugin/PluginRepository.php | 89 +- .../PublicLink/PublicLinkRepository.php | 50 +- lib/SP/Repositories/Repository.php | 20 +- ...mInterface.php => RepositoryInterface.php} | 33 +- lib/SP/Repositories/RepositoryItemTrait.php | 52 +- lib/SP/Repositories/Tag/TagRepository.php | 52 +- lib/SP/Repositories/Track/TrackRepository.php | 20 +- lib/SP/Repositories/Track/TrackRequest.php | 43 +- .../User/UserPassRecoverRepository.php | 26 +- lib/SP/Repositories/User/UserRepository.php | 120 +- .../UserGroup/UserGroupRepository.php | 64 +- .../UserGroup/UserToUserGroupRepository.php | 28 +- .../UserProfile/UserProfileRepository.php | 64 +- lib/SP/Services/Account/AccountAcl.php | 447 +- lib/SP/Services/Account/AccountAclService.php | 148 +- .../Services/Account/AccountBulkRequest.php | 39 +- .../Services/Account/AccountCryptService.php | 44 +- .../Services/Account/AccountFileService.php | 76 +- lib/SP/Services/Account/AccountFilterUser.php | 53 +- .../Account/AccountHistoryService.php | 96 +- lib/SP/Services/Account/AccountInterface.php | 56 - .../Account/AccountPasswordRequest.php | 24 +- .../Services/Account/AccountPresetService.php | 31 +- lib/SP/Services/Account/AccountRequest.php | 139 +- .../Services/Account/AccountSearchFilter.php | 297 +- lib/SP/Services/Account/AccountSearchItem.php | 315 +- .../Services/Account/AccountSearchService.php | 273 +- lib/SP/Services/Account/AccountService.php | 320 +- .../Account/AccountServiceInterface.php | 6 +- .../Account/AccountToFavoriteService.php | 32 +- .../Services/Account/AccountToTagService.php | 25 +- lib/SP/Services/Api/ApiRequest.php | 76 +- lib/SP/Services/Api/ApiRequestData.php | 4 +- lib/SP/Services/Api/ApiRequestException.php | 4 +- lib/SP/Services/Api/ApiResponse.php | 41 +- lib/SP/Services/Api/ApiService.php | 187 +- lib/SP/Services/Api/JsonRpcResponse.php | 44 +- lib/SP/Services/Auth/AuthException.php | 4 +- lib/SP/Services/Auth/LoginResponse.php | 30 +- lib/SP/Services/Auth/LoginService.php | 148 +- .../Services/AuthToken/AuthTokenService.php | 166 +- lib/SP/Services/Backup/FileBackupService.php | 132 +- lib/SP/Services/Category/CategoryService.php | 65 +- lib/SP/Services/Client/ClientService.php | 87 +- .../Services/Config/ConfigBackupService.php | 49 +- lib/SP/Services/Config/ConfigService.php | 76 +- lib/SP/Services/Crypt/MasterPassService.php | 64 +- .../Services/Crypt/SecureSessionService.php | 56 +- .../Crypt/TemporaryMasterPassService.php | 143 +- .../Crypt/UpdateMasterPassRequest.php | 74 +- .../CustomField/CustomFieldCryptService.php | 92 +- .../CustomField/CustomFieldDefService.php | 128 +- .../Services/CustomField/CustomFieldItem.php | 8 +- .../CustomField/CustomFieldService.php | 155 +- .../CustomField/CustomFieldTypeService.php | 26 +- lib/SP/Services/EventLog/EventlogService.php | 29 +- lib/SP/Services/Export/VerifyResult.php | 35 +- lib/SP/Services/Export/XmlExportService.php | 231 +- lib/SP/Services/Export/XmlVerifyService.php | 107 +- lib/SP/Services/Import/CsvImport.php | 9 +- lib/SP/Services/Import/CsvImportBase.php | 78 +- lib/SP/Services/Import/FileImport.php | 58 +- lib/SP/Services/Import/ImportException.php | 4 +- lib/SP/Services/Import/ImportInterface.php | 8 +- lib/SP/Services/Import/ImportParams.php | 83 +- lib/SP/Services/Import/ImportService.php | 56 +- lib/SP/Services/Import/ImportTrait.php | 139 +- lib/SP/Services/Import/KeepassImport.php | 60 +- lib/SP/Services/Import/SyspassImport.php | 132 +- lib/SP/Services/Import/XmlFileImport.php | 33 +- lib/SP/Services/Import/XmlImport.php | 53 +- lib/SP/Services/Import/XmlImportBase.php | 57 +- lib/SP/Services/Import/XmlImportTrait.php | 91 - .../Install/DatabaseSetupInterface.php | 6 +- lib/SP/Services/Install/InstallData.php | 229 +- lib/SP/Services/Install/Installer.php | 96 +- lib/SP/Services/Install/MySQL.php | 76 +- .../ItemPreset/ItemPresetInterface.php | 13 +- .../Services/ItemPreset/ItemPresetRequest.php | 24 +- .../Services/ItemPreset/ItemPresetService.php | 96 +- lib/SP/Services/Ldap/LdapCheckService.php | 52 +- lib/SP/Services/Ldap/LdapImportParams.php | 34 +- lib/SP/Services/Ldap/LdapImportService.php | 91 +- lib/SP/Services/Mail/MailService.php | 96 +- .../Notification/NotificationService.php | 177 +- lib/SP/Services/Plugin/PluginDataService.php | 114 +- lib/SP/Services/Plugin/PluginService.php | 143 +- lib/SP/Services/PublicLink/PublicLinkKey.php | 31 +- .../Services/PublicLink/PublicLinkService.php | 180 +- lib/SP/Services/Service.php | 50 +- lib/SP/Services/ServiceException.php | 4 +- lib/SP/Services/ServiceItemInterface.php | 38 - lib/SP/Services/ServiceItemTrait.php | 10 +- lib/SP/Services/Tag/TagService.php | 80 +- lib/SP/Services/Task/Task.php | 138 +- lib/SP/Services/Task/TaskFactory.php | 57 +- lib/SP/Services/Task/TaskService.php | 81 +- lib/SP/Services/Track/TrackService.php | 80 +- lib/SP/Services/Upgrade/UpgradeAppService.php | 46 +- lib/SP/Services/Upgrade/UpgradeAuthToken.php | 56 +- .../Services/Upgrade/UpgradeConfigService.php | 127 +- .../Upgrade/UpgradeCustomFieldData.php | 34 +- .../Upgrade/UpgradeCustomFieldDefinition.php | 181 +- .../Upgrade/UpgradeDatabaseService.php | 85 +- lib/SP/Services/Upgrade/UpgradeException.php | 4 +- lib/SP/Services/Upgrade/UpgradeInterface.php | 21 +- lib/SP/Services/Upgrade/UpgradePlugin.php | 12 +- lib/SP/Services/Upgrade/UpgradePublicLink.php | 85 +- lib/SP/Services/Upgrade/UpgradeUtil.php | 47 +- lib/SP/Services/User/UpdatePassRequest.php | 51 +- .../User/UpdatedMasterPassException.php | 20 +- lib/SP/Services/User/UserLoginRequest.php | 79 +- lib/SP/Services/User/UserLoginResponse.php | 420 +- lib/SP/Services/User/UserPassResponse.php | 72 +- lib/SP/Services/User/UserPassService.php | 143 +- lib/SP/Services/User/UserService.php | 228 +- .../Services/UserGroup/UserGroupService.php | 143 +- .../UserGroup/UserToUserGroupService.php | 81 +- .../UserPassRecoverService.php | 88 +- .../UserProfile/UserProfileService.php | 107 +- lib/SP/Services/Wiki/DokuWikiApi.php | 280 - lib/SP/Services/Wiki/DokuWikiApiBase.php | 233 - lib/SP/Services/Wiki/DokuWikiApiParse.php | 38 - .../Storage/Database/DBStorageInterface.php | 4 +- lib/SP/Storage/Database/Database.php | 206 +- .../Database/DatabaseConnectionData.php | 106 +- lib/SP/Storage/Database/DatabaseException.php | 4 +- .../Database/DatabaseFileInterface.php | 10 +- lib/SP/Storage/Database/DatabaseInterface.php | 50 +- lib/SP/Storage/Database/DatabaseUtil.php | 50 +- lib/SP/Storage/Database/MySQLFileParser.php | 37 +- lib/SP/Storage/Database/MySQLHandler.php | 48 +- lib/SP/Storage/Database/QueryData.php | 187 +- lib/SP/Storage/Database/QueryResult.php | 96 +- lib/SP/Storage/File/ArchiveHandler.php | 58 +- lib/SP/Storage/File/FileCache.php | 8 +- lib/SP/Storage/File/FileCacheBase.php | 45 +- lib/SP/Storage/File/FileCacheInterface.php | 22 +- lib/SP/Storage/File/FileCachePacked.php | 18 +- lib/SP/Storage/File/FileException.php | 4 +- lib/SP/Storage/File/FileHandler.php | 141 +- .../Storage/File/XmlFileStorageInterface.php | 19 +- lib/SP/Storage/File/XmlHandler.php | 102 +- lib/SP/Util/ArrayUtil.php | 30 +- lib/SP/Util/Checks.php | 8 +- lib/SP/Util/Connection.php | 82 +- lib/SP/Util/ConnectionInterface.php | 20 +- lib/SP/Util/DateUtil.php | 8 +- lib/SP/Util/ErrorUtil.php | 63 +- lib/SP/Util/FileUtil.php | 29 +- lib/SP/Util/Filter.php | 69 +- lib/SP/Util/HttpUtil.php | 29 +- lib/SP/Util/ImageUtil.php | 35 +- lib/SP/Util/Link.php | 23 +- lib/SP/Util/PasswordUtil.php | 37 +- lib/SP/Util/Util.php | 101 +- lib/SP/Util/VersionUtil.php | 24 +- tests/SP/Core/Crypt/CryptPKITest.php | 2 +- tests/SP/DatabaseTrait.php | 11 - tests/SP/Modules/Cli/CliTestCase.php | 12 +- .../SP/Repositories/AccountRepositoryTest.php | 4 +- .../SP/Repositories/ClientRepositoryTest.php | 8 +- tests/SP/Repositories/TagRepositoryTest.php | 6 +- tests/SP/Repositories/TrackRepositoryTest.php | 9 +- .../Repositories/UserGroupRepositoryTest.php | 4 +- .../UserProfileRepositoryTest.php | 2 +- tests/SP/Repositories/UserRepositoryTest.php | 2 +- .../Account/AccountAclServiceTest.php | 2 +- .../Account/AccountSearchServiceTest.php | 2 +- .../Config/ConfigBackupServiceTest.php | 5 +- .../SP/Services/Plugin/PluginServiceTest.php | 16 +- .../PublicLink/PublicLinkServiceTest.php | 4 +- tests/SP/Services/Track/TrackServiceTest.php | 14 +- tests/SP/Services/User/UserServiceTest.php | 11 +- tests/SP/WebTestCase.php | 42 +- tests/SP/bootstrap.php | 2 +- tests/phpunit.xml | 6 +- tests/res/config/config.xml | 18 +- 638 files changed, 21764 insertions(+), 22315 deletions(-) delete mode 100644 lib/SP/Config/ConfigCache.php create mode 100644 lib/SP/Config/ConfigDataInterface.php delete mode 100644 lib/SP/Config/ConfigInterface.php rename lib/SP/Repositories/{RepositoryItemInterface.php => RepositoryInterface.php} (73%) delete mode 100644 lib/SP/Services/Account/AccountInterface.php delete mode 100644 lib/SP/Services/Import/XmlImportTrait.php delete mode 100644 lib/SP/Services/ServiceItemInterface.php delete mode 100644 lib/SP/Services/Wiki/DokuWikiApi.php delete mode 100644 lib/SP/Services/Wiki/DokuWikiApiBase.php delete mode 100644 lib/SP/Services/Wiki/DokuWikiApiParse.php diff --git a/api.php b/api.php index 6d73daf3..80988ac6 100644 --- a/api.php +++ b/api.php @@ -22,7 +22,7 @@ * along with sysPass. If not, see . */ -define('APP_ROOT', __DIR__); -define('APP_MODULE', 'api'); +const APP_ROOT = __DIR__; +const APP_MODULE = 'api'; require APP_ROOT . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'Base.php'; diff --git a/app/modules/api/Controllers/AccountController.php b/app/modules/api/Controllers/AccountController.php index 103638e9..f0d6d9e9 100644 --- a/app/modules/api/Controllers/AccountController.php +++ b/app/modules/api/Controllers/AccountController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers; @@ -54,19 +54,13 @@ final class AccountController extends ControllerBase { use ItemTrait; - /** - * @var AccountPresetService - */ - private $accountPresetService; - /** - * @var AccountService - */ - private $accountService; + private ?AccountPresetService $accountPresetService = null; + private ?AccountService $accountService = null; /** * viewAction */ - public function viewAction() + public function viewAction(): void { try { @@ -90,12 +84,16 @@ final class AccountController extends ControllerBase ->withUserGroupsById($accountResponse) ->withTagsById($accountResponse); - $this->eventDispatcher->notifyEvent('show.account', - new Event($this, EventMessage::factory() - ->addDescription(__u('Account displayed')) - ->addDetail(__u('Name'), $accountDetails->getName()) - ->addDetail(__u('Client'), $accountDetails->getClientName()) - ->addDetail('ID', $id)) + $this->eventDispatcher->notifyEvent( + 'show.account', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Account displayed')) + ->addDetail(__u('Name'), $accountDetails->getName()) + ->addDetail(__u('Client'), $accountDetails->getClientName()) + ->addDetail('ID', $id) + ) ); $adapter = new AccountAdapter($this->configData); @@ -107,7 +105,9 @@ final class AccountController extends ControllerBase $this->fractal->parseIncludes(['customFields']); } - $this->returnResponse(ApiResponse::makeSuccess($out->toArray(), $id)); + $this->returnResponse( + ApiResponse::makeSuccess($out->toArray(), $id) + ); } catch (Exception $e) { $this->returnResponseException($e); @@ -118,28 +118,38 @@ final class AccountController extends ControllerBase /** * viewPassAction */ - public function viewPassAction() + public function viewPassAction(): void { try { $this->setupApi(ActionsInterface::ACCOUNT_VIEW_PASS); $id = $this->apiService->getParamInt('id', true); $accountPassData = $this->accountService->getPasswordForId($id); - $password = Crypt::decrypt($accountPassData->getPass(), $accountPassData->getKey(), $this->apiService->getMasterPass()); + $password = Crypt::decrypt( + $accountPassData->getPass(), + $accountPassData->getKey(), + $this->apiService->getMasterPass() + ); $this->accountService->incrementDecryptCounter($id); $accountDetails = $this->accountService->getById($id)->getAccountVData(); - $this->eventDispatcher->notifyEvent('show.account.pass', - new Event($this, EventMessage::factory() - ->addDescription(__u('Password viewed')) - ->addDetail(__u('Name'), $accountDetails->getName()) - ->addDetail(__u('Client'), $accountDetails->getClientName()) - ->addDetail('ID', $id)) + $this->eventDispatcher->notifyEvent( + 'show.account.pass', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Password viewed')) + ->addDetail(__u('Name'), $accountDetails->getName()) + ->addDetail(__u('Client'), $accountDetails->getClientName()) + ->addDetail('ID', $id) + ) ); - $this->returnResponse(ApiResponse::makeSuccess(["password" => $password], $id)); + $this->returnResponse( + ApiResponse::makeSuccess(["password" => $password], $id) + ); } catch (Exception $e) { processException($e); @@ -150,7 +160,7 @@ final class AccountController extends ControllerBase /** * viewPassAction */ - public function editPassAction() + public function editPassAction(): void { try { $this->setupApi(ActionsInterface::ACCOUNT_EDIT_PASS); @@ -167,15 +177,25 @@ final class AccountController extends ControllerBase $accountDetails = $this->accountService->getById($accountRequest->id)->getAccountVData(); - $this->eventDispatcher->notifyEvent('edit.account.pass', - new Event($this, EventMessage::factory() - ->addDescription(__u('Password updated')) - ->addDetail(__u('Name'), $accountDetails->getName()) - ->addDetail(__u('Client'), $accountDetails->getClientName()) - ->addDetail('ID', $accountDetails->getId())) + $this->eventDispatcher->notifyEvent( + 'edit.account.pass', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Password updated')) + ->addDetail(__u('Name'), $accountDetails->getName()) + ->addDetail(__u('Client'), $accountDetails->getClientName()) + ->addDetail('ID', $accountDetails->getId()) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($accountDetails, $accountRequest->id, __('Password updated'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $accountDetails, + $accountRequest->id, + __('Password updated') + ) + ); } catch (Exception $e) { processException($e); @@ -186,7 +206,7 @@ final class AccountController extends ControllerBase /** * createAction */ - public function createAction() + public function createAction(): void { try { $this->setupApi(ActionsInterface::ACCOUNT_CREATE); @@ -217,15 +237,25 @@ final class AccountController extends ControllerBase $accountDetails = $this->accountService->getById($accountId)->getAccountVData(); - $this->eventDispatcher->notifyEvent('create.account', - new Event($this, EventMessage::factory() - ->addDescription(__u('Account created')) - ->addDetail(__u('Name'), $accountDetails->getName()) - ->addDetail(__u('Client'), $accountDetails->getClientName()) - ->addDetail('ID', $accountDetails->getId())) + $this->eventDispatcher->notifyEvent( + 'create.account', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Account created')) + ->addDetail(__u('Name'), $accountDetails->getName()) + ->addDetail(__u('Client'), $accountDetails->getClientName()) + ->addDetail('ID', $accountDetails->getId()) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($accountDetails, $accountId, __('Account created'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $accountDetails, + $accountId, + __('Account created') + ) + ); } catch (Exception $e) { processException($e); @@ -236,7 +266,7 @@ final class AccountController extends ControllerBase /** * editAction */ - public function editAction() + public function editAction(): void { try { $this->setupApi(ActionsInterface::ACCOUNT_EDIT); @@ -259,7 +289,7 @@ final class AccountController extends ControllerBase $tagsId = array_map('intval', $this->apiService->getParamArray('tagsId', false, [])); - if (!empty($tagsId)) { + if (count($tagsId) !== 0) { $accountRequest->updateTags = true; $accountRequest->tags = $tagsId; } @@ -268,15 +298,25 @@ final class AccountController extends ControllerBase $accountDetails = $this->accountService->getById($accountRequest->id)->getAccountVData(); - $this->eventDispatcher->notifyEvent('edit.account', - new Event($this, EventMessage::factory() - ->addDescription(__u('Account updated')) - ->addDetail(__u('Name'), $accountDetails->getName()) - ->addDetail(__u('Client'), $accountDetails->getClientName()) - ->addDetail('ID', $accountDetails->getId())) + $this->eventDispatcher->notifyEvent( + 'edit.account', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Account updated')) + ->addDetail(__u('Name'), $accountDetails->getName()) + ->addDetail(__u('Client'), $accountDetails->getClientName()) + ->addDetail('ID', $accountDetails->getId()) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($accountDetails, $accountRequest->id, __('Account updated'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $accountDetails, + $accountRequest->id, + __('Account updated') + ) + ); } catch (Exception $e) { processException($e); @@ -287,7 +327,7 @@ final class AccountController extends ControllerBase /** * searchAction */ - public function searchAction() + public function searchAction(): void { try { $this->setupApi(ActionsInterface::ACCOUNT_SEARCH); @@ -299,7 +339,7 @@ final class AccountController extends ControllerBase $tagsId = array_map('intval', $this->apiService->getParamArray('tagsId', false, [])); - if (!empty($tagsId)) { + if (count($tagsId) !== 0) { $accountSearchFilter->setTagsId($tagsId); } @@ -321,7 +361,9 @@ final class AccountController extends ControllerBase $this->returnResponse( ApiResponse::makeSuccess( - $this->accountService->getByFilter($accountSearchFilter)->getDataAsArray())); + $this->accountService->getByFilter($accountSearchFilter)->getDataAsArray() + ) + ); } catch (Exception $e) { processException($e); @@ -332,7 +374,7 @@ final class AccountController extends ControllerBase /** * deleteAction */ - public function deleteAction() + public function deleteAction(): void { try { $this->setupApi(ActionsInterface::ACCOUNT_DELETE); @@ -343,15 +385,25 @@ final class AccountController extends ControllerBase $this->accountService->delete($id); - $this->eventDispatcher->notifyEvent('delete.account', - new Event($this, EventMessage::factory() - ->addDescription(__u('Account removed')) - ->addDetail(__u('Name'), $accountDetails->getName()) - ->addDetail(__u('Client'), $accountDetails->getClientName()) - ->addDetail('ID', $id)) + $this->eventDispatcher->notifyEvent( + 'delete.account', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Account removed')) + ->addDetail(__u('Name'), $accountDetails->getName()) + ->addDetail(__u('Client'), $accountDetails->getClientName()) + ->addDetail('ID', $id) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($accountDetails, $id, __('Account removed'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $accountDetails, + $id, + __('Account removed') + ) + ); } catch (Exception $e) { processException($e); @@ -364,7 +416,7 @@ final class AccountController extends ControllerBase * @throws NotFoundException * @throws InvalidClassException */ - protected function initialize() + protected function initialize(): void { $this->accountService = $this->dic->get(AccountService::class); $this->accountPresetService = $this->dic->get(AccountPresetService::class); diff --git a/app/modules/api/Controllers/CategoryController.php b/app/modules/api/Controllers/CategoryController.php index b1260d4b..4223ec1d 100644 --- a/app/modules/api/Controllers/CategoryController.php +++ b/app/modules/api/Controllers/CategoryController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers; @@ -51,15 +51,12 @@ final class CategoryController extends ControllerBase { use ItemTrait; - /** - * @var CategoryService - */ - private $categoryService; + private ?CategoryService $categoryService = null; /** * viewAction */ - public function viewAction() + public function viewAction(): void { try { $this->setupApi(ActionsInterface::CATEGORY_VIEW); @@ -71,11 +68,15 @@ final class CategoryController extends ControllerBase $categoryData = $this->categoryService->getById($id); - $this->eventDispatcher->notifyEvent('show.category', - new Event($this, EventMessage::factory() - ->addDescription(__u('Category displayed')) - ->addDetail(__u('Name'), $categoryData->getName()) - ->addDetail('ID', $id)) + $this->eventDispatcher->notifyEvent( + 'show.category', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Category displayed')) + ->addDetail(__u('Name'), $categoryData->getName()) + ->addDetail('ID', $id) + ) ); $out = $this->fractal @@ -87,7 +88,9 @@ final class CategoryController extends ControllerBase $this->fractal->parseIncludes(['customFields']); } - $this->returnResponse(ApiResponse::makeSuccess($out->toArray(), $id)); + $this->returnResponse( + ApiResponse::makeSuccess($out->toArray(), $id) + ); } catch (Exception $e) { processException($e); @@ -98,7 +101,7 @@ final class CategoryController extends ControllerBase /** * createAction */ - public function createAction() + public function createAction(): void { try { $this->setupApi(ActionsInterface::CATEGORY_CREATE); @@ -109,14 +112,24 @@ final class CategoryController extends ControllerBase $id = $this->categoryService->create($categoryData); - $this->eventDispatcher->notifyEvent('create.category', - new Event($this, EventMessage::factory() - ->addDescription(__u('Category added')) - ->addDetail(__u('Name'), $categoryData->getName()) - ->addDetail('ID', $id)) + $this->eventDispatcher->notifyEvent( + 'create.category', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Category added')) + ->addDetail(__u('Name'), $categoryData->getName()) + ->addDetail('ID', $id) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($categoryData, $id, __('Category added'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $categoryData, + $id, + __('Category added') + ) + ); } catch (Exception $e) { processException($e); @@ -127,7 +140,7 @@ final class CategoryController extends ControllerBase /** * editAction */ - public function editAction() + public function editAction(): void { try { $this->setupApi(ActionsInterface::CATEGORY_EDIT); @@ -139,14 +152,24 @@ final class CategoryController extends ControllerBase $this->categoryService->update($categoryData); - $this->eventDispatcher->notifyEvent('edit.category', - new Event($this, EventMessage::factory() - ->addDescription(__u('Category updated')) - ->addDetail(__u('Name'), $categoryData->getName()) - ->addDetail('ID', $categoryData->getId())) + $this->eventDispatcher->notifyEvent( + 'edit.category', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Category updated')) + ->addDetail(__u('Name'), $categoryData->getName()) + ->addDetail('ID', $categoryData->getId()) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($categoryData, $categoryData->getId(), __('Category updated'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $categoryData, + $categoryData->getId(), + __('Category updated') + ) + ); } catch (Exception $e) { processException($e); @@ -157,7 +180,7 @@ final class CategoryController extends ControllerBase /** * deleteAction */ - public function deleteAction() + public function deleteAction(): void { try { $this->setupApi(ActionsInterface::CATEGORY_DELETE); @@ -168,14 +191,24 @@ final class CategoryController extends ControllerBase $this->categoryService->delete($id); - $this->eventDispatcher->notifyEvent('delete.category', - new Event($this, EventMessage::factory() - ->addDescription(__u('Category deleted')) - ->addDetail(__u('Name'), $categoryData->getName()) - ->addDetail('ID', $categoryData->getId())) + $this->eventDispatcher->notifyEvent( + 'delete.category', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Category deleted')) + ->addDetail(__u('Name'), $categoryData->getName()) + ->addDetail('ID', $categoryData->getId()) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($categoryData, $id, __('Category deleted'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $categoryData, + $id, + __('Category deleted') + ) + ); } catch (Exception $e) { processException($e); @@ -186,7 +219,7 @@ final class CategoryController extends ControllerBase /** * searchAction */ - public function searchAction() + public function searchAction(): void { try { $this->setupApi(ActionsInterface::CATEGORY_SEARCH); @@ -197,7 +230,11 @@ final class CategoryController extends ControllerBase $this->eventDispatcher->notifyEvent('search.category', new Event($this)); - $this->returnResponse(ApiResponse::makeSuccess($this->categoryService->search($itemSearchData)->getDataAsArray())); + $this->returnResponse( + ApiResponse::makeSuccess( + $this->categoryService->search($itemSearchData)->getDataAsArray() + ) + ); } catch (Exception $e) { processException($e); @@ -212,7 +249,7 @@ final class CategoryController extends ControllerBase * @throws NotFoundException * @throws InvalidClassException */ - protected function initialize() + protected function initialize(): void { $this->categoryService = $this->dic->get(CategoryService::class); $this->apiService->setHelpClass(CategoryHelp::class); diff --git a/app/modules/api/Controllers/ClientController.php b/app/modules/api/Controllers/ClientController.php index 089924ab..0453ac31 100644 --- a/app/modules/api/Controllers/ClientController.php +++ b/app/modules/api/Controllers/ClientController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers; @@ -50,15 +50,12 @@ final class ClientController extends ControllerBase { use ItemTrait; - /** - * @var ClientService - */ - private $clientService; + private ?ClientService $clientService = null; /** * viewAction */ - public function viewAction() + public function viewAction(): void { try { $this->setupApi(ActionsInterface::CLIENT_VIEW); @@ -71,11 +68,15 @@ final class ClientController extends ControllerBase $this->eventDispatcher->notifyEvent('show.client', new Event($this)); - $this->eventDispatcher->notifyEvent('show.client', - new Event($this, EventMessage::factory() - ->addDescription(__u('Client displayed')) - ->addDetail(__u('Name'), $clientData->getName()) - ->addDetail('ID', $id)) + $this->eventDispatcher->notifyEvent( + 'show.client', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Client displayed')) + ->addDetail(__u('Name'), $clientData->getName()) + ->addDetail('ID', $id) + ) ); if ($customFields) { @@ -91,7 +92,9 @@ final class ClientController extends ControllerBase $this->fractal->parseIncludes(['customFields']); } - $this->returnResponse(ApiResponse::makeSuccess($out->toArray(), $id)); + $this->returnResponse( + ApiResponse::makeSuccess($out->toArray(), $id) + ); } catch (Exception $e) { processException($e); @@ -102,7 +105,7 @@ final class ClientController extends ControllerBase /** * createAction */ - public function createAction() + public function createAction(): void { try { $this->setupApi(ActionsInterface::CLIENT_CREATE); @@ -114,14 +117,24 @@ final class ClientController extends ControllerBase $id = $this->clientService->create($clientData); - $this->eventDispatcher->notifyEvent('create.client', - new Event($this, EventMessage::factory() - ->addDescription(__u('Client added')) - ->addDetail(__u('Name'), $clientData->getName()) - ->addDetail('ID', $id)) + $this->eventDispatcher->notifyEvent( + 'create.client', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Client added')) + ->addDetail(__u('Name'), $clientData->getName()) + ->addDetail('ID', $id) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($clientData, $id, __('Client added'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $clientData, + $id, + __('Client added') + ) + ); } catch (Exception $e) { processException($e); @@ -132,7 +145,7 @@ final class ClientController extends ControllerBase /** * editAction */ - public function editAction() + public function editAction(): void { try { $this->setupApi(ActionsInterface::CLIENT_EDIT); @@ -145,14 +158,24 @@ final class ClientController extends ControllerBase $this->clientService->update($clientData); - $this->eventDispatcher->notifyEvent('edit.client', - new Event($this, EventMessage::factory() - ->addDescription(__u('Client updated')) - ->addDetail(__u('Name'), $clientData->getName()) - ->addDetail('ID', $clientData->getId())) + $this->eventDispatcher->notifyEvent( + 'edit.client', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Client updated')) + ->addDetail(__u('Name'), $clientData->getName()) + ->addDetail('ID', $clientData->getId()) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($clientData, $clientData->getId(), __('Client updated'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $clientData, + $clientData->getId(), + __('Client updated') + ) + ); } catch (Exception $e) { processException($e); @@ -163,7 +186,7 @@ final class ClientController extends ControllerBase /** * deleteAction */ - public function deleteAction() + public function deleteAction(): void { try { $this->setupApi(ActionsInterface::CLIENT_DELETE); @@ -174,14 +197,24 @@ final class ClientController extends ControllerBase $this->clientService->delete($id); - $this->eventDispatcher->notifyEvent('delete.client', - new Event($this, EventMessage::factory() - ->addDescription(__u('Client deleted')) - ->addDetail(__u('Name'), $clientData->getName()) - ->addDetail('ID', $id)) + $this->eventDispatcher->notifyEvent( + 'delete.client', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Client deleted')) + ->addDetail(__u('Name'), $clientData->getName()) + ->addDetail('ID', $id) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($clientData, $id, __('Client deleted'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $clientData, + $id, + __('Client deleted') + ) + ); } catch (Exception $e) { $this->returnResponseException($e); @@ -192,7 +225,7 @@ final class ClientController extends ControllerBase /** * searchAction */ - public function searchAction() + public function searchAction(): void { try { $this->setupApi(ActionsInterface::CLIENT_SEARCH); @@ -203,7 +236,11 @@ final class ClientController extends ControllerBase $this->eventDispatcher->notifyEvent('search.client', new Event($this)); - $this->returnResponse(ApiResponse::makeSuccess($this->clientService->search($itemSearchData)->getDataAsArray())); + $this->returnResponse( + ApiResponse::makeSuccess( + $this->clientService->search($itemSearchData)->getDataAsArray() + ) + ); } catch (Exception $e) { processException($e); @@ -216,7 +253,7 @@ final class ClientController extends ControllerBase * @throws NotFoundException * @throws InvalidClassException */ - protected function initialize() + protected function initialize(): void { $this->clientService = $this->dic->get(ClientService::class); $this->apiService->setHelpClass(ClientHelp::class); diff --git a/app/modules/api/Controllers/ConfigController.php b/app/modules/api/Controllers/ConfigController.php index bc74ca7d..78da2558 100644 --- a/app/modules/api/Controllers/ConfigController.php +++ b/app/modules/api/Controllers/ConfigController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers; @@ -44,7 +44,7 @@ final class ConfigController extends ControllerBase /** * backupAction */ - public function backupAction() + public function backupAction(): void { try { $this->setupApi(ActionsInterface::CONFIG_BACKUP_RUN); @@ -54,13 +54,23 @@ final class ConfigController extends ControllerBase $this->dic->get(FileBackupService::class) ->doBackup($path); - $this->eventDispatcher->notifyEvent('run.backup.end', - new Event($this, EventMessage::factory() - ->addDescription(__u('Application and database backup completed successfully')) - ->addDetail(__u('Path'), $path)) + $this->eventDispatcher->notifyEvent( + 'run.backup.end', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Application and database backup completed successfully')) + ->addDetail(__u('Path'), $path) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($path, null, __('Backup process finished'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $path, + null, + __('Backup process finished') + ) + ); } catch (Exception $e) { processException($e); @@ -71,7 +81,7 @@ final class ConfigController extends ControllerBase /** * exportAction */ - public function exportAction() + public function exportAction(): void { try { $this->setupApi(ActionsInterface::CONFIG_EXPORT_RUN); @@ -79,21 +89,35 @@ final class ConfigController extends ControllerBase $password = $this->apiService->getParamString('password'); $path = $this->apiService->getParamString('path', false, BACKUP_PATH); - $this->eventDispatcher->notifyEvent('run.export.start', - new Event($this, EventMessage::factory() - ->addDescription(__u('sysPass XML export')) - ->addDetail(__u('Path'), $path)) + $this->eventDispatcher->notifyEvent( + 'run.export.start', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('sysPass XML export')) + ->addDetail(__u('Path'), $path) + ) ); $this->dic->get(XmlExportService::class) ->doExport($path, $password); - $this->eventDispatcher->notifyEvent('run.export.end', - new Event($this, EventMessage::factory() - ->addDescription(__u('Export process finished'))) + $this->eventDispatcher->notifyEvent( + 'run.export.end', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Export process finished')) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($path, null, __('Export process finished'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $path, + null, + __('Export process finished') + ) + ); } catch (Exception $e) { processException($e); @@ -104,7 +128,7 @@ final class ConfigController extends ControllerBase /** * @throws InvalidClassException */ - protected function initialize() + protected function initialize(): void { $this->apiService->setHelpClass(ConfigHelp::class); } diff --git a/app/modules/api/Controllers/ControllerBase.php b/app/modules/api/Controllers/ControllerBase.php index 1b6ecc44..ac030574 100644 --- a/app/modules/api/Controllers/ControllerBase.php +++ b/app/modules/api/Controllers/ControllerBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,19 +19,17 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers; -use DI\Container; -use DI\DependencyException; -use DI\NotFoundException; use Exception; use Klein\Klein; use League\Fractal\Manager; use Psr\Container\ContainerInterface; use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Acl\Acl; use SP\Core\Context\StatelessContext; use SP\Core\Events\EventDispatcher; @@ -49,62 +47,23 @@ use SP\Services\ServiceException; */ abstract class ControllerBase { - const SEARCH_COUNT_ITEMS = 25; - /** - * @var ContainerInterface - */ - protected $dic; - /** - * @var string - */ - protected $controllerName; - /** - * @var - */ - protected $actionName; - /** - * @var StatelessContext - */ - protected $context; - /** - * @var EventDispatcher - */ - protected $eventDispatcher; - /** - * @var ApiService - */ - protected $apiService; - /** - * @var Klein - */ - protected $router; - /** - * @var ConfigData - */ - protected $configData; - /** - * @var Manager - */ - protected $fractal; - /** - * @var Acl - */ - protected $acl; - /** - * @var bool - */ - private $isAuthenticated = false; + protected const SEARCH_COUNT_ITEMS = 25; + protected ContainerInterface $dic; + protected string $controllerName; + protected string $actionName; + protected StatelessContext $context; + protected EventDispatcher $eventDispatcher; + protected ApiService $apiService; + protected Klein $router; + protected ConfigDataInterface $configData; + protected Manager $fractal; + protected Acl $acl; + private bool $isAuthenticated = false; - /** - * Constructor - * - * @param Container $container - * @param string $actionName - * - * @throws DependencyException - * @throws NotFoundException - */ - public final function __construct(Container $container, string $actionName) + final public function __construct( + ContainerInterface $container, + string $actionName + ) { $this->dic = $container; $this->context = $container->get(StatelessContext::class); @@ -123,31 +82,21 @@ abstract class ControllerBase } } - /** - * @return string - */ final protected function getControllerName(): string { $class = static::class; - return substr($class, strrpos($class, '\\') + 1, -strlen('Controller')) ?: ''; + return substr( + $class, + strrpos($class, '\\') + 1, + -strlen('Controller')) ?: ''; } /** - * @return bool - */ - protected function isAuthenticated(): bool - { - return $this->isAuthenticated; - } - - /** - * @param int $actionId - * * @throws SPException * @throws ServiceException */ - final protected function setupApi(int $actionId) + final protected function setupApi(int $actionId): void { $this->apiService->setup($actionId); @@ -158,17 +107,20 @@ abstract class ControllerBase * Devuelve una respuesta en formato JSON con el estado y el mensaje. * * {"jsonrpc": "2.0", "result": 19, "id": 3} - * - * @param ApiResponse $apiResponse */ - final protected function returnResponse(ApiResponse $apiResponse) + final protected function returnResponse(ApiResponse $apiResponse): void { try { if ($this->isAuthenticated === false) { throw new SPException(__u('Unauthorized access')); } - $this->sendJsonResponse(JsonRpcResponse::getResponse($apiResponse, $this->apiService->getRequestId())); + $this->sendJsonResponse( + JsonRpcResponse::getResponse( + $apiResponse, + $this->apiService->getRequestId() + ) + ); } catch (SPException $e) { processException($e); @@ -178,20 +130,20 @@ abstract class ControllerBase /** * Returns a JSON response back to the browser - * - * @param string $response */ - final private function sendJsonResponse(string $response) + private function sendJsonResponse(string $response): void { $json = Json::factory($this->router->response()); $json->returnRawJson($response); } - /** - * @param Exception $e - */ - final protected function returnResponseException(Exception $e) + final protected function returnResponseException(Exception $e): void { - $this->sendJsonResponse(JsonRpcResponse::getResponseException($e, $this->apiService->getRequestId())); + $this->sendJsonResponse( + JsonRpcResponse::getResponseException( + $e, + $this->apiService->getRequestId() + ) + ); } } \ No newline at end of file diff --git a/app/modules/api/Controllers/Help/AccountHelp.php b/app/modules/api/Controllers/Help/AccountHelp.php index 7b6b37db..3ecb6eb7 100644 --- a/app/modules/api/Controllers/Help/AccountHelp.php +++ b/app/modules/api/Controllers/Help/AccountHelp.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers\Help; diff --git a/app/modules/api/Controllers/Help/CategoryHelp.php b/app/modules/api/Controllers/Help/CategoryHelp.php index a7a7868e..1784b9b6 100644 --- a/app/modules/api/Controllers/Help/CategoryHelp.php +++ b/app/modules/api/Controllers/Help/CategoryHelp.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers\Help; diff --git a/app/modules/api/Controllers/Help/ClientHelp.php b/app/modules/api/Controllers/Help/ClientHelp.php index 4f6f2fdd..f785b225 100644 --- a/app/modules/api/Controllers/Help/ClientHelp.php +++ b/app/modules/api/Controllers/Help/ClientHelp.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers\Help; diff --git a/app/modules/api/Controllers/Help/ConfigHelp.php b/app/modules/api/Controllers/Help/ConfigHelp.php index 5a6342af..c41a0f32 100644 --- a/app/modules/api/Controllers/Help/ConfigHelp.php +++ b/app/modules/api/Controllers/Help/ConfigHelp.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers\Help; diff --git a/app/modules/api/Controllers/Help/HelpInterface.php b/app/modules/api/Controllers/Help/HelpInterface.php index e617dd25..b8cd6430 100644 --- a/app/modules/api/Controllers/Help/HelpInterface.php +++ b/app/modules/api/Controllers/Help/HelpInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers\Help; diff --git a/app/modules/api/Controllers/Help/HelpTrait.php b/app/modules/api/Controllers/Help/HelpTrait.php index bfee7b34..4bb3ac07 100644 --- a/app/modules/api/Controllers/Help/HelpTrait.php +++ b/app/modules/api/Controllers/Help/HelpTrait.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers\Help; @@ -39,7 +39,7 @@ trait HelpTrait public static function getHelpFor(string $action): array { if (strpos($action, '/') !== false) { - list(, $action) = explode('/', $action); + [, $action] = explode('/', $action); } if (method_exists(static::class, $action)) { @@ -61,8 +61,10 @@ trait HelpTrait private static function getItem( string $name, string $description, - bool $required = false): array + bool $required = false): array { - return [$name => ['description' => $description, 'required' => $required]]; + return [ + $name => ['description' => $description, 'required' => $required] + ]; } } \ No newline at end of file diff --git a/app/modules/api/Controllers/Help/TagHelp.php b/app/modules/api/Controllers/Help/TagHelp.php index c5da50ee..fffd2462 100644 --- a/app/modules/api/Controllers/Help/TagHelp.php +++ b/app/modules/api/Controllers/Help/TagHelp.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers\Help; diff --git a/app/modules/api/Controllers/Help/UserGroupHelp.php b/app/modules/api/Controllers/Help/UserGroupHelp.php index 10f4bf85..3d00000d 100644 --- a/app/modules/api/Controllers/Help/UserGroupHelp.php +++ b/app/modules/api/Controllers/Help/UserGroupHelp.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers\Help; diff --git a/app/modules/api/Controllers/TagController.php b/app/modules/api/Controllers/TagController.php index fb8706b3..377328b4 100644 --- a/app/modules/api/Controllers/TagController.php +++ b/app/modules/api/Controllers/TagController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers; @@ -44,15 +44,12 @@ use SP\Services\Tag\TagService; */ final class TagController extends ControllerBase { - /** - * @var TagService - */ - private $tagService; + private ?TagService $tagService = null; /** * viewAction */ - public function viewAction() + public function viewAction(): void { try { $this->setupApi(ActionsInterface::TAG_VIEW); @@ -60,11 +57,13 @@ final class TagController extends ControllerBase $id = $this->apiService->getParamInt('id', true); $tagData = $this->tagService->getById($id); - $this->eventDispatcher->notifyEvent('show.tag', + $this->eventDispatcher->notifyEvent( + 'show.tag', new Event($this, EventMessage::factory() ->addDescription(__u('Tag displayed')) ->addDetail(__u('Name'), $tagData->getName()) - ->addDetail('ID', $id)) + ->addDetail('ID', $id) + ) ); $this->returnResponse(ApiResponse::makeSuccess($tagData, $id)); @@ -78,7 +77,7 @@ final class TagController extends ControllerBase /** * createAction */ - public function createAction() + public function createAction(): void { try { $this->setupApi(ActionsInterface::TAG_CREATE); @@ -88,14 +87,24 @@ final class TagController extends ControllerBase $id = $this->tagService->create($tagData); - $this->eventDispatcher->notifyEvent('create.tag', - new Event($this, EventMessage::factory() - ->addDescription(__u('Tag added')) - ->addDetail(__u('Name'), $tagData->getName()) - ->addDetail('ID', $id)) + $this->eventDispatcher->notifyEvent( + 'create.tag', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Tag added')) + ->addDetail(__u('Name'), $tagData->getName()) + ->addDetail('ID', $id) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($tagData, $id, __('Tag added'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $tagData, + $id, + __('Tag added') + ) + ); } catch (Exception $e) { processException($e); @@ -106,7 +115,7 @@ final class TagController extends ControllerBase /** * editAction */ - public function editAction() + public function editAction(): void { try { $this->setupApi(ActionsInterface::TAG_EDIT); @@ -117,14 +126,24 @@ final class TagController extends ControllerBase $this->tagService->update($tagData); - $this->eventDispatcher->notifyEvent('edit.tag', - new Event($this, EventMessage::factory() - ->addDescription(__u('Tag updated')) - ->addDetail(__u('Name'), $tagData->getName()) - ->addDetail('ID', $tagData->getId())) + $this->eventDispatcher->notifyEvent( + 'edit.tag', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Tag updated')) + ->addDetail(__u('Name'), $tagData->getName()) + ->addDetail('ID', $tagData->getId()) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($tagData, $tagData->getId(), __('Tag updated'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $tagData, + $tagData->getId(), + __('Tag updated') + ) + ); } catch (Exception $e) { processException($e); @@ -135,7 +154,7 @@ final class TagController extends ControllerBase /** * deleteAction */ - public function deleteAction() + public function deleteAction(): void { try { $this->setupApi(ActionsInterface::TAG_DELETE); @@ -146,14 +165,24 @@ final class TagController extends ControllerBase $this->tagService->delete($id); - $this->eventDispatcher->notifyEvent('delete.tag', - new Event($this, EventMessage::factory() - ->addDescription(__u('Tag removed')) - ->addDetail(__u('Name'), $tagData->getName()) - ->addDetail('ID', $id)) + $this->eventDispatcher->notifyEvent( + 'delete.tag', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Tag removed')) + ->addDetail(__u('Name'), $tagData->getName()) + ->addDetail('ID', $id) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($tagData, $id, __('Tag removed'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $tagData, + $id, + __('Tag removed') + ) + ); } catch (Exception $e) { processException($e); @@ -164,7 +193,7 @@ final class TagController extends ControllerBase /** * searchAction */ - public function searchAction() + public function searchAction(): void { try { $this->setupApi(ActionsInterface::TAG_SEARCH); @@ -173,9 +202,16 @@ final class TagController extends ControllerBase $itemSearchData->setSeachString($this->apiService->getParamString('text')); $itemSearchData->setLimitCount($this->apiService->getParamInt('count', false, self::SEARCH_COUNT_ITEMS)); - $this->eventDispatcher->notifyEvent('search.tag', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'search.tag', + new Event($this) + ); - $this->returnResponse(ApiResponse::makeSuccess($this->tagService->search($itemSearchData)->getDataAsArray())); + $this->returnResponse( + ApiResponse::makeSuccess( + $this->tagService->search($itemSearchData)->getDataAsArray() + ) + ); } catch (Exception $e) { processException($e); @@ -184,11 +220,9 @@ final class TagController extends ControllerBase } /** - * @throws DependencyException - * @throws NotFoundException - * @throws InvalidClassException + * @throws \SP\Core\Exceptions\InvalidClassException */ - protected function initialize() + protected function initialize(): void { $this->tagService = $this->dic->get(TagService::class); $this->apiService->setHelpClass(TagHelp::class); diff --git a/app/modules/api/Controllers/UserGroupController.php b/app/modules/api/Controllers/UserGroupController.php index 6d7a964b..4b43f029 100644 --- a/app/modules/api/Controllers/UserGroupController.php +++ b/app/modules/api/Controllers/UserGroupController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api\Controllers; @@ -44,15 +44,12 @@ use SP\Services\UserGroup\UserGroupService; */ final class UserGroupController extends ControllerBase { - /** - * @var UserGroupService - */ - private $userGroupService; + private ?UserGroupService $userGroupService = null; /** * viewAction */ - public function viewAction() + public function viewAction(): void { try { $this->setupApi(ActionsInterface::GROUP_VIEW); @@ -60,14 +57,20 @@ final class UserGroupController extends ControllerBase $id = $this->apiService->getParamInt('id', true); $userGroupData = $this->userGroupService->getById($id); - $this->eventDispatcher->notifyEvent('show.userGroup', - new Event($this, EventMessage::factory() - ->addDescription(__u('Group viewed')) - ->addDetail(__u('Name'), $userGroupData->getName()) - ->addDetail('ID', $id)) + $this->eventDispatcher->notifyEvent( + 'show.userGroup', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Group viewed')) + ->addDetail(__u('Name'), $userGroupData->getName()) + ->addDetail('ID', $id) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($userGroupData, $id)); + $this->returnResponse( + ApiResponse::makeSuccess($userGroupData, $id) + ); } catch (Exception $e) { processException($e); @@ -78,7 +81,7 @@ final class UserGroupController extends ControllerBase /** * createAction */ - public function createAction() + public function createAction(): void { try { $this->setupApi(ActionsInterface::GROUP_CREATE); @@ -90,14 +93,22 @@ final class UserGroupController extends ControllerBase $id = $this->userGroupService->create($userGroupData); - $this->eventDispatcher->notifyEvent('create.userGroup', + $this->eventDispatcher->notifyEvent( + 'create.userGroup', new Event($this, EventMessage::factory() ->addDescription(__u('Group added')) ->addDetail(__u('Name'), $userGroupData->getName()) - ->addDetail('ID', $id)) + ->addDetail('ID', $id) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($userGroupData, $id, __('Group added'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $userGroupData, + $id, + __('Group added') + ) + ); } catch (Exception $e) { processException($e); @@ -108,7 +119,7 @@ final class UserGroupController extends ControllerBase /** * editAction */ - public function editAction() + public function editAction(): void { try { $this->setupApi(ActionsInterface::GROUP_EDIT); @@ -121,15 +132,25 @@ final class UserGroupController extends ControllerBase $this->userGroupService->update($userGroupData); - $this->eventDispatcher->notifyEvent('edit.userGroup', - new Event($this, EventMessage::factory() - ->addDescription(__u('Group updated')) - ->addDetail(__u('Name'), $userGroupData->getName()) - ->addDetail('ID', $userGroupData->getId()) - ->addExtra('userGroupId', $userGroupData->getId())) + $this->eventDispatcher->notifyEvent( + 'edit.userGroup', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Group updated')) + ->addDetail(__u('Name'), $userGroupData->getName()) + ->addDetail('ID', $userGroupData->getId()) + ->addExtra('userGroupId', $userGroupData->getId()) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($userGroupData, $userGroupData->getId(), __('Group updated'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $userGroupData, + $userGroupData->getId(), + __('Group updated') + ) + ); } catch (Exception $e) { processException($e); @@ -140,7 +161,7 @@ final class UserGroupController extends ControllerBase /** * deleteAction */ - public function deleteAction() + public function deleteAction(): void { try { $this->setupApi(ActionsInterface::GROUP_DELETE); @@ -151,15 +172,25 @@ final class UserGroupController extends ControllerBase $this->userGroupService->delete($id); - $this->eventDispatcher->notifyEvent('delete.userGroup', - new Event($this, EventMessage::factory() - ->addDescription(__u('Group deleted')) - ->addDetail(__u('Name'), $userGroupData->getName()) - ->addDetail('ID', $id) - ->addExtra('userGroupId', $id)) + $this->eventDispatcher->notifyEvent( + 'delete.userGroup', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Group deleted')) + ->addDetail(__u('Name'), $userGroupData->getName()) + ->addDetail('ID', $id) + ->addExtra('userGroupId', $id) + ) ); - $this->returnResponse(ApiResponse::makeSuccess($userGroupData, $id, __('Group deleted'))); + $this->returnResponse( + ApiResponse::makeSuccess( + $userGroupData, + $id, + __('Group deleted') + ) + ); } catch (Exception $e) { processException($e); @@ -170,7 +201,7 @@ final class UserGroupController extends ControllerBase /** * searchAction */ - public function searchAction() + public function searchAction(): void { try { $this->setupApi(ActionsInterface::GROUP_SEARCH); @@ -179,9 +210,16 @@ final class UserGroupController extends ControllerBase $itemSearchData->setSeachString($this->apiService->getParamString('text')); $itemSearchData->setLimitCount($this->apiService->getParamInt('count', false, self::SEARCH_COUNT_ITEMS)); - $this->eventDispatcher->notifyEvent('search.userGroup', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'search.userGroup', + new Event($this) + ); - $this->returnResponse(ApiResponse::makeSuccess($this->userGroupService->search($itemSearchData)->getDataAsArray())); + $this->returnResponse( + ApiResponse::makeSuccess( + $this->userGroupService->search($itemSearchData)->getDataAsArray() + ) + ); } catch (Exception $e) { processException($e); @@ -190,11 +228,9 @@ final class UserGroupController extends ControllerBase } /** - * @throws DependencyException - * @throws NotFoundException - * @throws InvalidClassException + * @throws \SP\Core\Exceptions\InvalidClassException */ - protected function initialize() + protected function initialize(): void { $this->userGroupService = $this->dic->get(UserGroupService::class); $this->apiService->setHelpClass(TagHelp::class); diff --git a/app/modules/api/Init.php b/app/modules/api/Init.php index 39e4741b..9c74d258 100644 --- a/app/modules/api/Init.php +++ b/app/modules/api/Init.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Api; @@ -42,24 +42,14 @@ use SP\Util\HttpUtil; /** * Class Init - * - * @package api */ final class Init extends ModuleBase { - /** - * @var StatelessContext - */ - protected $context; - /** - * @var Language - */ - protected $language; + protected StatelessContext $context; + protected Language $language; /** * Module constructor. - * - * @param ContainerInterface $container */ public function __construct(ContainerInterface $container) { @@ -70,16 +60,13 @@ final class Init extends ModuleBase } /** - * @param string $controller - * - * @throws ContextException - * @throws InitializationException - * @throws DependencyException - * @throws NotFoundException - * @throws EnvironmentIsBrokenException - * @throws FileException + * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException + * @throws \JsonException + * @throws \SP\Core\Context\ContextException + * @throws \SP\Core\Exceptions\InitializationException + * @throws \SP\Storage\File\FileException */ - public function initialize(string $controller) + public function initialize(string $controller): void { logger(__FUNCTION__); @@ -127,7 +114,7 @@ final class Init extends ModuleBase * * @throws InitializationException */ - private function checkInstalled() + private function checkInstalled(): void { if (!$this->configData->isInstalled()) { throw new InitializationException('Not installed'); @@ -141,7 +128,7 @@ final class Init extends ModuleBase * @throws FileException * @throws InitializationException */ - private function checkUpgrade() + private function checkUpgrade(): void { UpgradeUtil::fixAppUpgrade($this->configData, $this->config); diff --git a/app/modules/api/module.php b/app/modules/api/module.php index 205d247e..62202b4f 100644 --- a/app/modules/api/module.php +++ b/app/modules/api/module.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,8 +19,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ -define('MODULE_PATH', __DIR__); -define('PLUGINS_PATH', MODULE_PATH . DIRECTORY_SEPARATOR . 'plugins'); +const MODULE_PATH = __DIR__; +const PLUGINS_PATH = MODULE_PATH . DIRECTORY_SEPARATOR . 'plugins'; diff --git a/app/modules/cli/Commands/BackupCommand.php b/app/modules/cli/Commands/BackupCommand.php index 7aec502e..18d72a3a 100644 --- a/app/modules/cli/Commands/BackupCommand.php +++ b/app/modules/cli/Commands/BackupCommand.php @@ -52,9 +52,6 @@ final class BackupCommand extends CommandBase * @var string */ protected static $defaultName = 'sp:backup'; - /** - * @var FileBackupService - */ private FileBackupService $fileBackupService; public function __construct(FileBackupService $fileBackupService, @@ -77,13 +74,10 @@ final class BackupCommand extends CommandBase BACKUP_PATH); } - /** - * @param InputInterface $input - * @param OutputInterface $output - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output): int + protected function execute( + InputInterface $input, + OutputInterface $output + ): int { $style = new SymfonyStyle($input, $output); @@ -119,13 +113,10 @@ final class BackupCommand extends CommandBase } } - /** - * @param InputInterface $input - * @param StyleInterface $style - * - * @return string - */ - private function getPath(InputInterface $input, StyleInterface $style): string + private function getPath( + InputInterface $input, + StyleInterface $style + ): string { $path = self::getEnvVarOrOption('path', $input); diff --git a/app/modules/cli/Commands/CommandBase.php b/app/modules/cli/Commands/CommandBase.php index 32e147fa..4ac7eb74 100644 --- a/app/modules/cli/Commands/CommandBase.php +++ b/app/modules/cli/Commands/CommandBase.php @@ -26,7 +26,7 @@ namespace SP\Modules\Cli\Commands; use Psr\Log\LoggerInterface; use SP\Config\Config; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -37,29 +37,11 @@ use Symfony\Component\Console\Input\InputInterface; */ abstract class CommandBase extends Command { - /** - * @var string[] - */ public static array $envVarsMapping = []; - /** - * @var LoggerInterface - */ protected LoggerInterface $logger; - /** - * @var Config - */ protected Config $config; - /** - * @var ConfigData - */ - protected ConfigData $configData; + protected ConfigDataInterface $configData; - /** - * CommandBase constructor. - * - * @param LoggerInterface $logger - * @param Config $config - */ public function __construct( LoggerInterface $logger, Config $config @@ -73,9 +55,6 @@ abstract class CommandBase extends Command } /** - * @param string $option - * @param InputInterface $input - * * @return array|false|mixed|string */ protected static function getEnvVarOrOption( @@ -88,8 +67,6 @@ abstract class CommandBase extends Command } /** - * @param string $option - * * @return string|false */ protected static function getEnvVarForOption(string $option) @@ -98,9 +75,6 @@ abstract class CommandBase extends Command } /** - * @param string $argument - * @param InputInterface $input - * * @return array|false|mixed|string */ protected static function getEnvVarOrArgument( diff --git a/app/modules/cli/Commands/Crypt/UpdateMasterPasswordCommand.php b/app/modules/cli/Commands/Crypt/UpdateMasterPasswordCommand.php index 247e2c6f..95879504 100644 --- a/app/modules/cli/Commands/Crypt/UpdateMasterPasswordCommand.php +++ b/app/modules/cli/Commands/Crypt/UpdateMasterPasswordCommand.php @@ -63,26 +63,10 @@ final class UpdateMasterPasswordCommand extends CommandBase * @var string */ protected static $defaultName = 'sp:crypt:update-master-password'; - /** - * @var MasterPassService - */ private MasterPassService $masterPassService; - /** - * @var ConfigService - */ private ConfigService $configService; - /** - * @var \SP\Services\Account\AccountService - */ private AccountService $accountService; - /** - * @param \SP\Services\Crypt\MasterPassService $masterPassService - * @param \SP\Services\Account\AccountService $accountService - * @param \SP\Services\Config\ConfigService $configService - * @param \Psr\Log\LoggerInterface $logger - * @param \SP\Config\Config $config - */ public function __construct(MasterPassService $masterPassService, AccountService $accountService, ConfigService $configService, @@ -114,13 +98,10 @@ final class UpdateMasterPasswordCommand extends CommandBase __('Skip asking to confirm the update')); } - /** - * @param InputInterface $input - * @param OutputInterface $output - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output): int + protected function execute( + InputInterface $input, + OutputInterface $output + ): int { $style = new SymfonyStyle($input, $output); @@ -208,9 +189,6 @@ final class UpdateMasterPasswordCommand extends CommandBase } /** - * @param InputInterface $input - * @param StyleInterface $style - * * @return array|false|mixed|string */ private function getMasterPassword( @@ -249,9 +227,6 @@ final class UpdateMasterPasswordCommand extends CommandBase } /** - * @param InputInterface $input - * @param StyleInterface $style - * * @return array|false|mixed|string */ private function getCurrentMasterPassword( @@ -300,13 +275,10 @@ final class UpdateMasterPasswordCommand extends CommandBase } } - /** - * @param InputInterface $input - * @param StyleInterface $style - * - * @return bool - */ - private function getUpdate(InputInterface $input, StyleInterface $style): bool + private function getUpdate( + InputInterface $input, + StyleInterface $style + ): bool { $option = 'update'; diff --git a/app/modules/cli/Commands/InstallCommand.php b/app/modules/cli/Commands/InstallCommand.php index 24143458..827484d9 100644 --- a/app/modules/cli/Commands/InstallCommand.php +++ b/app/modules/cli/Commands/InstallCommand.php @@ -67,9 +67,6 @@ final class InstallCommand extends CommandBase * @var string */ protected static $defaultName = 'sp:install'; - /** - * @var Installer - */ private Installer $installer; public function __construct(LoggerInterface $logger, @@ -127,13 +124,10 @@ final class InstallCommand extends CommandBase __('Skip asking to confirm the installation')); } - /** - * @param InputInterface $input - * @param OutputInterface $output - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output): int + protected function execute( + InputInterface $input, + OutputInterface $output + ): int { $style = new SymfonyStyle($input, $output); @@ -175,13 +169,12 @@ final class InstallCommand extends CommandBase } /** - * @param InputInterface $input - * @param StyleInterface $style - * - * @return InstallData * @throws InstallError */ - private function getInstallData(InputInterface $input, StyleInterface $style): InstallData + private function getInstallData( + InputInterface $input, + StyleInterface $style + ): InstallData { $adminPassword = $this->getAdminPassword($input, $style); $masterPassword = $this->getMasterPassword($input, $style); @@ -208,9 +201,6 @@ final class InstallCommand extends CommandBase } /** - * @param InputInterface $input - * @param StyleInterface $style - * * @return array|false|mixed|string * @throws InstallError */ @@ -256,9 +246,6 @@ final class InstallCommand extends CommandBase /** - * @param InputInterface $input - * @param StyleInterface $style - * * @return array|false|mixed|string * @throws InstallError */ @@ -298,9 +285,6 @@ final class InstallCommand extends CommandBase } /** - * @param InputInterface $input - * @param StyleInterface $style - * * @return array|false|mixed|string */ private function getDatabasePassword( @@ -320,9 +304,6 @@ final class InstallCommand extends CommandBase } /** - * @param InputInterface $input - * @param StyleInterface $style - * * @return array|false|mixed|string */ private function getLanguage( @@ -345,11 +326,6 @@ final class InstallCommand extends CommandBase return $language; } - /** - * @param InputInterface $input - * - * @return bool - */ private function isHostingMode(InputInterface $input): bool { $option = 'hostingMode'; @@ -362,9 +338,6 @@ final class InstallCommand extends CommandBase } /** - * @param InputInterface $input - * - * @return bool * @throws InstallError */ private function getForceInstall(InputInterface $input): bool @@ -384,13 +357,10 @@ final class InstallCommand extends CommandBase return $force; } - /** - * @param InputInterface $input - * @param StyleInterface $style - * - * @return bool - */ - private function getInstall(InputInterface $input, StyleInterface $style): bool + private function getInstall( + InputInterface $input, + StyleInterface $style + ): bool { $option = 'install'; diff --git a/app/modules/cli/Commands/Validators.php b/app/modules/cli/Commands/Validators.php index 6cf02631..246d045f 100644 --- a/app/modules/cli/Commands/Validators.php +++ b/app/modules/cli/Commands/Validators.php @@ -31,13 +31,10 @@ use RuntimeException; */ final class Validators { - /** - * @param string|null $value - * @param string|null $message - * - * @return string - */ - public static function valueNotEmpty(?string $value, ?string $message): string + public static function valueNotEmpty( + ?string $value, + ?string $message + ): string { if (empty($value)) { throw new RuntimeException($message ?? __u('Value cannot be blank')); diff --git a/app/modules/cli/Init.php b/app/modules/cli/Init.php index 4540341d..39bf4903 100644 --- a/app/modules/cli/Init.php +++ b/app/modules/cli/Init.php @@ -24,11 +24,7 @@ namespace SP\Modules\Cli; -use DI\DependencyException; -use DI\NotFoundException; -use Exception; use Psr\Container\ContainerInterface; -use SP\Core\Context\ContextException; use SP\Core\Context\StatelessContext; use SP\Core\Language; use SP\Core\ModuleBase; @@ -52,23 +48,12 @@ final class Init extends ModuleBase BackupCommand::class, UpdateMasterPasswordCommand::class ]; - /** - * @var StatelessContext - */ - protected $context; - /** - * @var Language - */ - protected $language; - /** - * @var Application - */ - protected $application; + protected StatelessContext $context; + protected Language $language; + protected Application $application; /** * Module constructor. - * - * @param ContainerInterface $container */ public function __construct(ContainerInterface $container) { @@ -80,13 +65,10 @@ final class Init extends ModuleBase } /** - * @param string $controller - * - * @throws ContextException - * @throws DependencyException - * @throws NotFoundException + * @throws \SP\Core\Context\ContextException + * @throws \Exception */ - public function initialize(string $controller) + public function initialize(string $controller): void { logger(__FUNCTION__); @@ -103,9 +85,7 @@ final class Init extends ModuleBase } /** - * @throws DependencyException - * @throws NotFoundException - * @throws Exception + * @throws \Exception */ private function initCli(): void { diff --git a/app/modules/web/Controllers/AccessManagerController.php b/app/modules/web/Controllers/AccessManagerController.php index a9d23e46..d7901bb0 100644 --- a/app/modules/web/Controllers/AccessManagerController.php +++ b/app/modules/web/Controllers/AccessManagerController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -27,6 +27,7 @@ namespace SP\Modules\Web\Controllers; use DI\DependencyException; use DI\NotFoundException; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; @@ -53,14 +54,8 @@ use SP\Services\UserProfile\UserProfileService; */ final class AccessManagerController extends ControllerBase { - /** - * @var ItemSearchData - */ - protected $itemSearchData; - /** - * @var TabsGridHelper - */ - protected $tabsGridHelper; + protected ?ItemSearchData $itemSearchData = null; + protected ?TabsGridHelper $tabsGridHelper = null; /** * @throws DependencyException @@ -68,7 +63,7 @@ final class AccessManagerController extends ControllerBase * @throws ConstraintException * @throws QueryException */ - public function indexAction() + public function indexAction(): void { $this->getGridTabs(); } @@ -81,36 +76,42 @@ final class AccessManagerController extends ControllerBase * @throws ConstraintException * @throws QueryException */ - protected function getGridTabs() + protected function getGridTabs(): void { $this->itemSearchData = new ItemSearchData(); $this->itemSearchData->setLimitCount($this->configData->getAccountCount()); $this->tabsGridHelper = $this->dic->get(TabsGridHelper::class); - if ($this->checkAccess(Acl::USER)) { + if ($this->checkAccess(ActionsInterface::USER)) { $this->tabsGridHelper->addTab($this->getUsersList()); } - if ($this->checkAccess(Acl::GROUP)) { + if ($this->checkAccess(ActionsInterface::GROUP)) { $this->tabsGridHelper->addTab($this->getUsersGroupList()); } - if ($this->checkAccess(Acl::PROFILE)) { + if ($this->checkAccess(ActionsInterface::PROFILE)) { $this->tabsGridHelper->addTab($this->getUsersProfileList()); } - if ($this->checkAccess(Acl::AUTHTOKEN)) { + if ($this->checkAccess(ActionsInterface::AUTHTOKEN)) { $this->tabsGridHelper->addTab($this->getAuthTokensList()); } - if ($this->configData->isPublinksEnabled() && $this->checkAccess(Acl::PUBLICLINK)) { + if ($this->configData->isPublinksEnabled() + && $this->checkAccess(ActionsInterface::PUBLICLINK)) { $this->tabsGridHelper->addTab($this->getPublicLinksList()); } - $this->eventDispatcher->notifyEvent('show.itemlist.accesses', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.itemlist.accesses', + new Event($this) + ); - $this->tabsGridHelper->renderTabs(Acl::getActionRoute(Acl::ACCESS_MANAGE), $this->request->analyzeInt('tabIndex', 0)); + $this->tabsGridHelper->renderTabs( + Acl::getActionRoute(ActionsInterface::ACCESS_MANAGE), + $this->request->analyzeInt('tabIndex', 0)); $this->view(); } @@ -127,7 +128,8 @@ final class AccessManagerController extends ControllerBase protected function getUsersList(): DataGridTab { return $this->dic->get(UserGrid::class) - ->getGrid($this->dic->get(UserService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(UserService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -143,7 +145,8 @@ final class AccessManagerController extends ControllerBase protected function getUsersGroupList(): DataGridTab { return $this->dic->get(UserGroupGrid::class) - ->getGrid($this->dic->get(UserGroupService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(UserGroupService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -159,7 +162,8 @@ final class AccessManagerController extends ControllerBase protected function getUsersProfileList(): DataGridTab { return $this->dic->get(UserProfileGrid::class) - ->getGrid($this->dic->get(UserProfileService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(UserProfileService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -175,7 +179,8 @@ final class AccessManagerController extends ControllerBase protected function getAuthTokensList(): DataGridTab { return $this->dic->get(AuthTokenGrid::class) - ->getGrid($this->dic->get(AuthTokenService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(AuthTokenService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -191,7 +196,8 @@ final class AccessManagerController extends ControllerBase protected function getPublicLinksList(): DataGridTab { return $this->dic->get(PublicLinkGrid::class) - ->getGrid($this->dic->get(PublicLinkService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(PublicLinkService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -209,7 +215,7 @@ final class AccessManagerController extends ControllerBase * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); } diff --git a/app/modules/web/Controllers/AccountController.php b/app/modules/web/Controllers/AccountController.php index d602c3c2..f2338214 100644 --- a/app/modules/web/Controllers/AccountController.php +++ b/app/modules/web/Controllers/AccountController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -33,7 +33,7 @@ use Psr\Container\NotFoundExceptionInterface; use SP\Bootstrap; use SP\Core\Acl\Acl; use SP\Core\Acl\ActionsInterface; -use SP\Core\Context\SessionContext; +use SP\Core\Context\ContextBase; use SP\Core\Crypt\Vault; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; @@ -80,34 +80,34 @@ final class AccountController extends ControllerBase implements CrudControllerIn { use JsonTrait, ItemTrait; - /** - * @var AccountService - */ - protected $accountService; - /** - * @var ThemeIcons - */ - protected $icons; + protected ?AccountService $accountService = null; + protected ?ThemeIcons $icons = null; /** * Index action * * @throws ContainerExceptionInterface */ - public function indexAction() + public function indexAction(): void { try { $accountSearchHelper = $this->dic->get(AccountSearchHelper::class); $accountSearchHelper->getSearchBox(); $accountSearchHelper->getAccountSearch(); - $this->eventDispatcher->notifyEvent('show.account.search', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.account.search', + new Event($this) + ); $this->view(); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); ErrorUtil::showExceptionInView($this->view, $e); } @@ -117,14 +117,18 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function searchAction() + public function searchAction(): ?bool { try { $accountSearchHelper = $this->dic->get(AccountSearchHelper::class); $accountSearchHelper->getAccountSearch(); - $this->eventDispatcher->notifyEvent('show.account.search', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.account.search', + new Event($this) + ); return $this->returnJsonResponseData([ 'html' => $this->render() @@ -132,7 +136,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -146,7 +153,7 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function viewAction(int $id) + public function viewAction(int $id): void { try { $this->view->addTemplate('account'); @@ -159,7 +166,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn $accountHelper = $this->dic->get(AccountHelper::class); $accountHelper->setIsView(true); - $accountHelper->setViewForAccount($accountDetailsResponse, Acl::ACCOUNT_VIEW); + $accountHelper->setViewForAccount( + $accountDetailsResponse, + ActionsInterface::ACCOUNT_VIEW + ); $this->view->assign('title', [ @@ -171,7 +181,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn $this->accountService->incrementViewCounter($id); - $this->eventDispatcher->notifyEvent('show.account', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.account', + new Event($this) + ); if ($this->isAjax === false) { $this->upgradeView(); @@ -181,7 +194,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); if ($this->isAjax === false && !$this->view->isUpgraded() @@ -201,7 +217,7 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function viewLinkAction(string $hash) + public function viewLinkAction(string $hash): void { try { $layoutHelper = $this->dic->get(LayoutHelper::class); @@ -219,10 +235,16 @@ final class AccountController extends ControllerBase implements CrudControllerIn $this->accountService->incrementDecryptCounter($publicLinkData->getItemId()); /** @var Vault $vault */ - $vault = unserialize($publicLinkData->getData()); + $vault = unserialize( + $publicLinkData->getData(), + ['allowed_classes' => [Vault::class]] + ); /** @var AccountExtData $accountData */ - $accountData = Util::unserialize(AccountExtData::class, $vault->getData($publicLinkService->getPublicLinkKey($publicLinkData->getHash())->getKey())); + $accountData = Util::unserialize( + AccountExtData::class, + $vault->getData($publicLinkService->getPublicLinkKey($publicLinkData->getHash())->getKey()) + ); $this->view->assign('title', [ @@ -233,25 +255,36 @@ final class AccountController extends ControllerBase implements CrudControllerIn ); $this->view->assign('isView', true); - $this->view->assign('useImage', $this->configData->isPublinksImageEnabled() || $this->configData->isAccountPassToImage()); + $this->view->assign('useImage', + $this->configData->isPublinksImageEnabled() + || $this->configData->isAccountPassToImage()); if ($this->view->useImage) { $imageUtil = $this->dic->get(ImageUtil::class); - $this->view->assign('accountPassImage', $imageUtil->convertText($accountData->getPass())); + $this->view->assign( + 'accountPassImage', + $imageUtil->convertText($accountData->getPass()) + ); } else { - $this->view->assign('copyPassRoute', Acl::getActionRoute(Acl::ACCOUNT_VIEW_PASS)); + $this->view->assign( + 'copyPassRoute', + Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW_PASS) + ); } $this->view->assign('accountData', $accountData); - $clientAddress = $this->configData->isDemoEnabled() ? '***' : $this->request->getClientAddress(true); + $clientAddress = $this->configData->isDemoEnabled() + ? '***' + : $this->request->getClientAddress(true); $baseUrl = ($this->configData->getApplicationUrl() ?: Bootstrap::$WEBURI) . Bootstrap::$SUBURI; $deepLink = new Uri($baseUrl); $deepLink->addParam('r', Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) . '/' . $accountData->getId()); - $this->eventDispatcher->notifyEvent('show.account.link', + $this->eventDispatcher->notifyEvent( + 'show.account.link', new Event($this, EventMessage::factory() ->addDescription(__u('Link viewed')) ->addDetail(__u('Account'), $accountData->getName()) @@ -264,14 +297,22 @@ final class AccountController extends ControllerBase implements CrudControllerIn ->addExtra('notify', $publicLinkData->isNotify())) ); } else { - ErrorUtil::showErrorInView($this->view, ErrorUtil::ERR_PAGE_NO_PERMISSION, true, 'account-link'); + ErrorUtil::showErrorInView( + $this->view, + ErrorUtil::ERR_PAGE_NO_PERMISSION, + true, + 'account-link' + ); } $this->view(); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); ErrorUtil::showExceptionInView($this->view, $e, 'account-link'); } @@ -280,11 +321,11 @@ final class AccountController extends ControllerBase implements CrudControllerIn /** * Create action */ - public function createAction() + public function createAction(): void { try { $accountHelper = $this->dic->get(AccountHelper::class); - $accountHelper->setViewForBlank(Acl::ACCOUNT_CREATE); + $accountHelper->setViewForBlank(ActionsInterface::ACCOUNT_CREATE); $this->view->addTemplate('account'); $this->view->assign('title', @@ -296,7 +337,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn ); $this->view->assign('formRoute', 'account/saveCreate'); - $this->eventDispatcher->notifyEvent('show.account.create', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.account.create', + new Event($this) + ); if ($this->isAjax === false) { $this->upgradeView(); @@ -324,7 +368,7 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function copyAction(int $id) + public function copyAction(int $id): void { try { $accountDetailsResponse = $this->accountService->getById($id); @@ -334,7 +378,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn ->withTagsById($accountDetailsResponse); $accountHelper = $this->dic->get(AccountHelper::class); - $accountHelper->setViewForAccount($accountDetailsResponse, Acl::ACCOUNT_COPY); + $accountHelper->setViewForAccount( + $accountDetailsResponse, + ActionsInterface::ACCOUNT_COPY + ); $this->view->addTemplate('account'); $this->view->assign('title', @@ -346,7 +393,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn ); $this->view->assign('formRoute', 'account/saveCopy'); - $this->eventDispatcher->notifyEvent('show.account.copy', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.account.copy', + new Event($this) + ); if ($this->isAjax === false) { $this->upgradeView(); @@ -356,7 +406,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); if ($this->isAjax === false && !$this->view->isUpgraded() @@ -376,7 +429,7 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function editAction(int $id) + public function editAction(int $id): void { try { $accountDetailsResponse = $this->accountService->getById($id); @@ -386,7 +439,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn ->withTagsById($accountDetailsResponse); $accountHelper = $this->dic->get(AccountHelper::class); - $accountHelper->setViewForAccount($accountDetailsResponse, Acl::ACCOUNT_EDIT); + $accountHelper->setViewForAccount( + $accountDetailsResponse, + ActionsInterface::ACCOUNT_EDIT + ); $this->view->addTemplate('account'); $this->view->assign('title', @@ -400,7 +456,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn $this->accountService->incrementViewCounter($id); - $this->eventDispatcher->notifyEvent('show.account.edit', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.account.edit', + new Event($this) + ); if ($this->isAjax === false) { $this->upgradeView(); @@ -410,7 +469,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); if ($this->isAjax === false && !$this->view->isUpgraded() @@ -428,7 +490,7 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @param int|null $id Account's ID * */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): void { try { $accountDetailsResponse = $this->accountService->getById($id); @@ -437,7 +499,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn ->withUserGroupsById($accountDetailsResponse); $accountHelper = $this->dic->get(AccountHelper::class); - $accountHelper->setViewForAccount($accountDetailsResponse, Acl::ACCOUNT_DELETE); + $accountHelper->setViewForAccount( + $accountDetailsResponse, + ActionsInterface::ACCOUNT_DELETE + ); $this->view->addTemplate('account'); $this->view->assign('title', @@ -449,7 +514,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn ); $this->view->assign('formRoute', 'account/saveDelete'); - $this->eventDispatcher->notifyEvent('show.account.delete', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.account.delete', + new Event($this) + ); if ($this->isAjax === false) { $this->upgradeView(); @@ -459,7 +527,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); if ($this->isAjax === false && !$this->view->isUpgraded() @@ -479,7 +550,7 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function editPassAction(int $id) + public function editPassAction(int $id): void { try { $accountDetailsResponse = $this->accountService->getById($id); @@ -488,7 +559,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn ->withUserGroupsById($accountDetailsResponse); $accountHelper = $this->dic->get(AccountHelper::class); - $accountHelper->setViewForAccount($accountDetailsResponse, Acl::ACCOUNT_EDIT_PASS); + $accountHelper->setViewForAccount( + $accountDetailsResponse, + ActionsInterface::ACCOUNT_EDIT_PASS + ); $this->view->addTemplate('account-editpass'); $this->view->assign('title', @@ -500,7 +574,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn ); $this->view->assign('formRoute', 'account/saveEditPass'); - $this->eventDispatcher->notifyEvent('show.account.editpass', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.account.editpass', + new Event($this) + ); if ($this->isAjax === false) { $this->upgradeView(); @@ -510,7 +587,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); if ($this->isAjax === false && !$this->view->isUpgraded() @@ -518,7 +598,11 @@ final class AccountController extends ControllerBase implements CrudControllerIn $this->upgradeView(); } - ErrorUtil::showExceptionInView($this->view, $e, 'account-editpass'); + ErrorUtil::showExceptionInView( + $this->view, + $e, + 'account-editpass' + ); } } @@ -530,14 +614,17 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function viewHistoryAction(int $id) + public function viewHistoryAction(int $id): void { try { $accountHistoryService = $this->dic->get(AccountHistoryService::class); $accountHistoryData = $accountHistoryService->getById($id); $accountHistoryHelper = $this->dic->get(AccountHistoryHelper::class); - $accountHistoryHelper->setView($accountHistoryData, Acl::ACCOUNT_HISTORY_VIEW); + $accountHistoryHelper->setView( + $accountHistoryData, + ActionsInterface::ACCOUNT_HISTORY_VIEW + ); $this->view->addTemplate('account-history'); @@ -551,7 +638,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn $this->view->assign('formRoute', 'account/saveRestore'); - $this->eventDispatcher->notifyEvent('show.account.history', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.account.history', + new Event($this) + ); if ($this->isAjax === false) { $this->upgradeView(); @@ -561,7 +651,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); if ($this->isAjax === false && !$this->view->isUpgraded() @@ -569,7 +662,11 @@ final class AccountController extends ControllerBase implements CrudControllerIn $this->upgradeView(); } - ErrorUtil::showExceptionInView($this->view, $e, 'account-history'); + ErrorUtil::showExceptionInView( + $this->view, + $e, + 'account-history' + ); } } @@ -581,17 +678,23 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function requestAccessAction(int $id) + public function requestAccessAction(int $id): void { try { $accountHelper = $this->dic->get(AccountHelper::class); $accountHelper->setIsView(true); - $accountHelper->setViewForRequest($this->accountService->getById($id), Acl::ACCOUNT_REQUEST); + $accountHelper->setViewForRequest( + $this->accountService->getById($id), + ActionsInterface::ACCOUNT_REQUEST + ); $this->view->addTemplate('account-request'); $this->view->assign('formRoute', 'account/saveRequest'); - $this->eventDispatcher->notifyEvent('show.account.request', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.account.request', + new Event($this) + ); if ($this->isAjax === false) { $this->upgradeView(); @@ -601,7 +704,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); if ($this->isAjax === false && !$this->view->isUpgraded() @@ -609,7 +715,11 @@ final class AccountController extends ControllerBase implements CrudControllerIn $this->upgradeView(); } - ErrorUtil::showExceptionInView($this->view, $e, 'account-request'); + ErrorUtil::showExceptionInView( + $this->view, + $e, + 'account-request' + ); } } @@ -620,10 +730,11 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @param int $parentId * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function viewPassAction(int $id, int $parentId = 0) + public function viewPassAction(int $id, int $parentId = 0): ?bool { try { $accountPassHelper = $this->dic->get(AccountPasswordHelper::class); @@ -632,7 +743,7 @@ final class AccountController extends ControllerBase implements CrudControllerIn $passwordPreset = $this->getPasswordPreset(); $useImage = $this->configData->isAccountPassToImage() - || $passwordPreset !== null && $passwordPreset->isUseImage(); + || ($passwordPreset !== null && $passwordPreset->isUseImage()); $this->view->assign('isLinked', $parentId > 0); @@ -640,7 +751,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn $this->accountService->incrementDecryptCounter($id); - $this->eventDispatcher->notifyEvent('show.account.pass', + $this->eventDispatcher->notifyEvent( + 'show.account.pass', new Event($this, EventMessage::factory() ->addDescription(__u('Password viewed')) ->addDetail(__u('Account'), $account->getName())) @@ -650,7 +762,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -682,10 +797,11 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @param int $id Account's ID * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function viewPassHistoryAction(int $id) + public function viewPassHistoryAction(int $id): ?bool { try { $accountPassHelper = $this->dic->get(AccountPasswordHelper::class); @@ -694,13 +810,14 @@ final class AccountController extends ControllerBase implements CrudControllerIn $passwordPreset = $this->getPasswordPreset(); $useImage = $this->configData->isAccountPassToImage() - || $passwordPreset !== null && $passwordPreset->isUseImage(); + || ($passwordPreset !== null && $passwordPreset->isUseImage()); $this->view->assign('isLinked', 0); $data = $accountPassHelper->getPasswordView($account, $useImage); - $this->eventDispatcher->notifyEvent('show.account.pass.history', + $this->eventDispatcher->notifyEvent( + 'show.account.pass.history', new Event($this, EventMessage::factory() ->addDescription(__u('Password viewed')) ->addDetail(__u('Account'), $account->getName())) @@ -710,7 +827,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -732,7 +852,7 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @throws ServiceException * @throws SPException */ - public function copyPassAction(int $id) + public function copyPassAction(int $id): bool { $accountPassHelper = $this->dic->get(AccountPasswordHelper::class); @@ -742,7 +862,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn 'accpass' => $accountPassHelper->getPasswordClear($account), ]; - $this->eventDispatcher->notifyEvent('copy.account.pass', + $this->eventDispatcher->notifyEvent( + 'copy.account.pass', new Event($this, EventMessage::factory() ->addDescription(__u('Password copied')) ->addDetail(__u('Account'), $account->getName())) @@ -767,7 +888,7 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @throws ServiceException * @throws SPException */ - public function copyPassHistoryAction(int $id) + public function copyPassHistoryAction(int $id): bool { $accountPassHelper = $this->dic->get(AccountPasswordHelper::class); @@ -777,7 +898,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn 'accpass' => $accountPassHelper->getPasswordClear($account), ]; - $this->eventDispatcher->notifyEvent('copy.account.pass.history', + $this->eventDispatcher->notifyEvent( + 'copy.account.pass.history', new Event($this, EventMessage::factory() ->addDescription(__u('Password copied')) ->addDetail(__u('Account'), $account->getName())) @@ -789,40 +911,49 @@ final class AccountController extends ControllerBase implements CrudControllerIn /** * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function saveCopyAction() + public function saveCopyAction(): void { $this->saveCreateAction(); } /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveCreateAction() + public function saveCreateAction(): ?bool { try { $form = new AccountForm($this->dic); - $form->validate(Acl::ACCOUNT_CREATE); + $form->validate(ActionsInterface::ACCOUNT_CREATE); $accountId = $this->accountService->create($form->getItemData()); - $accountDetails = $this->accountService->getById($accountId)->getAccountVData(); + $accountDetails = $this->accountService + ->getById($accountId) + ->getAccountVData(); - $this->eventDispatcher->notifyEvent('create.account', + $this->eventDispatcher->notifyEvent( + 'create.account', new Event($this, EventMessage::factory() ->addDescription(__u('Account created')) ->addDetail(__u('Account'), $accountDetails->getName()) ->addDetail(__u('Client'), $accountDetails->getClientName())) ); - $this->addCustomFieldsForItem(Acl::ACCOUNT, $accountId, $this->request); + $this->addCustomFieldsForItem( + ActionsInterface::ACCOUNT, + $accountId, + $this->request + ); return $this->returnJsonResponseData( [ 'itemId' => $accountId, - 'nextAction' => Acl::getActionRoute(Acl::ACCOUNT_EDIT) + 'nextAction' => Acl::getActionRoute(ActionsInterface::ACCOUNT_EDIT) ], JsonResponse::JSON_SUCCESS, __u('Account created') @@ -832,7 +963,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -846,32 +980,40 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function saveEditAction(int $id) + public function saveEditAction(int $id): ?bool { try { $form = new AccountForm($this->dic, $id); - $form->validate(Acl::ACCOUNT_EDIT); + $form->validate(ActionsInterface::ACCOUNT_EDIT); $itemData = $form->getItemData(); $this->accountService->update($itemData); - $accountDetails = $this->accountService->getById($id)->getAccountVData(); + $accountDetails = $this->accountService + ->getById($id) + ->getAccountVData(); - $this->eventDispatcher->notifyEvent('edit.account', + $this->eventDispatcher->notifyEvent( + 'edit.account', new Event($this, EventMessage::factory() ->addDescription(__u('Account updated')) ->addDetail(__u('Account'), $accountDetails->getName()) ->addDetail(__u('Client'), $accountDetails->getClientName())) ); - $this->updateCustomFieldsForItem(Acl::ACCOUNT, $id, $this->request); + $this->updateCustomFieldsForItem( + ActionsInterface::ACCOUNT, + $id, + $this->request + ); return $this->returnJsonResponseData( [ 'itemId' => $id, - 'nextAction' => Acl::getActionRoute(Acl::ACCOUNT_VIEW) + 'nextAction' => Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) ], JsonResponse::JSON_SUCCESS, __u('Account updated') @@ -881,7 +1023,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -893,20 +1038,24 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @param int $id Account's ID * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function saveEditPassAction(int $id): bool { try { $form = new AccountForm($this->dic, $id); - $form->validate(Acl::ACCOUNT_EDIT_PASS); + $form->validate(ActionsInterface::ACCOUNT_EDIT_PASS); $this->accountService->editPassword($form->getItemData()); - $accountDetails = $this->accountService->getById($id)->getAccountVData(); + $accountDetails = $this->accountService + ->getById($id) + ->getAccountVData(); - $this->eventDispatcher->notifyEvent('edit.account.pass', + $this->eventDispatcher->notifyEvent( + 'edit.account.pass', new Event($this, EventMessage::factory() ->addDescription(__u('Password updated')) ->addDetail(__u('Account'), $accountDetails->getName()) @@ -916,7 +1065,7 @@ final class AccountController extends ControllerBase implements CrudControllerIn return $this->returnJsonResponseData( [ 'itemId' => $id, - 'nextAction' => Acl::getActionRoute(Acl::ACCOUNT_VIEW) + 'nextAction' => Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) ], JsonResponse::JSON_SUCCESS, __u('Password updated') @@ -926,7 +1075,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -939,17 +1091,21 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @param int $id Account's ID * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function saveEditRestoreAction(int $historyId, int $id): bool { try { $this->accountService->editRestore($historyId, $id); - $accountDetails = $this->accountService->getById($id)->getAccountVData(); + $accountDetails = $this->accountService + ->getById($id) + ->getAccountVData(); - $this->eventDispatcher->notifyEvent('edit.account.restore', + $this->eventDispatcher->notifyEvent( + 'edit.account.restore', new Event($this, EventMessage::factory() ->addDescription(__u('Account restored')) ->addDetail(__u('Account'), $accountDetails->getName()) @@ -959,7 +1115,7 @@ final class AccountController extends ControllerBase implements CrudControllerIn return $this->returnJsonResponseData( [ 'itemId' => $id, - 'nextAction' => Acl::getActionRoute(Acl::ACCOUNT_VIEW) + 'nextAction' => Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) ], JsonResponse::JSON_SUCCESS, __u('Account restored') @@ -967,7 +1123,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -979,44 +1138,40 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @param int $id Account's ID * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function saveDeleteAction(int $id): bool { try { - if ($id === null) { - $this->accountService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); - - $this->eventDispatcher->notifyEvent( - 'delete.account.selection', - new Event($this, EventMessage::factory() - ->addDescription(__u('Accounts removed'))) - ); - - $this->deleteCustomFieldsForItem(Acl::ACCOUNT, $id); - - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Accounts removed')); - } - - $accountDetails = $this->accountService->getById($id)->getAccountVData(); + $accountDetails = $this->accountService + ->getById($id) + ->getAccountVData(); $this->accountService->delete($id); - $this->eventDispatcher->notifyEvent('delete.account', + $this->eventDispatcher->notifyEvent( + 'delete.account', new Event($this, EventMessage::factory() ->addDescription(__u('Account removed')) ->addDetail(__u('Account'), $accountDetails->getName()) ->addDetail(__u('Client'), $accountDetails->getClientName())) ); - $this->deleteCustomFieldsForItem(Acl::ACCOUNT, $id); + $this->deleteCustomFieldsForItem(ActionsInterface::ACCOUNT, $id); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Account removed')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Account removed') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -1028,8 +1183,9 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @param int $id Account's ID * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function saveRequestAction(int $id): bool { @@ -1062,15 +1218,18 @@ final class AccountController extends ControllerBase implements CrudControllerIn ->addExtra('accountId', $id) ->addExtra('whoId', $this->userData->getId()) ->setExtra('userId', $usersId) - ->setExtra('email', array_map(function ($value) { - return $value->email; - }, $userService->getUserEmailById($usersId)))) + ->setExtra('email', array_map( + static function ($value) { + return $value->email; + }, + $userService->getUserEmailById($usersId)) + )) ); return $this->returnJsonResponseData( [ 'itemId' => $id, - 'nextAction' => Acl::getActionRoute(Acl::ACCOUNT) + 'nextAction' => Acl::getActionRoute(ActionsInterface::ACCOUNT) ], JsonResponse::JSON_SUCCESS, __u('Request done') @@ -1080,7 +1239,10 @@ final class AccountController extends ControllerBase implements CrudControllerIn } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -1094,14 +1256,14 @@ final class AccountController extends ControllerBase implements CrudControllerIn * @throws AuthException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { if ($this->actionName !== 'viewLinkAction') { $this->checkLoggedIn(); } if (DEBUG === true - && $this->session->getAppStatus() === SessionContext::APP_STATUS_RELOADED + && $this->session->getAppStatus() === ContextBase::APP_STATUS_RELOADED ) { $this->session->resetAppStatus(); diff --git a/app/modules/web/Controllers/AccountFavoriteController.php b/app/modules/web/Controllers/AccountFavoriteController.php index bc60a70c..9941ebeb 100644 --- a/app/modules/web/Controllers/AccountFavoriteController.php +++ b/app/modules/web/Controllers/AccountFavoriteController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -42,28 +42,35 @@ final class AccountFavoriteController extends SimpleControllerBase { use JsonTrait; - /** - * @var AccountToFavoriteService - */ - private $accountFavoriteService; + private ?AccountToFavoriteService $accountFavoriteService = null; /** * @param int $accountId * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function markAction(int $accountId): bool { try { - $this->accountFavoriteService->add($accountId, $this->session->getUserData()->getId()); + $this->accountFavoriteService->add( + $accountId, + $this->session->getUserData()->getId() + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Favorite added')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Favorite added') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -73,19 +80,29 @@ final class AccountFavoriteController extends SimpleControllerBase * @param int $accountId * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function unmarkAction(int $accountId): bool { try { - $this->accountFavoriteService->delete($accountId, $this->session->getUserData()->getId()); + $this->accountFavoriteService->delete( + $accountId, + $this->session->getUserData()->getId() + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Favorite deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Favorite deleted') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -96,7 +113,7 @@ final class AccountFavoriteController extends SimpleControllerBase * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checks(); diff --git a/app/modules/web/Controllers/AccountFileController.php b/app/modules/web/Controllers/AccountFileController.php index 4290b9f1..d9f3005b 100644 --- a/app/modules/web/Controllers/AccountFileController.php +++ b/app/modules/web/Controllers/AccountFileController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -30,6 +30,7 @@ use Exception; use Psr\Container\ContainerExceptionInterface; use RuntimeException; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -59,14 +60,11 @@ use SP\Util\FileUtil; */ final class AccountFileController extends ControllerBase implements CrudControllerInterface { - const MIME_VIEW = ['text/plain']; + private const MIME_VIEW = ['text/plain']; use JsonTrait, ItemTrait; - /** - * @var AccountFileService - */ - protected $accountFileService; + protected ?AccountFileService $accountFileService = null; /** * View action @@ -74,10 +72,11 @@ final class AccountFileController extends ControllerBase implements CrudControll * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function viewAction(int $id) + public function viewAction(int $id): bool { try { if (null === ($fileData = $this->accountFileService->getById($id))) { @@ -91,7 +90,8 @@ final class AccountFileController extends ControllerBase implements CrudControll $this->view->assign('fileData', $fileData); $this->view->assign('isImage', 1); - $this->eventDispatcher->notifyEvent('show.accountFile', + $this->eventDispatcher->notifyEvent( + 'show.accountFile', new Event($this, EventMessage::factory() ->addDescription(__u('File viewed')) @@ -107,7 +107,8 @@ final class AccountFileController extends ControllerBase implements CrudControll $this->view->assign('mime', $type); $this->view->assign('data', htmlentities($fileData->getContent())); - $this->eventDispatcher->notifyEvent('show.accountFile', + $this->eventDispatcher->notifyEvent( + 'show.accountFile', new Event($this, EventMessage::factory() ->addDescription(__u('File viewed')) @@ -119,12 +120,18 @@ final class AccountFileController extends ControllerBase implements CrudControll } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } - return $this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('File not supported for preview')); + return $this->returnJsonResponse( + JsonResponse::JSON_WARNING, + __u('File not supported for preview') + ); } /** @@ -141,7 +148,8 @@ final class AccountFileController extends ControllerBase implements CrudControll throw new SPException(__u('File does not exist'), SPException::INFO); } - $this->eventDispatcher->notifyEvent('download.accountFile', + $this->eventDispatcher->notifyEvent( + 'download.accountFile', new Event($this, EventMessage::factory() ->addDescription(__u('File downloaded')) ->addDetail(__u('File'), $fileData->getName())) @@ -157,9 +165,15 @@ final class AccountFileController extends ControllerBase implements CrudControll $type = strtolower($fileData->getType()); if ($type === 'application/pdf') { - $disposition = sprintf('inline; filename="%s"', $fileData->getName()); + $disposition = sprintf( + 'inline; filename="%s"', + $fileData->getName() + ); } else { - $disposition = sprintf('attachment; filename="%s"', $fileData->getName()); + $disposition = sprintf( + 'attachment; filename="%s"', + $fileData->getName() + ); $response->header('Set-Cookie', 'fileDownload=true; path=/'); } @@ -170,7 +184,10 @@ final class AccountFileController extends ControllerBase implements CrudControll } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); } return ''; @@ -182,8 +199,9 @@ final class AccountFileController extends ControllerBase implements CrudControll * @param int $accountId * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function uploadAction(int $accountId): bool { @@ -196,7 +214,7 @@ final class AccountFileController extends ControllerBase implements CrudControll $filesAllowedMime = $this->configData->getFilesAllowedMime(); - if (empty($filesAllowedMime)) { + if (count($filesAllowedMime) === 0) { throw new SPException(__u('There aren\'t any allowed MIME types')); } @@ -243,7 +261,8 @@ final class AccountFileController extends ControllerBase implements CrudControll ->getById($accountId) ->getAccountVData(); - $this->eventDispatcher->notifyEvent('upload.accountFile', + $this->eventDispatcher->notifyEvent( + 'upload.accountFile', new Event($this, EventMessage::factory() ->addDescription(__u('File saved')) @@ -259,13 +278,23 @@ final class AccountFileController extends ControllerBase implements CrudControll } catch (SPException $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); - return $this->returnJsonResponse(1, $e->getMessage(), [$e->getHint()]); + return $this->returnJsonResponse( + 1, + $e->getMessage(), + [$e->getHint()] + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -282,9 +311,11 @@ final class AccountFileController extends ControllerBase implements CrudControll */ private function checkAllowedMimeType(FileData $fileData, FileHandler $fileHandler): string { - if (in_array($fileData->getType(), $this->configData->getFilesAllowedMime())) { + if (in_array($fileData->getType(), $this->configData->getFilesAllowedMime(), true)) { return $fileData->getType(); - } elseif (in_array($fileHandler->getFileType(), $this->configData->getFilesAllowedMime())) { + } + + if (in_array($fileHandler->getFileType(), $this->configData->getFilesAllowedMime(), true)) { return $fileHandler->getFileType(); } @@ -304,10 +335,11 @@ final class AccountFileController extends ControllerBase implements CrudControll * @throws ConstraintException * @throws QueryException * @throws SPException + * @throws \JsonException */ - public function searchAction() + public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::ACCOUNT_FILE_SEARCH)) { + if (!$this->acl->checkUserAccess(ActionsInterface::ACCOUNT_FILE_SEARCH)) { return $this->returnJsonResponse( JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation') @@ -315,7 +347,10 @@ final class AccountFileController extends ControllerBase implements CrudControll } $this->view->addTemplate('datagrid-table', 'grid'); - $this->view->assign('index', $this->request->analyzeInt('activetab', 0)); + $this->view->assign( + 'index', + $this->request->analyzeInt('activetab', 0) + ); $this->view->assign('data', $this->getSearchGrid()); return $this->returnJsonResponseData(['html' => $this->render()]); @@ -331,17 +366,23 @@ final class AccountFileController extends ControllerBase implements CrudControll */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $fileGrid = $this->dic->get(FileGrid::class); - return $fileGrid->updatePager($fileGrid->getGrid($this->accountFileService->search($itemSearchData)), $itemSearchData); + return $fileGrid->updatePager( + $fileGrid->getGrid($this->accountFileService->search($itemSearchData)), + $itemSearchData + ); } /** * Create action */ - public function createAction() + public function createAction(): void { throw new RuntimeException('Not implemented'); } @@ -351,7 +392,7 @@ final class AccountFileController extends ControllerBase implements CrudControll * * @param $id */ - public function editAction($id) + public function editAction($id): void { throw new RuntimeException('Not implemented'); } @@ -362,16 +403,18 @@ final class AccountFileController extends ControllerBase implements CrudControll * @param int|null $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): bool { try { if ($id === null) { $this->accountFileService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); - $this->eventDispatcher->notifyEvent('delete.accountFile.selection', + $this->eventDispatcher->notifyEvent( + 'delete.accountFile.selection', new Event($this, EventMessage::factory() ->addDescription(__u('Files deleted'))) ); @@ -379,7 +422,8 @@ final class AccountFileController extends ControllerBase implements CrudControll return $this->returnJsonResponse(0, __u('Files deleted')); } - $this->eventDispatcher->notifyEvent('delete.accountFile', + $this->eventDispatcher->notifyEvent( + 'delete.accountFile', new Event($this, EventMessage::factory() ->addDescription(__u('File deleted')) ->addDetail(__u('File'), $id)) @@ -391,7 +435,10 @@ final class AccountFileController extends ControllerBase implements CrudControll } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -400,7 +447,7 @@ final class AccountFileController extends ControllerBase implements CrudControll /** * Saves create action */ - public function saveCreateAction() + public function saveCreateAction(): void { throw new RuntimeException('Not implemented'); } @@ -410,7 +457,7 @@ final class AccountFileController extends ControllerBase implements CrudControll * * @param $id */ - public function saveEditAction($id) + public function saveEditAction($id): void { throw new RuntimeException('Not implemented'); } @@ -422,7 +469,7 @@ final class AccountFileController extends ControllerBase implements CrudControll * * @throws ContainerExceptionInterface */ - public function listAction(int $accountId) + public function listAction(int $accountId): void { if (!$this->configData->isFilesEnabled()) { echo __('Files management disabled'); @@ -434,25 +481,40 @@ final class AccountFileController extends ControllerBase implements CrudControll $this->view->assign('deleteEnabled', $this->request->analyzeInt('del', false)); $this->view->assign('files', $this->dic->get(AccountFileService::class)->getByAccountId($accountId)); - $this->view->assign('fileViewRoute', Acl::getActionRoute(Acl::ACCOUNT_FILE_VIEW)); - $this->view->assign('fileDownloadRoute', Acl::getActionRoute(Acl::ACCOUNT_FILE_DOWNLOAD)); - $this->view->assign('fileDeleteRoute', Acl::getActionRoute(Acl::ACCOUNT_FILE_DELETE)); + $this->view->assign('fileViewRoute', Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_VIEW)); + $this->view->assign('fileDownloadRoute', Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_DOWNLOAD)); + $this->view->assign('fileDeleteRoute', Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_DELETE)); - if (!is_array($this->view->files) || count($this->view->files) === 0) { - $this->view->addTemplate('no_records_found', '_partials'); + if (!is_array($this->view->files) + || count($this->view->files) === 0) { + $this->view->addTemplate( + 'no_records_found', + '_partials' + ); - $this->view->assign('message', __('There are no linked files for the account')); + $this->view->assign( + 'message', + __('There are no linked files for the account') + ); $this->view(); return; } - $this->eventDispatcher->notifyEvent('list.accountFile', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'list.accountFile', + new Event($this) + ); } catch (Exception $e) { processException($e); - ErrorUtil::showErrorInView($this->view, ErrorUtil::ERR_EXCEPTION, true, 'files-list'); + ErrorUtil::showErrorInView( + $this->view, + ErrorUtil::ERR_EXCEPTION, + true, + 'files-list' + ); } $this->view(); @@ -466,7 +528,7 @@ final class AccountFileController extends ControllerBase implements CrudControll * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/AccountHistoryManagerController.php b/app/modules/web/Controllers/AccountHistoryManagerController.php index beb432cc..3c96bcef 100644 --- a/app/modules/web/Controllers/AccountHistoryManagerController.php +++ b/app/modules/web/Controllers/AccountHistoryManagerController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -27,13 +27,12 @@ namespace SP\Modules\Web\Controllers; use DI\DependencyException; use DI\NotFoundException; use Exception; -use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; use SP\Core\Exceptions\SessionTimeout; -use SP\Core\Exceptions\SPException; use SP\Html\DataGrid\DataGridInterface; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\AccountHistoryGrid; @@ -52,23 +51,23 @@ final class AccountHistoryManagerController extends ControllerBase { use JsonTrait, ItemTrait; - /** - * @var AccountHistoryService - */ - protected $accountHistoryService; + protected ?AccountHistoryService $accountHistoryService = null; /** * @return bool - * @throws DependencyException - * @throws NotFoundException - * @throws ConstraintException - * @throws QueryException - * @throws SPException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::ACCOUNTMGR_HISTORY_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::ACCOUNTMGR_HISTORY_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); @@ -88,11 +87,17 @@ final class AccountHistoryManagerController extends ControllerBase */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $historyGrid = $this->dic->get(AccountHistoryGrid::class); - return $historyGrid->updatePager($historyGrid->getGrid($this->accountHistoryService->search($itemSearchData)), $itemSearchData); + return $historyGrid->updatePager( + $historyGrid->getGrid($this->accountHistoryService->search($itemSearchData)), + $itemSearchData + ); } /** @@ -101,8 +106,9 @@ final class AccountHistoryManagerController extends ControllerBase * @param int|null $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function deleteAction(?int $id = null): bool { @@ -110,28 +116,46 @@ final class AccountHistoryManagerController extends ControllerBase if ($id === null) { $this->accountHistoryService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); - $this->eventDispatcher->notifyEvent('delete.accountHistory.selection', - new Event($this, EventMessage::factory()->addDescription(__u('Accounts removed'))) + $this->eventDispatcher->notifyEvent( + 'delete.accountHistory.selection', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Accounts removed')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Accounts removed')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Accounts removed') + ); } $accountDetails = $this->accountHistoryService->getById($id); $this->accountHistoryService->delete($id); - $this->eventDispatcher->notifyEvent('delete.accountHistory', - new Event($this, EventMessage::factory() - ->addDescription(__u('Account removed')) - ->addDetail(__u('Account'), $accountDetails->getName()) - ->addDetail(__u('Client'), $accountDetails->getClientName())) + $this->eventDispatcher->notifyEvent( + 'delete.accountHistory', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Account removed')) + ->addDetail(__u('Account'), $accountDetails->getName()) + ->addDetail(__u('Client'), $accountDetails->getClientName()) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Account removed')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Account removed') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -143,8 +167,9 @@ final class AccountHistoryManagerController extends ControllerBase * @param int $id Account's history ID * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function restoreAction(int $id): bool { @@ -159,18 +184,28 @@ final class AccountHistoryManagerController extends ControllerBase $accountService->createFromHistory($accountDetails); } - $this->eventDispatcher->notifyEvent('restore.accountHistory', - new Event($this, EventMessage::factory() - ->addDescription(__u('Account restored')) - ->addDetail(__u('Account'), $accountDetails->getName()) - ->addDetail(__u('Client'), $accountDetails->getClientName())) + $this->eventDispatcher->notifyEvent( + 'restore.accountHistory', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Account restored')) + ->addDetail(__u('Account'), $accountDetails->getName()) + ->addDetail(__u('Client'), $accountDetails->getClientName()) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Account restored')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Account restored') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -184,7 +219,7 @@ final class AccountHistoryManagerController extends ControllerBase * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/AccountManagerController.php b/app/modules/web/Controllers/AccountManagerController.php index 939f7914..8c626173 100644 --- a/app/modules/web/Controllers/AccountManagerController.php +++ b/app/modules/web/Controllers/AccountManagerController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -28,6 +28,7 @@ use DI\DependencyException; use DI\NotFoundException; use Exception; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -63,14 +64,8 @@ final class AccountManagerController extends ControllerBase { use JsonTrait, ItemTrait; - /** - * @var AccountService - */ - protected $accountService; - /** - * @var AccountSearchService - */ - protected $accountSearchService; + protected ?AccountService $accountService = null; + protected ?AccountSearchService $accountSearchService = null; /** * @return bool @@ -79,11 +74,15 @@ final class AccountManagerController extends ControllerBase * @throws ConstraintException * @throws QueryException * @throws SPException + * @throws \JsonException */ public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::ACCOUNTMGR_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::ACCOUNTMGR_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); @@ -104,15 +103,21 @@ final class AccountManagerController extends ControllerBase */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $accountGrid = $this->dic->get(AccountGrid::class); $filter = new AccountSearchFilter(); $filter->setLimitCount($itemSearchData->getLimitCount()); $filter->setLimitStart($itemSearchData->getLimitStart()); - $filter->setStringFilters($this->accountSearchService->analyzeQueryFilters($itemSearchData->getSeachString())); - $filter->setCleanTxtSearch($this->accountSearchService->getCleanString()); + + if (!empty($itemSearchData->getSeachString())) { + $filter->setStringFilters($this->accountSearchService->analyzeQueryFilters($itemSearchData->getSeachString())); + $filter->setCleanTxtSearch($this->accountSearchService->getCleanString()); + } return $accountGrid->updatePager( $accountGrid->getGrid( @@ -126,8 +131,9 @@ final class AccountManagerController extends ControllerBase * @param int|null $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function deleteAction(?int $id = null): bool { @@ -135,29 +141,46 @@ final class AccountManagerController extends ControllerBase if ($id === null) { $this->accountService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); - $this->deleteCustomFieldsForItem(Acl::ACCOUNT, $id); + $this->deleteCustomFieldsForItem(ActionsInterface::ACCOUNT, $id); - $this->eventDispatcher->notifyEvent('delete.account.selection', - new Event($this, EventMessage::factory()->addDescription(__u('Accounts removed'))) + $this->eventDispatcher->notifyEvent( + 'delete.account.selection', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Accounts removed')) + ) ); - return $this->returnJsonResponseData(JsonResponse::JSON_SUCCESS, __u('Accounts removed')); + return $this->returnJsonResponseData( + JsonResponse::JSON_SUCCESS, + __u('Accounts removed') + ); } - $accountDetails = $this->accountService->getById($id)->getAccountVData(); + $accountDetails = $this->accountService + ->getById($id) + ->getAccountVData(); $this->accountService->delete($id); - $this->deleteCustomFieldsForItem(Acl::ACCOUNT, $id); + $this->deleteCustomFieldsForItem(ActionsInterface::ACCOUNT, $id); - $this->eventDispatcher->notifyEvent('delete.account', - new Event($this, EventMessage::factory() - ->addDescription(__u('Account removed')) - ->addDetail(__u('Account'), $accountDetails->getName()) - ->addDetail(__u('Client'), $accountDetails->getClientName())) + $this->eventDispatcher->notifyEvent( + 'delete.account', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Account removed')) + ->addDetail(__u('Account'), $accountDetails->getName()) + ->addDetail(__u('Client'), $accountDetails->getClientName()) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Account removed')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Account removed') + ); } catch (Exception $e) { processException($e); @@ -171,12 +194,13 @@ final class AccountManagerController extends ControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ public function saveBulkEditAction(): bool { try { $form = new AccountForm($this->dic); - $form->validate(Acl::ACCOUNTMGR_BULK_EDIT); + $form->validate(ActionsInterface::ACCOUNTMGR_BULK_EDIT); $request = new AccountBulkRequest( Util::itemsIdAdapter($this->request->analyzeString('itemsId')), @@ -190,14 +214,19 @@ final class AccountManagerController extends ControllerBase $this->accountService->updateBulk($request); -// $this->updateCustomFieldsForItem(Acl::ACCOUNT, $id, $this->request); - - $this->eventDispatcher->notifyEvent('edit.account.bulk', - new Event($this, EventMessage::factory() - ->addDescription(__u('Accounts updated'))) + $this->eventDispatcher->notifyEvent( + 'edit.account.bulk', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Accounts updated')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Accounts updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Accounts updated') + ); } catch (Exception $e) { processException($e); @@ -209,14 +238,18 @@ final class AccountManagerController extends ControllerBase * bulkEditAction * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function bulkEditAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::ACCOUNTMGR)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::ACCOUNTMGR)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('Bulk Update')); @@ -226,7 +259,10 @@ final class AccountManagerController extends ControllerBase $this->setViewData(); - $this->eventDispatcher->notifyEvent('show.account.bulkEdit', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.account.bulkEdit', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { @@ -239,7 +275,7 @@ final class AccountManagerController extends ControllerBase /** * Sets view data */ - protected function setViewData() + protected function setViewData(): void { $this->view->addTemplate('account_bulkedit', 'itemshow'); @@ -276,7 +312,7 @@ final class AccountManagerController extends ControllerBase * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/AuthTokenController.php b/app/modules/web/Controllers/AuthTokenController.php index 11e3698d..641cf82c 100644 --- a/app/modules/web/Controllers/AuthTokenController.php +++ b/app/modules/web/Controllers/AuthTokenController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -28,6 +28,7 @@ use DI\DependencyException; use DI\NotFoundException; use Exception; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -58,10 +59,7 @@ final class AuthTokenController extends ControllerBase implements CrudController { use JsonTrait, ItemTrait; - /** - * @var AuthTokenService - */ - protected $authTokenService; + protected ?AuthTokenService $authTokenService = null; /** * Search action @@ -72,15 +70,22 @@ final class AuthTokenController extends ControllerBase implements CrudController * @throws ConstraintException * @throws QueryException * @throws SPException + * @throws \JsonException */ - public function searchAction() + public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); - $this->view->assign('index', $this->request->analyzeInt('activetab', 0)); + $this->view->assign( + 'index', + $this->request->analyzeInt('activetab', 0) + ); $this->view->assign('data', $this->getSearchGrid()); return $this->returnJsonResponseData(['html' => $this->render()]); @@ -96,7 +101,10 @@ final class AuthTokenController extends ControllerBase implements CrudController */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $authTokenGrid = $this->dic->get(AuthTokenGrid::class); @@ -108,14 +116,18 @@ final class AuthTokenController extends ControllerBase implements CrudController /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function createAction() + public function createAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('New Authorization')); @@ -124,13 +136,19 @@ final class AuthTokenController extends ControllerBase implements CrudController $this->setViewData(); - $this->eventDispatcher->notifyEvent('show.authToken.create', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.authToken.create', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -148,18 +166,31 @@ final class AuthTokenController extends ControllerBase implements CrudController * @throws SPException * @throws ServiceException */ - protected function setViewData(?int $authTokenId = null) + protected function setViewData(?int $authTokenId = null): void { $this->view->addTemplate('auth_token', 'itemshow'); - $authToken = $authTokenId ? $this->authTokenService->getById($authTokenId) : new AuthTokenData(); + $authToken = $authTokenId + ? $this->authTokenService->getById($authTokenId) + : new AuthTokenData(); $this->view->assign('authToken', $authToken); - $this->view->assign('users', SelectItemAdapter::factory(UserService::getItemsBasic())->getItemsFromModelSelected([$authToken->getUserId()])); - $this->view->assign('actions', SelectItemAdapter::factory(AuthTokenService::getTokenActions())->getItemsFromArraySelected([$authToken->getActionId()])); + $this->view->assign( + 'users', + SelectItemAdapter::factory(UserService::getItemsBasic()) + ->getItemsFromModelSelected([$authToken->getUserId()]) + ); + $this->view->assign( + 'actions', + SelectItemAdapter::factory(AuthTokenService::getTokenActions()) + ->getItemsFromArraySelected([$authToken->getActionId()]) + ); - $this->view->assign('nextAction', Acl::getActionRoute(Acl::ACCESS_MANAGE)); + $this->view->assign( + 'nextAction', + Acl::getActionRoute(ActionsInterface::ACCESS_MANAGE) + ); if ($this->view->isView === true) { $this->view->assign('disabled', 'disabled'); @@ -169,7 +200,10 @@ final class AuthTokenController extends ControllerBase implements CrudController $this->view->assign('readonly', false); } - $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::AUTHTOKEN, $authTokenId)); + $this->view->assign( + 'customFields', + $this->getCustomFieldsForItem(ActionsInterface::AUTHTOKEN, $authTokenId) + ); } /** @@ -178,14 +212,18 @@ final class AuthTokenController extends ControllerBase implements CrudController * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function editAction(int $id) + public function editAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('Edit Authorization')); @@ -195,7 +233,10 @@ final class AuthTokenController extends ControllerBase implements CrudController $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.authToken.edit', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.authToken.edit', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { @@ -215,44 +256,64 @@ final class AuthTokenController extends ControllerBase implements CrudController * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): bool { try { - if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_DELETE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_DELETE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } if ($id === null) { - $this->authTokenService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); + $this->authTokenService + ->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); - $this->deleteCustomFieldsForItem(Acl::AUTHTOKEN, $id); + $this->deleteCustomFieldsForItem(ActionsInterface::AUTHTOKEN, $id); - $this->eventDispatcher->notifyEvent('delete.authToken.selection', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'delete.authToken.selection', + new Event( + $this, EventMessage::factory() - ->addDescription(__u('Authorizations deleted'))) + ->addDescription(__u('Authorizations deleted')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Authorizations deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Authorizations deleted') + ); } $this->authTokenService->delete($id); - $this->deleteCustomFieldsForItem(Acl::AUTHTOKEN, $id); + $this->deleteCustomFieldsForItem(ActionsInterface::AUTHTOKEN, $id); - $this->eventDispatcher->notifyEvent('delete.authToken', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'delete.authToken', + new Event( + $this, EventMessage::factory() ->addDescription(__u('Authorization deleted')) - ->addDetail(__u('Authorization'), $id)) + ->addDetail(__u('Authorization'), $id) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Authorization deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Authorization deleted') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -262,33 +323,52 @@ final class AuthTokenController extends ControllerBase implements CrudController * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function saveCreateAction() + public function saveCreateAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } - $form = new AuthTokenForm($this->dic); - $form->validate(Acl::AUTHTOKEN_CREATE); + $form->validate(ActionsInterface::AUTHTOKEN_CREATE); $apiTokenData = $form->getItemData(); $id = $this->authTokenService->create($apiTokenData); - $this->addCustomFieldsForItem(Acl::AUTHTOKEN, $id, $this->request); + $this->addCustomFieldsForItem( + ActionsInterface::AUTHTOKEN, + $id, + $this->request + ); - $this->eventDispatcher->notifyEvent('create.authToken', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'create.authToken', + new Event($this) + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Authorization added')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Authorization added') + ); } catch (ValidationException $e) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage()); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + $e->getMessage() + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -302,47 +382,69 @@ final class AuthTokenController extends ControllerBase implements CrudController * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function saveEditAction(int $id) + public function saveEditAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new AuthTokenForm($this->dic, $id); - $form->validate(Acl::AUTHTOKEN_EDIT); + $form->validate(ActionsInterface::AUTHTOKEN_EDIT); if ($form->isRefresh()) { $this->authTokenService->refreshAndUpdate($form->getItemData()); - $this->eventDispatcher->notifyEvent('refresh.authToken', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'refresh.authToken', + new Event( + $this, EventMessage::factory() ->addDescription(__u('Authorization updated')) - ->addDetail(__u('Authorization'), $id)) + ->addDetail(__u('Authorization'), $id) + ) ); } else { $this->authTokenService->update($form->getItemData()); $this->eventDispatcher->notifyEvent('edit.authToken', - new Event($this, + new Event( + $this, EventMessage::factory() ->addDescription(__u('Authorization updated')) - ->addDetail(__u('Authorization'), $id)) + ->addDetail(__u('Authorization'), $id) + ) ); } - $this->updateCustomFieldsForItem(Acl::AUTHTOKEN, $id, $this->request); + $this->updateCustomFieldsForItem( + ActionsInterface::AUTHTOKEN, + $id, + $this->request + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Authorization updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Authorization updated') + ); } catch (ValidationException $e) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage()); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + $e->getMessage() + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -356,12 +458,16 @@ final class AuthTokenController extends ControllerBase implements CrudController * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function viewAction(int $id) + public function viewAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_VIEW)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_VIEW)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('View Authorization')); @@ -370,17 +476,24 @@ final class AuthTokenController extends ControllerBase implements CrudController $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.authToken', - new Event($this, EventMessage::factory() - ->addDescription(__u('Authorization viewed')) - ->addDetail(__u('Authorization'), $id)) + $this->eventDispatcher->notifyEvent( + 'show.authToken', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Authorization viewed')) + ->addDetail(__u('Authorization'), $id) + ) ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -394,7 +507,7 @@ final class AuthTokenController extends ControllerBase implements CrudController * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/BootstrapController.php b/app/modules/web/Controllers/BootstrapController.php index 41c66f83..5428fe3b 100644 --- a/app/modules/web/Controllers/BootstrapController.php +++ b/app/modules/web/Controllers/BootstrapController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -96,7 +96,10 @@ final class BootstrapController extends SimpleControllerBase private function getNotificationsEnabled(): bool { if ($this->session->isLoggedIn()) { - return $this->session->getUserData()->getPreferences()->isCheckNotifications(); + return $this->session + ->getUserData() + ->getPreferences() + ->isCheckNotifications(); } return false; @@ -107,7 +110,10 @@ final class BootstrapController extends SimpleControllerBase */ private function getCookiesEnabled(): bool { - return $this->router->request()->cookies()->get(session_name()) !== null; + return $this->router + ->request() + ->cookies() + ->get(session_name()) !== null; } /** @@ -143,7 +149,8 @@ final class BootstrapController extends SimpleControllerBase private function getPublicKey(): string { try { - return $this->session->getPublicKey() ?: $this->dic->get(CryptPKI::class)->getPublicKey(); + return $this->session->getPublicKey() + ?: $this->dic->get(CryptPKI::class)->getPublicKey(); } catch (FileException $e) { processException($e); @@ -151,14 +158,6 @@ final class BootstrapController extends SimpleControllerBase } } - /** - * @return void - */ - protected function initialize() - { - // TODO: Implement initialize() method. - } - /** * Generate the CSRF token if not set * @@ -170,4 +169,12 @@ final class BootstrapController extends SimpleControllerBase return $this->session->getCSRF(); } + + /** + * @return void + */ + protected function initialize(): void + { + // TODO: Implement initialize() method. + } } \ No newline at end of file diff --git a/app/modules/web/Controllers/CategoryController.php b/app/modules/web/Controllers/CategoryController.php index 49cc314b..658bc1b8 100644 --- a/app/modules/web/Controllers/CategoryController.php +++ b/app/modules/web/Controllers/CategoryController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -28,6 +28,7 @@ use DI\DependencyException; use DI\NotFoundException; use Exception; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -57,10 +58,7 @@ final class CategoryController extends ControllerBase implements CrudControllerI { use JsonTrait, ItemTrait; - /** - * @var CategoryService - */ - protected $categoryService; + protected ?CategoryService $categoryService = null; /** * Search action @@ -71,15 +69,22 @@ final class CategoryController extends ControllerBase implements CrudControllerI * @throws ConstraintException * @throws QueryException * @throws SPException + * @throws \JsonException */ - public function searchAction() + public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::CATEGORY_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CATEGORY_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); - $this->view->assign('index', $this->request->analyzeInt('activetab', 0)); + $this->view->assign( + 'index', + $this->request->analyzeInt('activetab', 0) + ); $this->view->assign('data', $this->getSearchGrid()); return $this->returnJsonResponseData(['html' => $this->render()]); @@ -95,23 +100,33 @@ final class CategoryController extends ControllerBase implements CrudControllerI */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $itemsGridHelper = $this->dic->get(CategoryGrid::class); - return $itemsGridHelper->updatePager($itemsGridHelper->getGrid($this->categoryService->search($itemSearchData)), $itemSearchData); + return $itemsGridHelper->updatePager( + $itemsGridHelper->getGrid($this->categoryService->search($itemSearchData)), + $itemSearchData + ); } /** * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function createAction() + public function createAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::CATEGORY_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CATEGORY_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('New Category')); @@ -120,13 +135,19 @@ final class CategoryController extends ControllerBase implements CrudControllerI $this->setViewData(); - $this->eventDispatcher->notifyEvent('show.category.create', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.category.create', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -149,11 +170,16 @@ final class CategoryController extends ControllerBase implements CrudControllerI { $this->view->addTemplate('category', 'itemshow'); - $category = $categoryId ? $this->categoryService->getById($categoryId) : new CategoryData(); + $category = $categoryId + ? $this->categoryService->getById($categoryId) + : new CategoryData(); $this->view->assign('category', $category); - $this->view->assign('nextAction', Acl::getActionRoute(Acl::ITEMS_MANAGE)); + $this->view->assign( + 'nextAction', + Acl::getActionRoute(ActionsInterface::ITEMS_MANAGE) + ); if ($this->view->isView === true) { $this->view->assign('disabled', 'disabled'); @@ -163,8 +189,14 @@ final class CategoryController extends ControllerBase implements CrudControllerI $this->view->assign('readonly', false); } - $this->view->assign('showViewCustomPass', $this->acl->checkUserAccess(Acl::CUSTOMFIELD_VIEW_PASS)); - $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::CATEGORY, $categoryId)); + $this->view->assign( + 'showViewCustomPass', + $this->acl->checkUserAccess(ActionsInterface::CUSTOMFIELD_VIEW_PASS) + ); + $this->view->assign( + 'customFields', + $this->getCustomFieldsForItem(ActionsInterface::CATEGORY, $categoryId) + ); } /** @@ -175,12 +207,16 @@ final class CategoryController extends ControllerBase implements CrudControllerI * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function editAction(int $id) + public function editAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::CATEGORY_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CATEGORY_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('Edit Category')); @@ -190,13 +226,19 @@ final class CategoryController extends ControllerBase implements CrudControllerI $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.category.edit', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.category.edit', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -210,44 +252,64 @@ final class CategoryController extends ControllerBase implements CrudControllerI * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): bool { try { - if (!$this->acl->checkUserAccess(Acl::CATEGORY_DELETE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CATEGORY_DELETE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } if ($id === null) { - $this->categoryService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); + $this->categoryService + ->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); - $this->deleteCustomFieldsForItem(Acl::CATEGORY, $id); + $this->deleteCustomFieldsForItem(ActionsInterface::CATEGORY, $id); - $this->eventDispatcher->notifyEvent('delete.category', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'delete.category', + new Event( + $this, EventMessage::factory() - ->addDescription(__u('Categories deleted'))) + ->addDescription(__u('Categories deleted')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Categories deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Categories deleted') + ); } $this->categoryService->delete($id); - $this->deleteCustomFieldsForItem(Acl::CATEGORY, $id); + $this->deleteCustomFieldsForItem(ActionsInterface::CATEGORY, $id); - $this->eventDispatcher->notifyEvent('delete.category', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'delete.category', + new Event( + $this, EventMessage::factory() ->addDescription(__u('Category deleted')) - ->addDetail(__u('Category'), $id)) + ->addDetail(__u('Category'), $id) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Category deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Category deleted') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -257,37 +319,54 @@ final class CategoryController extends ControllerBase implements CrudControllerI * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function saveCreateAction() + public function saveCreateAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::CATEGORY_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CATEGORY_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new CategoryForm($this->dic); - $form->validate(Acl::CATEGORY_CREATE); + $form->validate(ActionsInterface::CATEGORY_CREATE); $itemData = $form->getItemData(); $id = $this->categoryService->create($itemData); - $this->eventDispatcher->notifyEvent('create.category', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'create.category', + new Event( + $this, EventMessage::factory() ->addDescription(__u('Category added')) - ->addDetail(__u('Category'), $itemData->getName())) + ->addDetail(__u('Category'), $itemData->getName()) + ) ); - $this->addCustomFieldsForItem(Acl::CATEGORY, $id, $this->request); + $this->addCustomFieldsForItem( + ActionsInterface::CATEGORY, + $id, + $this->request + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Category added')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Category added') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -301,12 +380,16 @@ final class CategoryController extends ControllerBase implements CrudControllerI * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function saveEditAction(int $id) + public function saveEditAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::CATEGORY_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CATEGORY_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new CategoryForm($this->dic, $id); @@ -316,22 +399,35 @@ final class CategoryController extends ControllerBase implements CrudControllerI $this->categoryService->update($itemData); - $this->eventDispatcher->notifyEvent('edit.category', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'edit.category', + new Event( + $this, EventMessage::factory() ->addDescription(__u('Category updated')) - ->addDetail(__u('Category'), $itemData->getName())) + ->addDetail(__u('Category'), $itemData->getName()) + ) ); - $this->updateCustomFieldsForItem(Acl::CATEGORY, $id, $this->request); + $this->updateCustomFieldsForItem( + ActionsInterface::CATEGORY, + $id, + $this->request + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Category updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Category updated') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -345,12 +441,16 @@ final class CategoryController extends ControllerBase implements CrudControllerI * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function viewAction(int $id) + public function viewAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::CATEGORY_VIEW)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CATEGORY_VIEW)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('View Category')); @@ -358,13 +458,19 @@ final class CategoryController extends ControllerBase implements CrudControllerI $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.category', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.category', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -378,7 +484,7 @@ final class CategoryController extends ControllerBase implements CrudControllerI * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/ClientController.php b/app/modules/web/Controllers/ClientController.php index 31bd2f4e..7f94d375 100644 --- a/app/modules/web/Controllers/ClientController.php +++ b/app/modules/web/Controllers/ClientController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -29,6 +29,7 @@ use DI\DependencyException; use DI\NotFoundException; use Exception; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -58,10 +59,7 @@ final class ClientController extends ControllerBase implements CrudControllerInt { use JsonTrait, ItemTrait; - /** - * @var ClientService - */ - protected $clientService; + protected ?ClientService $clientService = null; /** * Search action @@ -72,15 +70,22 @@ final class ClientController extends ControllerBase implements CrudControllerInt * @throws ConstraintException * @throws QueryException * @throws SPException + * @throws \JsonException */ - public function searchAction() + public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::CLIENT_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CLIENT_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); - $this->view->assign('index', $this->request->analyzeInt('activetab', 0)); + $this->view->assign( + 'index', + $this->request->analyzeInt('activetab', 0) + ); $this->view->assign('data', $this->getSearchGrid()); return $this->returnJsonResponseData(['html' => $this->render()]); @@ -96,23 +101,33 @@ final class ClientController extends ControllerBase implements CrudControllerInt */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $clientGrid = $this->dic->get(ClientGrid::class); - return $clientGrid->updatePager($clientGrid->getGrid($this->clientService->search($itemSearchData)), $itemSearchData); + return $clientGrid->updatePager( + $clientGrid->getGrid($this->clientService->search($itemSearchData)), + $itemSearchData + ); } /** * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function createAction() + public function createAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::CLIENT_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CLIENT_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('New Client')); @@ -121,13 +136,19 @@ final class ClientController extends ControllerBase implements CrudControllerInt $this->setViewData(); - $this->eventDispatcher->notifyEvent('show.client.create', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.client.create', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -146,15 +167,20 @@ final class ClientController extends ControllerBase implements CrudControllerInt * @throws SPException * @throws ServiceException */ - protected function setViewData(?int $clientId = null) + protected function setViewData(?int $clientId = null): void { $this->view->addTemplate('client', 'itemshow'); - $client = $clientId ? $this->clientService->getById($clientId) : new ClientData(); + $client = $clientId + ? $this->clientService->getById($clientId) + : new ClientData(); $this->view->assign('client', $client); - $this->view->assign('nextAction', Acl::getActionRoute(Acl::ITEMS_MANAGE)); + $this->view->assign( + 'nextAction', + Acl::getActionRoute(ActionsInterface::ITEMS_MANAGE) + ); if ($this->view->isView === true) { $this->view->assign('disabled', 'disabled'); @@ -164,8 +190,14 @@ final class ClientController extends ControllerBase implements CrudControllerInt $this->view->assign('readonly', false); } - $this->view->assign('showViewCustomPass', $this->acl->checkUserAccess(Acl::CUSTOMFIELD_VIEW_PASS)); - $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::CLIENT, $clientId)); + $this->view->assign( + 'showViewCustomPass', + $this->acl->checkUserAccess(ActionsInterface::CUSTOMFIELD_VIEW_PASS) + ); + $this->view->assign( + 'customFields', + $this->getCustomFieldsForItem(ActionsInterface::CLIENT, $clientId) + ); } /** @@ -174,14 +206,18 @@ final class ClientController extends ControllerBase implements CrudControllerInt * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function editAction(int $id) + public function editAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::CLIENT_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CLIENT_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('Edit Client')); @@ -190,13 +226,19 @@ final class ClientController extends ControllerBase implements CrudControllerInt $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.client.edit', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.client.edit', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -210,41 +252,63 @@ final class ClientController extends ControllerBase implements CrudControllerInt * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): bool { try { - if (!$this->acl->checkUserAccess(Acl::CLIENT_DELETE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CLIENT_DELETE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } if ($id === null) { - $this->clientService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); + $this->clientService + ->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); - $this->deleteCustomFieldsForItem(Acl::CLIENT, $id); + $this->deleteCustomFieldsForItem(ActionsInterface::CLIENT, $id); - $this->eventDispatcher->notifyEvent('delete.client.selection', - new Event($this, EventMessage::factory() - ->addDescription(__u('Clients deleted'))) + $this->eventDispatcher->notifyEvent( + 'delete.client.selection', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Clients deleted')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Clients deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Clients deleted') + ); } $this->clientService->delete($id); - $this->deleteCustomFieldsForItem(Acl::CLIENT, $id); + $this->deleteCustomFieldsForItem(ActionsInterface::CLIENT, $id); - $this->eventDispatcher->notifyEvent('delete.client', - new Event($this, EventMessage::factory() - ->addDescription(__u('Client deleted')) - ->addDetail(__u('Client'), $id)) + $this->eventDispatcher->notifyEvent( + 'delete.client', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Client deleted')) + ->addDetail(__u('Client'), $id) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Client deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Client deleted') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -254,37 +318,54 @@ final class ClientController extends ControllerBase implements CrudControllerInt * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function saveCreateAction() + public function saveCreateAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::CLIENT_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CLIENT_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new ClientForm($this->dic); - $form->validate(Acl::CLIENT_CREATE); + $form->validate(ActionsInterface::CLIENT_CREATE); $itemData = $form->getItemData(); $id = $this->clientService->create($itemData); - $this->eventDispatcher->notifyEvent('create.client', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'create.client', + new Event( + $this, EventMessage::factory() ->addDescription(__u('Client added')) - ->addDetail(__u('Client'), $itemData->getName())) + ->addDetail(__u('Client'), $itemData->getName()) + ) ); - $this->addCustomFieldsForItem(Acl::CLIENT, $id, $this->request); + $this->addCustomFieldsForItem( + ActionsInterface::CLIENT, + $id, + $this->request + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Client added')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Client added') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -298,35 +379,52 @@ final class ClientController extends ControllerBase implements CrudControllerInt * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function saveEditAction(int $id) + public function saveEditAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::CLIENT_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CLIENT_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new ClientForm($this->dic, $id); - $form->validate(Acl::CLIENT_EDIT); + $form->validate(ActionsInterface::CLIENT_EDIT); $this->clientService->update($form->getItemData()); - $this->eventDispatcher->notifyEvent('edit.client', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'edit.client', + new Event( + $this, EventMessage::factory() ->addDescription(__u('Client updated')) - ->addDetail(__u('Client'), $id)) + ->addDetail(__u('Client'), $id) + ) ); - $this->updateCustomFieldsForItem(Acl::CLIENT, $id, $this->request); + $this->updateCustomFieldsForItem( + ActionsInterface::CLIENT, + $id, + $this->request + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Client updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Client updated') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -340,12 +438,16 @@ final class ClientController extends ControllerBase implements CrudControllerInt * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function viewAction(int $id) + public function viewAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::CLIENT_VIEW)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CLIENT_VIEW)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('View Client')); @@ -353,13 +455,19 @@ final class ClientController extends ControllerBase implements CrudControllerInt $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.client', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.client', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -373,7 +481,7 @@ final class ClientController extends ControllerBase implements CrudControllerInt * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/ConfigAccountController.php b/app/modules/web/Controllers/ConfigAccountController.php index ad852122..97aa5220 100644 --- a/app/modules/web/Controllers/ConfigAccountController.php +++ b/app/modules/web/Controllers/ConfigAccountController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -30,7 +30,6 @@ use SP\Core\Acl\ActionsInterface; use SP\Core\Acl\UnauthorizedPageException; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; -use SP\Core\Exceptions\SessionTimeout; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Traits\ConfigTrait; @@ -47,6 +46,7 @@ final class ConfigAccountController extends SimpleControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ public function saveAction(): bool { @@ -71,7 +71,10 @@ final class ConfigAccountController extends SimpleControllerBase $filesAllowedSize = $this->request->analyzeInt('files_allowed_size', 1024); if ($filesAllowedSize > 16384) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Maximum size per file is 16MB')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Maximum size per file is 16MB') + ); } $configData->setFilesEnabled(true); @@ -119,22 +122,24 @@ final class ConfigAccountController extends SimpleControllerBase } /** - * @return bool - * @throws SessionTimeout - * @throws DependencyException - * @throws NotFoundException + * @return void + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\SessionTimeout */ - protected function initialize() + protected function initialize(): void { try { $this->checks(); $this->checkAccess(ActionsInterface::CONFIG_ACCOUNT); } catch (UnauthorizedPageException $e) { - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); - return $this->returnJsonResponseException($e); + $this->returnJsonResponseException($e); } - - return true; } } \ No newline at end of file diff --git a/app/modules/web/Controllers/ConfigBackupController.php b/app/modules/web/Controllers/ConfigBackupController.php index 9198dc66..6c0d3fdb 100644 --- a/app/modules/web/Controllers/ConfigBackupController.php +++ b/app/modules/web/Controllers/ConfigBackupController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -27,7 +27,7 @@ namespace SP\Modules\Web\Controllers; use DI\DependencyException; use DI\NotFoundException; use Exception; -use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Acl\UnauthorizedPageException; use SP\Core\Context\SessionContext; use SP\Core\Events\Event; @@ -53,11 +53,15 @@ final class ConfigBackupController extends SimpleControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ public function fileBackupAction(): bool { if ($this->config->getConfigData()->isDemoEnabled()) { - return $this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Ey, this is a DEMO!!')); + return $this->returnJsonResponse( + JsonResponse::JSON_WARNING, + __u('Ey, this is a DEMO!!') + ); } try { @@ -66,12 +70,19 @@ final class ConfigBackupController extends SimpleControllerBase $this->dic->get(FileBackupService::class) ->doBackup(BACKUP_PATH); - $this->eventDispatcher->notifyEvent('run.backup.end', - new Event($this, EventMessage::factory() - ->addDescription(__u('Application and database backup completed successfully'))) + $this->eventDispatcher->notifyEvent(' + run.backup.end', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Application and database backup completed successfully')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Backup process finished')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Backup process finished') + ); } catch (Exception $e) { processException($e); @@ -85,6 +96,7 @@ final class ConfigBackupController extends SimpleControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ public function xmlExportAction(): bool { @@ -92,13 +104,20 @@ final class ConfigBackupController extends SimpleControllerBase $exportPasswordR = $this->request->analyzeEncrypted('exportPwdR'); if (!empty($exportPassword) && $exportPassword !== $exportPasswordR) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Passwords do not match')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Passwords do not match') + ); } try { - $this->eventDispatcher->notifyEvent('run.export.start', - new Event($this, EventMessage::factory() - ->addDescription(__u('sysPass XML export'))) + $this->eventDispatcher->notifyEvent( + 'run.export.start', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('sysPass XML export')) + ) ); SessionContext::close(); @@ -106,41 +125,57 @@ final class ConfigBackupController extends SimpleControllerBase $export = $this->dic->get(XmlExportService::class); $export->doExport(BACKUP_PATH, $exportPassword); - $this->eventDispatcher->notifyEvent('run.export.end', - new Event($this, EventMessage::factory() - ->addDescription(__u('Export process finished'))) + $this->eventDispatcher->notifyEvent( + 'run.export.end', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Export process finished')) + ) ); $verify = $this->dic->get(XmlVerifyService::class); if ($export->isEncrypted()) { - $verifyResult = $verify->verifyEncrypted($export->getExportFile(), $exportPassword); + $verifyResult = $verify->verifyEncrypted( + $export->getExportFile(), + $exportPassword + ); } else { $verifyResult = $verify->verify($export->getExportFile()); } $nodes = $verifyResult->getNodes(); - $this->eventDispatcher->notifyEvent('run.export.verify', - new Event($this, EventMessage::factory() - ->addDescription(__u('Verification of exported data finished')) - ->addDetail(__u('Version'), $verifyResult->getVersion()) - ->addDetail(__u('Encrypted'), $verifyResult->isEncrypted() ? __u('Yes') : __u('No')) - ->addDetail(__u('Accounts'), $nodes['Account']) - ->addDetail(__u('Clients'), $nodes['Client']) - ->addDetail(__u('Categories'), $nodes['Category']) - ->addDetail(__u('Tags'), $nodes['Tag']) + $this->eventDispatcher->notifyEvent( + 'run.export.verify', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Verification of exported data finished')) + ->addDetail(__u('Version'), $verifyResult->getVersion()) + ->addDetail(__u('Encrypted'), $verifyResult->isEncrypted() ? __u('Yes') : __u('No')) + ->addDetail(__u('Accounts'), $nodes['Account']) + ->addDetail(__u('Clients'), $nodes['Client']) + ->addDetail(__u('Categories'), $nodes['Category']) + ->addDetail(__u('Tags'), $nodes['Tag']) ) ); // Create the XML archive after verifying the export integrity $export->createArchive(); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Export process finished')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Export process finished') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -154,32 +189,44 @@ final class ConfigBackupController extends SimpleControllerBase try { SessionContext::close(); - $filePath = XmlExportService::getExportFilename(BACKUP_PATH, $this->configData->getExportHash(), true); + $filePath = XmlExportService::getExportFilename( + BACKUP_PATH, + $this->configData->getExportHash(), + true + ); $file = new FileHandler($filePath); $file->checkFileExists(); - $this->eventDispatcher->notifyEvent('download.exportFile', - new Event($this, EventMessage::factory() - ->addDescription(__u('File downloaded')) - ->addDetail(__u('File'), str_replace(APP_ROOT, '', $file->getFile()))) + $this->eventDispatcher->notifyEvent( + 'download.exportFile', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('File downloaded')) + ->addDetail(__u('File'), str_replace(APP_ROOT, '', $file->getFile())) + ) ); - $response = $this->router->response(); - $response->header('Cache-Control', 'max-age=60, must-revalidate'); - $response->header('Content-length', $file->getFileSize()); - $response->header('Content-type', $file->getFileType()); - $response->header('Content-Description', ' sysPass file'); - $response->header('Content-transfer-encoding', 'chunked'); - $response->header('Content-Disposition', 'attachment; filename="' . basename($file->getFile()) . '"'); - $response->header('Set-Cookie', 'fileDownload=true; path=/'); - $response->send(); + $this->router + ->response() + ->header('Cache-Control', 'max-age=60, must-revalidate') + ->header('Content-length', $file->getFileSize()) + ->header('Content-type', $file->getFileType()) + ->header('Content-Description', ' sysPass file') + ->header('Content-transfer-encoding', 'chunked') + ->header('Content-Disposition', 'attachment; filename="' . basename($file->getFile()) . '"') + ->header('Set-Cookie', 'fileDownload=true; path=/') + ->send(); $file->readChunked(); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); } return ''; @@ -197,32 +244,44 @@ final class ConfigBackupController extends SimpleControllerBase try { SessionContext::close(); - $filePath = FileBackupService::getAppBackupFilename(BACKUP_PATH, $this->configData->getBackupHash(), true); + $filePath = FileBackupService::getAppBackupFilename( + BACKUP_PATH, + $this->configData->getBackupHash(), + true + ); $file = new FileHandler($filePath); $file->checkFileExists(); - $this->eventDispatcher->notifyEvent('download.backupAppFile', - new Event($this, EventMessage::factory() - ->addDescription(__u('File downloaded')) - ->addDetail(__u('File'), str_replace(APP_ROOT, '', $file->getFile()))) + $this->eventDispatcher->notifyEvent( + 'download.backupAppFile', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('File downloaded')) + ->addDetail(__u('File'), str_replace(APP_ROOT, '', $file->getFile())) + ) ); - $response = $this->router->response(); - $response->header('Cache-Control', 'max-age=60, must-revalidate'); - $response->header('Content-length', $file->getFileSize()); - $response->header('Content-type', $file->getFileType()); - $response->header('Content-Description', ' sysPass file'); - $response->header('Content-transfer-encoding', 'chunked'); - $response->header('Content-Disposition', 'attachment; filename="' . basename($file->getFile()) . '"'); - $response->header('Set-Cookie', 'fileDownload=true; path=/'); - $response->send(); + $this->router + ->response() + ->header('Cache-Control', 'max-age=60, must-revalidate') + ->header('Content-length', $file->getFileSize()) + ->header('Content-type', $file->getFileType()) + ->header('Content-Description', ' sysPass file') + ->header('Content-transfer-encoding', 'chunked') + ->header('Content-Disposition', 'attachment; filename="' . basename($file->getFile()) . '"') + ->header('Set-Cookie', 'fileDownload=true; path=/') + ->send(); $file->readChunked(); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); } return ''; @@ -240,32 +299,44 @@ final class ConfigBackupController extends SimpleControllerBase try { SessionContext::close(); - $filePath = FileBackupService::getDbBackupFilename(BACKUP_PATH, $this->configData->getBackupHash(), true); + $filePath = FileBackupService::getDbBackupFilename( + BACKUP_PATH, + $this->configData->getBackupHash(), + true + ); $file = new FileHandler($filePath); $file->checkFileExists(); - $this->eventDispatcher->notifyEvent('download.backupDbFile', - new Event($this, EventMessage::factory() - ->addDescription(__u('File downloaded')) - ->addDetail(__u('File'), str_replace(APP_ROOT, '', $file->getFile()))) + $this->eventDispatcher->notifyEvent( + 'download.backupDbFile', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('File downloaded')) + ->addDetail(__u('File'), str_replace(APP_ROOT, '', $file->getFile())) + ) ); - $response = $this->router->response(); - $response->header('Cache-Control', 'max-age=60, must-revalidate'); - $response->header('Content-length', $file->getFileSize()); - $response->header('Content-type', $file->getFileType()); - $response->header('Content-Description', ' sysPass file'); - $response->header('Content-transfer-encoding', 'chunked'); - $response->header('Content-Disposition', 'attachment; filename="' . basename($file->getFile()) . '"'); - $response->header('Set-Cookie', 'fileDownload=true; path=/'); - $response->send(); + $this->router + ->response() + ->header('Cache-Control', 'max-age=60, must-revalidate') + ->header('Content-length', $file->getFileSize()) + ->header('Content-type', $file->getFileType()) + ->header('Content-Description', ' sysPass file') + ->header('Content-transfer-encoding', 'chunked') + ->header('Content-Disposition', 'attachment; filename="' . basename($file->getFile()) . '"') + ->header('Set-Cookie', 'fileDownload=true; path=/') + ->send(); $file->readChunked(); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); } return ''; @@ -277,14 +348,18 @@ final class ConfigBackupController extends SimpleControllerBase * @throws DependencyException * @throws NotFoundException * @throws SessionTimeout + * @throws \JsonException */ - protected function initialize() + protected function initialize(): void { try { $this->checks(); - $this->checkAccess(Acl::CONFIG_BACKUP); + $this->checkAccess(ActionsInterface::CONFIG_BACKUP); } catch (UnauthorizedPageException $e) { - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); $this->returnJsonResponseException($e); } diff --git a/app/modules/web/Controllers/ConfigDokuWikiController.php b/app/modules/web/Controllers/ConfigDokuWikiController.php index e683b232..4c1bcc96 100644 --- a/app/modules/web/Controllers/ConfigDokuWikiController.php +++ b/app/modules/web/Controllers/ConfigDokuWikiController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,18 +19,17 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; use DI\DependencyException; use DI\NotFoundException; -use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Acl\UnauthorizedPageException; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; -use SP\Core\Exceptions\SessionTimeout; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Traits\ConfigTrait; @@ -47,6 +46,7 @@ final class ConfigDokuWikiController extends SimpleControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ public function saveAction(): bool { @@ -63,7 +63,10 @@ final class ConfigDokuWikiController extends SimpleControllerBase // Valores para la conexión a la API de DokuWiki if ($dokuWikiEnabled && (!$dokuWikiUrl || !$dokuWikiUrlBase)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Missing DokuWiki parameters')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Missing DokuWiki parameters') + ); } if ($dokuWikiEnabled) { @@ -77,34 +80,42 @@ final class ConfigDokuWikiController extends SimpleControllerBase if ($configData->isDokuwikiEnabled() === false) { $eventMessage->addDescription(__u('DokuWiki enabled')); } - } elseif ($dokuWikiEnabled === false && $configData->isDokuwikiEnabled()) { + } elseif ($configData->isDokuwikiEnabled()) { $configData->setDokuwikiEnabled(false); $eventMessage->addDescription(__u('DokuWiki disabled')); } - return $this->saveConfig($configData, $this->config, function () use ($eventMessage) { - $this->eventDispatcher->notifyEvent('save.config.dokuwiki', new Event($this, $eventMessage)); - }); + return $this->saveConfig( + $configData, + $this->config, + function () use ($eventMessage) { + $this->eventDispatcher->notifyEvent( + 'save.config.dokuwiki', + new Event($this, $eventMessage) + ); + }); } /** - * @return bool - * @throws SessionTimeout - * @throws DependencyException - * @throws NotFoundException + * @return void + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\SessionTimeout */ - protected function initialize() + protected function initialize(): void { try { $this->checks(); - $this->checkAccess(Acl::CONFIG_WIKI); + $this->checkAccess(ActionsInterface::CONFIG_WIKI); } catch (UnauthorizedPageException $e) { - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); - return $this->returnJsonResponseException($e); + $this->returnJsonResponseException($e); } - - return true; } } \ No newline at end of file diff --git a/app/modules/web/Controllers/ConfigEncryptionController.php b/app/modules/web/Controllers/ConfigEncryptionController.php index 92263f68..925b607d 100644 --- a/app/modules/web/Controllers/ConfigEncryptionController.php +++ b/app/modules/web/Controllers/ConfigEncryptionController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -27,23 +27,18 @@ namespace SP\Modules\Web\Controllers; use DI\DependencyException; use DI\NotFoundException; use Exception; -use SP\Core\Acl\Acl; use SP\Core\Acl\ActionsInterface; use SP\Core\Acl\UnauthorizedPageException; use SP\Core\Crypt\Hash; use SP\Core\Crypt\Session as CryptSession; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; -use SP\Core\Exceptions\SessionTimeout; -use SP\Core\Exceptions\SPException; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Traits\JsonTrait; -use SP\Repositories\NoSuchItemException; use SP\Services\Config\ConfigService; use SP\Services\Crypt\MasterPassService; use SP\Services\Crypt\TemporaryMasterPassService; use SP\Services\Crypt\UpdateMasterPassRequest; -use SP\Services\ServiceException; use SP\Services\Task\TaskFactory; /** @@ -57,11 +52,11 @@ final class ConfigEncryptionController extends SimpleControllerBase /** * @return bool - * @throws DependencyException - * @throws NotFoundException - * @throws NoSuchItemException - * @throws ServiceException - * @throws SPException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Repositories\NoSuchItemException + * @throws \SP\Services\ServiceException */ public function saveAction(): bool { @@ -147,15 +142,23 @@ final class ConfigEncryptionController extends SimpleControllerBase $task ); - $this->eventDispatcher->notifyEvent('update.masterPassword.start', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'update.masterPassword.start', + new Event($this) + ); $mastePassService->changeMasterPassword($request); - $this->eventDispatcher->notifyEvent('update.masterPassword.end', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'update.masterPassword.end', + new Event($this) + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', new Event($e) + ); return $this->returnJsonResponseException($e); } finally { @@ -165,15 +168,24 @@ final class ConfigEncryptionController extends SimpleControllerBase } } else { try { - $this->eventDispatcher->notifyEvent('update.masterPassword.hash', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'update.masterPassword.hash', + new Event($this) + ); $mastePassService->updateConfig(Hash::hashKey($newMasterPass)); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Error while saving the Master Password\'s hash')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Error while saving the Master Password\'s hash') + ); } } @@ -190,28 +202,47 @@ final class ConfigEncryptionController extends SimpleControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ public function refreshAction(): bool { try { if ($this->config->getConfigData()->isDemoEnabled()) { - return $this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Ey, this is a DEMO!!')); + return $this->returnJsonResponse( + JsonResponse::JSON_WARNING, + __u('Ey, this is a DEMO!!') + ); } $masterPassService = $this->dic->get(MasterPassService::class); $masterPassService->updateConfig(Hash::hashKey(CryptSession::getSessionKey($this->session))); - $this->eventDispatcher->notifyEvent('refresh.masterPassword.hash', - new Event($this, EventMessage::factory()->addDescription(__u('Master password hash updated')))); + $this->eventDispatcher->notifyEvent( + 'refresh.masterPassword.hash', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Master password hash updated')) + ) + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Master password hash updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Master password hash updated') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Error while updating the master password hash')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Error while updating the master password hash') + ); } } @@ -219,8 +250,9 @@ final class ConfigEncryptionController extends SimpleControllerBase * Create a temporary master pass * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function saveTempAction(): bool { @@ -248,7 +280,10 @@ final class ConfigEncryptionController extends SimpleControllerBase } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponse( JsonResponse::JSON_WARNING, @@ -258,33 +293,41 @@ final class ConfigEncryptionController extends SimpleControllerBase } } - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Temporary password generated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Temporary password generated') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } } /** - * @return bool - * @throws DependencyException - * @throws NotFoundException - * @throws SessionTimeout + * @return void + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\SessionTimeout */ - protected function initialize() + protected function initialize(): void { try { $this->checks(); $this->checkAccess(ActionsInterface::CONFIG_CRYPT); } catch (UnauthorizedPageException $e) { - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); - return $this->returnJsonResponseException($e); + $this->returnJsonResponseException($e); } - - return true; } } \ No newline at end of file diff --git a/app/modules/web/Controllers/ConfigGeneralController.php b/app/modules/web/Controllers/ConfigGeneralController.php index bb6be0a2..50a40793 100644 --- a/app/modules/web/Controllers/ConfigGeneralController.php +++ b/app/modules/web/Controllers/ConfigGeneralController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,22 +19,19 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; -use DI\DependencyException; -use DI\NotFoundException; use Exception; use RuntimeException; use SP\Config\ConfigUtil; -use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Acl\UnauthorizedPageException; use SP\Core\Context\SessionContext; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; -use SP\Core\Exceptions\SessionTimeout; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Traits\ConfigTrait; use SP\Services\Config\ConfigBackupService; @@ -51,9 +48,9 @@ final class ConfigGeneralController extends SimpleControllerBase use ConfigTrait; /** - * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function saveAction(): bool { @@ -91,15 +88,24 @@ final class ConfigGeneralController extends SimpleControllerBase $syslogPort = $this->request->analyzeInt('remotesyslog_port', 0); $configData->setLogEnabled($logEnabled); - $configData->setLogEvents($this->request->analyzeArray('log_events', function ($items) { - return ConfigUtil::eventsAdapter($items); - }, [])); + $configData->setLogEvents( + $this->request->analyzeArray( + 'log_events', + function ($items) { + return ConfigUtil::eventsAdapter($items); + }, + [] + ) + ); $configData->setSyslogEnabled($syslogEnabled); if ($remoteSyslogEnabled) { if (!$syslogServer || !$syslogPort) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Missing remote syslog parameters')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Missing remote syslog parameters') + ); } $configData->setSyslogRemoteEnabled(true); @@ -125,7 +131,10 @@ final class ConfigGeneralController extends SimpleControllerBase // Valores para Proxy if ($proxyEnabled && (!$proxyServer || !$proxyPort)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Missing Proxy parameters ')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Missing Proxy parameters ') + ); } if ($proxyEnabled) { @@ -177,7 +186,10 @@ final class ConfigGeneralController extends SimpleControllerBase $this->config, function () use ($eventMessage, $configData) { if ($configData->isMaintenance()) { - Util::lockApp($this->session->getUserData()->getId(), 'config'); + Util::lockApp( + $this->session->getUserData()->getId(), + 'config' + ); } $this->eventDispatcher->notifyEvent( @@ -188,10 +200,7 @@ final class ConfigGeneralController extends SimpleControllerBase ); } - /** - * @return bool - */ - public function downloadLogAction() + public function downloadLogAction(): string { if ($this->configData->isDemoEnabled()) { return __('Ey, this is a DEMO!!'); @@ -203,10 +212,14 @@ final class ConfigGeneralController extends SimpleControllerBase $file = new FileHandler(LOG_FILE); $file->checkFileExists(); - $this->eventDispatcher->notifyEvent('download.logFile', - new Event($this, EventMessage::factory() - ->addDescription(__u('File downloaded')) - ->addDetail(__u('File'), str_replace(APP_ROOT, '', $file->getFile()))) + $this->eventDispatcher->notifyEvent( + 'download.logFile', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('File downloaded')) + ->addDetail(__u('File'), str_replace(APP_ROOT, '', $file->getFile())) + ) ); $response = $this->router->response(); @@ -223,38 +236,38 @@ final class ConfigGeneralController extends SimpleControllerBase } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); } return ''; } - /** - * @param string $type - * - * @return bool - */ - public function downloadConfigBackupAction(string $type) + public function downloadConfigBackupAction(string $type): string { if ($this->configData->isDemoEnabled()) { return __('Ey, this is a DEMO!!'); } try { - $this->eventDispatcher->notifyEvent('download.configBackupFile', - new Event($this, EventMessage::factory() - ->addDescription(__u('File downloaded')) - ->addDetail(__u('File'), 'config.json')) + $this->eventDispatcher->notifyEvent( + 'download.configBackupFile', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('File downloaded')) + ->addDetail(__u('File'), 'config.json') + ) ); $configBackupService = $this->dic->get(ConfigBackupService::class); - switch ($type) { - case 'json': - $data = ConfigBackupService::configToJson($configBackupService->getBackup()); - break; - default: - throw new RuntimeException('Not implemented'); + if ($type === 'json') { + $data = ConfigBackupService::configToJson($configBackupService->getBackup()); + } else { + throw new RuntimeException('Not implemented'); } $response = $this->router->response(); @@ -273,29 +286,31 @@ final class ConfigGeneralController extends SimpleControllerBase } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); } return ''; } /** - * @return bool - * @throws SessionTimeout - * @throws DependencyException - * @throws NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\SessionTimeout */ - protected function initialize() + protected function initialize(): void { try { $this->checks(); - $this->checkAccess(Acl::CONFIG_GENERAL); + $this->checkAccess(ActionsInterface::CONFIG_GENERAL); } catch (UnauthorizedPageException $e) { - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); - return $this->returnJsonResponseException($e); + $this->returnJsonResponseException($e); } - - return true; } } \ No newline at end of file diff --git a/app/modules/web/Controllers/ConfigImportController.php b/app/modules/web/Controllers/ConfigImportController.php index 21cd2ec2..86bc571f 100644 --- a/app/modules/web/Controllers/ConfigImportController.php +++ b/app/modules/web/Controllers/ConfigImportController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -29,7 +29,7 @@ use DI\NotFoundException; use Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; -use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Acl\UnauthorizedPageException; use SP\Core\Context\SessionContext; use SP\Core\Events\Event; @@ -53,11 +53,15 @@ final class ConfigImportController extends SimpleControllerBase /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface + * @throws \JsonException */ public function importAction(): bool { if ($this->config->getConfigData()->isDemoEnabled()) { - return $this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Ey, this is a DEMO!!')); + return $this->returnJsonResponse( + JsonResponse::JSON_WARNING, + __u('Ey, this is a DEMO!!') + ); } $importParams = new ImportParams(); @@ -75,8 +79,13 @@ final class ConfigImportController extends SimpleControllerBase $counter = $this->dic->get(ImportService::class) ->doImport($importParams, FileImport::fromRequest('inFile', $this->request)); - $this->eventDispatcher->notifyEvent('run.import.end', - new Event($this, EventMessage::factory()->addDetail(__u('Accounts imported'), $counter)) + $this->eventDispatcher->notifyEvent( + 'run.import.end', + new Event( + $this, + EventMessage::factory() + ->addDetail(__u('Accounts imported'), $counter) + ) ); if ($counter > 0) { @@ -95,7 +104,10 @@ final class ConfigImportController extends SimpleControllerBase } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -106,18 +118,20 @@ final class ConfigImportController extends SimpleControllerBase * @throws SessionTimeout * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - protected function initialize() + protected function initialize(): void { try { $this->checks(); - $this->checkAccess(Acl::CONFIG_IMPORT); + $this->checkAccess(ActionsInterface::CONFIG_IMPORT); } catch (UnauthorizedPageException $e) { - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); - return $this->returnJsonResponseException($e); + $this->returnJsonResponseException($e); } - - return true; } } \ No newline at end of file diff --git a/app/modules/web/Controllers/ConfigLdapController.php b/app/modules/web/Controllers/ConfigLdapController.php index a8cf1043..a9580ff3 100644 --- a/app/modules/web/Controllers/ConfigLdapController.php +++ b/app/modules/web/Controllers/ConfigLdapController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -29,12 +29,11 @@ use DI\NotFoundException; use Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; -use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Acl\UnauthorizedPageException; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\CheckException; -use SP\Core\Exceptions\SessionTimeout; use SP\Core\Exceptions\SPException; use SP\Core\Exceptions\ValidationException; use SP\Http\JsonResponse; @@ -59,6 +58,7 @@ final class ConfigLdapController extends SimpleControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ public function saveAction(): bool { @@ -74,8 +74,14 @@ final class ConfigLdapController extends SimpleControllerBase $ldapParams = $this->getLdapParamsFromRequest(); // Valores para la configuración de LDAP - if ($ldapEnabled && !($ldapParams->getServer() || $ldapParams->getSearchBase() || $ldapParams->getBindDn())) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Missing LDAP parameters')); + if ($ldapEnabled + && !($ldapParams->getServer() + || $ldapParams->getSearchBase() + || $ldapParams->getBindDn())) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Missing LDAP parameters') + ); } if ($ldapEnabled) { @@ -108,16 +114,28 @@ final class ConfigLdapController extends SimpleControllerBase $eventMessage->addDescription(__u('LDAP disabled')); } else { - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('No changes')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('No changes') + ); } - return $this->saveConfig($configData, $this->config, function () use ($eventMessage) { - $this->eventDispatcher->notifyEvent('save.config.ldap', new Event($this, $eventMessage)); - }); + return $this->saveConfig( + $configData, + $this->config, + function () use ($eventMessage) { + $this->eventDispatcher->notifyEvent( + 'save.config.ldap', + new Event($this, $eventMessage) + ); + }); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -131,13 +149,13 @@ final class ConfigLdapController extends SimpleControllerBase { $data = LdapParams::getServerAndPort($this->request->analyzeString('ldap_server')); - if ($data === false) { + if (count($data) === 0) { throw new ValidationException(__u('Wrong LDAP parameters')); } $params = new LdapParams(); $params->setServer($data['server']); - $params->setPort(isset($data['port']) ? $data['port'] : 389); + $params->setPort($data['port'] ?? 389); $params->setSearchBase($this->request->analyzeString('ldap_base')); $params->setGroup($this->request->analyzeString('ldap_group')); $params->setBindDn($this->request->analyzeString('ldap_binduser')); @@ -156,6 +174,7 @@ final class ConfigLdapController extends SimpleControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ public function checkAction(): bool { @@ -191,7 +210,10 @@ final class ConfigLdapController extends SimpleControllerBase } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -201,6 +223,7 @@ final class ConfigLdapController extends SimpleControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ public function checkImportAction(): bool { @@ -243,7 +266,10 @@ final class ConfigLdapController extends SimpleControllerBase } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -254,12 +280,16 @@ final class ConfigLdapController extends SimpleControllerBase * * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface + * @throws \JsonException */ public function importAction(): bool { try { if ($this->configData->isDemoEnabled()) { - return $this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Ey, this is a DEMO!!')); + return $this->returnJsonResponse( + JsonResponse::JSON_WARNING, + __u('Ey, this is a DEMO!!') + ); } $ldapImportParams = new LdapImportParams(); @@ -284,9 +314,13 @@ final class ConfigLdapController extends SimpleControllerBase $ldapParams = $this->getLdapParamsFromRequest(); - $this->eventDispatcher->notifyEvent('import.ldap.start', - new Event($this, EventMessage::factory() - ->addDescription(__u('LDAP Import'))) + $this->eventDispatcher->notifyEvent( + 'import.ldap.start', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('LDAP Import')) + ) ); $userLdapService = $this->dic->get(LdapImportService::class); @@ -296,9 +330,13 @@ final class ConfigLdapController extends SimpleControllerBase $userLdapService->importGroups($ldapParams, $ldapImportParams); } - $this->eventDispatcher->notifyEvent('import.ldap.end', - new Event($this, EventMessage::factory() - ->addDescription(__u('Import finished'))) + $this->eventDispatcher->notifyEvent( + 'import.ldap.end', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Import finished')) + ) ); if ($userLdapService->getTotalObjects() === 0) { @@ -317,35 +355,36 @@ final class ConfigLdapController extends SimpleControllerBase } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } } /** - * @return bool - * @throws SessionTimeout - * @throws DependencyException - * @throws NotFoundException + * @return void + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\SessionTimeout */ - protected function initialize() + protected function initialize(): void { try { $this->checks(); - $this->checkAccess(Acl::CONFIG_LDAP); + $this->checkAccess(ActionsInterface::CONFIG_LDAP); $this->extensionChecker->checkLdapAvailable(true); - } catch (UnauthorizedPageException $e) { - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + } catch (UnauthorizedPageException | CheckException $e) { + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); - return $this->returnJsonResponseException($e); - } catch (CheckException $e) { - $this->eventDispatcher->notifyEvent('exception', new Event($e)); - - return $this->returnJsonResponseException($e); + $this->returnJsonResponseException($e); } - - return true; } } diff --git a/app/modules/web/Controllers/ConfigMailController.php b/app/modules/web/Controllers/ConfigMailController.php index 95d7bd3a..56ceb048 100644 --- a/app/modules/web/Controllers/ConfigMailController.php +++ b/app/modules/web/Controllers/ConfigMailController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -28,11 +28,10 @@ use DI\DependencyException; use DI\NotFoundException; use Exception; use SP\Config\ConfigUtil; -use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Acl\UnauthorizedPageException; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; -use SP\Core\Exceptions\SessionTimeout; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Traits\ConfigTrait; use SP\Providers\Mail\MailParams; @@ -51,6 +50,7 @@ final class ConfigMailController extends SimpleControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ public function saveAction(): bool { @@ -73,7 +73,10 @@ final class ConfigMailController extends SimpleControllerBase if ($mailEnabled && (empty($mailServer) || empty($mailFrom)) ) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Missing Mail parameters')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Missing Mail parameters') + ); } if ($mailEnabled) { @@ -110,7 +113,10 @@ final class ConfigMailController extends SimpleControllerBase $eventMessage->addDescription(__u('Mail disabled')); } else { - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('No changes')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('No changes') + ); } return $this->saveConfig( @@ -129,8 +135,9 @@ final class ConfigMailController extends SimpleControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function checkAction() + public function checkAction(): bool { $mailParams = new MailParams(); $mailParams->server = $this->request->analyzeString('mail_server'); @@ -141,7 +148,9 @@ final class ConfigMailController extends SimpleControllerBase $mailRecipients = ConfigUtil::mailAddressesAdapter($this->request->analyzeString('mail_recipients')); // Valores para la configuración del Correo - if (empty($mailParams->server) || empty($mailParams->from) || empty($mailRecipients)) { + if (empty($mailParams->server) + || empty($mailParams->from) + || count($mailRecipients) === 0) { return $this->returnJsonResponse( JsonResponse::JSON_ERROR, __u('Missing Mail parameters') @@ -156,10 +165,14 @@ final class ConfigMailController extends SimpleControllerBase try { $this->dic->get(MailService::class)->check($mailParams, $mailRecipients[0]); - $this->eventDispatcher->notifyEvent('send.mail.check', - new Event($this, EventMessage::factory() - ->addDescription(__u('Email sent')) - ->addDetail(__u('Recipient'), $mailRecipients[0])) + $this->eventDispatcher->notifyEvent( + 'send.mail.check', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Email sent')) + ->addDetail(__u('Recipient'), $mailRecipients[0]) + ) ); return $this->returnJsonResponse( @@ -170,29 +183,34 @@ final class ConfigMailController extends SimpleControllerBase } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } } /** - * @return bool - * @throws DependencyException - * @throws NotFoundException - * @throws SessionTimeout + * @return void + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\SessionTimeout */ - protected function initialize() + protected function initialize(): void { try { $this->checks(); - $this->checkAccess(Acl::CONFIG_MAIL); + $this->checkAccess(ActionsInterface::CONFIG_MAIL); } catch (UnauthorizedPageException $e) { - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); - return $this->returnJsonResponseException($e); + $this->returnJsonResponseException($e); } - - return true; } } \ No newline at end of file diff --git a/app/modules/web/Controllers/ConfigManagerController.php b/app/modules/web/Controllers/ConfigManagerController.php index 1f631dfe..ffa53c63 100644 --- a/app/modules/web/Controllers/ConfigManagerController.php +++ b/app/modules/web/Controllers/ConfigManagerController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -29,6 +29,7 @@ use DI\NotFoundException; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\AppInfoInterface; use SP\Core\Crypt\CryptSessionHandler; use SP\Core\Events\Event; @@ -67,22 +68,17 @@ use SP\Util\Util; /** * Class ConfigManagerController - * - * @package SP\Modules\Web\Controllers */ final class ConfigManagerController extends ControllerBase { - /** - * @var TabsHelper - */ - protected $tabsHelper; + protected ?TabsHelper $tabsHelper = null; /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface * @throws SPException */ - public function indexAction() + public function indexAction(): void { $this->getTabs(); } @@ -94,51 +90,54 @@ final class ConfigManagerController extends ControllerBase * @throws NotFoundExceptionInterface * @throws SPException */ - protected function getTabs() + protected function getTabs(): void { $this->tabsHelper = $this->dic->get(TabsHelper::class); - if ($this->checkAccess(Acl::CONFIG_GENERAL)) { + if ($this->checkAccess(ActionsInterface::CONFIG_GENERAL)) { $this->tabsHelper->addTab($this->getConfigGeneral()); } - if ($this->checkAccess(Acl::CONFIG_ACCOUNT)) { + if ($this->checkAccess(ActionsInterface::CONFIG_ACCOUNT)) { $this->tabsHelper->addTab($this->getAccountConfig()); } - if ($this->checkAccess(Acl::CONFIG_WIKI)) { + if ($this->checkAccess(ActionsInterface::CONFIG_WIKI)) { $this->tabsHelper->addTab($this->getWikiConfig()); } - if ($this->checkAccess(Acl::CONFIG_LDAP)) { + if ($this->checkAccess(ActionsInterface::CONFIG_LDAP)) { $this->tabsHelper->addTab($this->getLdapConfig()); } - if ($this->checkAccess(Acl::CONFIG_MAIL)) { + if ($this->checkAccess(ActionsInterface::CONFIG_MAIL)) { $this->tabsHelper->addTab($this->getMailConfig()); } - if ($this->checkAccess(Acl::CONFIG_CRYPT)) { + if ($this->checkAccess(ActionsInterface::CONFIG_CRYPT)) { $this->tabsHelper->addTab($this->getEncryptionConfig()); } - if ($this->checkAccess(Acl::CONFIG_BACKUP)) { + if ($this->checkAccess(ActionsInterface::CONFIG_BACKUP)) { $this->tabsHelper->addTab($this->getBackupConfig()); } - if ($this->checkAccess(Acl::CONFIG_IMPORT)) { + if ($this->checkAccess(ActionsInterface::CONFIG_IMPORT)) { $this->tabsHelper->addTab($this->getImportConfig()); } - if ($this->checkAccess(Acl::CONFIG_GENERAL)) { + if ($this->checkAccess(ActionsInterface::CONFIG_GENERAL)) { $this->tabsHelper->addTab($this->getInfo()); } - $this->eventDispatcher->notifyEvent('show.config', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.config', + new Event($this) + ); $this->tabsHelper->renderTabs( - Acl::getActionRoute(Acl::CONFIG), + Acl::getActionRoute(ActionsInterface::CONFIG), $this->request->analyzeInt('tabIndex', 0) ); @@ -146,7 +145,6 @@ final class ConfigManagerController extends ControllerBase } /** - * @return DataTab * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface * @throws CheckException @@ -175,7 +173,6 @@ final class ConfigManagerController extends ControllerBase $this->configData->isDemoEnabled() && !$this->userData->getIsAdminApp() ? 'disabled' : '' ); - $template->assign('users', SelectItemAdapter::factory( UserService::getItemsBasic() @@ -195,7 +192,10 @@ final class ConfigManagerController extends ControllerBase $template->assign('curlIsAvailable', $this->extensionChecker->checkCurlAvailable()); - $events = array_merge(LogInterface::EVENTS, $this->configData->getLogEvents()); + $events = array_merge( + LogInterface::EVENTS, + $this->configData->getLogEvents() + ); sort($events, SORT_STRING); @@ -211,7 +211,6 @@ final class ConfigManagerController extends ControllerBase } /** - * @return DataTab * @throws DependencyException * @throws NotFoundException * @throws CheckException @@ -222,19 +221,31 @@ final class ConfigManagerController extends ControllerBase $template = clone $this->view; $template->setBase('config'); $template->addTemplate('accounts'); - $template->assign('gdIsAvailable', $this->extensionChecker->checkGdAvailable()); - - $mimeTypesAvailable = array_map(function ($value) { - return $value['type']; - }, $this->dic->get(MimeTypes::class)->getMimeTypes()); - - $mimeTypes = SelectItemAdapter::factory( - array_merge($mimeTypesAvailable, $this->configData->getFilesAllowedMime()) + $template->assign( + 'gdIsAvailable', + $this->extensionChecker->checkGdAvailable() ); - $template->assign('mimeTypes', $mimeTypes->getItemsFromArraySelected( - $this->configData->getFilesAllowedMime(), - true) + $mimeTypesAvailable = array_map( + static function ($value) { + return $value['type']; + }, + $this->dic->get(MimeTypes::class)->getMimeTypes() + ); + + $mimeTypes = SelectItemAdapter::factory( + array_merge( + $mimeTypesAvailable, + $this->configData->getFilesAllowedMime() + ) + ); + + $template->assign( + 'mimeTypes', + $mimeTypes->getItemsFromArraySelected( + $this->configData->getFilesAllowedMime(), + true + ) ); return new DataTab(__('Accounts'), $template); @@ -250,13 +261,15 @@ final class ConfigManagerController extends ControllerBase $template->setBase('config'); $template->addTemplate('wiki'); - $template->assign('curlIsAvailable', $this->extensionChecker->checkCurlAvailable()); + $template->assign( + 'curlIsAvailable', + $this->extensionChecker->checkCurlAvailable() + ); return new DataTab(__('Wiki'), $template); } /** - * @return DataTab * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface * @throws CheckException @@ -309,7 +322,6 @@ final class ConfigManagerController extends ControllerBase } /** - * @return DataTab * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ @@ -331,19 +343,28 @@ final class ConfigManagerController extends ControllerBase )->getItemsFromModel() ); - $events = array_merge(MailHandler::EVENTS, $this->configData->getMailEvents()); + $mailEvents = $this->configData->getMailEvents(); + + $events = array_merge( + MailHandler::EVENTS, + $mailEvents + ); sort($events, SORT_STRING); - $template->assign('mailEvents', SelectItemAdapter::factory($events) - ->getItemsFromArraySelected($this->configData->getMailEvents(), true) + $template->assign( + 'mailEvents', + SelectItemAdapter::factory($events) + ->getItemsFromArraySelected( + $mailEvents, + true + ) ); return new DataTab(__('Mail'), $template); } /** - * @return DataTab * @throws DependencyException * @throws NotFoundException * @throws ConstraintException @@ -361,36 +382,50 @@ final class ConfigManagerController extends ControllerBase $template->assign('numAccounts', $numAccounts); if ($numAccounts > 150) { - $template->assign('taskId', Task::genTaskId('masterpass')); + $template->assign( + 'taskId', + Task::genTaskId('masterpass') + ); } $configService = $this->dic->get(ConfigService::class); - $template->assign('lastUpdateMPass', + $template->assign( + 'lastUpdateMPass', $configService->getByParam('lastupdatempass', 0) ); - $template->assign('tempMasterPassTime', + $template->assign( + 'tempMasterPassTime', $configService->getByParam(TemporaryMasterPassService::PARAM_TIME, 0) ); - $template->assign('tempMasterMaxTime', + $template->assign( + 'tempMasterMaxTime', $configService->getByParam(TemporaryMasterPassService::PARAM_MAX_TIME, 0) ); - $tempMasterAttempts = sprintf('%d/%d', + $tempMasterAttempts = sprintf( + '%d/%d', $configService->getByParam(TemporaryMasterPassService::PARAM_ATTEMPTS, 0), - TemporaryMasterPassService::MAX_ATTEMPTS); + TemporaryMasterPassService::MAX_ATTEMPTS + ); $template->assign('tempMasterAttempts', $tempMasterAttempts); - $template->assign('tempMasterPass', $this->session->getTemporaryMasterPass()); + $template->assign( + 'tempMasterPass', + $this->session->getTemporaryMasterPass() + ); - $template->assign('userGroups', SelectItemAdapter::factory(UserGroupService::getItemsBasic())->getItemsFromModel()); + $template->assign( + 'userGroups', + SelectItemAdapter::factory(UserGroupService::getItemsBasic()) + ->getItemsFromModel() + ); return new DataTab(__('Encryption'), $template); } /** - * @return DataTab * @throws CheckException */ protected function getBackupConfig(): DataTab @@ -398,8 +433,10 @@ final class ConfigManagerController extends ControllerBase $template = clone $this->view; $template->setBase('config'); $template->addTemplate('backup'); - $template->assign('pharIsAvailable', - $this->extensionChecker->checkPharAvailable()); + $template->assign( + 'pharIsAvailable', + $this->extensionChecker->checkPharAvailable() + ); $template->assign('siteName', AppInfoInterface::APP_NAME); @@ -427,12 +464,14 @@ final class ConfigManagerController extends ControllerBase $backupDbFile->checkFileExists(); $template->assign('hasBackup', true); - $template->assign('lastBackupTime', + $template->assign( + 'lastBackupTime', date('r', $backupAppFile->getFileTime()) ); } catch (FileException $e) { $template->assign('hasBackup', false); - $template->assign('lastBackupTime', + $template->assign( + 'lastBackupTime', __('There aren\'t any backups available') ); } @@ -455,36 +494,36 @@ final class ConfigManagerController extends ControllerBase } /** - * @return DataTab * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function getImportConfig() + protected function getImportConfig(): DataTab { $template = clone $this->view; $template->setBase('config'); $template->addTemplate('import'); - $template->assign('userGroups', SelectItemAdapter::factory( - UserGroupService::getItemsBasic()) - ->getItemsFromModelSelected([$this->userData->getUserGroupId()]) + $template->assign( + 'userGroups', + SelectItemAdapter::factory(UserGroupService::getItemsBasic()) + ->getItemsFromModelSelected([$this->userData->getUserGroupId()]) ); - $template->assign('users', SelectItemAdapter::factory( - UserService::getItemsBasic()) - ->getItemsFromModelSelected([$this->userData->getId()]) + $template->assign( + 'users', + SelectItemAdapter::factory(UserService::getItemsBasic()) + ->getItemsFromModelSelected([$this->userData->getId()]) ); return new DataTab(__('Import Accounts'), $template); } /** - * @return DataTab * @throws DependencyException * @throws NotFoundException * @throws NoSuchItemException * @throws ServiceException */ - protected function getInfo() + protected function getInfo(): DataTab { $template = clone $this->view; $template->setBase('config'); @@ -493,34 +532,43 @@ final class ConfigManagerController extends ControllerBase $databaseUtil = $this->dic->get(DatabaseUtil::class); $template->assign('dbInfo', $databaseUtil->getDBinfo()); - $template->assign('dbName', + $template->assign( + 'dbName', $this->configData->getDbName() . '@' . $this->configData->getDbHost() ); - $template->assign('configBackupDate', + $template->assign( + 'configBackupDate', date('r', $this->dic->get(ConfigService::class)->getByParam('config_backup_date', 0)) ); - $template->assign('plugins', + $template->assign( + 'plugins', $this->dic->get(PluginManager::class)->getLoadedPlugins() ); - $template->assign('locale', + $template->assign( + 'locale', Language::$localeStatus ?: sprintf('%s (%s)', $this->configData->getSiteLang(), __('Not installed')) ); - $template->assign('securedSession', + $template->assign( + 'securedSession', CryptSessionHandler::$isSecured ); - $template->assign('missingExtensions', + $template->assign( + 'missingExtensions', $this->extensionChecker->getMissing() ); - $template->assign('downloadRate', + $template->assign( + 'downloadRate', round(Util::getMaxDownloadChunk() / 1024 / 1024) ); $isDemo = $this->configData->isDemoEnabled(); - $template->assign('downloadConfigBackup', + $template->assign( + 'downloadConfigBackup', !$isDemo && $this->userData->getIsAdminApp() ); - $template->assign('downloadLog', + $template->assign( + 'downloadLog', !$isDemo && is_readable(LOG_FILE) && $this->userData->getIsAdminApp() @@ -529,9 +577,6 @@ final class ConfigManagerController extends ControllerBase return new DataTab(__('Information'), $template); } - /** - * @return TabsHelper - */ public function getTabsHelper(): TabsHelper { return $this->tabsHelper; @@ -543,7 +588,7 @@ final class ConfigManagerController extends ControllerBase * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); } diff --git a/app/modules/web/Controllers/ConfigWikiController.php b/app/modules/web/Controllers/ConfigWikiController.php index 4e2226ce..cbb29db5 100644 --- a/app/modules/web/Controllers/ConfigWikiController.php +++ b/app/modules/web/Controllers/ConfigWikiController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,18 +19,17 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; use DI\DependencyException; use DI\NotFoundException; -use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Acl\UnauthorizedPageException; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; -use SP\Core\Exceptions\SessionTimeout; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Traits\ConfigTrait; @@ -47,6 +46,7 @@ final class ConfigWikiController extends SimpleControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ public function saveAction(): bool { @@ -61,7 +61,10 @@ final class ConfigWikiController extends SimpleControllerBase // Valores para la conexión a la Wiki if ($wikiEnabled && (!$wikiSearchUrl || !$wikiPageUrl || !$wikiFilter)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Missing Wiki parameters')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Missing Wiki parameters') + ); } if ($wikiEnabled) { @@ -79,28 +82,37 @@ final class ConfigWikiController extends SimpleControllerBase $eventMessage->addDescription(__u('Wiki disabled')); } - return $this->saveConfig($configData, $this->config, function () use ($eventMessage) { - $this->eventDispatcher->notifyEvent('save.config.wiki', new Event($this, $eventMessage)); - }); + return $this->saveConfig( + $configData, + $this->config, + function () use ($eventMessage) { + $this->eventDispatcher->notifyEvent( + 'save.config.wiki', + new Event($this, $eventMessage) + ); + } + ); } /** - * @return bool - * @throws DependencyException - * @throws NotFoundException - * @throws SessionTimeout + * @return void + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\SessionTimeout */ - protected function initialize() + protected function initialize(): void { try { $this->checks(); - $this->checkAccess(Acl::CONFIG_WIKI); + $this->checkAccess(ActionsInterface::CONFIG_WIKI); } catch (UnauthorizedPageException $e) { - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); - return $this->returnJsonResponseException($e); + $this->returnJsonResponseException($e); } - - return true; } } \ No newline at end of file diff --git a/app/modules/web/Controllers/ControllerBase.php b/app/modules/web/Controllers/ControllerBase.php index 89e12da5..6bf6b50c 100644 --- a/app/modules/web/Controllers/ControllerBase.php +++ b/app/modules/web/Controllers/ControllerBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,20 +19,17 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; defined('APP_ROOT') || die(); -use DI\Container; use DI\DependencyException; use DI\NotFoundException; use Exception; -use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; -use Psr\Container\NotFoundExceptionInterface; use SP\Core\Crypt\Hash; use SP\Core\Exceptions\FileNotFoundException; use SP\Core\Exceptions\SessionTimeout; @@ -55,43 +52,33 @@ abstract class ControllerBase /** * Constantes de errores */ - const ERR_UNAVAILABLE = 0; - const ERR_ACCOUNT_NO_PERMISSION = 1; - const ERR_PAGE_NO_PERMISSION = 2; - const ERR_UPDATE_MPASS = 3; - const ERR_OPERATION_NO_PERMISSION = 4; - const ERR_EXCEPTION = 5; + public const ERR_UNAVAILABLE = 0; + public const ERR_ACCOUNT_NO_PERMISSION = 1; + public const ERR_PAGE_NO_PERMISSION = 2; + public const ERR_UPDATE_MPASS = 3; + public const ERR_OPERATION_NO_PERMISSION = 4; + public const ERR_EXCEPTION = 5; /** * @var Template Instancia del motor de plantillas a utilizar */ - protected $view; - /** - * @var UserLoginResponse - */ - protected $userData; - /** - * @var ProfileData - */ - protected $userProfileData; - /** - * @var ContainerInterface - */ - protected $dic; - /** - * @var bool - */ - protected $isAjax = false; + protected Template $view; + protected ?UserLoginResponse $userData = null; + protected ?ProfileData $userProfileData = null; + protected ContainerInterface $dic; + protected bool $isAjax = false; /** * Constructor * - * @param Container $container - * @param $actionName + * @param \Psr\Container\ContainerInterface $container + * @param string $actionName * - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface + * @throws \JsonException */ - public final function __construct(Container $container, $actionName) + final public function __construct( + ContainerInterface $container, + string $actionName + ) { $this->dic = $container; $this->actionName = $actionName; @@ -123,40 +110,48 @@ abstract class ControllerBase /** * Set view variables - * - * @param bool $loggedIn */ - private function setViewVars($loggedIn = false) + private function setViewVars(bool $loggedIn = false): void { - $this->view->assign('timeStart', $this->request->getServer('REQUEST_TIME_FLOAT')); + $this->view->assign( + 'timeStart', + $this->request->getServer('REQUEST_TIME_FLOAT') + ); $this->view->assign('queryTimeStart', microtime()); if ($loggedIn) { $this->view->assign('ctx_userId', $this->userData->getId()); - $this->view->assign('ctx_userGroupId', $this->userData->getUserGroupId()); - $this->view->assign('ctx_userIsAdminApp', $this->userData->getIsAdminApp()); - $this->view->assign('ctx_userIsAdminAcc', $this->userData->getIsAdminAcc()); + $this->view->assign( + 'ctx_userGroupId', + $this->userData->getUserGroupId() + ); + $this->view->assign( + 'ctx_userIsAdminApp', + $this->userData->getIsAdminApp() + ); + $this->view->assign( + 'ctx_userIsAdminAcc', + $this->userData->getIsAdminAcc() + ); } $this->view->assign('isDemo', $this->configData->isDemoEnabled()); - $this->view->assign('themeUri', $this->view->getTheme()->getThemeUri()); + $this->view->assign( + 'themeUri', + $this->view->getTheme()->getThemeUri() + ); $this->view->assign('configData', $this->configData); // Pass the action name to the template as a variable $this->view->assign($this->actionName, true); } - /** - * @return void - */ - protected abstract function initialize(); + abstract protected function initialize(): void; /** - * @return void - * @throws DependencyException - * @throws NotFoundException + * @throws \JsonException */ - private function handleSessionTimeout() + private function handleSessionTimeout(): void { $this->sessionLogout( $this->request, @@ -172,7 +167,7 @@ abstract class ControllerBase /** * Mostrar los datos de la plantilla */ - protected function view() + protected function view(): void { try { $this->router->response() @@ -203,10 +198,8 @@ abstract class ControllerBase /** * Upgrades a View to use a full page layout - * - * @param string $page */ - protected function upgradeView($page = null) + protected function upgradeView(?string $page = null): void { $this->view->upgrade(); @@ -214,10 +207,14 @@ abstract class ControllerBase return; } - $this->view->assign('contentPage', $page ?: strtolower($this->controllerName)); + $this->view->assign( + 'contentPage', + $page ?: strtolower($this->controllerName) + ); try { - $this->dic->get(LayoutHelper::class)->getFullLayout('main', $this->acl); + $this->dic->get(LayoutHelper::class) + ->getFullLayout('main', $this->acl); } catch (Exception $e) { processException($e); } @@ -226,13 +223,16 @@ abstract class ControllerBase /** * Obtener los datos para la vista de depuración */ - protected function getDebug() + protected function getDebug(): void { global $memInit; $this->view->addTemplate('debug', 'common'); - $this->view->assign('time', getElapsedTime($this->router->request()->server()->get('REQUEST_TIME_FLOAT'))); + $this->view->assign( + 'time', + getElapsedTime($this->router->request()->server()->get('REQUEST_TIME_FLOAT')) + ); $this->view->assign('memInit', $memInit / 1000); $this->view->assign('memEnd', memory_get_usage() / 1000); } @@ -240,14 +240,12 @@ abstract class ControllerBase /** * Comprobar si el usuario está logado. * - * @param bool $requireAuthCompleted - * * @throws AuthException * @throws DependencyException * @throws NotFoundException * @throws SessionTimeout */ - protected function checkLoggedIn($requireAuthCompleted = true) + protected function checkLoggedIn(bool $requireAuthCompleted = true): void { if ($this->session->isLoggedIn() === false || $this->session->getAuthCompleted() !== $requireAuthCompleted @@ -275,7 +273,7 @@ abstract class ControllerBase * * Prepares view's variables to pass in a signed URI */ - final protected function prepareSignedUriOnView() + final protected function prepareSignedUriOnView(): void { $from = $this->request->analyzeString('from'); @@ -284,7 +282,10 @@ abstract class ControllerBase $this->request->verifySignature($this->configData->getPasswordSalt()); $this->view->assign('from', $from); - $this->view->assign('from_hash', Hash::signMessage($from, $this->configData->getPasswordSalt())); + $this->view->assign( + 'from_hash', + Hash::signMessage($from, $this->configData->getPasswordSalt()) + ); } catch (SPException $e) { processException($e); } @@ -294,12 +295,11 @@ abstract class ControllerBase /** * Comprobar si está permitido el acceso al módulo/página. * - * @param null $action La acción a comprobar - * - * @return bool + * @param int $action La acción a comprobar */ - protected function checkAccess($action): bool + protected function checkAccess(int $action): bool { - return $this->userData->getIsAdminApp() || $this->acl->checkUserAccess($action); + return $this->userData->getIsAdminApp() + || $this->acl->checkUserAccess($action); } } \ No newline at end of file diff --git a/app/modules/web/Controllers/CustomFieldController.php b/app/modules/web/Controllers/CustomFieldController.php index 02490559..53ce173d 100644 --- a/app/modules/web/Controllers/CustomFieldController.php +++ b/app/modules/web/Controllers/CustomFieldController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -28,12 +28,12 @@ use DI\DependencyException; use DI\NotFoundException; use Exception; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; use SP\Core\Exceptions\SessionTimeout; -use SP\Core\Exceptions\SPException; use SP\Core\Exceptions\ValidationException; use SP\DataModel\CustomFieldDefinitionData; use SP\Html\DataGrid\DataGridInterface; @@ -58,29 +58,32 @@ final class CustomFieldController extends ControllerBase implements CrudControll { use JsonTrait, ItemTrait; - /** - * @var CustomFieldDefService - */ - protected $customFieldService; + protected ?CustomFieldDefService $customFieldService = null; /** * Search action * * @return bool - * @throws DependencyException - * @throws NotFoundException - * @throws ConstraintException - * @throws QueryException - * @throws SPException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function searchAction() + public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::CUSTOMFIELD_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CUSTOMFIELD_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); - $this->view->assign('index', $this->request->analyzeInt('activetab', 0)); + $this->view->assign( + 'index', + $this->request->analyzeInt('activetab', 0) + ); $this->view->assign('data', $this->getSearchGrid()); return $this->returnJsonResponseData(['html' => $this->render()]); @@ -96,22 +99,29 @@ final class CustomFieldController extends ControllerBase implements CrudControll */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $customFieldGrid = $this->dic->get(CustomFieldGrid::class); - return $customFieldGrid->updatePager($customFieldGrid->getGrid($this->customFieldService->search($itemSearchData)), $itemSearchData); + return $customFieldGrid->updatePager( + $customFieldGrid->getGrid($this->customFieldService->search($itemSearchData)), + $itemSearchData + ); } /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function createAction() + public function createAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::CUSTOMFIELD_CREATE)) { + if (!$this->acl->checkUserAccess(ActionsInterface::CUSTOMFIELD_CREATE)) { return $this->returnJsonResponse( JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation') @@ -124,13 +134,19 @@ final class CustomFieldController extends ControllerBase implements CrudControll $this->setViewData(); - $this->eventDispatcher->notifyEvent('show.customField.create', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.customField.create', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -145,17 +161,30 @@ final class CustomFieldController extends ControllerBase implements CrudControll * @throws QueryException * @throws NoSuchItemException */ - protected function setViewData(?int $customFieldId = null) + protected function setViewData(?int $customFieldId = null): void { $this->view->addTemplate('custom_field', 'itemshow'); - $customField = $customFieldId ? $this->customFieldService->getById($customFieldId) : new CustomFieldDefinitionData(); + $customField = $customFieldId + ? $this->customFieldService->getById($customFieldId) + : new CustomFieldDefinitionData(); $this->view->assign('field', $customField); - $this->view->assign('types', SelectItemAdapter::factory(CustomFieldTypeService::getItemsBasic())->getItemsFromModelSelected([$customField->getTypeId()])); - $this->view->assign('modules', SelectItemAdapter::factory(CustomFieldDefService::getFieldModules())->getItemsFromArraySelected([$customField->getModuleId()])); + $this->view->assign( + 'types', + SelectItemAdapter::factory(CustomFieldTypeService::getItemsBasic()) + ->getItemsFromModelSelected([$customField->getTypeId()]) + ); + $this->view->assign( + 'modules', + SelectItemAdapter::factory(CustomFieldDefService::getFieldModules()) + ->getItemsFromArraySelected([$customField->getModuleId()]) + ); - $this->view->assign('nextAction', Acl::getActionRoute(Acl::ITEMS_MANAGE)); + $this->view->assign( + 'nextAction', + Acl::getActionRoute(ActionsInterface::ITEMS_MANAGE) + ); if ($this->view->isView === true) { $this->view->assign('disabled', 'disabled'); @@ -174,12 +203,16 @@ final class CustomFieldController extends ControllerBase implements CrudControll * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function editAction(int $id) + public function editAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::CUSTOMFIELD_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CUSTOMFIELD_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('Edit Field')); @@ -188,13 +221,19 @@ final class CustomFieldController extends ControllerBase implements CrudControll $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.customField.edit', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.customField.edit', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -206,35 +245,57 @@ final class CustomFieldController extends ControllerBase implements CrudControll * @param int|null $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): bool { try { - if (!$this->acl->checkUserAccess(Acl::CUSTOMFIELD_DELETE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CUSTOMFIELD_DELETE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } if ($id === null) { - $this->customFieldService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); + $this->customFieldService + ->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); - $this->eventDispatcher->notifyEvent('delete.customField.selection', - new Event($this, EventMessage::factory()->addDescription(__u('Fields deleted'))) + $this->eventDispatcher->notifyEvent( + 'delete.customField.selection', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Fields deleted')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Fields deleted')); - } else { - $this->customFieldService->delete($id); - - $this->eventDispatcher->notifyEvent('delete.customField', new Event($this)); - - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Field deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Fields deleted') + ); } + + $this->customFieldService->delete($id); + + $this->eventDispatcher->notifyEvent( + 'delete.customField', + new Event($this) + ); + + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Field deleted') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -244,34 +305,48 @@ final class CustomFieldController extends ControllerBase implements CrudControll * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function saveCreateAction() + public function saveCreateAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::CUSTOMFIELD_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CUSTOMFIELD_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new CustomFieldDefForm($this->dic); - $form->validate(Acl::CUSTOMFIELD_CREATE); + $form->validate(ActionsInterface::CUSTOMFIELD_CREATE); $itemData = $form->getItemData(); $this->customFieldService->create($itemData); - $this->eventDispatcher->notifyEvent('create.customField', - new Event($this, EventMessage::factory() - ->addDescription(__u('Field added')) - ->addDetail(__u('Field'), $itemData->getName())) + $this->eventDispatcher->notifyEvent( + 'create.customField', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Field added')) + ->addDetail(__u('Field'), $itemData->getName()) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Field added')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Field added') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -285,34 +360,48 @@ final class CustomFieldController extends ControllerBase implements CrudControll * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function saveEditAction(int $id) + public function saveEditAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::CUSTOMFIELD_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CUSTOMFIELD_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new CustomFieldDefForm($this->dic, $id); - $form->validate(Acl::CUSTOMFIELD_EDIT); + $form->validate(ActionsInterface::CUSTOMFIELD_EDIT); $itemData = $form->getItemData(); $this->customFieldService->update($itemData); - $this->eventDispatcher->notifyEvent('edit.customField', - new Event($this, EventMessage::factory() - ->addDescription(__u('Field updated')) - ->addDetail(__u('Field'), $itemData->getName())) + $this->eventDispatcher->notifyEvent( + 'edit.customField', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Field updated')) + ->addDetail(__u('Field'), $itemData->getName()) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Field updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Field updated') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -324,14 +413,18 @@ final class CustomFieldController extends ControllerBase implements CrudControll * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function viewAction(int $id) + public function viewAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::CUSTOMFIELD_VIEW)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::CUSTOMFIELD_VIEW)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('View Field')); @@ -339,13 +432,22 @@ final class CustomFieldController extends ControllerBase implements CrudControll $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.customField', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.customField', + new Event($this) + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage()); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + $e->getMessage() + ); } return $this->returnJsonResponseData(['html' => $this->render()]); @@ -359,7 +461,7 @@ final class CustomFieldController extends ControllerBase implements CrudControll * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/ErrorController.php b/app/modules/web/Controllers/ErrorController.php index 5c67045f..bbda186c 100644 --- a/app/modules/web/Controllers/ErrorController.php +++ b/app/modules/web/Controllers/ErrorController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -40,18 +40,9 @@ use SP\Mvc\View\Template; */ final class ErrorController { - /** - * @var Template - */ - protected $view; - /** - * @var Klein - */ - protected $router; - /** - * @var LayoutHelper - */ - protected $layoutHelper; + protected Template $view; + protected Klein $router; + protected LayoutHelper $layoutHelper; /** * ErrorController constructor. @@ -75,7 +66,7 @@ final class ErrorController /** * indexAction */ - public function indexAction() + public function indexAction(): void { $this->layoutHelper->getPublicLayout('error'); $this->view(); @@ -84,7 +75,7 @@ final class ErrorController /** * Mostrar los datos de la plantilla */ - protected function view() + protected function view(): void { try { echo $this->view->render(); @@ -100,15 +91,18 @@ final class ErrorController /** * maintenanceErrorAction */ - public function maintenanceErrorAction() + public function maintenanceErrorAction(): void { $this->layoutHelper->getPublicLayout('error-maintenance'); - $this->view->append('errors', [ - 'type' => SPException::WARNING, - 'description' => __('Application on maintenance'), - 'hint' => __('It will be running shortly') - ]); + $this->view->append( + 'errors', + [ + 'type' => SPException::WARNING, + 'description' => __('Application on maintenance'), + 'hint' => __('It will be running shortly') + ] + ); $this->view(); } @@ -116,15 +110,18 @@ final class ErrorController /** * databaseErrorAction */ - public function databaseErrorAction() + public function databaseErrorAction(): void { $this->layoutHelper->getPublicLayout('error-database'); - $this->view->append('errors', [ - 'type' => SPException::CRITICAL, - 'description' => __('Error while checking the database'), - 'hint' => __('Please contact to the administrator') - ]); + $this->view->append( + 'errors', + [ + 'type' => SPException::CRITICAL, + 'description' => __('Error while checking the database'), + 'hint' => __('Please contact to the administrator') + ] + ); $this->view(); } @@ -132,15 +129,18 @@ final class ErrorController /** * databaseConnectionAction */ - public function databaseConnectionAction() + public function databaseConnectionAction(): void { $this->layoutHelper->getPublicLayout('error-database'); - $this->view->append('errors', [ - 'type' => SPException::CRITICAL, - 'description' => __('Unable to connect to DB'), - 'hint' => __('Please contact to the administrator') - ]); + $this->view->append( + 'errors', + [ + 'type' => SPException::CRITICAL, + 'description' => __('Unable to connect to DB'), + 'hint' => __('Please contact to the administrator') + ] + ); $this->view(); } diff --git a/app/modules/web/Controllers/EventlogController.php b/app/modules/web/Controllers/EventlogController.php index 4f264c16..ae2a606c 100644 --- a/app/modules/web/Controllers/EventlogController.php +++ b/app/modules/web/Controllers/EventlogController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -27,7 +27,7 @@ namespace SP\Modules\Web\Controllers; use DI\DependencyException; use DI\NotFoundException; use Exception; -use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -50,10 +50,7 @@ final class EventlogController extends ControllerBase { use JsonTrait, ItemTrait; - /** - * @var EventlogService - */ - protected $eventLogService; + protected ?EventlogService $eventLogService = null; /** * indexAction @@ -64,9 +61,9 @@ final class EventlogController extends ControllerBase * @throws QueryException * @throws SPException */ - public function indexAction() + public function indexAction(): void { - if (!$this->acl->checkUserAccess(Acl::EVENTLOG)) { + if (!$this->acl->checkUserAccess(ActionsInterface::EVENTLOG)) { return; } @@ -88,27 +85,36 @@ final class EventlogController extends ControllerBase */ protected function getSearchGrid(): EventlogController { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $eventlogGrid = $this->dic->get(EventlogGrid::class); - return $eventlogGrid->updatePager($eventlogGrid->getGrid($this->eventLogService->search($itemSearchData)), $itemSearchData); + return $eventlogGrid->updatePager( + $eventlogGrid->getGrid($this->eventLogService->search($itemSearchData)), + $itemSearchData + ); } /** * searchAction * * @return bool - * @throws DependencyException - * @throws NotFoundException - * @throws ConstraintException - * @throws QueryException - * @throws SPException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::EVENTLOG_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::EVENTLOG_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table-simple', 'grid'); @@ -120,18 +126,26 @@ final class EventlogController extends ControllerBase /** * @return bool * @throws DependencyException - * @throws NotFoundException + * @throws NotFoundException|\JsonException */ public function clearAction(): bool { try { $this->eventLogService->clear(); - $this->eventDispatcher->notifyEvent('clear.eventlog', - new Event($this, EventMessage::factory()->addDescription(__u('Event log cleared'))) + $this->eventDispatcher->notifyEvent( + 'clear.eventlog', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Event log cleared')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Event log cleared')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Event log cleared') + ); } catch (Exception $e) { processException($e); @@ -145,7 +159,7 @@ final class EventlogController extends ControllerBase * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/Helpers/Account/AccountActionsDto.php b/app/modules/web/Controllers/Helpers/Account/AccountActionsDto.php index bb11fa59..c629e5d2 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountActionsDto.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountActionsDto.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Account; @@ -31,31 +31,16 @@ namespace SP\Modules\Web\Controllers\Helpers\Account; */ final class AccountActionsDto { - /** - * @var int - */ - private $accountId; - /** - * @var int - */ - private $accountHistoryId; - /** - * @var int - */ - private $accountParentId; - /** - * @var int - */ - private $publicLinkId; - /** - * @var int - */ - private $publicLinkCreatorId; + private ?int $accountId; + private ?int $accountHistoryId; + private ?int $accountParentId; + private ?int $publicLinkId = null; + private ?int $publicLinkCreatorId = null; /** * AccountActionsDto constructor. * - * @param int|null $accountId + * @param int|null $accountId * @param int|null $accountHistoryId * @param int|null $accountParentId */ @@ -120,7 +105,7 @@ final class AccountActionsDto /** * @param int $publicLinkId */ - public function setPublicLinkId(int $publicLinkId) + public function setPublicLinkId(int $publicLinkId): void { $this->publicLinkId = $publicLinkId; } @@ -136,7 +121,7 @@ final class AccountActionsDto /** * @param int $publicLinkCreatorId */ - public function setPublicLinkCreatorId(int $publicLinkCreatorId) + public function setPublicLinkCreatorId(int $publicLinkCreatorId): void { $this->publicLinkCreatorId = $publicLinkCreatorId; } diff --git a/app/modules/web/Controllers/Helpers/Account/AccountActionsHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountActionsHelper.php index 5477b928..62252fb5 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountActionsHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountActionsHelper.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Account; @@ -40,14 +40,8 @@ use SP\Services\Account\AccountSearchItem; */ final class AccountActionsHelper extends HelperBase { - /** - * @var ThemeIcons - */ - protected $icons; - /** - * @var string - */ - protected $sk; + protected ?ThemeIcons $icons = null; + protected ?string $sk = null; /** * @return DataGridAction @@ -61,9 +55,18 @@ final class AccountActionsHelper extends HelperBase $action->setTitle(__('Account Details')); $action->addClass('btn-action'); $action->setIcon($this->icons->getIconView()); - $action->setRuntimeFilter(AccountSearchItem::class, 'isShowView'); - $action->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW)); - $action->addData('onclick', Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW)); + $action->setRuntimeFilter( + AccountSearchItem::class, + 'isShowView' + ); + $action->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) + ); + $action->addData( + 'onclick', + Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) + ); $action->addAttribute('type', 'button'); return $action; @@ -77,14 +80,20 @@ final class AccountActionsHelper extends HelperBase * * @return DataGridAction[] */ - public function getActionsForAccount(AccountAcl $accountAcl, AccountActionsDto $accountActionsDto): array + public function getActionsForAccount( + AccountAcl $accountAcl, + AccountActionsDto $accountActionsDto + ): array { $actions = []; $actionBack = $this->getBackAction(); if ($accountActionsDto->isHistory()) { - $actionBack->addData('item-id', $accountActionsDto->getAccountId()); + $actionBack->addData( + 'item-id', + $accountActionsDto->getAccountId() + ); $actionBack->setName(__('View Current')); $actionBack->setTitle(__('View Current')); } else { @@ -95,30 +104,40 @@ final class AccountActionsHelper extends HelperBase $actions[] = $actionBack; if ($accountAcl->isShowEditPass()) { - $actions[] = $this->getEditPassAction()->addData('item-id', $accountActionsDto->getAccountId()); + $actions[] = $this->getEditPassAction() + ->addData('item-id', $accountActionsDto->getAccountId()); } if ($accountAcl->isShowEdit()) { - $actions[] = $this->getEditAction()->addData('item-id', $accountActionsDto->getAccountId()); + $actions[] = $this->getEditAction() + ->addData('item-id', $accountActionsDto->getAccountId()); } if ($accountAcl->getActionId() === ActionsInterface::ACCOUNT_VIEW && !$accountAcl->isShowEdit() && $this->configData->isMailRequestsEnabled() ) { - $actions[] = $this->getRequestAction()->addData('item-id', $accountActionsDto->getAccountId()); + $actions[] = $this->getRequestAction() + ->addData('item-id', $accountActionsDto->getAccountId()); } if ($accountAcl->isShowRestore()) { $actionRestore = $this->getRestoreAction(); - $actionRestore->addData('item-id', $accountActionsDto->getAccountId()); - $actionRestore->addData('history-id', $accountActionsDto->getAccountHistoryId()); + $actionRestore->addData( + 'item-id', + $accountActionsDto->getAccountId() + ); + $actionRestore->addData( + 'history-id', + $accountActionsDto->getAccountHistoryId() + ); $actions[] = $actionRestore; } if ($accountAcl->isShowSave()) { - $actions[] = $this->getSaveAction()->addAttribute('form', 'frmAccount'); + $actions[] = $this->getSaveAction() + ->addAttribute('form', 'frmAccount'); } return $actions; @@ -135,8 +154,14 @@ final class AccountActionsHelper extends HelperBase $action->setTitle(__('Back')); $action->addClass('btn-action'); $action->setIcon($this->icons->getIconBack()); - $action->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW)); - $action->addData('onclick', Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW)); + $action->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) + ); + $action->addData( + 'onclick', + Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) + ); $action->addAttribute('type', 'button'); return $action; @@ -154,9 +179,18 @@ final class AccountActionsHelper extends HelperBase $action->setTitle(__('Edit Account Password')); $action->addClass('btn-action'); $action->setIcon($this->icons->getIconEditPass()); - $action->setRuntimeFilter(AccountSearchItem::class, 'isShowViewPass'); - $action->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_EDIT_PASS)); - $action->addData('onclick', Acl::getActionRoute(ActionsInterface::ACCOUNT_EDIT_PASS)); + $action->setRuntimeFilter( + AccountSearchItem::class, + 'isShowViewPass' + ); + $action->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_EDIT_PASS) + ); + $action->addData( + 'onclick', + Acl::getActionRoute(ActionsInterface::ACCOUNT_EDIT_PASS) + ); $action->addAttribute('type', 'button'); return $action; @@ -174,9 +208,18 @@ final class AccountActionsHelper extends HelperBase $action->setTitle(__('Edit Account')); $action->addClass('btn-action'); $action->setIcon($this->icons->getIconEdit()); - $action->setRuntimeFilter(AccountSearchItem::class, 'isShowEdit'); - $action->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_EDIT)); - $action->addData('onclick', Acl::getActionRoute(ActionsInterface::ACCOUNT_EDIT)); + $action->setRuntimeFilter( + AccountSearchItem::class, + 'isShowEdit' + ); + $action->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_EDIT) + ); + $action->addData( + 'onclick', + Acl::getActionRoute(ActionsInterface::ACCOUNT_EDIT) + ); $action->addAttribute('type', 'button'); return $action; @@ -193,9 +236,18 @@ final class AccountActionsHelper extends HelperBase $action->setTitle(__('Request Modification')); $action->addClass('btn-action'); $action->setIcon($this->icons->getIconEmail()); - $action->setRuntimeFilter(AccountSearchItem::class, 'isShowRequest'); - $action->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_REQUEST)); - $action->addData('onclick', Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW)); + $action->setRuntimeFilter( + AccountSearchItem::class, + 'isShowRequest' + ); + $action->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_REQUEST) + ); + $action->addData( + 'onclick', + Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) + ); $action->addAttribute('type', 'submit'); return $action; @@ -247,14 +299,18 @@ final class AccountActionsHelper extends HelperBase * * @return DataGridAction[] */ - public function getActionsGrouppedForAccount(AccountAcl $accountAcl, AccountActionsDto $accountActionsDto): array + public function getActionsGrouppedForAccount( + AccountAcl $accountAcl, + AccountActionsDto $accountActionsDto + ): array { $userData = $this->context->getUserData(); $actions = []; if ($accountAcl->isShowDelete()) { - $actions[] = $this->getDeleteAction()->addData('item-id', $accountActionsDto->getAccountId()); + $actions[] = $this->getDeleteAction() + ->addData('item-id', $accountActionsDto->getAccountId()); } if ($accountActionsDto->isHistory() === false @@ -268,7 +324,10 @@ final class AccountActionsHelper extends HelperBase if ($itemId) { $actionRefresh = $this->getPublicLinkRefreshAction(); $actionRefresh->addData('item-id', $itemId); - $actionRefresh->addData('account-id', $accountActionsDto->getAccountId()); + $actionRefresh->addData( + 'account-id', + $accountActionsDto->getAccountId() + ); $actions[] = $actionRefresh; @@ -277,13 +336,19 @@ final class AccountActionsHelper extends HelperBase ) { $actionDelete = $this->getPublicLinkDeleteAction(); $actionDelete->addData('item-id', $itemId); - $actionDelete->addData('account-id', $accountActionsDto->getAccountId()); + $actionDelete->addData( + 'account-id', + $accountActionsDto->getAccountId() + ); $actions[] = $actionDelete; } } else { $action = $this->getPublicLinkAction(); - $action->addData('account-id', $accountActionsDto->getAccountId()); + $action->addData( + 'account-id', + $accountActionsDto->getAccountId() + ); $actions[] = $action; } @@ -292,25 +357,44 @@ final class AccountActionsHelper extends HelperBase if ($accountAcl->isShowViewPass()) { if ($accountActionsDto->isHistory()) { $actionViewPass = $this->getViewPassHistoryAction() - ->addData('item-id', $accountActionsDto->getAccountHistoryId()); + ->addData( + 'item-id', + $accountActionsDto->getAccountHistoryId() + ); $actionCopy = $this->getCopyPassHistoryAction() - ->addData('item-id', $accountActionsDto->getAccountHistoryId()); + ->addData( + 'item-id', + $accountActionsDto->getAccountHistoryId() + ); } else { $actionViewPass = $this->getViewPassAction() - ->addData('item-id', $accountActionsDto->getAccountId()); + ->addData( + 'item-id', + $accountActionsDto->getAccountId() + ); $actionCopy = $this->getCopyPassAction() - ->addData('item-id', $accountActionsDto->getAccountId()); + ->addData( + 'item-id', + $accountActionsDto->getAccountId() + ); } - $actionViewPass->addData('parent-id', $accountActionsDto->getAccountParentId()); - $actionCopy->addData('parent-id', $accountActionsDto->getAccountParentId()); + $actionViewPass->addData( + 'parent-id', + $accountActionsDto->getAccountParentId() + ); + $actionCopy->addData( + 'parent-id', + $accountActionsDto->getAccountParentId() + ); $actions[] = $actionViewPass; $actions[] = $actionCopy; } if ($accountAcl->isShowCopy()) { - $actions[] = $this->getCopyAction()->addData('item-id', $accountActionsDto->getAccountId()); + $actions[] = $this->getCopyAction() + ->addData('item-id', $accountActionsDto->getAccountId()); } return $actions; @@ -328,9 +412,18 @@ final class AccountActionsHelper extends HelperBase $action->setTitle(__('Remove Account')); $action->addClass('btn-action'); $action->setIcon($this->icons->getIconDelete()); - $action->setRuntimeFilter(AccountSearchItem::class, 'isShowDelete'); - $action->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_DELETE)); - $action->addData('onclick', Acl::getActionRoute(ActionsInterface::ACCOUNT_DELETE)); + $action->setRuntimeFilter( + AccountSearchItem::class, + 'isShowDelete' + ); + $action->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_DELETE) + ); + $action->addData( + 'onclick', + Acl::getActionRoute(ActionsInterface::ACCOUNT_DELETE) + ); $action->addAttribute('type', 'button'); return $action; @@ -347,9 +440,15 @@ final class AccountActionsHelper extends HelperBase $action->setTitle(__('Update Public Link')); $action->addClass('btn-action'); $action->setIcon($this->icons->getIconPublicLink()); - $action->addData('action-route', Acl::getActionRoute(ActionsInterface::PUBLICLINK_REFRESH)); + $action->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PUBLICLINK_REFRESH) + ); $action->addData('onclick', 'link/refresh'); - $action->addData('action-next', Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW)); + $action->addData( + 'action-next', + Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) + ); $action->addAttribute('type', 'button'); return $action; @@ -369,9 +468,15 @@ final class AccountActionsHelper extends HelperBase $action->setTitle(__('Delete Public Link')); $action->addClass('btn-action'); $action->setIcon($icon); - $action->addData('action-route', Acl::getActionRoute(ActionsInterface::PUBLICLINK_DELETE)); + $action->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PUBLICLINK_DELETE) + ); $action->addData('onclick', 'link/delete'); - $action->addData('action-next', Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW)); + $action->addData( + 'action-next', + Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) + ); $action->addAttribute('type', 'button'); return $action; @@ -388,9 +493,15 @@ final class AccountActionsHelper extends HelperBase $action->setTitle(__('Create Public Link')); $action->addClass('btn-action'); $action->setIcon($this->icons->getIconPublicLink()); - $action->addData('action-route', 'publicLink/saveCreateFromAccount'); + $action->addData( + 'action-route', + 'publicLink/saveCreateFromAccount' + ); $action->addData('onclick', 'link/save'); - $action->addData('action-next', Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW)); + $action->addData( + 'action-next', + Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) + ); $action->addAttribute('type', 'button'); return $action; @@ -408,10 +519,19 @@ final class AccountActionsHelper extends HelperBase $action->setTitle(__('View password')); $action->addClass('btn-action'); $action->setIcon($this->icons->getIconViewPass()); - $action->setRuntimeFilter(AccountSearchItem::class, 'isShowViewPass'); - $action->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_HISTORY_VIEW_PASS)); + $action->setRuntimeFilter( + AccountSearchItem::class, + 'isShowViewPass' + ); + $action->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_HISTORY_VIEW_PASS) + ); $action->addData('action-full', 1); - $action->addData('onclick', Acl::getActionRoute(ActionsInterface::ACCOUNT_HISTORY_VIEW_PASS)); + $action->addData( + 'onclick', + Acl::getActionRoute(ActionsInterface::ACCOUNT_HISTORY_VIEW_PASS) + ); $action->addAttribute('type', 'button'); return $action; @@ -430,8 +550,14 @@ final class AccountActionsHelper extends HelperBase $action->addClass('btn-action'); $action->addClass('clip-pass-button'); $action->setIcon($this->icons->getIconClipboard()); - $action->setRuntimeFilter(AccountSearchItem::class, 'isShowCopyPass'); - $action->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_HISTORY_COPY_PASS)); + $action->setRuntimeFilter( + AccountSearchItem::class, + 'isShowCopyPass' + ); + $action->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_HISTORY_COPY_PASS) + ); $action->addData('action-full', 0); $action->addData('useclipboard', '1'); $action->addAttribute('type', 'button'); @@ -451,10 +577,19 @@ final class AccountActionsHelper extends HelperBase $action->setTitle(__('View password')); $action->addClass('btn-action'); $action->setIcon($this->icons->getIconViewPass()); - $action->setRuntimeFilter(AccountSearchItem::class, 'isShowViewPass'); - $action->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW_PASS)); + $action->setRuntimeFilter( + AccountSearchItem::class, + 'isShowViewPass' + ); + $action->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW_PASS) + ); $action->addData('action-full', 1); - $action->addData('onclick', Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW_PASS)); + $action->addData( + 'onclick', + Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW_PASS) + ); $action->addAttribute('type', 'button'); return $action; @@ -473,8 +608,14 @@ final class AccountActionsHelper extends HelperBase $action->addClass('btn-action'); $action->addClass('clip-pass-button'); $action->setIcon($this->icons->getIconClipboard()); - $action->setRuntimeFilter(AccountSearchItem::class, 'isShowCopyPass'); - $action->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_COPY_PASS)); + $action->setRuntimeFilter( + AccountSearchItem::class, + 'isShowCopyPass' + ); + $action->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_COPY_PASS) + ); $action->addData('action-full', 0); $action->addData('useclipboard', '1'); $action->addAttribute('type', 'button'); @@ -494,9 +635,18 @@ final class AccountActionsHelper extends HelperBase $action->setTitle(__('Copy Account')); $action->addClass('btn-action'); $action->setIcon($this->icons->getIconCopy()); - $action->setRuntimeFilter(AccountSearchItem::class, 'isShowCopy'); - $action->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_COPY)); - $action->addData('onclick', Acl::getActionRoute(ActionsInterface::ACCOUNT_COPY)); + $action->setRuntimeFilter( + AccountSearchItem::class, + 'isShowCopy' + ); + $action->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_COPY) + ); + $action->addData( + 'onclick', + Acl::getActionRoute(ActionsInterface::ACCOUNT_COPY) + ); $action->addAttribute('type', 'button'); return $action; @@ -505,7 +655,7 @@ final class AccountActionsHelper extends HelperBase /** * Initialize class */ - protected function initialize() + protected function initialize(): void { $this->icons = $this->view->getTheme()->getIcons(); } diff --git a/app/modules/web/Controllers/Helpers/Account/AccountHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountHelper.php index 5559abc2..14012967 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountHelper.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Account; @@ -34,7 +34,6 @@ use SP\Core\Acl\Acl; use SP\Core\Acl\ActionsInterface; use SP\Core\Acl\UnauthorizedPageException; use SP\Core\Exceptions\ConstraintException; -use SP\Core\Exceptions\NoSuchPropertyException; use SP\Core\Exceptions\QueryException; use SP\Core\Exceptions\SPException; use SP\DataModel\Dto\AccountAclDto; @@ -71,42 +70,15 @@ final class AccountHelper extends HelperBase { use ItemTrait; - /** - * @var Acl - */ - private $acl; - /** - * @var AccountService - */ - private $accountService; - /** - * @var AccountHistoryService - */ - private $accountHistoryService; - /** - * @var PublicLinkService - */ - private $publicLinkService; - /** - * @var ItemPresetService - */ - private $itemPresetService; - /** - * @var string - */ - private $actionId; - /** - * @var AccountAcl - */ - private $accountAcl; - /** - * @var int con el Id de la cuenta - */ - private $accountId; - /** - * @var bool - */ - private $isView = false; + private ?Acl $acl = null; + private ?AccountService $accountService = null; + private ?AccountHistoryService $accountHistoryService = null; + private ?PublicLinkService $publicLinkService = null; + private ?ItemPresetService $itemPresetService = null; + private ?int $actionId = null; + private ?AccountAcl $accountAcl = null; + private ?int $accountId = null; + private bool $isView = false; /** * Sets account's view variables @@ -121,7 +93,10 @@ final class AccountHelper extends HelperBase * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function setViewForAccount(AccountDetailsResponse $accountDetailsResponse, int $actionId) + public function setViewForAccount( + AccountDetailsResponse $accountDetailsResponse, + int $actionId + ): void { $this->accountId = $accountDetailsResponse->getAccountVData()->getId(); $this->actionId = $actionId; @@ -142,31 +117,39 @@ final class AccountHelper extends HelperBase $selectTags = SelectItemAdapter::factory(TagService::getItemsBasic()); $usersView = SelectItemAdapter::getIdFromArrayOfObjects( - array_filter($accountDetailsResponse->getUsers(), - function ($value) { + array_filter( + $accountDetailsResponse->getUsers(), + static function ($value) { return (int)$value->isEdit === 0; - }) + } + ) ); $usersEdit = SelectItemAdapter::getIdFromArrayOfObjects( - array_filter($accountDetailsResponse->getUsers(), - function ($value) { + array_filter( + $accountDetailsResponse->getUsers(), + static function ($value) { return (int)$value->isEdit === 1; - }) + } + ) ); $userGroupsView = SelectItemAdapter::getIdFromArrayOfObjects( - array_filter($accountDetailsResponse->getUserGroups(), - function ($value) { + array_filter( + $accountDetailsResponse->getUserGroups(), + static function ($value) { return (int)$value->isEdit === 0; - }) + } + ) ); $userGroupsEdit = SelectItemAdapter::getIdFromArrayOfObjects( - array_filter($accountDetailsResponse->getUserGroups(), - function ($value) { + array_filter( + $accountDetailsResponse->getUserGroups(), + static function ($value) { return (int)$value->isEdit === 1; - }) + } + ) ); $this->view->assign('otherUsersView', @@ -234,27 +217,32 @@ final class AccountHelper extends HelperBase $userData = $this->context->getUserData(); $userProfileData = $this->context->getUserProfile(); - $this->view->assign('allowPrivate', + $this->view->assign( + 'allowPrivate', ($userProfileData->isAccPrivate() && $accountData->getUserId() === $userData->getId()) || $userData->getIsAdminApp() ); - $this->view->assign('allowPrivateGroup', + $this->view->assign( + 'allowPrivateGroup', ($userProfileData->isAccPrivateGroup() && $accountData->getUserGroupId() === $userData->getUserGroupId()) || $userData->getIsAdminApp() ); - $this->view->assign('accountPassDate', + $this->view->assign( + 'accountPassDate', date('Y-m-d H:i:s', $accountData->getPassDate()) ); - $this->view->assign('accountPassDateChange', + $this->view->assign( + 'accountPassDateChange', $accountData->getPassDateChange() > 0 ? gmdate('Y-m-d', $accountData->getPassDateChange()) : 0 ); - $this->view->assign('linkedAccounts', + $this->view->assign( + 'linkedAccounts', $this->accountService->getLinked($this->accountId) ); @@ -264,13 +252,15 @@ final class AccountHelper extends HelperBase $accountActionsHelper = $this->dic->get(AccountActionsHelper::class); - $this->view->assign('accountActions', + $this->view->assign( + 'accountActions', $accountActionsHelper->getActionsForAccount( $this->accountAcl, $accountActionsDto ) ); - $this->view->assign('accountActionsMenu', + $this->view->assign( + 'accountActionsMenu', $accountActionsHelper->getActionsGrouppedForAccount( $this->accountAcl, $accountActionsDto @@ -288,16 +278,16 @@ final class AccountHelper extends HelperBase * @throws NotFoundException * @throws ServiceException */ - public function checkActionAccess() + public function checkActionAccess(): void { if (!$this->acl->checkUserAccess($this->actionId)) { - throw new UnauthorizedPageException(UnauthorizedPageException::INFO); + throw new UnauthorizedPageException(SPException::INFO); } if (!$this->dic->get(MasterPassService::class) ->checkUserUpdateMPass($this->context->getUserData()->getLastUpdateMPass()) ) { - throw new UpdatedMasterPassException(UpdatedMasterPassException::INFO); + throw new UpdatedMasterPassException(SPException::INFO); } } @@ -316,10 +306,14 @@ final class AccountHelper extends HelperBase protected function checkAccess(AccountDetailsResponse $accountDetailsResponse): AccountAcl { $accountAcl = $this->dic->get(AccountAclService::class) - ->getAcl($this->actionId, AccountAclDto::makeFromAccount($accountDetailsResponse)); + ->getAcl( + $this->actionId, + AccountAclDto::makeFromAccount($accountDetailsResponse) + ); - if ($accountAcl === null || $accountAcl->checkAccountAccess($this->actionId) === false) { - throw new AccountPermissionException(AccountPermissionException::INFO); + if ($accountAcl === null + || $accountAcl->checkAccountAccess($this->actionId) === false) { + throw new AccountPermissionException(SPException::INFO); } return $accountAcl; @@ -335,7 +329,7 @@ final class AccountHelper extends HelperBase * @throws SPException * @throws ServiceException */ - protected function setViewCommon() + protected function setViewCommon(): void { $this->view->assign('isView', $this->isView); @@ -348,71 +342,80 @@ final class AccountHelper extends HelperBase ) ); - $this->view->assign('categories', + $this->view->assign( + 'categories', SelectItemAdapter::factory($this->dic->get(CategoryService::class) ->getAllBasic())->getItemsFromModel() ); - - $this->view->assign('clients', + $this->view->assign( + 'clients', SelectItemAdapter::factory($this->dic->get(ClientService::class) ->getAllForUser())->getItemsFromModel() ); - - $this->view->assign('mailRequestEnabled', + $this->view->assign( + 'mailRequestEnabled', $this->configData->isMailRequestsEnabled() ); - $this->view->assign('passToImageEnabled', + $this->view->assign( + 'passToImageEnabled', $this->configData->isAccountPassToImage() ); - - $this->view->assign('otherAccounts', - $this->accountService->getForUser($this->accountId)); - - $this->view->assign('addClientEnabled', + $this->view->assign( + 'otherAccounts', + $this->accountService->getForUser($this->accountId) + ); + $this->view->assign( + 'addClientEnabled', !$this->isView && $this->acl->checkUserAccess(ActionsInterface::CLIENT) ); - $this->view->assign('addClientRoute', + $this->view->assign( + 'addClientRoute', Acl::getActionRoute(ActionsInterface::CLIENT_CREATE) ); - - $this->view->assign('addCategoryEnabled', + $this->view->assign( + 'addCategoryEnabled', !$this->isView && $this->acl->checkUserAccess(ActionsInterface::CATEGORY) ); - - $this->view->assign('addCategoryRoute', - Acl::getActionRoute(ActionsInterface::CATEGORY_CREATE)); - - $this->view->assign('addTagEnabled', + $this->view->assign( + 'addCategoryRoute', + Acl::getActionRoute(ActionsInterface::CATEGORY_CREATE) + ); + $this->view->assign( + 'addTagEnabled', !$this->isView && $this->acl->checkUserAccess(ActionsInterface::TAG) ); - $this->view->assign('addTagRoute', + $this->view->assign( + 'addTagRoute', Acl::getActionRoute(ActionsInterface::TAG_CREATE) ); - - $this->view->assign('fileListRoute', + $this->view->assign( + 'fileListRoute', Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_LIST) ); - $this->view->assign('fileUploadRoute', + $this->view->assign( + 'fileUploadRoute', Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_UPLOAD) ); - - $this->view->assign('disabled', + $this->view->assign( + 'disabled', $this->isView ? 'disabled' : '' ); - $this->view->assign('readonly', + $this->view->assign( + 'readonly', $this->isView ? 'readonly' : '' ); - - $this->view->assign('showViewCustomPass', + $this->view->assign( + 'showViewCustomPass', $this->accountAcl->isShowViewPass() ); $this->view->assign('accountAcl', $this->accountAcl); if ($this->accountId) { - $this->view->assign('deepLink', + $this->view->assign( + 'deepLink', Link::getDeepLink( $this->accountId, $this->actionId, @@ -425,21 +428,21 @@ final class AccountHelper extends HelperBase /** * Sets account's view for a blank form * - * @param $actionId + * @param int $actionId * * @return void - * @throws ConstraintException - * @throws DependencyException - * @throws NoSuchItemException - * @throws NoSuchPropertyException - * @throws NotFoundException - * @throws QueryException - * @throws SPException - * @throws ServiceException - * @throws UnauthorizedPageException - * @throws UpdatedMasterPassException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \SP\Core\Acl\UnauthorizedPageException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\NoSuchPropertyException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + * @throws \SP\Repositories\NoSuchItemException + * @throws \SP\Services\ServiceException + * @throws \SP\Services\User\UpdatedMasterPassException */ - public function setViewForBlank($actionId) + public function setViewForBlank(int $actionId): void { $this->actionId = $actionId; $this->accountAcl = new AccountAcl($actionId); @@ -471,45 +474,58 @@ final class AccountHelper extends HelperBase $selectUserGroups = SelectItemAdapter::factory(UserGroupService::getItemsBasic()); $selectTags = SelectItemAdapter::factory(TagService::getItemsBasic()); - $this->view->assign('accountPassDateChange', + $this->view->assign( + 'accountPassDateChange', date('Y-m-d', time() + 7776000) ); - $this->view->assign('otherUsersView', + $this->view->assign( + 'otherUsersView', $selectUsers->getItemsFromModelSelected($accountPermission->getUsersView()) ); - $this->view->assign('otherUsersEdit', + $this->view->assign( + 'otherUsersEdit', $selectUsers->getItemsFromModelSelected($accountPermission->getUsersEdit()) ); - $this->view->assign('otherUserGroupsView', + $this->view->assign( + 'otherUserGroupsView', $selectUserGroups->getItemsFromModelSelected($accountPermission->getUserGroupsView()) ); - $this->view->assign('otherUserGroupsEdit', + $this->view->assign( + 'otherUserGroupsEdit', $selectUserGroups->getItemsFromModelSelected($accountPermission->getUserGroupsEdit()) ); - $this->view->assign('users', + $this->view->assign( + 'users', $selectUsers->getItemsFromModel() ); - $this->view->assign('userGroups', + $this->view->assign( + 'userGroups', $selectUserGroups->getItemsFromModel() ); - $this->view->assign('tags', + $this->view->assign( + 'tags', $selectTags->getItemsFromModel() ); - $this->view->assign('allowPrivate', + $this->view->assign( + 'allowPrivate', $userProfileData->isAccPrivate() || $userData->getIsAdminApp() ); - $this->view->assign('allowPrivateGroup', + $this->view->assign( + 'allowPrivateGroup', $userProfileData->isAccPrivateGroup() || $userData->getIsAdminApp() ); - $this->view->assign('privateUserCheck', + $this->view->assign( + 'privateUserCheck', $accountPrivate->isPrivateUser() ); - $this->view->assign('privateUserGroupCheck', + $this->view->assign( + 'privateUserGroupCheck', $accountPrivate->isPrivateGroup() ); $this->view->assign('accountId', 0); $this->view->assign('gotData', false); - $this->view->assign('accountActions', + $this->view->assign( + 'accountActions', $this->dic->get(AccountActionsHelper::class) ->getActionsForAccount( $this->accountAcl, @@ -534,7 +550,10 @@ final class AccountHelper extends HelperBase * @throws NotFoundException * @throws ServiceException */ - public function setViewForRequest(AccountDetailsResponse $accountDetailsResponse, int $actionId): bool + public function setViewForRequest( + AccountDetailsResponse $accountDetailsResponse, + int $actionId + ): bool { $this->accountId = $accountDetailsResponse->getAccountVData()->getId(); $this->actionId = $actionId; @@ -544,14 +563,17 @@ final class AccountHelper extends HelperBase $accountData = $accountDetailsResponse->getAccountVData(); - $this->view->assign('accountId', + $this->view->assign( + 'accountId', $accountData->getId() ); - $this->view->assign('accountData', + $this->view->assign( + 'accountData', $accountDetailsResponse->getAccountVData() ); - $this->view->assign('accountActions', + $this->view->assign( + 'accountActions', $this->dic->get(AccountActionsHelper::class) ->getActionsForAccount($this->accountAcl, new AccountActionsDto( @@ -567,16 +589,16 @@ final class AccountHelper extends HelperBase /** * @param bool $isView */ - public function setIsView(bool $isView) + public function setIsView(bool $isView): void { - $this->isView = (bool)$isView; + $this->isView = $isView; } /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->acl = $this->dic->get(Acl::class); $this->accountService = $this->dic->get(AccountService::class); @@ -584,7 +606,7 @@ final class AccountHelper extends HelperBase $this->publicLinkService = $this->dic->get(PublicLinkService::class); $this->itemPresetService = $this->dic->get(ItemPresetService::class); - $this->view->assign('changesHash', ''); + $this->view->assign('changesHash'); $this->view->assign('chkUserEdit', false); $this->view->assign('chkGroupEdit', false); } diff --git a/app/modules/web/Controllers/Helpers/Account/AccountHistoryHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountHistoryHelper.php index 214d4c68..7ec712b9 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountHistoryHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountHistoryHelper.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Account; @@ -55,30 +55,12 @@ use SP\Services\User\UpdatedMasterPassException; */ final class AccountHistoryHelper extends HelperBase { - /** - * @var Acl - */ - protected $acl; - /** - * @var AccountHistoryService - */ - protected $accountHistoryService; - /** - * @var int - */ - protected $accountId; - /** - * @var int - */ - protected $actionId; - /** - * @var int - */ - protected $accountHistoryId; - /** - * @var AccountAcl - */ - protected $accountAcl; + protected ?Acl $acl = null; + protected ?AccountHistoryService $accountHistoryService = null; + protected ?int $accountId = null; + protected ?int $actionId = null; + protected ?int $accountHistoryId = null; + protected ?AccountAcl $accountAcl = null; /** * @param AccountHistoryData $accountHistoryData @@ -94,7 +76,10 @@ final class AccountHistoryHelper extends HelperBase * @throws NoSuchItemException * @throws ServiceException */ - public function setView(AccountHistoryData $accountHistoryData, int $actionId) + public function setView( + AccountHistoryData $accountHistoryData, + int $actionId + ): void { $this->actionId = $actionId; $this->accountHistoryId = $accountHistoryData->getId(); @@ -110,28 +95,50 @@ final class AccountHistoryHelper extends HelperBase $this->view->assign('actionId', $this->actionId); $this->view->assign('accountId', $this->accountId); - $this->view->assign('historyData', + $this->view->assign( + 'historyData', SelectItemAdapter::factory($this->accountHistoryService->getHistoryForAccount($this->accountId)) ->getItemsFromArraySelected([$this->accountHistoryId])); - $this->view->assign('accountPassDate', date('Y-m-d H:i:s', $accountHistoryData->getPassDate())); - $this->view->assign('accountPassDateChange', date('Y-m-d', $accountHistoryData->getPassDateChange() ?: 0)); - $this->view->assign('categories', + $this->view->assign( + 'accountPassDate', + date('Y-m-d H:i:s', $accountHistoryData->getPassDate()) + ); + $this->view->assign( + 'accountPassDateChange', + date('Y-m-d', $accountHistoryData->getPassDateChange() ?: 0) + ); + $this->view->assign( + 'categories', SelectItemAdapter::factory(CategoryService::getItemsBasic()) - ->getItemsFromModelSelected([$accountHistoryData->getCategoryId()])); - $this->view->assign('clients', + ->getItemsFromModelSelected([$accountHistoryData->getCategoryId()]) + ); + $this->view->assign( + 'clients', SelectItemAdapter::factory(ClientService::getItemsBasic()) - ->getItemsFromModelSelected([$accountHistoryData->getClientId()])); - $this->view->assign('isModified', strtotime($accountHistoryData->getDateEdit()) !== false); + ->getItemsFromModelSelected([$accountHistoryData->getClientId()]) + ); + $this->view->assign( + 'isModified', + strtotime($accountHistoryData->getDateEdit()) !== false + ); $accountActionsHelper = $this->dic->get(AccountActionsHelper::class); - $accountActionsDto = new AccountActionsDto($this->accountId, $this->accountHistoryId, 0); + $accountActionsDto = new AccountActionsDto( + $this->accountId, + $this->accountHistoryId, + 0 + ); - $this->view->assign('accountActions', - $accountActionsHelper->getActionsForAccount($this->accountAcl, $accountActionsDto)); - $this->view->assign('accountActionsMenu', - $accountActionsHelper->getActionsGrouppedForAccount($this->accountAcl, $accountActionsDto)); + $this->view->assign( + 'accountActions', + $accountActionsHelper->getActionsForAccount($this->accountAcl, $accountActionsDto) + ); + $this->view->assign( + 'accountActionsMenu', + $accountActionsHelper->getActionsGrouppedForAccount($this->accountAcl, $accountActionsDto) + ); } /** @@ -142,16 +149,16 @@ final class AccountHistoryHelper extends HelperBase * @throws NoSuchItemException * @throws ServiceException */ - protected function checkActionAccess() + protected function checkActionAccess(): void { if (!$this->acl->checkUserAccess($this->actionId)) { - throw new UnauthorizedPageException(UnauthorizedPageException::INFO); + throw new UnauthorizedPageException(SPException::INFO); } if (!$this->dic->get(MasterPassService::class) ->checkUserUpdateMPass($this->context->getUserData()->getLastUpdateMPass()) ) { - throw new UpdatedMasterPassException(UpdatedMasterPassException::INFO); + throw new UpdatedMasterPassException(SPException::INFO); } } @@ -166,7 +173,7 @@ final class AccountHistoryHelper extends HelperBase * @throws ConstraintException * @throws QueryException */ - protected function checkAccess(AccountHistoryData $accountHistoryData) + protected function checkAccess(AccountHistoryData $accountHistoryData): void { $acccountAclDto = AccountAclDto::makeFromAccountHistory( $accountHistoryData, @@ -190,7 +197,7 @@ final class AccountHistoryHelper extends HelperBase * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->acl = $this->dic->get(Acl::class); $this->accountHistoryService = $this->dic->get(AccountHistoryService::class); diff --git a/app/modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php index 8d122f15..45db46ef 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Account; @@ -47,10 +47,7 @@ use SP\Util\ImageUtil; */ final class AccountPasswordHelper extends HelperBase { - /** - * @var Acl - */ - private $acl; + private ?Acl $acl = null; /** * @param AccountPassData $accountData @@ -66,7 +63,10 @@ final class AccountPasswordHelper extends HelperBase * @throws NoSuchItemException * @throws ServiceException */ - public function getPasswordView(AccountPassData $accountData, bool $useImage): array + public function getPasswordView( + AccountPassData $accountData, + bool $useImage + ): array { $this->checkActionAccess(); @@ -80,11 +80,20 @@ final class AccountPasswordHelper extends HelperBase if ($useImage) { $imageUtil = $this->dic->get(ImageUtil::class); - $this->view->assign('login', $imageUtil->convertText($accountData->getLogin())); - $this->view->assign('pass', $imageUtil->convertText($pass)); + $this->view->assign( + 'login', + $imageUtil->convertText($accountData->getLogin()) + ); + $this->view->assign( + 'pass', + $imageUtil->convertText($pass) + ); } else { $this->view->assign('login', $accountData->getLogin()); - $this->view->assign('pass', htmlspecialchars($pass, ENT_COMPAT)); + $this->view->assign( + 'pass', + htmlspecialchars($pass, ENT_COMPAT) + ); } return [ @@ -96,7 +105,7 @@ final class AccountPasswordHelper extends HelperBase /** * @throws HelperException */ - private function checkActionAccess() + private function checkActionAccess(): void { if (!$this->acl->checkUserAccess(ActionsInterface::ACCOUNT_VIEW_PASS)) { throw new HelperException(__u('You don\'t have permission to access this account')); @@ -130,9 +139,9 @@ final class AccountPasswordHelper extends HelperBase return trim( Crypt::decrypt( - $accountData->getPass(), - $accountData->getKey(), - CryptSession::getSessionKey($this->context) + $accountData->getPass(), + $accountData->getKey(), + CryptSession::getSessionKey($this->context) ) ); } @@ -141,7 +150,7 @@ final class AccountPasswordHelper extends HelperBase * @throws DependencyException * @throws NotFoundException */ - protected function initialize() + protected function initialize(): void { $this->acl = $this->dic->get(Acl::class); } diff --git a/app/modules/web/Controllers/Helpers/Account/AccountSearchHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountSearchHelper.php index ac1c748d..93392291 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountSearchHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountSearchHelper.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Account; @@ -57,35 +57,11 @@ final class AccountSearchHelper extends HelperBase /** * @var bool Indica si el filtrado de cuentas está activo */ - private $filterOn = false; - /** - * @var string - */ - private $sk; - /** - * @var int - */ - private $queryTimeStart = 0; - /** - * @var bool - */ - private $isAjax = false; - /** - * @var bool - */ - private $isIndex = false; - /** - * @var AccountSearchFilter - */ - private $accountSearchFilter; - - /** - * @param boolean $isAjax - */ - public function setIsAjax(bool $isAjax) - { - $this->isAjax = $isAjax; - } + private bool $filterOn = false; + private int $queryTimeStart = 0; + private bool $isAjax = false; + private bool $isIndex = false; + private ?AccountSearchFilter $accountSearchFilter = null; /** * Obtener los datos para la caja de búsqueda @@ -95,22 +71,28 @@ final class AccountSearchHelper extends HelperBase * @throws ConstraintException * @throws QueryException */ - public function getSearchBox() + public function getSearchBox(): void { $this->view->addTemplate('search-searchbox'); - $this->view->assign('clients', + $this->view->assign( + 'clients', SelectItemAdapter::factory( $this->dic->get(ClientService::class) - ->getAllForUser())->getItemsFromModelSelected([$this->accountSearchFilter->getClientId()])); - $this->view->assign('categories', + ->getAllForUser())->getItemsFromModelSelected([$this->accountSearchFilter->getClientId()]) + ); + $this->view->assign( + 'categories', SelectItemAdapter::factory( CategoryService::getItemsBasic()) - ->getItemsFromModelSelected([$this->accountSearchFilter->getCategoryId()])); - $this->view->assign('tags', + ->getItemsFromModelSelected([$this->accountSearchFilter->getCategoryId()]) + ); + $this->view->assign( + 'tags', SelectItemAdapter::factory( TagService::getItemsBasic()) - ->getItemsFromModelSelected($this->accountSearchFilter->getTagsId())); + ->getItemsFromModelSelected($this->accountSearchFilter->getTagsId()) + ); } /** @@ -122,7 +104,7 @@ final class AccountSearchHelper extends HelperBase * @throws QueryException * @throws SPException */ - public function getAccountSearch() + public function getAccountSearch(): void { $this->view->addTemplate('search-index'); @@ -148,18 +130,28 @@ final class AccountSearchHelper extends HelperBase AccountSearchItem::$showTags = $userPreferences->isShowAccountSearchFilters(); if (AccountSearchItem::$wikiEnabled) { - $wikiFilter = array_map(function ($value) { - return preg_quote($value, '/'); - }, $this->configData->getWikiFilter()); + $wikiFilter = array_map( + static function ($value) { + return preg_quote($value, '/'); + }, + $this->configData->getWikiFilter() + ); - $this->view->assign('wikiFilter', implode('|', $wikiFilter)); - $this->view->assign('wikiPageUrl', $this->configData->getWikiPageurl()); + $this->view->assign( + 'wikiFilter', + implode('|', $wikiFilter) + ); + $this->view->assign( + 'wikiPageUrl', + $this->configData->getWikiPageurl() + ); } $accountSearchService = $this->dic->get(AccountSearchService::class); $dataGrid = $this->getGrid(); - $dataGrid->getData()->setData($accountSearchService->processSearchResults($this->accountSearchFilter)); + $dataGrid->getData() + ->setData($accountSearchService->processSearchResults($this->accountSearchFilter)); $dataGrid->updatePager(); $dataGrid->setTime(round(getElapsedTime($this->queryTimeStart), 5)); @@ -186,7 +178,10 @@ final class AccountSearchHelper extends HelperBase $gridActionOptional->setName(__('More Actions')); $gridActionOptional->setTitle(__('More Actions')); $gridActionOptional->setIcon($icons->getIconOptional()); - $gridActionOptional->setRuntimeFilter(AccountSearchItem::class, 'isShowOptional'); + $gridActionOptional->setRuntimeFilter( + AccountSearchItem::class, + 'isShowOptional' + ); $gridActionOptional->addData('onclick', 'account/menu'); $gridPager = new DataGridPager(); @@ -213,15 +208,30 @@ final class AccountSearchHelper extends HelperBase $dataGrid = new DataGrid($this->view->getTheme()); $dataGrid->setId('gridSearch'); $dataGrid->setDataHeaderTemplate('search-header'); - $dataGrid->setDataRowTemplate('search-rows', $this->view->getBase()); - $dataGrid->setDataPagerTemplate('datagrid-nav-full', 'grid'); + $dataGrid->setDataRowTemplate( + 'search-rows', + $this->view->getBase() + ); + $dataGrid->setDataPagerTemplate( + 'datagrid-nav-full', + 'grid' + ); $dataGrid->setHeader($this->getHeaderSort()); $dataGrid->addDataAction($actions->getViewAction()); $dataGrid->addDataAction($actions->getViewPassAction()); $dataGrid->addDataAction($actions->getCopyPassAction()); - $dataGrid->addDataAction($actions->getEditAction(), !$showOptionalActions); - $dataGrid->addDataAction($actions->getCopyAction(), !$showOptionalActions); - $dataGrid->addDataAction($actions->getDeleteAction(), !$showOptionalActions); + $dataGrid->addDataAction( + $actions->getEditAction(), + !$showOptionalActions + ); + $dataGrid->addDataAction( + $actions->getCopyAction(), + !$showOptionalActions + ); + $dataGrid->addDataAction( + $actions->getDeleteAction(), + !$showOptionalActions + ); $dataGrid->addDataAction($actions->getRequestAction()); $dataGrid->setPager($gridPager); $dataGrid->setData(new DataGridData()); @@ -286,7 +296,7 @@ final class AccountSearchHelper extends HelperBase /** * Initialize */ - protected function initialize() + protected function initialize(): void { $this->queryTimeStart = microtime(true); $this->isIndex = $this->request->analyzeString('r') === Acl::getActionRoute(ActionsInterface::ACCOUNT); @@ -309,17 +319,46 @@ final class AccountSearchHelper extends HelperBase $this->accountSearchFilter = $this->getFilters(); - $this->view->assign('searchCustomer', $this->accountSearchFilter->getClientId()); - $this->view->assign('searchCategory', $this->accountSearchFilter->getCategoryId()); - $this->view->assign('searchTags', $this->accountSearchFilter->getTagsId()); - $this->view->assign('searchTxt', $this->accountSearchFilter->getTxtSearch()); - $this->view->assign('searchGlobal', $this->accountSearchFilter->getGlobalSearch()); - $this->view->assign('searchFavorites', $this->accountSearchFilter->isSearchFavorites()); - - $this->view->assign('searchRoute', Acl::getActionRoute(ActionsInterface::ACCOUNT_SEARCH)); - $this->view->assign('favoriteRouteOn', Acl::getActionRoute(ActionsInterface::ACCOUNT_FAVORITE_ADD)); - $this->view->assign('favoriteRouteOff', Acl::getActionRoute(ActionsInterface::ACCOUNT_FAVORITE_DELETE)); - $this->view->assign('viewAccountRoute', Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW)); + $this->view->assign( + 'searchCustomer', + $this->accountSearchFilter->getClientId() + ); + $this->view->assign( + 'searchCategory', + $this->accountSearchFilter->getCategoryId() + ); + $this->view->assign( + 'searchTags', + $this->accountSearchFilter->getTagsId() + ); + $this->view->assign( + 'searchTxt', + $this->accountSearchFilter->getTxtSearch() + ); + $this->view->assign( + 'searchGlobal', + $this->accountSearchFilter->getGlobalSearch() + ); + $this->view->assign( + 'searchFavorites', + $this->accountSearchFilter->isSearchFavorites() + ); + $this->view->assign( + 'searchRoute', + Acl::getActionRoute(ActionsInterface::ACCOUNT_SEARCH) + ); + $this->view->assign( + 'favoriteRouteOn', + Acl::getActionRoute(ActionsInterface::ACCOUNT_FAVORITE_ADD) + ); + $this->view->assign( + 'favoriteRouteOff', + Acl::getActionRoute(ActionsInterface::ACCOUNT_FAVORITE_DELETE) + ); + $this->view->assign( + 'viewAccountRoute', + Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) + ); } /** @@ -349,7 +388,7 @@ final class AccountSearchHelper extends HelperBase $accountSearchFilter->setGlobalSearch($this->request->analyzeBool('gsearch', false)); $accountSearchFilter->setClientId($this->request->analyzeInt('client', 0)); $accountSearchFilter->setCategoryId($this->request->analyzeInt('category', 0)); - $accountSearchFilter->setTagsId($this->request->analyzeArray('tags')); + $accountSearchFilter->setTagsId($this->request->analyzeArray('tags', null, [])); $accountSearchFilter->setSearchFavorites($this->request->analyzeBool('searchfav', false)); $accountSearchFilter->setTxtSearch($this->request->analyzeString('search')); $accountSearchFilter->setSortViews($userPreferences->isSortViews()); diff --git a/app/modules/web/Controllers/Helpers/Grid/AccountGrid.php b/app/modules/web/Controllers/Helpers/Grid/AccountGrid.php index 09591ee8..b38ebbcf 100644 --- a/app/modules/web/Controllers/Helpers/Grid/AccountGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/AccountGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,10 +43,7 @@ use SP\Storage\Database\QueryResult; */ final class AccountGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -148,7 +145,10 @@ final class AccountGrid extends GridBase $gridActionSearch->setName('frmSearchAccount'); $gridActionSearch->setTitle(__('Search for Account')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNTMGR_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNTMGR_SEARCH) + ); return $gridActionSearch; } @@ -165,7 +165,10 @@ final class AccountGrid extends GridBase $gridAction->setTitle(__('Account Details')); $gridAction->setIcon($this->icons->getIconView()); $gridAction->setOnClickFunction(Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW)); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_VIEW) + ); return $gridAction; } @@ -182,7 +185,10 @@ final class AccountGrid extends GridBase $gridAction->setTitle(__('Remove Account')); $gridAction->setIcon($this->icons->getIconDelete()); $gridAction->setOnClickFunction('appMgmt/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNTMGR_DELETE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNTMGR_DELETE) + ); return $gridAction; } @@ -199,7 +205,10 @@ final class AccountGrid extends GridBase $gridAction->setTitle(__('Bulk Update')); $gridAction->setIcon($this->icons->getIconEdit()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNTMGR_BULK_EDIT)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNTMGR_BULK_EDIT) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/AccountHistoryGrid.php b/app/modules/web/Controllers/Helpers/Grid/AccountHistoryGrid.php index 4225dadd..76830c54 100644 --- a/app/modules/web/Controllers/Helpers/Grid/AccountHistoryGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/AccountHistoryGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -42,10 +42,7 @@ use SP\Storage\Database\QueryResult; */ final class AccountHistoryGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -126,8 +123,16 @@ final class AccountHistoryGrid extends GridBase $gridData->addDataRowSource('clientName'); $gridData->addDataRowSource('categoryName'); $gridData->addDataRowSource('date'); - $gridData->addDataRowSourceWithIcon('isModify', $iconEdit->setTitle(__('Modified'))->setClass('opacity50')); - $gridData->addDataRowSourceWithIcon('isDeleted', $iconDelete->setTitle(__('Removed'))->setClass('opacity50')); + $gridData->addDataRowSourceWithIcon( + 'isModify', + $iconEdit->setTitle(__('Modified')) + ->setClass('opacity50') + ); + $gridData->addDataRowSourceWithIcon( + 'isDeleted', + $iconDelete->setTitle(__('Removed')) + ->setClass('opacity50') + ); $gridData->setData($this->queryResult); return $gridData; @@ -144,7 +149,10 @@ final class AccountHistoryGrid extends GridBase $gridActionSearch->setName('frmSearchAccountHistory'); $gridActionSearch->setTitle(__('Search for Account')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNTMGR_HISTORY_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNTMGR_HISTORY_SEARCH) + ); return $gridActionSearch; } @@ -161,7 +169,10 @@ final class AccountHistoryGrid extends GridBase $gridAction->setTitle(__('Account Restore')); $gridAction->setIcon($this->icons->getIconRestore()); $gridAction->setOnClickFunction('accountManager/restore'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNTMGR_HISTORY_RESTORE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNTMGR_HISTORY_RESTORE) + ); return $gridAction; } @@ -178,7 +189,10 @@ final class AccountHistoryGrid extends GridBase $gridAction->setTitle(__('Remove Account')); $gridAction->setIcon($this->icons->getIconDelete()); $gridAction->setOnClickFunction('appMgmt/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNTMGR_HISTORY_DELETE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNTMGR_HISTORY_DELETE) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/AuthTokenGrid.php b/app/modules/web/Controllers/Helpers/Grid/AuthTokenGrid.php index e4a34e8e..9f15e761 100644 --- a/app/modules/web/Controllers/Helpers/Grid/AuthTokenGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/AuthTokenGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,10 +43,7 @@ use SP\Storage\Database\QueryResult; */ final class AuthTokenGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -119,9 +116,13 @@ final class AuthTokenGrid extends GridBase $gridData = new DataGridData(); $gridData->setDataRowSourceId('id'); $gridData->addDataRowSource('userLogin'); - $gridData->addDataRowSource('actionId', false, function ($value) { - return Acl::getActionInfo($value); - }); + $gridData->addDataRowSource( + 'actionId', + false, + function ($value) { + return Acl::getActionInfo($value); + } + ); $gridData->setData($this->queryResult); return $gridData; @@ -139,7 +140,10 @@ final class AuthTokenGrid extends GridBase $gridActionSearch->setName('frmSearchToken'); $gridActionSearch->setTitle(__('Search for Token')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::AUTHTOKEN_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::AUTHTOKEN_SEARCH) + ); return $gridActionSearch; } @@ -157,7 +161,10 @@ final class AuthTokenGrid extends GridBase $gridAction->setIcon($this->icons->getIconAdd()); $gridAction->setSkip(true); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::AUTHTOKEN_CREATE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::AUTHTOKEN_CREATE) + ); return $gridAction; } @@ -174,7 +181,10 @@ final class AuthTokenGrid extends GridBase $gridAction->setTitle(__('View Authorization token')); $gridAction->setIcon($this->icons->getIconView()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::AUTHTOKEN_VIEW)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::AUTHTOKEN_VIEW) + ); return $gridAction; } @@ -191,7 +201,10 @@ final class AuthTokenGrid extends GridBase $gridAction->setTitle(__('Edit Authorization')); $gridAction->setIcon($this->icons->getIconEdit()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::AUTHTOKEN_EDIT)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::AUTHTOKEN_EDIT) + ); return $gridAction; } @@ -208,7 +221,10 @@ final class AuthTokenGrid extends GridBase $gridAction->setTitle(__('Delete Authorization')); $gridAction->setIcon($this->icons->getIconDelete()); $gridAction->setOnClickFunction('appMgmt/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::AUTHTOKEN_DELETE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::AUTHTOKEN_DELETE) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/CategoryGrid.php b/app/modules/web/Controllers/Helpers/Grid/CategoryGrid.php index c9620ef4..1f7652cb 100644 --- a/app/modules/web/Controllers/Helpers/Grid/CategoryGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/CategoryGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,10 +43,7 @@ use SP\Storage\Database\QueryResult; */ final class CategoryGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -136,7 +133,10 @@ final class CategoryGrid extends GridBase $gridActionSearch->setName('frmSearchCategory'); $gridActionSearch->setTitle(__('Search for Category')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::CATEGORY_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::CATEGORY_SEARCH) + ); return $gridActionSearch; } @@ -154,7 +154,10 @@ final class CategoryGrid extends GridBase $gridAction->setIcon($this->icons->getIconAdd()); $gridAction->setSkip(true); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::CATEGORY_CREATE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::CATEGORY_CREATE) + ); return $gridAction; } @@ -171,7 +174,10 @@ final class CategoryGrid extends GridBase $gridAction->setTitle(__('Edit Category')); $gridAction->setIcon($this->icons->getIconEdit()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::CATEGORY_EDIT)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::CATEGORY_EDIT) + ); return $gridAction; } @@ -188,7 +194,10 @@ final class CategoryGrid extends GridBase $gridAction->setTitle(__('Delete Category')); $gridAction->setIcon($this->icons->getIconDelete()); $gridAction->setOnClickFunction('appMgmt/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::CATEGORY_DELETE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::CATEGORY_DELETE) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/ClientGrid.php b/app/modules/web/Controllers/Helpers/Grid/ClientGrid.php index 378701a3..e01b6659 100644 --- a/app/modules/web/Controllers/Helpers/Grid/ClientGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/ClientGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -42,10 +42,7 @@ use SP\Storage\Database\QueryResult; */ final class ClientGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -119,9 +116,13 @@ final class ClientGrid extends GridBase $gridData->setDataRowSourceId('id'); $gridData->addDataRowSource('name'); $gridData->addDataRowSource('description'); - $gridData->addDataRowSource('isGlobal', false, function ($value) { - return $value ? __('YES') : __('NO'); - }); + $gridData->addDataRowSource( + 'isGlobal', + false, + function ($value) { + return $value ? __('YES') : __('NO'); + } + ); $gridData->setData($this->queryResult); return $gridData; @@ -139,7 +140,10 @@ final class ClientGrid extends GridBase $gridActionSearch->setName('frmSearchClient'); $gridActionSearch->setTitle(__('Search for Client')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::CLIENT_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::CLIENT_SEARCH) + ); return $gridActionSearch; } @@ -157,7 +161,10 @@ final class ClientGrid extends GridBase $gridAction->setIcon($this->icons->getIconAdd()); $gridAction->setSkip(true); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::CLIENT_CREATE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::CLIENT_CREATE) + ); return $gridAction; } @@ -174,7 +181,10 @@ final class ClientGrid extends GridBase $gridAction->setTitle(__('Edit Client')); $gridAction->setIcon($this->icons->getIconEdit()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::CLIENT_EDIT)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::CLIENT_EDIT) + ); return $gridAction; } @@ -191,7 +201,10 @@ final class ClientGrid extends GridBase $gridAction->setTitle(__('Delete Client')); $gridAction->setIcon($this->icons->getIconDelete()); $gridAction->setOnClickFunction('appMgmt/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::CLIENT_DELETE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::CLIENT_DELETE) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/CustomFieldGrid.php b/app/modules/web/Controllers/Helpers/Grid/CustomFieldGrid.php index 29a56efb..b82269c1 100644 --- a/app/modules/web/Controllers/Helpers/Grid/CustomFieldGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/CustomFieldGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,10 +43,7 @@ use SP\Storage\Database\QueryResult; */ final class CustomFieldGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -121,11 +118,18 @@ final class CustomFieldGrid extends GridBase $gridData = new DataGridData(); $gridData->setDataRowSourceId('id'); $gridData->addDataRowSource('name'); - $gridData->addDataRowSource('moduleId', false, function ($value) { - return CustomFieldDefService::getFieldModuleById($value); - }); + $gridData->addDataRowSource( + 'moduleId', + false, + function ($value) { + return CustomFieldDefService::getFieldModuleById($value); + } + ); $gridData->addDataRowSource('typeName'); - $gridData->addDataRowSourceWithIcon('isEncrypted', $this->icons->getIconEditPass()->setTitle(__('Encrypted'))); + $gridData->addDataRowSourceWithIcon( + 'isEncrypted', + $this->icons->getIconEditPass()->setTitle(__('Encrypted')) + ); $gridData->setData($this->queryResult); return $gridData; @@ -143,7 +147,10 @@ final class CustomFieldGrid extends GridBase $gridActionSearch->setName('frmSearchCustomField'); $gridActionSearch->setTitle(__('Search for Field')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::CUSTOMFIELD_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::CUSTOMFIELD_SEARCH) + ); return $gridActionSearch; } @@ -161,7 +168,10 @@ final class CustomFieldGrid extends GridBase $gridAction->setIcon($this->icons->getIconAdd()); $gridAction->setSkip(true); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::CUSTOMFIELD_CREATE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::CUSTOMFIELD_CREATE) + ); return $gridAction; } @@ -178,7 +188,10 @@ final class CustomFieldGrid extends GridBase $gridAction->setTitle(__('Edit Field')); $gridAction->setIcon($this->icons->getIconEdit()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::CUSTOMFIELD_EDIT)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::CUSTOMFIELD_EDIT) + ); return $gridAction; } @@ -195,7 +208,10 @@ final class CustomFieldGrid extends GridBase $gridAction->setTitle(__('Delete Field')); $gridAction->setIcon($this->icons->getIconDelete()); $gridAction->setOnClickFunction('appMgmt/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::CUSTOMFIELD_DELETE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::CUSTOMFIELD_DELETE) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/EventlogGrid.php b/app/modules/web/Controllers/Helpers/Grid/EventlogGrid.php index 3d9328eb..405bd7d3 100644 --- a/app/modules/web/Controllers/Helpers/Grid/EventlogGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/EventlogGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,10 +43,7 @@ use SP\Storage\Database\QueryResult; */ final class EventlogGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -126,10 +123,16 @@ final class EventlogGrid extends GridBase function ($value) use ($isDemoMode) { return $isDemoMode ? '*.*.*.*' : $value; }); - $gridData->addDataRowSource('description', false, + $gridData->addDataRowSource( + 'description', + false, function ($value) use ($isDemoMode) { if ($isDemoMode) { - $value = preg_replace('/\d+\.\d+\.\d+\.\d+/', '*.*.*.*', $value); + $value = preg_replace( + '/\d+\.\d+\.\d+\.\d+/', + '*.*.*.*', + $value + ); } if (preg_match('/^SQL.*/m', $value)) { @@ -137,7 +140,8 @@ final class EventlogGrid extends GridBase '/([a-zA-Z_]+),/m', '/(UPDATE|DELETE|TRUNCATE|INSERT|SELECT|WHERE|LEFT|ORDER|LIMIT|FROM)/m'], ['\\1,
', '
\\1'], - $value); + $value + ); } return wordwrap( @@ -146,7 +150,9 @@ final class EventlogGrid extends GridBase '
', true ); - }, false); + }, + false + ); $gridData->setData($this->queryResult); return $gridData; @@ -164,7 +170,10 @@ final class EventlogGrid extends GridBase $gridActionSearch->setName('frmSearchEvent'); $gridActionSearch->setTitle(__('Search for Events')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::EVENTLOG_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::EVENTLOG_SEARCH) + ); return $gridActionSearch; } @@ -182,8 +191,11 @@ final class EventlogGrid extends GridBase $gridAction->setTitle(__('Refresh')); $gridAction->setIcon($this->icons->getIconRefresh()); $gridAction->setOnClickFunction('eventlog/refresh'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::EVENTLOG_SEARCH)); $gridAction->addData('action-form', 'frmSearchEvent'); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::EVENTLOG_SEARCH) + ); return $gridAction; } @@ -201,7 +213,10 @@ final class EventlogGrid extends GridBase $gridAction->setTitle(__('Clear the event log out')); $gridAction->setIcon($this->icons->getIconClear()); $gridAction->setOnClickFunction('eventlog/clear'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::EVENTLOG_CLEAR)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::EVENTLOG_CLEAR) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/FileGrid.php b/app/modules/web/Controllers/Helpers/Grid/FileGrid.php index cce772d3..fc78540c 100644 --- a/app/modules/web/Controllers/Helpers/Grid/FileGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/FileGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -42,10 +42,7 @@ use SP\Storage\Database\QueryResult; */ final class FileGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -124,9 +121,13 @@ final class FileGrid extends GridBase $gridData->addDataRowSource('clientName'); $gridData->addDataRowSource('name'); $gridData->addDataRowSource('type'); - $gridData->addDataRowSource('size', false, function ($value) { - return sprintf('%.2f KB', $value / 1000); - }); + $gridData->addDataRowSource( + 'size', + false, + function ($value) { + return sprintf('%.2f KB', $value / 1000); + } + ); $gridData->setData($this->queryResult); return $gridData; @@ -144,7 +145,10 @@ final class FileGrid extends GridBase $gridActionSearch->setName('frmSearchFile'); $gridActionSearch->setTitle(__('Search for File')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_SEARCH) + ); return $gridActionSearch; } @@ -161,8 +165,11 @@ final class FileGrid extends GridBase $gridAction->setTitle(__('View File')); $gridAction->setIcon($this->icons->getIconView()); $gridAction->setOnClickFunction('file/view'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_VIEW)); $gridAction->setFilterRowSource('type', 'application/pdf'); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_VIEW) + ); return $gridAction; } @@ -179,10 +186,15 @@ final class FileGrid extends GridBase $gridAction->setTitle(__('Download File')); $gridAction->setIcon($this->icons->getIconDownload()); $gridAction->setOnClickFunction('file/download'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_DOWNLOAD)); - $gridAction->setRuntimeData(function ($dataItem) use ($gridAction) { - return ['item-type' => $dataItem->type]; - }); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_DOWNLOAD) + ); + $gridAction->setRuntimeData( + function ($dataItem) { + return ['item-type' => $dataItem->type]; + } + ); return $gridAction; } @@ -199,7 +211,10 @@ final class FileGrid extends GridBase $gridAction->setTitle(__('Delete File')); $gridAction->setIcon($this->icons->getIconDelete()); $gridAction->setOnClickFunction('appMgmt/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_DELETE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_DELETE) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/GridBase.php b/app/modules/web/Controllers/Helpers/Grid/GridBase.php index 3bdf66f8..78179324 100644 --- a/app/modules/web/Controllers/Helpers/Grid/GridBase.php +++ b/app/modules/web/Controllers/Helpers/Grid/GridBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,18 +43,9 @@ use SP\Modules\Web\Controllers\Helpers\HelperBase; */ abstract class GridBase extends HelperBase implements GridInterface { - /** - * @var float - */ - protected $queryTimeStart; - /** - * @var ThemeIcons - */ - protected $icons; - /** - * @var Acl - */ - protected $acl; + protected ?float $queryTimeStart = null; + protected ?ThemeIcons $icons = null; + protected ?Acl $acl = null; /** * Actualizar los datos del paginador @@ -64,12 +55,15 @@ abstract class GridBase extends HelperBase implements GridInterface * * @return DataGridInterface */ - public function updatePager(DataGridInterface $dataGrid, ItemSearchData $itemSearchData): DataGridInterface + public function updatePager( + DataGridInterface $dataGrid, + ItemSearchData $itemSearchData + ): DataGridInterface { $dataGrid->getPager() ->setLimitStart($itemSearchData->getLimitStart()) ->setLimitCount($itemSearchData->getLimitCount()) - ->setFilterOn($itemSearchData->getSeachString() !== ''); + ->setFilterOn(!empty($itemSearchData->getSeachString())); $dataGrid->updatePager(); @@ -83,7 +77,9 @@ abstract class GridBase extends HelperBase implements GridInterface * * @return DataGridPager */ - final protected function getPager(DataGridActionSearch $sourceAction): DataGridPager + final protected function getPager( + DataGridActionSearch $sourceAction + ): DataGridPager { $gridPager = new DataGridPager(); $gridPager->setSourceAction($sourceAction); @@ -102,7 +98,7 @@ abstract class GridBase extends HelperBase implements GridInterface * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - final protected function initialize() + final protected function initialize(): void { $this->queryTimeStart = microtime(true); $this->acl = $this->dic->get(Acl::class); @@ -112,15 +108,15 @@ abstract class GridBase extends HelperBase implements GridInterface /** * @return DataGridInterface */ - protected abstract function getGridLayout(): DataGridInterface; + abstract protected function getGridLayout(): DataGridInterface; /** * @return DataGridHeader */ - protected abstract function getHeader(): DataGridHeader; + abstract protected function getHeader(): DataGridHeader; /** * @return DataGridData */ - protected abstract function getData(): DataGridData; + abstract protected function getData(): DataGridData; } \ No newline at end of file diff --git a/app/modules/web/Controllers/Helpers/Grid/GridInterface.php b/app/modules/web/Controllers/Helpers/Grid/GridInterface.php index 2c25cf09..affc4c9b 100644 --- a/app/modules/web/Controllers/Helpers/Grid/GridInterface.php +++ b/app/modules/web/Controllers/Helpers/Grid/GridInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; diff --git a/app/modules/web/Controllers/Helpers/Grid/ItemPresetGrid.php b/app/modules/web/Controllers/Helpers/Grid/ItemPresetGrid.php index be4ecde6..f0c4e1f2 100644 --- a/app/modules/web/Controllers/Helpers/Grid/ItemPresetGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/ItemPresetGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,10 +43,7 @@ use SP\Storage\Database\QueryResult; */ final class ItemPresetGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -147,7 +144,10 @@ final class ItemPresetGrid extends GridBase $gridActionSearch->setName('frmSearchItemPreset'); $gridActionSearch->setTitle(__('Search for Value')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::ITEMPRESET_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ITEMPRESET_SEARCH) + ); return $gridActionSearch; } @@ -260,7 +260,10 @@ final class ItemPresetGrid extends GridBase $gridAction->setTitle(__('Edit Value')); $gridAction->setIcon($this->icons->getIconEdit()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::ITEMPRESET_EDIT)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ITEMPRESET_EDIT) + ); return $gridAction; } @@ -277,7 +280,10 @@ final class ItemPresetGrid extends GridBase $gridAction->setTitle(__('Delete Value')); $gridAction->setIcon($this->icons->getIconDelete()); $gridAction->setOnClickFunction('appMgmt/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::ITEMPRESET_DELETE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::ITEMPRESET_DELETE) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/NotificationGrid.php b/app/modules/web/Controllers/Helpers/Grid/NotificationGrid.php index 6aa57795..ac7eeb93 100644 --- a/app/modules/web/Controllers/Helpers/Grid/NotificationGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/NotificationGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -46,14 +46,8 @@ use SP\Util\DateUtil; */ final class NotificationGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; - /** - * @var bool - */ - private $isAdminApp; + private ?QueryResult $queryResult = null; + private ?bool $isAdminApp = null; /** * @param QueryResult $queryResult @@ -71,7 +65,7 @@ final class NotificationGrid extends GridBase $grid->addDataAction($searchAction); $grid->setPager($this->getPager($searchAction)); - $this->isAdminApp = (bool)$this->context->getUserData()->getIsAdminApp(); + $this->isAdminApp = $this->context->getUserData()->getIsAdminApp(); if ($this->isAdminApp) { $grid->addDataAction($this->getCreateAction()); @@ -141,18 +135,34 @@ final class NotificationGrid extends GridBase // Grid Data $gridData = new DataGridData(); $gridData->setDataRowSourceId('id'); - $gridData->addDataRowSource('date', false, + $gridData->addDataRowSource( + 'date', + false, function ($value) { return DateUtil::getDateFromUnix($value); - }); + } + ); $gridData->addDataRowSource('type'); $gridData->addDataRowSource('component'); - $gridData->addDataRowSource('description', false, function ($data) { - return Html::stripTags($data); - }); - $gridData->addDataRowSourceWithIcon('checked', $this->icons->getIconEnabled()->setTitle(__('Read'))); - $gridData->addDataRowSourceWithIcon('onlyAdmin', $this->icons->getIconAppAdmin()->setTitle(__('Only Admins'))); - $gridData->addDataRowSourceWithIcon('sticky', $this->icons->getIconGroup()->setTitle(__('Global'))); + $gridData->addDataRowSource( + 'description', + false, + function ($data) { + return Html::stripTags($data); + } + ); + $gridData->addDataRowSourceWithIcon( + 'checked', + $this->icons->getIconEnabled()->setTitle(__('Read')) + ); + $gridData->addDataRowSourceWithIcon( + 'onlyAdmin', + $this->icons->getIconAppAdmin()->setTitle(__('Only Admins')) + ); + $gridData->addDataRowSourceWithIcon( + 'sticky', + $this->icons->getIconGroup()->setTitle(__('Global')) + ); $gridData->setData($this->queryResult); return $gridData; @@ -170,7 +180,10 @@ final class NotificationGrid extends GridBase $gridActionSearch->setName('frmSearchNotification'); $gridActionSearch->setTitle(__('Search for Notification')); $gridActionSearch->setOnSubmitFunction('notification/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::NOTIFICATION_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::NOTIFICATION_SEARCH) + ); return $gridActionSearch; } @@ -188,7 +201,10 @@ final class NotificationGrid extends GridBase $gridAction->setIcon($this->icons->getIconAdd()); $gridAction->setSkip(true); $gridAction->setOnClickFunction('notification/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::NOTIFICATION_CREATE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::NOTIFICATION_CREATE) + ); return $gridAction; } @@ -205,7 +221,10 @@ final class NotificationGrid extends GridBase $gridAction->setTitle(__('View Notification')); $gridAction->setIcon($this->icons->getIconView()); $gridAction->setOnClickFunction('notification/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::NOTIFICATION_VIEW)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::NOTIFICATION_VIEW) + ); return $gridAction; } @@ -215,7 +234,9 @@ final class NotificationGrid extends GridBase * * @return DataGridActionInterface */ - private function setNonAdminFilter(DataGridActionInterface $gridAction): DataGridActionInterface + private function setNonAdminFilter( + DataGridActionInterface $gridAction + ): DataGridActionInterface { if (!$this->isAdminApp) { $gridAction->setFilterRowSource('sticky'); @@ -236,8 +257,14 @@ final class NotificationGrid extends GridBase $gridAction->setIcon($this->icons->getIconEnabled()); $gridAction->setOnClickFunction('notification/check'); $gridAction->setFilterRowSource('checked'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::NOTIFICATION_CHECK)); - $gridAction->addData('action-next', Acl::getActionRoute(ActionsInterface::NOTIFICATION)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::NOTIFICATION_CHECK) + ); + $gridAction->addData( + 'action-next', + Acl::getActionRoute(ActionsInterface::NOTIFICATION) + ); return $gridAction; } @@ -253,7 +280,10 @@ final class NotificationGrid extends GridBase $gridAction->setTitle(__('Edit Notification')); $gridAction->setIcon($this->icons->getIconEdit()); $gridAction->setOnClickFunction('notification/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::NOTIFICATION_EDIT)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::NOTIFICATION_EDIT) + ); return $gridAction; } @@ -271,8 +301,14 @@ final class NotificationGrid extends GridBase $gridAction->setIcon($this->icons->getIconDelete()); $gridAction->setOnClickFunction('notification/delete'); $gridAction->setFilterRowSource('checked', 0); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::NOTIFICATION_DELETE)); - $gridAction->addData('action-next', Acl::getActionRoute(ActionsInterface::NOTIFICATION)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::NOTIFICATION_DELETE) + ); + $gridAction->addData( + 'action-next', + Acl::getActionRoute(ActionsInterface::NOTIFICATION) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/PluginGrid.php b/app/modules/web/Controllers/Helpers/Grid/PluginGrid.php index 9a3887b1..6656393d 100644 --- a/app/modules/web/Controllers/Helpers/Grid/PluginGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/PluginGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,10 +43,7 @@ use SP\Storage\Database\QueryResult; */ final class PluginGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -114,9 +111,20 @@ final class PluginGrid extends GridBase $gridData = new DataGridData(); $gridData->setDataRowSourceId('id'); $gridData->addDataRowSource('name'); - $gridData->addDataRowSourceWithIcon('enabled', $this->icons->getIconEnabled()); - $gridData->addDataRowSourceWithIcon('enabled', $this->icons->getIconDisabled(), 0); - $gridData->addDataRowSourceWithIcon('available', $this->icons->getIconDelete()->setTitle(__('Unavailable')), 0); + $gridData->addDataRowSourceWithIcon( + 'enabled', + $this->icons->getIconEnabled() + ); + $gridData->addDataRowSourceWithIcon( + 'enabled', + $this->icons->getIconDisabled(), + 0 + ); + $gridData->addDataRowSourceWithIcon( + 'available', + $this->icons->getIconDelete()->setTitle(__('Unavailable')), + 0 + ); $gridData->setData($this->queryResult); return $gridData; @@ -134,7 +142,10 @@ final class PluginGrid extends GridBase $gridActionSearch->setName('frmSearchPlugin'); $gridActionSearch->setTitle(__('Search for Plugin')); $gridActionSearch->setOnSubmitFunction('plugin/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::PLUGIN_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PLUGIN_SEARCH) + ); return $gridActionSearch; } @@ -152,7 +163,10 @@ final class PluginGrid extends GridBase $gridAction->setIcon($this->icons->getIconView()); $gridAction->setOnClickFunction('plugin/show'); $gridAction->setFilterRowSource('available', 0); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::PLUGIN_VIEW)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PLUGIN_VIEW) + ); return $gridAction; } @@ -170,7 +184,10 @@ final class PluginGrid extends GridBase $gridAction->setOnClickFunction('plugin/toggle'); $gridAction->setFilterRowSource('enabled'); $gridAction->setFilterRowSource('available', 0); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::PLUGIN_ENABLE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PLUGIN_ENABLE) + ); $gridAction->addData('action-method', 'get'); return $gridAction; @@ -189,7 +206,10 @@ final class PluginGrid extends GridBase $gridAction->setOnClickFunction('plugin/toggle'); $gridAction->setFilterRowSource('enabled', 0); $gridAction->setFilterRowSource('available', 0); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::PLUGIN_DISABLE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PLUGIN_DISABLE) + ); $gridAction->addData('action-method', 'get'); return $gridAction; @@ -207,9 +227,15 @@ final class PluginGrid extends GridBase $gridAction->setIcon($this->icons->getIconRefresh()); $gridAction->setOnClickFunction('plugin/reset'); $gridAction->setFilterRowSource('available', 0); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::PLUGIN_RESET)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PLUGIN_RESET) + ); $gridAction->addData('action-method', 'get'); - $gridAction->addData('action-next', Acl::getActionRoute(ActionsInterface::PLUGIN)); + $gridAction->addData( + 'action-next', + Acl::getActionRoute(ActionsInterface::PLUGIN) + ); return $gridAction; } @@ -225,10 +251,16 @@ final class PluginGrid extends GridBase $gridAction->setName(__('Delete Plugin')); $gridAction->setTitle(__('Delete Plugin')); $gridAction->setIcon($this->icons->getIconDelete()); - $gridAction->setFilterRowSource('available', 1); + $gridAction->setFilterRowSource('available'); $gridAction->setOnClickFunction('plugin/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::PLUGIN_DELETE)); - $gridAction->addData('action-next', Acl::getActionRoute(ActionsInterface::PLUGIN)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PLUGIN_DELETE) + ); + $gridAction->addData( + 'action-next', + Acl::getActionRoute(ActionsInterface::PLUGIN) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/PublicLinkGrid.php b/app/modules/web/Controllers/Helpers/Grid/PublicLinkGrid.php index ed1ee5b7..0a99c43d 100644 --- a/app/modules/web/Controllers/Helpers/Grid/PublicLinkGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/PublicLinkGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,10 +43,7 @@ use SP\Storage\Database\QueryResult; */ final class PublicLinkGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -73,7 +70,8 @@ final class PublicLinkGrid extends GridBase ->setName(__('Delete Selected')) ->setTitle(__('Delete Selected')) ->setIsSelection(true), - true); + true + ); $grid->setTime(round(getElapsedTime($this->queryTimeStart), 5)); @@ -129,9 +127,13 @@ final class PublicLinkGrid extends GridBase $gridData->addDataRowSource('getDateAddFormat', true); $gridData->addDataRowSource('getDateExpireFormat', true); $gridData->addDataRowSource('userLogin'); - $gridData->addDataRowSource('notify', false, function ($value) { - return $value ? __('ON') : __('OFF'); - }); + $gridData->addDataRowSource( + 'notify', + false, + function ($value) { + return $value ? __('ON') : __('OFF'); + } + ); $gridData->addDataRowSource('getCountViewsString', true); $gridData->setData($this->queryResult); @@ -150,7 +152,10 @@ final class PublicLinkGrid extends GridBase $gridActionSearch->setName('frmSearchLink'); $gridActionSearch->setTitle(__('Search for Link')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::PUBLICLINK_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PUBLICLINK_SEARCH) + ); return $gridActionSearch; } @@ -168,7 +173,10 @@ final class PublicLinkGrid extends GridBase $gridAction->setIcon($this->icons->getIconAdd()); $gridAction->setSkip(true); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::PUBLICLINK_CREATE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PUBLICLINK_CREATE) + ); return $gridAction; } @@ -185,7 +193,10 @@ final class PublicLinkGrid extends GridBase $gridAction->setTitle(__('View Link')); $gridAction->setIcon($this->icons->getIconView()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::PUBLICLINK_VIEW)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PUBLICLINK_VIEW) + ); return $gridAction; } @@ -201,7 +212,10 @@ final class PublicLinkGrid extends GridBase $gridAction->setTitle(__('Renew Link')); $gridAction->setIcon($this->icons->getIconRefresh()); $gridAction->setOnClickFunction('link/refresh'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::PUBLICLINK_REFRESH)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PUBLICLINK_REFRESH) + ); return $gridAction; } @@ -218,7 +232,10 @@ final class PublicLinkGrid extends GridBase $gridAction->setTitle(__('Delete Link')); $gridAction->setIcon($this->icons->getIconDelete()); $gridAction->setOnClickFunction('appMgmt/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::PUBLICLINK_DELETE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PUBLICLINK_DELETE) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/TagGrid.php b/app/modules/web/Controllers/Helpers/Grid/TagGrid.php index 816c52f1..a2d46e2c 100644 --- a/app/modules/web/Controllers/Helpers/Grid/TagGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/TagGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,10 +43,7 @@ use SP\Storage\Database\QueryResult; */ final class TagGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -72,7 +69,8 @@ final class TagGrid extends GridBase ->setName(__('Delete Selected')) ->setTitle(__('Delete Selected')) ->setIsSelection(true), - true); + true + ); $grid->setTime(round(getElapsedTime($this->queryTimeStart), 5)); @@ -134,7 +132,10 @@ final class TagGrid extends GridBase $gridActionSearch->setName('frmSearchTag'); $gridActionSearch->setTitle(__('Search for Tag')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::TAG_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::TAG_SEARCH) + ); return $gridActionSearch; } @@ -152,7 +153,10 @@ final class TagGrid extends GridBase $gridAction->setIcon($this->icons->getIconAdd()); $gridAction->setSkip(true); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::TAG_CREATE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::TAG_CREATE) + ); return $gridAction; } @@ -169,7 +173,10 @@ final class TagGrid extends GridBase $gridAction->setTitle(__('Edit Tag')); $gridAction->setIcon($this->icons->getIconEdit()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::TAG_EDIT)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::TAG_EDIT) + ); return $gridAction; } @@ -186,7 +193,10 @@ final class TagGrid extends GridBase $gridAction->setTitle(__('Delete Tag')); $gridAction->setIcon($this->icons->getIconDelete()); $gridAction->setOnClickFunction('appMgmt/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::TAG_DELETE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::TAG_DELETE) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/TrackGrid.php b/app/modules/web/Controllers/Helpers/Grid/TrackGrid.php index fbec9215..9b736efa 100644 --- a/app/modules/web/Controllers/Helpers/Grid/TrackGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/TrackGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,10 +43,7 @@ use SP\Storage\Database\QueryResult; */ final class TrackGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + protected ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -120,29 +117,42 @@ final class TrackGrid extends GridBase $gridData->setDataRowSourceId('id'); $gridData->addDataRowSource('dateTime'); $gridData->addDataRowSource('dateTimeUnlock'); - $gridData->addDataRowSource('source', null, null, false); - $gridData->addDataRowSource('ipv4', null, function ($value) use ($demo) { - if ($value !== null) { - if ($demo) { - return '*.*.*.*'; + $gridData->addDataRowSource( + 'source', + null, + null, + false + ); + $gridData->addDataRowSource( + 'ipv4', + null, + function ($value) use ($demo) { + if ($value !== null) { + if ($demo) { + return '*.*.*.*'; + } + + return Address::fromBinary($value); } - return Address::fromBinary($value); + return ' '; } + ); + $gridData->addDataRowSource( + 'ipv6', + null, + function ($value) use ($demo) { + if ($value !== null) { + if ($demo) { + return '*.*.*.*'; + } - return ' '; - }); - $gridData->addDataRowSource('ipv6', null, function ($value) use ($demo) { - if ($value !== null) { - if ($demo) { - return '*.*.*.*'; + return Address::fromBinary($value); } - return Address::fromBinary($value); + return ' '; } - - return ' '; - }); + ); $gridData->addDataRowSource('userId'); $gridData->setData($this->queryResult); @@ -161,7 +171,10 @@ final class TrackGrid extends GridBase $gridActionSearch->setName('frmSearchTrack'); $gridActionSearch->setTitle(__('Search for track')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::TRACK_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::TRACK_SEARCH) + ); return $gridActionSearch; } @@ -179,8 +192,11 @@ final class TrackGrid extends GridBase $gridAction->setTitle(__('Refresh')); $gridAction->setIcon($this->icons->getIconRefresh()); $gridAction->setOnClickFunction('track/refresh'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::TRACK_SEARCH)); $gridAction->addData('action-form', 'frmSearchTrack'); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::TRACK_SEARCH) + ); return $gridAction; } @@ -198,7 +214,10 @@ final class TrackGrid extends GridBase $gridAction->setTitle(Acl::getActionInfo(ActionsInterface::TRACK_CLEAR)); $gridAction->setIcon($this->icons->getIconClear()); $gridAction->setOnClickFunction('track/clear'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::TRACK_CLEAR)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::TRACK_CLEAR) + ); return $gridAction; } @@ -215,8 +234,11 @@ final class TrackGrid extends GridBase $gridAction->setTitle(Acl::getActionInfo(ActionsInterface::TRACK_UNLOCK)); $gridAction->setIcon($this->icons->getIconCheck()); $gridAction->setOnClickFunction('track/unlock'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::TRACK_UNLOCK)); $gridAction->setFilterRowSource('tracked', 0); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::TRACK_UNLOCK) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/UserGrid.php b/app/modules/web/Controllers/Helpers/Grid/UserGrid.php index de4b473b..4e29033a 100644 --- a/app/modules/web/Controllers/Helpers/Grid/UserGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/UserGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,10 +43,7 @@ use SP\Storage\Database\QueryResult; */ final class UserGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -74,7 +71,8 @@ final class UserGrid extends GridBase ->setName(__('Delete Selected')) ->setTitle(__('Delete Selected')) ->setIsSelection(true), - true); + true + ); $grid->setTime(round(getElapsedTime($this->queryTimeStart), 5)); @@ -126,10 +124,22 @@ final class UserGrid extends GridBase $gridData->addDataRowSource('login'); $gridData->addDataRowSource('userProfileName'); $gridData->addDataRowSource('userGroupName'); - $gridData->addDataRowSourceWithIcon('isAdminApp', $this->icons->getIconAppAdmin()); - $gridData->addDataRowSourceWithIcon('isAdminAcc', $this->icons->getIconAccAdmin()); - $gridData->addDataRowSourceWithIcon('isLdap', $this->icons->getIconLdapUser()); - $gridData->addDataRowSourceWithIcon('isDisabled', $this->icons->getIconDisabled()); + $gridData->addDataRowSourceWithIcon( + 'isAdminApp', + $this->icons->getIconAppAdmin() + ); + $gridData->addDataRowSourceWithIcon( + 'isAdminAcc', + $this->icons->getIconAccAdmin() + ); + $gridData->addDataRowSourceWithIcon( + 'isLdap', + $this->icons->getIconLdapUser() + ); + $gridData->addDataRowSourceWithIcon( + 'isDisabled', + $this->icons->getIconDisabled() + ); $gridData->setData($this->queryResult); return $gridData; @@ -147,7 +157,10 @@ final class UserGrid extends GridBase $gridActionSearch->setName('frmSearchUser'); $gridActionSearch->setTitle(__('Search for User')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::USER_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::USER_SEARCH) + ); return $gridActionSearch; } @@ -165,41 +178,10 @@ final class UserGrid extends GridBase $gridAction->setIcon($this->icons->getIconAdd()); $gridAction->setSkip(true); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::USER_CREATE)); - - return $gridAction; - } - - /** - * @return DataGridAction - */ - private function getEditAction(): DataGridAction - { - $gridAction = new DataGridAction(); - $gridAction->setId(ActionsInterface::USER_EDIT); - $gridAction->setType(DataGridActionType::EDIT_ITEM); - $gridAction->setName(__('Edit User')); - $gridAction->setTitle(__('Edit User')); - $gridAction->setIcon($this->icons->getIconEdit()); - $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::USER_EDIT)); - - return $gridAction; - } - - /** - * @return DataGridAction - */ - private function getDeleteAction(): DataGridAction - { - $gridAction = new DataGridAction(); - $gridAction->setId(ActionsInterface::USER_DELETE); - $gridAction->setType(DataGridActionType::DELETE_ITEM); - $gridAction->setName(__('Delete User')); - $gridAction->setTitle(__('Delete User')); - $gridAction->setIcon($this->icons->getIconDelete()); - $gridAction->setOnClickFunction('appMgmt/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::USER_DELETE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::USER_CREATE) + ); return $gridAction; } @@ -216,7 +198,30 @@ final class UserGrid extends GridBase $gridAction->setTitle(__('View User Details')); $gridAction->setIcon($this->icons->getIconView()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::USER_VIEW)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::USER_VIEW) + ); + + return $gridAction; + } + + /** + * @return DataGridAction + */ + private function getEditAction(): DataGridAction + { + $gridAction = new DataGridAction(); + $gridAction->setId(ActionsInterface::USER_EDIT); + $gridAction->setType(DataGridActionType::EDIT_ITEM); + $gridAction->setName(__('Edit User')); + $gridAction->setTitle(__('Edit User')); + $gridAction->setIcon($this->icons->getIconEdit()); + $gridAction->setOnClickFunction('appMgmt/show'); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::USER_EDIT) + ); return $gridAction; } @@ -234,7 +239,30 @@ final class UserGrid extends GridBase $gridAction->setIcon($this->icons->getIconEditPass()); $gridAction->setOnClickFunction('appMgmt/show'); $gridAction->setFilterRowSource('isLdap'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::USER_EDIT_PASS)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::USER_EDIT_PASS) + ); + + return $gridAction; + } + + /** + * @return DataGridAction + */ + private function getDeleteAction(): DataGridAction + { + $gridAction = new DataGridAction(); + $gridAction->setId(ActionsInterface::USER_DELETE); + $gridAction->setType(DataGridActionType::DELETE_ITEM); + $gridAction->setName(__('Delete User')); + $gridAction->setTitle(__('Delete User')); + $gridAction->setIcon($this->icons->getIconDelete()); + $gridAction->setOnClickFunction('appMgmt/delete'); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::USER_DELETE) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/UserGroupGrid.php b/app/modules/web/Controllers/Helpers/Grid/UserGroupGrid.php index 5f73fe0c..0fd9bdde 100644 --- a/app/modules/web/Controllers/Helpers/Grid/UserGroupGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/UserGroupGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,10 +43,7 @@ use SP\Storage\Database\QueryResult; */ final class UserGroupGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -73,7 +70,8 @@ final class UserGroupGrid extends GridBase ->setName(__('Delete Selected')) ->setTitle(__('Delete Selected')) ->setIsSelection(true), - true); + true + ); $grid->setTime(round(getElapsedTime($this->queryTimeStart), 5)); @@ -137,7 +135,10 @@ final class UserGroupGrid extends GridBase $gridActionSearch->setName('frmSearchGroup'); $gridActionSearch->setTitle(__('Search for Group')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::GROUP_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::GROUP_SEARCH) + ); return $gridActionSearch; } @@ -155,7 +156,10 @@ final class UserGroupGrid extends GridBase $gridAction->setIcon($this->icons->getIconAdd()); $gridAction->setSkip(true); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::GROUP_CREATE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::GROUP_CREATE) + ); return $gridAction; } @@ -172,7 +176,10 @@ final class UserGroupGrid extends GridBase $gridAction->setTitle(__('View Group')); $gridAction->setIcon($this->icons->getIconView()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::GROUP_VIEW)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::GROUP_VIEW) + ); return $gridAction; } @@ -189,7 +196,10 @@ final class UserGroupGrid extends GridBase $gridAction->setTitle(__('Edit Group')); $gridAction->setIcon($this->icons->getIconEdit()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::GROUP_EDIT)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::GROUP_EDIT) + ); return $gridAction; } @@ -206,7 +216,10 @@ final class UserGroupGrid extends GridBase $gridAction->setTitle(__('Delete Group')); $gridAction->setIcon($this->icons->getIconDelete()); $gridAction->setOnClickFunction('appMgmt/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::GROUP_DELETE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::GROUP_DELETE) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/Grid/UserProfileGrid.php b/app/modules/web/Controllers/Helpers/Grid/UserProfileGrid.php index 4aebf581..b16890bf 100644 --- a/app/modules/web/Controllers/Helpers/Grid/UserProfileGrid.php +++ b/app/modules/web/Controllers/Helpers/Grid/UserProfileGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers\Grid; @@ -43,10 +43,7 @@ use SP\Storage\Database\QueryResult; */ final class UserProfileGrid extends GridBase { - /** - * @var QueryResult - */ - private $queryResult; + private ?QueryResult $queryResult = null; /** * @param QueryResult $queryResult @@ -73,7 +70,8 @@ final class UserProfileGrid extends GridBase ->setName(__('Delete Selected')) ->setTitle(__('Delete Selected')) ->setIsSelection(true), - true); + true + ); $grid->setTime(round(getElapsedTime($this->queryTimeStart), 5)); @@ -135,7 +133,10 @@ final class UserProfileGrid extends GridBase $gridActionSearch->setName('frmSearchProfile'); $gridActionSearch->setTitle(__('Search for Profile')); $gridActionSearch->setOnSubmitFunction('appMgmt/search'); - $gridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::PROFILE_SEARCH)); + $gridActionSearch->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PROFILE_SEARCH) + ); return $gridActionSearch; } @@ -153,7 +154,10 @@ final class UserProfileGrid extends GridBase $gridAction->setIcon($this->icons->getIconAdd()); $gridAction->setSkip(true); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::PROFILE_CREATE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PROFILE_CREATE) + ); return $gridAction; } @@ -170,7 +174,10 @@ final class UserProfileGrid extends GridBase $gridAction->setTitle(__('View Profile Details')); $gridAction->setIcon($this->icons->getIconView()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::PROFILE_VIEW)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PROFILE_VIEW) + ); return $gridAction; } @@ -187,7 +194,10 @@ final class UserProfileGrid extends GridBase $gridAction->setTitle(__('Edit Profile')); $gridAction->setIcon($this->icons->getIconEdit()); $gridAction->setOnClickFunction('appMgmt/show'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::PROFILE_EDIT)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PROFILE_EDIT) + ); return $gridAction; } @@ -204,7 +214,10 @@ final class UserProfileGrid extends GridBase $gridAction->setTitle(__('Delete Profile')); $gridAction->setIcon($this->icons->getIconDelete()); $gridAction->setOnClickFunction('appMgmt/delete'); - $gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::PROFILE_DELETE)); + $gridAction->addData( + 'action-route', + Acl::getActionRoute(ActionsInterface::PROFILE_DELETE) + ); return $gridAction; } diff --git a/app/modules/web/Controllers/Helpers/HelperBase.php b/app/modules/web/Controllers/Helpers/HelperBase.php index ae945c77..62a54821 100644 --- a/app/modules/web/Controllers/Helpers/HelperBase.php +++ b/app/modules/web/Controllers/Helpers/HelperBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers; @@ -29,9 +29,8 @@ use DI\DependencyException; use DI\NotFoundException; use Psr\Container\ContainerInterface; use SP\Config\Config; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Context\ContextInterface; -use SP\Core\Context\SessionContext; use SP\Core\Events\EventDispatcher; use SP\Http\Request; use SP\Mvc\View\Template; @@ -43,53 +42,26 @@ use SP\Mvc\View\Template; */ abstract class HelperBase { - /** - * @var Template - */ - protected $view; - /** - * @var ConfigData - */ - protected $configData; - /** - * @var SessionContext - */ - protected $context; - /** - * @var EventDispatcher - */ - protected $eventDispatcher; - /** - * @var Config - */ - protected $config; - /** - * @var ContainerInterface - */ - protected $dic; - /** - * @var Request - */ - protected $request; + protected Template $view; + protected ConfigDataInterface $configData; + protected ContextInterface $context; + protected EventDispatcher $eventDispatcher; + protected Config $config; + protected ContainerInterface $dic; + protected Request $request; /** * Constructor * - * @param Template $template - * @param Config $config - * @param ContextInterface $context - * @param EventDispatcher $eventDispatcher - * @param Container $container - * * @throws DependencyException * @throws NotFoundException */ final public function __construct( - Template $template, - Config $config, + Template $template, + Config $config, ContextInterface $context, - EventDispatcher $eventDispatcher, - Container $container) + EventDispatcher $eventDispatcher, + Container $container) { $this->dic = $container; $this->request = $this->dic->get(Request::class); diff --git a/app/modules/web/Controllers/Helpers/HelperException.php b/app/modules/web/Controllers/Helpers/HelperException.php index 7dc957cb..45c6539c 100644 --- a/app/modules/web/Controllers/Helpers/HelperException.php +++ b/app/modules/web/Controllers/Helpers/HelperException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,13 +19,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers; use Exception; -use Throwable; /** * Class HelperException @@ -34,19 +33,4 @@ use Throwable; */ final class HelperException extends Exception { - /** - * Construct the exception. Note: The message is NOT binary safe. - * - * @link http://php.net/manual/en/exception.construct.php - * - * @param string $message [optional] The Exception message to throw. - * @param int $code [optional] The Exception code. - * @param Throwable|null $previous [optional] The previous throwable used for the exception chaining. - * - * @since 5.1.0 - */ - public function __construct($message = "", $code = 0, Throwable $previous = null) - { - parent::__construct($message, $code, $previous); - } } \ No newline at end of file diff --git a/app/modules/web/Controllers/Helpers/ItemPresetHelper.php b/app/modules/web/Controllers/Helpers/ItemPresetHelper.php index 89b4414f..a96ba4ae 100644 --- a/app/modules/web/Controllers/Helpers/ItemPresetHelper.php +++ b/app/modules/web/Controllers/Helpers/ItemPresetHelper.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers; @@ -43,98 +43,130 @@ use SP\Services\UserProfile\UserProfileService; */ final class ItemPresetHelper extends HelperBase { - /** - * @var SelectItemAdapter - */ - private $users; - /** - * @var SelectItemAdapter - */ - private $userGroups; - /** - * @var SelectItemAdapter - */ - private $userProfiles; + private ?SelectItemAdapter $users = null; + private ?SelectItemAdapter $userGroups = null; + private ?SelectItemAdapter $userProfiles = null; /** - * @param ItemPresetData $itemPresetData - * * @throws NoSuchPropertyException */ - public function makeAccountPermissionView(ItemPresetData $itemPresetData) + public function makeAccountPermissionView(ItemPresetData $itemPresetData): void { - $accountPermission = $itemPresetData->hydrate(AccountPermission::class) ?: new AccountPermission(); + $accountPermission = $itemPresetData->hydrate(AccountPermission::class) + ?? new AccountPermission(); - $this->view->assign('typeTemplate', 'item_preset-permission'); - $this->view->assign('presetName', __('Permission Preset')); + $this->view->assign( + 'typeTemplate', + 'item_preset-permission' + ); + $this->view->assign( + 'presetName', + __('Permission Preset') + ); $this->view->assign('permission', $accountPermission); - $this->view->assign('usersView', $this->users->getItemsFromModelSelected($accountPermission->getUsersView())); - $this->view->assign('usersEdit', $this->users->getItemsFromModelSelected($accountPermission->getUsersEdit())); - $this->view->assign('userGroupsView', $this->userGroups->getItemsFromModelSelected($accountPermission->getUserGroupsView())); - $this->view->assign('userGroupsEdit', $this->userGroups->getItemsFromModelSelected($accountPermission->getUserGroupsEdit())); + $this->view->assign( + 'usersView', + $this->users->getItemsFromModelSelected($accountPermission->getUsersView()) + ); + $this->view->assign( + 'usersEdit', + $this->users->getItemsFromModelSelected($accountPermission->getUsersEdit()) + ); + $this->view->assign( + 'userGroupsView', + $this->userGroups->getItemsFromModelSelected($accountPermission->getUserGroupsView()) + ); + $this->view->assign( + 'userGroupsEdit', + $this->userGroups->getItemsFromModelSelected($accountPermission->getUserGroupsEdit()) + ); } /** - * @param ItemPresetData $itemPresetData - * * @throws NoSuchPropertyException */ - public function makeAccountPrivateView(ItemPresetData $itemPresetData) + public function makeAccountPrivateView(ItemPresetData $itemPresetData): void { - $accountPrivate = $itemPresetData->hydrate(AccountPrivate::class) ?: new AccountPrivate(); + $accountPrivate = $itemPresetData->hydrate(AccountPrivate::class) + ?? new AccountPrivate(); - $this->view->assign('typeTemplate', 'item_preset-private'); - $this->view->assign('presetName', __('Private Account Preset')); + $this->view->assign( + 'typeTemplate', + 'item_preset-private' + ); + $this->view->assign( + 'presetName', + __('Private Account Preset') + ); $this->view->assign('private', $accountPrivate); } /** - * @param ItemPresetData $itemPresetData - * * @throws NoSuchPropertyException * @throws InvalidArgumentException */ - public function makeSessionTimeoutView(ItemPresetData $itemPresetData) + public function makeSessionTimeoutView(ItemPresetData $itemPresetData): void { - $sessionTimeout = $itemPresetData->hydrate(SessionTimeout::class) ?: new SessionTimeout($this->request->getClientAddress(), 3600); + $sessionTimeout = $itemPresetData->hydrate(SessionTimeout::class) + ?? new SessionTimeout($this->request->getClientAddress(), 3600); - $this->view->assign('typeTemplate', 'item_preset-session_timeout'); - $this->view->assign('presetName', __('Session Timeout Preset')); + $this->view->assign( + 'typeTemplate', + 'item_preset-session_timeout' + ); + $this->view->assign( + 'presetName', + __('Session Timeout Preset') + ); $this->view->assign('sessionTimeout', $sessionTimeout); } /** - * @param ItemPresetData $itemPresetData - * * @throws NoSuchPropertyException */ - public function makeAccountPasswordView(ItemPresetData $itemPresetData) + public function makeAccountPasswordView(ItemPresetData $itemPresetData): void { - $password = $itemPresetData->hydrate(Password::class) ?: new Password; + $password = $itemPresetData->hydrate(Password::class) + ?? new Password; - $this->view->assign('typeTemplate', 'item_preset-password'); - $this->view->assign('presetName', __('Account Password Preset')); + $this->view->assign( + 'typeTemplate', + 'item_preset-password' + ); + $this->view->assign( + 'presetName', + __('Account Password Preset') + ); $this->view->assign('password', $password); - $this->view->assign('expireTimeMultiplier', Password::EXPIRE_TIME_MULTIPLIER); + $this->view->assign( + 'expireTimeMultiplier', + Password::EXPIRE_TIME_MULTIPLIER + ); } - /** - * @param ItemPresetData $itemPresetData - */ - public function setCommon(ItemPresetData $itemPresetData) + public function setCommon(ItemPresetData $itemPresetData): void { $this->users = SelectItemAdapter::factory(UserService::getItemsBasic()); $this->userGroups = SelectItemAdapter::factory(UserGroupService::getItemsBasic()); $this->userProfiles = SelectItemAdapter::factory(UserProfileService::getItemsBasic()); - $this->view->assign('users', $this->users->getItemsFromModelSelected([$itemPresetData->getUserId()])); - $this->view->assign('userGroups', $this->userGroups->getItemsFromModelSelected([$itemPresetData->getUserGroupId()])); - $this->view->assign('userProfiles', $this->userProfiles->getItemsFromModelSelected([$itemPresetData->getUserProfileId()])); + $this->view->assign( + 'users', + $this->users->getItemsFromModelSelected([$itemPresetData->getUserId()]) + ); + $this->view->assign( + 'userGroups', + $this->userGroups->getItemsFromModelSelected([$itemPresetData->getUserGroupId()]) + ); + $this->view->assign( + 'userProfiles', + $this->userProfiles->getItemsFromModelSelected([$itemPresetData->getUserProfileId()]) + ); } } \ No newline at end of file diff --git a/app/modules/web/Controllers/Helpers/LayoutHelper.php b/app/modules/web/Controllers/Helpers/LayoutHelper.php index e1be1d8e..1434769a 100644 --- a/app/modules/web/Controllers/Helpers/LayoutHelper.php +++ b/app/modules/web/Controllers/Helpers/LayoutHelper.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers; @@ -47,14 +47,8 @@ use SP\Util\VersionUtil; */ final class LayoutHelper extends HelperBase { - /** - * @var bool - */ - protected $loggedIn; - /** - * @var ThemeInterface - */ - protected $theme; + protected ?bool $loggedIn = null; + protected ?ThemeInterface $theme = null; /** * Sets a full layout page @@ -85,10 +79,8 @@ final class LayoutHelper extends HelperBase /** * Establecer la variable de página de la vista - * - * @param $page */ - public function setPage($page) + public function setPage(string $page): void { $this->view->assign('page', $page); } @@ -96,9 +88,9 @@ final class LayoutHelper extends HelperBase /** * Inicializar las variables para la vista principal de la aplicación */ - public function initBody() + public function initBody(): void { - $baseUrl = $this->configData->getApplicationUrl() ?: Bootstrap::$WEBURI; + $baseUrl = $this->configData->getApplicationUrl() ?? Bootstrap::$WEBURI; $this->view->assign('isInstalled', $this->configData->isInstalled()); $this->view->assign('app_name', AppInfoInterface::APP_NAME); @@ -133,21 +125,27 @@ final class LayoutHelper extends HelperBase /** * Obtener los datos para la cabcera de la página */ - protected function getResourcesLinks() + protected function getResourcesLinks(): void { $version = VersionUtil::getVersionStringNormalized(); - $baseUrl = ($this->configData->getApplicationUrl() ?: Bootstrap::$WEBURI) . Bootstrap::$SUBURI; + $baseUrl = ($this->configData->getApplicationUrl() ?? Bootstrap::$WEBURI) . Bootstrap::$SUBURI; $jsUri = new Uri($baseUrl); $jsUri->addParam('_r', 'resource/js'); $jsUri->addParam('_v', md5($version)); - $this->view->append('jsLinks', $jsUri->getUriSigned($this->configData->getPasswordSalt())); + $this->view->append( + 'jsLinks', + $jsUri->getUriSigned($this->configData->getPasswordSalt()) + ); $jsUri->resetParams() ->addParam('g', 1); - $this->view->append('jsLinks', $jsUri->getUriSigned($this->configData->getPasswordSalt())); + $this->view->append( + 'jsLinks', + $jsUri->getUriSigned($this->configData->getPasswordSalt()) + ); $themeInfo = $this->theme->getThemeInfo(); @@ -156,25 +154,35 @@ final class LayoutHelper extends HelperBase ->addParam('b', $this->theme->getThemePath() . DIRECTORY_SEPARATOR . 'js') ->addParam('f', implode(',', $themeInfo['js'])); - $this->view->append('jsLinks', $jsUri->getUriSigned($this->configData->getPasswordSalt())); + $this->view->append( + 'jsLinks', + $jsUri->getUriSigned($this->configData->getPasswordSalt()) + ); } $userPreferences = $this->context->getUserData()->getPreferences(); - if ($this->loggedIn && $userPreferences->getUserId() > 0) { + if ($this->loggedIn + && $userPreferences + && $userPreferences->getUserId() > 0) { $resultsAsCards = $userPreferences->isResultsAsCards(); } else { $resultsAsCards = $this->configData->isResultsAsCards(); } - $cssUri = new Uri($baseUrl); - $cssUri->addParam('_r', 'resource/css'); - $cssUri->addParam('_v', md5($version . $resultsAsCards)); + $cssUri = (new Uri($baseUrl)) + ->addParam('_r', 'resource/css') + ->addParam('_v', md5($version . $resultsAsCards)); - $this->view->append('cssLinks', $cssUri->getUriSigned($this->configData->getPasswordSalt())); + $this->view->append( + 'cssLinks', + $cssUri->getUriSigned($this->configData->getPasswordSalt()) + ); if (isset($themeInfo['css'])) { - $themeInfo['css'][] = $resultsAsCards ? 'search-card.min.css' : 'search-grid.min.css'; + $themeInfo['css'][] = $resultsAsCards + ? 'search-card.min.css' + : 'search-grid.min.css'; if ($this->configData->isDokuwikiEnabled()) { $themeInfo['css'][] = 'styles-wiki.min.css'; @@ -184,11 +192,16 @@ final class LayoutHelper extends HelperBase ->addParam('b', $this->theme->getThemePath() . DIRECTORY_SEPARATOR . 'css') ->addParam('f', implode(',', $themeInfo['css'])); - $this->view->append('cssLinks', $cssUri->getUriSigned($this->configData->getPasswordSalt())); + $this->view->append( + 'cssLinks', + $cssUri->getUriSigned($this->configData->getPasswordSalt()) + ); } // Cargar los recursos de los plugins - foreach ($this->dic->get(PluginManager::class)->getLoadedPlugins() as $plugin) { + $loadedPlugins = $this->dic->get(PluginManager::class)->getLoadedPlugins(); + + foreach ($loadedPlugins as $plugin) { $base = str_replace(APP_ROOT, '', $plugin->getBase()); $base .= DIRECTORY_SEPARATOR . 'public'; @@ -200,7 +213,10 @@ final class LayoutHelper extends HelperBase ->addParam('b', $base . DIRECTORY_SEPARATOR . 'js') ->addParam('f', implode(',', $jsResources)); - $this->view->append('jsLinks', $jsUri->getUriSigned($this->configData->getPasswordSalt())); + $this->view->append( + 'jsLinks', + $jsUri->getUriSigned($this->configData->getPasswordSalt()) + ); } if (count($cssResources) > 0) { @@ -208,7 +224,10 @@ final class LayoutHelper extends HelperBase ->addParam('b', $base . DIRECTORY_SEPARATOR . 'css') ->addParam('f', implode(',', $cssResources)); - $this->view->append('cssLinks', $cssUri->getUriSigned($this->configData->getPasswordSalt())); + $this->view->append( + 'cssLinks', + $cssUri->getUriSigned($this->configData->getPasswordSalt()) + ); } } } @@ -216,7 +235,7 @@ final class LayoutHelper extends HelperBase /** * Establecer las cabeceras HTTP */ - private function setResponseHeaders() + private function setResponseHeaders(): void { // UTF8 Headers header('Content-Type: text/html; charset=UTF-8'); @@ -229,7 +248,7 @@ final class LayoutHelper extends HelperBase /** * Obtener los datos para la mostrar la barra de sesión */ - public function getSessionBar() + public function getSessionBar(): void { $userType = null; @@ -243,10 +262,22 @@ final class LayoutHelper extends HelperBase } $this->view->assign('ctx_userType', $userType); - $this->view->assign('ctx_userLogin', mb_strtoupper($userData->getLogin())); - $this->view->assign('ctx_userName', $userData->getName() ?: mb_strtoupper($userData->getLogin())); - $this->view->assign('ctx_userGroup', $userData->getUserGroupName()); - $this->view->assign('showPassIcon', !($this->configData->isLdapEnabled() && $userData->getIsLdap())); + $this->view->assign( + 'ctx_userLogin', + mb_strtoupper($userData->getLogin()) + ); + $this->view->assign( + 'ctx_userName', + $userData->getName() ?: mb_strtoupper($userData->getLogin()) + ); + $this->view->assign( + 'ctx_userGroup', + $userData->getUserGroupName() + ); + $this->view->assign( + 'showPassIcon', + !($this->configData->isLdapEnabled() && $userData->getIsLdap()) + ); } /** @@ -254,7 +285,7 @@ final class LayoutHelper extends HelperBase * * @param Acl $acl */ - public function getMenu(Acl $acl) + public function getMenu(Acl $acl): void { $icons = $this->theme->getIcons(); $actions = []; @@ -387,7 +418,10 @@ final class LayoutHelper extends HelperBase * * @return LayoutHelper */ - public function getCustomLayout(string $template, string $page = ''): LayoutHelper + public function getCustomLayout( + string $template, + string $page = '' + ): LayoutHelper { $this->view->addTemplate('main', '_layouts'); $this->view->addContentTemplate($template); @@ -402,7 +436,7 @@ final class LayoutHelper extends HelperBase * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->theme = $this->dic->get(ThemeInterface::class); diff --git a/app/modules/web/Controllers/Helpers/TabsGridHelper.php b/app/modules/web/Controllers/Helpers/TabsGridHelper.php index 0687b940..8dc6684d 100644 --- a/app/modules/web/Controllers/Helpers/TabsGridHelper.php +++ b/app/modules/web/Controllers/Helpers/TabsGridHelper.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers; @@ -36,11 +36,11 @@ final class TabsGridHelper extends HelperBase /** * Máximo numero de acciones antes de agrupar */ - const MAX_NUM_ACTIONS = 3; + private const MAX_NUM_ACTIONS = 3; /** * @var DataGridTab[] */ - protected $tabs = []; + protected array $tabs = []; /** * Inicializar las plantillas para las pestañas @@ -48,7 +48,7 @@ final class TabsGridHelper extends HelperBase * @param string $route * @param int $activeTab */ - public function renderTabs(string $route, $activeTab = 0) + public function renderTabs(string $route, int $activeTab = 0): void { $this->view->addTemplate('datatabs-grid', 'grid'); @@ -63,7 +63,7 @@ final class TabsGridHelper extends HelperBase * * @param DataGridTab $tab */ - public function addTab(DataGridTab $tab) + public function addTab(DataGridTab $tab): void { $this->tabs[] = $tab; } diff --git a/app/modules/web/Controllers/Helpers/TabsHelper.php b/app/modules/web/Controllers/Helpers/TabsHelper.php index c5b05de2..048631a4 100644 --- a/app/modules/web/Controllers/Helpers/TabsHelper.php +++ b/app/modules/web/Controllers/Helpers/TabsHelper.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Helpers; @@ -36,11 +36,11 @@ final class TabsHelper extends HelperBase /** * Máximo numero de acciones antes de agrupar */ - const MAX_NUM_ACTIONS = 3; + private const MAX_NUM_ACTIONS = 3; /** * @var DataTab[] */ - protected $tabs = []; + protected array $tabs = []; /** * Inicializar las plantillas para las pestañas @@ -48,7 +48,7 @@ final class TabsHelper extends HelperBase * @param string $route * @param int $activeTab */ - public function renderTabs(string $route, $activeTab = 0) + public function renderTabs(string $route, int $activeTab = 0): void { $this->view->addTemplate('datatabs', 'common'); @@ -63,7 +63,7 @@ final class TabsHelper extends HelperBase * * @param DataTab $tab */ - public function addTab(DataTab $tab) + public function addTab(DataTab $tab): void { $this->tabs[] = $tab; } diff --git a/app/modules/web/Controllers/IndexController.php b/app/modules/web/Controllers/IndexController.php index ce63fd04..0cce608b 100644 --- a/app/modules/web/Controllers/IndexController.php +++ b/app/modules/web/Controllers/IndexController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -41,7 +41,7 @@ final class IndexController extends ControllerBase * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function indexAction() + public function indexAction(): void { if ($this->session->isLoggedIn() === false || $this->session->getAuthCompleted() === false @@ -49,7 +49,8 @@ final class IndexController extends ControllerBase $this->router->response() ->redirect('index.php?r=login'); } else { - $this->dic->get(LayoutHelper::class)->getFullLayout('main', $this->acl); + $this->dic->get(LayoutHelper::class) + ->getFullLayout('main', $this->acl); $this->view(); } @@ -58,7 +59,7 @@ final class IndexController extends ControllerBase /** * @return void */ - protected function initialize() + protected function initialize(): void { // TODO: Implement initialize() method. } diff --git a/app/modules/web/Controllers/InstallController.php b/app/modules/web/Controllers/InstallController.php index 3e2bb0c5..21c77050 100644 --- a/app/modules/web/Controllers/InstallController.php +++ b/app/modules/web/Controllers/InstallController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -50,7 +50,7 @@ final class InstallController extends ControllerBase * @throws DependencyException * @throws NotFoundException */ - public function indexAction() + public function indexAction(): void { if ($this->configData->isInstalled()) { $this->router->response() @@ -72,7 +72,11 @@ final class InstallController extends ControllerBase } $this->view->assign('errors', $errors); - $this->view->assign('langs', SelectItemAdapter::factory(Language::getAvailableLanguages())->getItemsFromArraySelected([Language::$globalLang])); + $this->view->assign( + 'langs', + SelectItemAdapter::factory(Language::getAvailableLanguages()) + ->getItemsFromArraySelected([Language::$globalLang]) + ); $this->view(); } @@ -81,6 +85,7 @@ final class InstallController extends ControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ public function installAction(): bool { @@ -98,7 +103,10 @@ final class InstallController extends ControllerBase try { $this->dic->get(Installer::class)->run($installData); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Installation finished')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Installation finished') + ); } catch (Exception $e) { processException($e); @@ -109,7 +117,7 @@ final class InstallController extends ControllerBase /** * @return void */ - protected function initialize() + protected function initialize(): void { // TODO: Implement initialize() method. } diff --git a/app/modules/web/Controllers/ItemManagerController.php b/app/modules/web/Controllers/ItemManagerController.php index 8761486c..3b2dd095 100644 --- a/app/modules/web/Controllers/ItemManagerController.php +++ b/app/modules/web/Controllers/ItemManagerController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -27,6 +27,7 @@ namespace SP\Modules\Web\Controllers; use DI\DependencyException; use DI\NotFoundException; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; @@ -59,14 +60,8 @@ use SP\Services\Tag\TagService; */ final class ItemManagerController extends ControllerBase { - /** - * @var ItemSearchData - */ - protected $itemSearchData; - /** - * @var TabsGridHelper - */ - protected $tabsGridHelper; + protected ?ItemSearchData $itemSearchData = null; + protected ?TabsGridHelper $tabsGridHelper = null; /** * @throws DependencyException @@ -74,7 +69,7 @@ final class ItemManagerController extends ControllerBase * @throws ConstraintException * @throws QueryException */ - public function indexAction() + public function indexAction(): void { $this->getGridTabs(); } @@ -87,48 +82,55 @@ final class ItemManagerController extends ControllerBase * @throws ConstraintException * @throws QueryException */ - protected function getGridTabs() + protected function getGridTabs(): void { $this->itemSearchData = new ItemSearchData(); $this->itemSearchData->setLimitCount($this->configData->getAccountCount()); $this->tabsGridHelper = $this->dic->get(TabsGridHelper::class); - if ($this->checkAccess(Acl::CATEGORY)) { + if ($this->checkAccess(ActionsInterface::CATEGORY)) { $this->tabsGridHelper->addTab($this->getCategoriesList()); } - if ($this->checkAccess(Acl::TAG)) { + if ($this->checkAccess(ActionsInterface::TAG)) { $this->tabsGridHelper->addTab($this->getTagsList()); } - if ($this->checkAccess(Acl::CLIENT)) { + if ($this->checkAccess(ActionsInterface::CLIENT)) { $this->tabsGridHelper->addTab($this->getClientsList()); } - if ($this->checkAccess(Acl::CUSTOMFIELD)) { + if ($this->checkAccess(ActionsInterface::CUSTOMFIELD)) { $this->tabsGridHelper->addTab($this->getCustomFieldsList()); } - if ($this->configData->isFilesEnabled() && $this->checkAccess(Acl::FILE)) { + if ($this->configData->isFilesEnabled() + && $this->checkAccess(ActionsInterface::FILE)) { $this->tabsGridHelper->addTab($this->getAccountFilesList()); } - if ($this->checkAccess(Acl::ACCOUNTMGR)) { + if ($this->checkAccess(ActionsInterface::ACCOUNTMGR)) { $this->tabsGridHelper->addTab($this->getAccountsList()); } - if ($this->checkAccess(Acl::ACCOUNTMGR_HISTORY)) { + if ($this->checkAccess(ActionsInterface::ACCOUNTMGR_HISTORY)) { $this->tabsGridHelper->addTab($this->getAccountsHistoryList()); } - if ($this->checkAccess(Acl::ITEMPRESET)) { + if ($this->checkAccess(ActionsInterface::ITEMPRESET)) { $this->tabsGridHelper->addTab($this->getItemPresetList()); } - $this->eventDispatcher->notifyEvent('show.itemlist.items', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.itemlist.items', + new Event($this) + ); - $this->tabsGridHelper->renderTabs(Acl::getActionRoute(Acl::ITEMS_MANAGE), $this->request->analyzeInt('tabIndex', 0)); + $this->tabsGridHelper->renderTabs( + Acl::getActionRoute(ActionsInterface::ITEMS_MANAGE), + $this->request->analyzeInt('tabIndex', 0) + ); $this->view(); } @@ -145,7 +147,8 @@ final class ItemManagerController extends ControllerBase protected function getCategoriesList(): DataGridTab { return $this->dic->get(CategoryGrid::class) - ->getGrid($this->dic->get(CategoryService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(CategoryService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -161,7 +164,8 @@ final class ItemManagerController extends ControllerBase protected function getTagsList(): DataGridTab { return $this->dic->get(TagGrid::class) - ->getGrid($this->dic->get(TagService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(TagService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -177,7 +181,8 @@ final class ItemManagerController extends ControllerBase protected function getClientsList(): DataGridTab { return $this->dic->get(ClientGrid::class) - ->getGrid($this->dic->get(ClientService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(ClientService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -193,7 +198,8 @@ final class ItemManagerController extends ControllerBase protected function getCustomFieldsList(): DataGridTab { return $this->dic->get(CustomFieldGrid::class) - ->getGrid($this->dic->get(CustomFieldDefService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(CustomFieldDefService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -209,7 +215,8 @@ final class ItemManagerController extends ControllerBase protected function getAccountFilesList(): DataGridTab { return $this->dic->get(FileGrid::class) - ->getGrid($this->dic->get(AccountFileService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(AccountFileService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -225,7 +232,8 @@ final class ItemManagerController extends ControllerBase protected function getAccountsList(): DataGridTab { return $this->dic->get(AccountGrid::class) - ->getGrid($this->dic->get(AccountService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(AccountService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -241,7 +249,8 @@ final class ItemManagerController extends ControllerBase protected function getAccountsHistoryList(): DataGridTab { return $this->dic->get(AccountHistoryGrid::class) - ->getGrid($this->dic->get(AccountHistoryService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(AccountHistoryService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -257,7 +266,8 @@ final class ItemManagerController extends ControllerBase protected function getItemPresetList(): DataGridTab { return $this->dic->get(ItemPresetGrid::class) - ->getGrid($this->dic->get(ItemPresetService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(ItemPresetService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -275,7 +285,7 @@ final class ItemManagerController extends ControllerBase * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); } diff --git a/app/modules/web/Controllers/ItemPresetController.php b/app/modules/web/Controllers/ItemPresetController.php index badb0845..d9a25420 100644 --- a/app/modules/web/Controllers/ItemPresetController.php +++ b/app/modules/web/Controllers/ItemPresetController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -28,6 +28,7 @@ use DI\DependencyException; use DI\NotFoundException; use Exception; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -61,10 +62,7 @@ final class ItemPresetController extends ControllerBase implements CrudControlle { use JsonTrait, ItemTrait; - /** - * @var ItemPresetService - */ - protected $itemPresetService; + protected ?ItemPresetService $itemPresetService = null; /** * View action @@ -72,14 +70,18 @@ final class ItemPresetController extends ControllerBase implements CrudControlle * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function viewAction(int $id) + public function viewAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::ITEMPRESET_VIEW)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::ITEMPRESET_VIEW)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('Display Value')); @@ -87,13 +89,19 @@ final class ItemPresetController extends ControllerBase implements CrudControlle $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.itemPreset', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.itemPreset', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -113,11 +121,13 @@ final class ItemPresetController extends ControllerBase implements CrudControlle * @throws NotFoundException * @throws QueryException */ - protected function setViewData(?int $id = null, ?string $type = null) + protected function setViewData(?int $id = null, ?string $type = null): void { $this->view->addTemplate('item_preset', 'itemshow'); - $itemPresetData = $id ? $this->itemPresetService->getById($id) : new ItemPresetData(); + $itemPresetData = $id + ? $this->itemPresetService->getById($id) + : new ItemPresetData(); $itemPresetHelper = $this->dic->get(ItemPresetHelper::class); $itemPresetHelper->setCommon($itemPresetData); @@ -142,7 +152,10 @@ final class ItemPresetController extends ControllerBase implements CrudControlle } $this->view->assign('preset', $itemPresetData); - $this->view->assign('nextAction', Acl::getActionRoute(Acl::ACCESS_MANAGE)); + $this->view->assign( + 'nextAction', + Acl::getActionRoute(ActionsInterface::ACCESS_MANAGE) + ); if ($this->view->isView === true) { $this->view->assign('disabled', 'disabled'); @@ -162,15 +175,22 @@ final class ItemPresetController extends ControllerBase implements CrudControlle * @throws ConstraintException * @throws QueryException * @throws SPException + * @throws \JsonException */ - public function searchAction() + public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::ITEMPRESET_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::ITEMPRESET_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); - $this->view->assign('index', $this->request->analyzeInt('activetab', 0)); + $this->view->assign( + 'index', + $this->request->analyzeInt('activetab', 0) + ); $this->view->assign('data', $this->getSearchGrid()); return $this->returnJsonResponseData(['html' => $this->render()]); @@ -186,7 +206,10 @@ final class ItemPresetController extends ControllerBase implements CrudControlle */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $grid = $this->dic->get(ItemPresetGrid::class); @@ -198,14 +221,18 @@ final class ItemPresetController extends ControllerBase implements CrudControlle /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function createAction() + public function createAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::ITEMPRESET_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::ITEMPRESET_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $args = func_get_args(); @@ -221,13 +248,19 @@ final class ItemPresetController extends ControllerBase implements CrudControlle $this->setViewData(null, $type); - $this->eventDispatcher->notifyEvent('show.itemPreset.create', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.itemPreset.create', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -239,14 +272,18 @@ final class ItemPresetController extends ControllerBase implements CrudControlle * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function editAction(int $id) + public function editAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::ITEMPRESET_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::ITEMPRESET_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('Edit Value')); @@ -255,13 +292,19 @@ final class ItemPresetController extends ControllerBase implements CrudControlle $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.itemPreset.edit', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.itemPreset.edit', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -273,42 +316,62 @@ final class ItemPresetController extends ControllerBase implements CrudControlle * @param int|null $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): bool { try { - if (!$this->acl->checkUserAccess(Acl::ITEMPRESET_DELETE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::ITEMPRESET_DELETE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } if ($id === null) { - $this->itemPresetService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); + $this->itemPresetService + ->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); - $this->eventDispatcher->notifyEvent('delete.itemPreset', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'delete.itemPreset', + new Event( + $this, EventMessage::factory() - ->addDescription(__u('Values deleted'))) + ->addDescription(__u('Values deleted')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Values deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Values deleted') + ); } $this->itemPresetService->delete($id); - $this->eventDispatcher->notifyEvent('delete.itemPreset', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'delete.itemPreset', + new Event( + $this, EventMessage::factory() ->addDescription(__u('Value deleted')) - ->addDetail(__u('ID'), $id)) + ->addDetail(__u('ID'), $id) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Value deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Value deleted') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -316,38 +379,51 @@ final class ItemPresetController extends ControllerBase implements CrudControlle /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveCreateAction() + public function saveCreateAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::ITEMPRESET_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::ITEMPRESET_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new ItemsPresetForm($this->dic); - $form->validate(Acl::ITEMPRESET_CREATE); + $form->validate(ActionsInterface::ITEMPRESET_CREATE); $itemData = $form->getItemData(); $id = $this->itemPresetService->create($itemData); - $this->eventDispatcher->notifyEvent('create.itemPreset', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'create.itemPreset', + new Event( + $this, EventMessage::factory() ->addDescription(__u('Value created')) ->addDetail(__u('Type'), $itemData->getItemPresetData()->getType()) - ->addDetail(__u('ID'), $id)) + ->addDetail(__u('ID'), $id) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Value created')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Value created') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -359,14 +435,18 @@ final class ItemPresetController extends ControllerBase implements CrudControlle * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveEditAction(int $id) + public function saveEditAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::ITEMPRESET_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::ITEMPRESET_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new ItemsPresetForm($this->dic, $id); @@ -376,21 +456,30 @@ final class ItemPresetController extends ControllerBase implements CrudControlle $this->itemPresetService->update($itemData); - $this->eventDispatcher->notifyEvent('edit.itemPreset', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'edit.itemPreset', + new Event( + $this, EventMessage::factory() ->addDescription(__u('Value updated')) ->addDetail(__u('Type'), $itemData->getItemPresetData()->getType()) - ->addDetail(__u('ID'), $id)) + ->addDetail(__u('ID'), $id) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Value updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Value updated') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -404,7 +493,7 @@ final class ItemPresetController extends ControllerBase implements CrudControlle * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/ItemsController.php b/app/modules/web/Controllers/ItemsController.php index 82c93f9f..cf35c2c9 100644 --- a/app/modules/web/Controllers/ItemsController.php +++ b/app/modules/web/Controllers/ItemsController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -55,12 +55,13 @@ final class ItemsController extends SimpleControllerBase * * @param int|null $accountId * - * @throws DependencyException - * @throws NotFoundException - * @throws ConstraintException - * @throws QueryException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function accountsUserAction(?int $accountId = null) + public function accountsUserAction(?int $accountId = null): void { $outItems = []; @@ -86,7 +87,7 @@ final class ItemsController extends SimpleControllerBase * @throws QueryException * @throws SPException */ - public function clientsAction() + public function clientsAction(): void { Json::factory($this->router->response()) ->returnRawJson( @@ -102,7 +103,7 @@ final class ItemsController extends SimpleControllerBase * @throws QueryException * @throws SPException */ - public function categoriesAction() + public function categoriesAction(): void { Json::factory($this->router->response()) ->returnRawJson( @@ -112,16 +113,16 @@ final class ItemsController extends SimpleControllerBase } /** - * @throws DependencyException - * @throws NotFoundException - * @throws ConstraintException - * @throws QueryException - * @throws SPException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function notificationsAction() + public function notificationsAction(): void { $notifications = array_map( - function ($notification) { + static function ($notification) { /** @@var $notification NotificationData */ return sprintf( '(%s) - %s', @@ -155,7 +156,7 @@ final class ItemsController extends SimpleControllerBase * @throws QueryException * @throws SPException */ - public function tagsAction() + public function tagsAction(): void { Json::factory($this->router->response()) ->returnRawJson( @@ -169,7 +170,7 @@ final class ItemsController extends SimpleControllerBase * * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checks(); } @@ -181,7 +182,7 @@ final class ItemsController extends SimpleControllerBase * * @return array */ - private function prepareItems(array $items) + private function prepareItems(array $items): array { $outItems = []; diff --git a/app/modules/web/Controllers/LoginController.php b/app/modules/web/Controllers/LoginController.php index 3fba7cd1..4c5150bf 100644 --- a/app/modules/web/Controllers/LoginController.php +++ b/app/modules/web/Controllers/LoginController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -28,7 +28,7 @@ use Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Bootstrap; -use SP\Core\Context\SessionContext; +use SP\Core\Context\ContextBase; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\SessionUtil; @@ -51,6 +51,7 @@ final class LoginController extends ControllerBase * * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface + * @throws \JsonException */ public function loginAction(): bool { @@ -76,19 +77,26 @@ final class LoginController extends ControllerBase return $uri->getUri(); }; - $this->eventDispatcher->notifyEvent('login.finish', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'login.finish', + new Event( + $this, EventMessage::factory() - ->addExtra('redirect', $redirector)) + ->addExtra('redirect', $redirector) + ) ); return $this->returnJsonResponseData([ - 'url' => $this->session->getTrasientKey('redirect') ?: $loginResponmse->getRedirect() + 'url' => $this->session->getTrasientKey('redirect') + ?: $loginResponmse->getRedirect() ]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponse($e->getCode(), $e->getMessage()); } @@ -97,14 +105,18 @@ final class LoginController extends ControllerBase /** * checkForwarded */ - private function checkForwarded() + private function checkForwarded(): void { $forward = $this->request->getForwardedFor(); if ($forward !== null) { - $this->eventDispatcher->notifyEvent('login.info', - new Event($this, EventMessage::factory() - ->addDetail('Forwarded', $this->configData->isDemoEnabled() ? '***' : implode(',', $forward))) + $this->eventDispatcher->notifyEvent( + 'login.info', + new Event( + $this, + EventMessage::factory() + ->addDetail('Forwarded', $this->configData->isDemoEnabled() ? '***' : implode(',', $forward)) + ) ); } } @@ -112,23 +124,27 @@ final class LoginController extends ControllerBase /** * Logout action */ - public function logoutAction() + public function logoutAction(): void { if ($this->session->isLoggedIn() === true) { $inactiveTime = abs(round((time() - $this->session->getLastActivity()) / 60, 2)); $totalTime = abs(round((time() - $this->session->getStartActivity()) / 60, 2)); - $this->eventDispatcher->notifyEvent('logout', - new Event($this, EventMessage::factory() - ->addDescription(__u('Logout session')) - ->addDetail(__u('User'), $this->session->getUserData()->getLogin()) - ->addDetail(__u('Inactive time'), $inactiveTime . ' min.') - ->addDetail(__u('Total time'), $totalTime . ' min.')) + $this->eventDispatcher->notifyEvent( + 'logout', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Logout session')) + ->addDetail(__u('User'), $this->session->getUserData()->getLogin()) + ->addDetail(__u('Inactive time'), $inactiveTime . ' min.') + ->addDetail(__u('Total time'), $totalTime . ' min.') + ) ); SessionUtil::cleanSession(); - $this->session->setAppStatus(SessionContext::APP_STATUS_LOGGEDOUT); + $this->session->setAppStatus(ContextBase::APP_STATUS_LOGGEDOUT); $layoutHelper = $this->dic->get(LayoutHelper::class); $layoutHelper->getCustomLayout('logout', 'logout'); @@ -145,12 +161,15 @@ final class LoginController extends ControllerBase * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function indexAction() + public function indexAction(): void { $this->dic->get(LayoutHelper::class) ->getCustomLayout('index', 'login'); - $this->view->assign('mailEnabled', $this->configData->isMailEnabled()); + $this->view->assign( + 'mailEnabled', + $this->configData->isMailEnabled() + ); $this->prepareSignedUriOnView(); @@ -160,7 +179,7 @@ final class LoginController extends ControllerBase /** * @return void */ - protected function initialize() + protected function initialize(): void { // TODO: Implement initialize() method. } diff --git a/app/modules/web/Controllers/NotificationController.php b/app/modules/web/Controllers/NotificationController.php index eacc3648..0d61a9fe 100644 --- a/app/modules/web/Controllers/NotificationController.php +++ b/app/modules/web/Controllers/NotificationController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -28,6 +28,7 @@ use DI\DependencyException; use DI\NotFoundException; use Exception; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -57,10 +58,7 @@ final class NotificationController extends ControllerBase implements CrudControl { use JsonTrait, ItemTrait; - /** - * @var NotificationService - */ - protected $notificationService; + protected ?NotificationService $notificationService = null; /** * indexAction @@ -71,9 +69,9 @@ final class NotificationController extends ControllerBase implements CrudControl * @throws QueryException * @throws SPException */ - public function indexAction() + public function indexAction(): void { - if (!$this->acl->checkUserAccess(Acl::NOTIFICATION)) { + if (!$this->acl->checkUserAccess(ActionsInterface::NOTIFICATION)) { return; } @@ -94,11 +92,17 @@ final class NotificationController extends ControllerBase implements CrudControl */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $notificationGrid = $this->dic->get(NotificationGrid::class); - return $notificationGrid->updatePager($notificationGrid->getGrid($this->notificationService->search($itemSearchData)), $itemSearchData); + return $notificationGrid->updatePager( + $notificationGrid->getGrid($this->notificationService->search($itemSearchData)), + $itemSearchData + ); } /** @@ -107,14 +111,18 @@ final class NotificationController extends ControllerBase implements CrudControl * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function viewAction(int $id) + public function viewAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::NOTIFICATION_VIEW)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::NOTIFICATION_VIEW)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('View Notification')); @@ -122,13 +130,19 @@ final class NotificationController extends ControllerBase implements CrudControl $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.notification', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.notification', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -143,19 +157,28 @@ final class NotificationController extends ControllerBase implements CrudControl * @throws QueryException * @throws NoSuchItemException */ - protected function setViewData(?int $notificationId = null) + protected function setViewData(?int $notificationId = null): void { $this->view->addTemplate('notification'); - $notification = $notificationId ? $this->notificationService->getById($notificationId) : new NotificationData(); + $notification = $notificationId + ? $this->notificationService->getById($notificationId) + : new NotificationData(); $this->view->assign('notification', $notification); if ($this->userData->getIsAdminApp()) { - $this->view->assign('users', SelectItemAdapter::factory(UserService::getItemsBasic())->getItemsFromModelSelected([$notification->userId])); + $this->view->assign( + 'users', + SelectItemAdapter::factory(UserService::getItemsBasic()) + ->getItemsFromModelSelected([$notification->userId]) + ); } - $this->view->assign('nextAction', Acl::getActionRoute(Acl::NOTIFICATION)); + $this->view->assign( + 'nextAction', + Acl::getActionRoute(ActionsInterface::NOTIFICATION) + ); if ($this->view->isView === true) { $this->view->assign('disabled', 'disabled'); @@ -168,16 +191,19 @@ final class NotificationController extends ControllerBase implements CrudControl /** * @return bool - * @throws DependencyException - * @throws NotFoundException - * @throws ConstraintException - * @throws QueryException - * @throws SPException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function searchAction() + public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::NOTIFICATION_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::NOTIFICATION_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); @@ -188,14 +214,18 @@ final class NotificationController extends ControllerBase implements CrudControl /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function createAction() + public function createAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::NOTIFICATION_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::NOTIFICATION_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('New Notification')); @@ -204,13 +234,19 @@ final class NotificationController extends ControllerBase implements CrudControl $this->setViewData(); - $this->eventDispatcher->notifyEvent('show.notification.create', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.notification.create', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -222,14 +258,18 @@ final class NotificationController extends ControllerBase implements CrudControl * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function editAction(int $id) + public function editAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::NOTIFICATION_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::NOTIFICATION_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('Edit Notification')); @@ -238,13 +278,19 @@ final class NotificationController extends ControllerBase implements CrudControl $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.notification.edit', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.notification.edit', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -256,10 +302,11 @@ final class NotificationController extends ControllerBase implements CrudControl * @param int|null $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): bool { try { if ($id === null) { @@ -269,13 +316,19 @@ final class NotificationController extends ControllerBase implements CrudControl $this->notificationService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); } - $this->eventDispatcher->notifyEvent('delete.notification.selection', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'delete.notification.selection', + new Event( + $this, EventMessage::factory() - ->addDescription(__u('Notifications deleted'))) + ->addDescription(__u('Notifications deleted')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Notifications deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Notifications deleted') + ); } if ($this->userData->getIsAdminApp()) { @@ -284,18 +337,27 @@ final class NotificationController extends ControllerBase implements CrudControl $this->notificationService->delete($id); } - $this->eventDispatcher->notifyEvent('delete.notification', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'delete.notification', + new Event( + $this, EventMessage::factory() ->addDescription(__u('Notification deleted')) - ->addDetail(__u('Notification'), $id)) + ->addDetail(__u('Notification'), $id) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Notification deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Notification deleted') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -307,30 +369,43 @@ final class NotificationController extends ControllerBase implements CrudControl * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function checkAction(int $id) + public function checkAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::NOTIFICATION_CHECK)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::NOTIFICATION_CHECK)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->notificationService->setCheckedById($id); - $this->eventDispatcher->notifyEvent('check.notification', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'check.notification', + new Event( + $this, EventMessage::factory() ->addDescription(__u('Notification read')) - ->addDetail(__u('Notification'), $id)) + ->addDetail(__u('Notification'), $id) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Notification read')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Notification read') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -338,32 +413,45 @@ final class NotificationController extends ControllerBase implements CrudControl /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveCreateAction() + public function saveCreateAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::NOTIFICATION_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::NOTIFICATION_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new NotificationForm($this->dic); - $form->validate(Acl::NOTIFICATION_CREATE); + $form->validate(ActionsInterface::NOTIFICATION_CREATE); $this->notificationService->create($form->getItemData()); - $this->eventDispatcher->notifyEvent('create.notification', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'create.notification', + new Event( + $this, EventMessage::factory() - ->addDescription(__u('Notification created'))) + ->addDescription(__u('Notification created')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Notification created')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Notification created') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -375,32 +463,45 @@ final class NotificationController extends ControllerBase implements CrudControl * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveEditAction(int $id) + public function saveEditAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::NOTIFICATION_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::NOTIFICATION_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new NotificationForm($this->dic, $id); - $form->validate(Acl::NOTIFICATION_EDIT); + $form->validate(ActionsInterface::NOTIFICATION_EDIT); $this->notificationService->update($form->getItemData()); - $this->eventDispatcher->notifyEvent('edit.notification', - new Event($this, + $this->eventDispatcher->notifyEvent( + 'edit.notification', + new Event( + $this, EventMessage::factory() - ->addDescription(__u('Notification updated'))) + ->addDescription(__u('Notification updated')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Notification updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Notification updated') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -412,7 +513,7 @@ final class NotificationController extends ControllerBase implements CrudControl * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/PluginController.php b/app/modules/web/Controllers/PluginController.php index 487a47b3..2e2e2ab0 100644 --- a/app/modules/web/Controllers/PluginController.php +++ b/app/modules/web/Controllers/PluginController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -28,6 +28,7 @@ use DI\DependencyException; use DI\NotFoundException; use Exception; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -55,14 +56,8 @@ final class PluginController extends ControllerBase { use JsonTrait, ItemTrait; - /** - * @var PluginService - */ - protected $pluginService; - /** - * @var PluginDataService - */ - protected $pluginDataService; + protected ?PluginService $pluginService = null; + protected ?PluginDataService $pluginDataService = null; /** * indexAction @@ -73,9 +68,9 @@ final class PluginController extends ControllerBase * @throws QueryException * @throws SPException */ - public function indexAction() + public function indexAction(): void { - if (!$this->acl->checkUserAccess(Acl::PLUGIN)) { + if (!$this->acl->checkUserAccess(ActionsInterface::PLUGIN)) { return; } @@ -96,27 +91,36 @@ final class PluginController extends ControllerBase */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $pluginGrid = $this->dic->get(PluginGrid::class); - return $pluginGrid->updatePager($pluginGrid->getGrid($this->pluginService->search($itemSearchData)), $itemSearchData); + return $pluginGrid->updatePager( + $pluginGrid->getGrid($this->pluginService->search($itemSearchData)), + $itemSearchData + ); } /** * Search action * * @return bool - * @throws DependencyException - * @throws NotFoundException - * @throws ConstraintException - * @throws QueryException - * @throws SPException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::PLUGIN_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PLUGIN_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); @@ -131,14 +135,18 @@ final class PluginController extends ControllerBase * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function viewAction(int $id) + public function viewAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::PLUGIN_VIEW)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PLUGIN_VIEW)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('View Plugin')); @@ -146,13 +154,19 @@ final class PluginController extends ControllerBase $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.plugin', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.plugin', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -169,17 +183,23 @@ final class PluginController extends ControllerBase * @throws QueryException * @throws NoSuchItemException */ - protected function setViewData(?int $pluginId = null) + protected function setViewData(?int $pluginId = null): void { $this->view->addTemplate('plugin'); - $pluginData = $pluginId ? $this->pluginService->getById($pluginId) : new PluginModel(); - $pluginInfo = $this->dic->get(PluginManager::class)->getPlugin($pluginData->getName()); + $pluginData = $pluginId + ? $this->pluginService->getById($pluginId) + : new PluginModel(); + $pluginInfo = $this->dic->get(PluginManager::class) + ->getPlugin($pluginData->getName()); $this->view->assign('plugin', $pluginData); $this->view->assign('pluginInfo', $pluginInfo); - $this->view->assign('nextAction', Acl::getActionRoute(Acl::ITEMS_MANAGE)); + $this->view->assign( + 'nextAction', + Acl::getActionRoute(ActionsInterface::ITEMS_MANAGE) + ); if ($this->view->isView === true) { $this->view->assign('disabled', 'disabled'); @@ -198,22 +218,33 @@ final class PluginController extends ControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function enableAction(int $id) + public function enableAction(int $id): bool { try { - $this->pluginService->toggleEnabled($id, 1); + $this->pluginService->toggleEnabled($id, true); - $this->eventDispatcher->notifyEvent('edit.plugin.enable', - new Event($this, - EventMessage::factory()->addDescription(__u('Plugin enabled'))) + $this->eventDispatcher->notifyEvent( + 'edit.plugin.enable', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Plugin enabled')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Plugin enabled')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Plugin enabled') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -227,22 +258,33 @@ final class PluginController extends ControllerBase * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function disableAction(int $id) + public function disableAction(int $id): bool { try { - $this->pluginService->toggleEnabled($id, 0); + $this->pluginService->toggleEnabled($id, false); - $this->eventDispatcher->notifyEvent('edit.plugin.disable', - new Event($this, - EventMessage::factory()->addDescription(__u('Plugin disabled'))) + $this->eventDispatcher->notifyEvent( + 'edit.plugin.disable', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Plugin disabled')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Plugin disabled')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Plugin disabled') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -254,25 +296,36 @@ final class PluginController extends ControllerBase * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function resetAction(int $id) + public function resetAction(int $id): bool { try { $pluginModel = $this->pluginService->getById($id); $this->pluginDataService->delete($pluginModel->getName()); - $this->eventDispatcher->notifyEvent('edit.plugin.reset', - new Event($this, - EventMessage::factory()->addDescription(__u('Plugin reset'))) + $this->eventDispatcher->notifyEvent( + 'edit.plugin.reset', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Plugin reset')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Plugin reset')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Plugin reset') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -284,33 +337,53 @@ final class PluginController extends ControllerBase * @param int|null $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): bool { try { - if (!$this->acl->checkUserAccess(Acl::PLUGIN_DELETE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PLUGIN_DELETE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } if ($id === null) { - $this->pluginService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); + $this->pluginService + ->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); - $this->eventDispatcher->notifyEvent('delete.plugin.selection', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'delete.plugin.selection', + new Event($this) + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Plugins deleted')); - } else { - $this->pluginService->delete($id); - - $this->eventDispatcher->notifyEvent('delete.plugin', new Event($this)); - - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Plugin deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Plugins deleted') + ); } + + $this->pluginService->delete($id); + + $this->eventDispatcher->notifyEvent( + 'delete.plugin', + new Event($this) + ); + + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Plugin deleted') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -322,7 +395,7 @@ final class PluginController extends ControllerBase * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/PublicLinkController.php b/app/modules/web/Controllers/PublicLinkController.php index c8584b18..438ea013 100644 --- a/app/modules/web/Controllers/PublicLinkController.php +++ b/app/modules/web/Controllers/PublicLinkController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -31,6 +31,7 @@ use Psr\Container\ContainerExceptionInterface; use RuntimeException; use SP\Bootstrap; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -62,29 +63,32 @@ final class PublicLinkController extends ControllerBase implements CrudControlle { use JsonTrait, ItemTrait; - /** - * @var PublicLinkService - */ - protected $publicLinkService; + protected ?PublicLinkService $publicLinkService = null; /** * Search action * * @return bool - * @throws DependencyException - * @throws NotFoundException - * @throws ConstraintException - * @throws QueryException - * @throws SPException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function searchAction() + public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::PUBLICLINK_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PUBLICLINK_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); - $this->view->assign('index', $this->request->analyzeInt('activetab', 0)); + $this->view->assign( + 'index', + $this->request->analyzeInt('activetab', 0) + ); $this->view->assign('data', $this->getSearchGrid()); return $this->returnJsonResponseData(['html' => $this->render()]); @@ -100,23 +104,33 @@ final class PublicLinkController extends ControllerBase implements CrudControlle */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $publicLinkGrid = $this->dic->get(PublicLinkGrid::class); - return $publicLinkGrid->updatePager($publicLinkGrid->getGrid($this->publicLinkService->search($itemSearchData)), $itemSearchData); + return $publicLinkGrid->updatePager( + $publicLinkGrid->getGrid($this->publicLinkService->search($itemSearchData)), + $itemSearchData + ); } /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function createAction() + public function createAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::PUBLICLINK_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PUBLICLINK_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('New Public Link')); @@ -125,13 +139,19 @@ final class PublicLinkController extends ControllerBase implements CrudControlle $this->setViewData(); - $this->eventDispatcher->notifyEvent('show.publicLink.create', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.publicLink.create', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -145,22 +165,37 @@ final class PublicLinkController extends ControllerBase implements CrudControlle * @throws ContainerExceptionInterface * @throws SPException */ - protected function setViewData(?int $publicLinkId = null) + protected function setViewData(?int $publicLinkId = null): void { $this->view->addTemplate('public_link', 'itemshow'); - $publicLink = $publicLinkId ? $this->publicLinkService->getById($publicLinkId) : new PublicLinkListData(); + $publicLink = $publicLinkId + ? $this->publicLinkService->getById($publicLinkId) + : new PublicLinkListData(); $this->view->assign('publicLink', $publicLink); - $this->view->assign('usageInfo', unserialize($publicLink->getUseInfo())); - $this->view->assign('accounts', SelectItemAdapter::factory($this->dic->get(AccountService::class)->getForUser())->getItemsFromModelSelected([$publicLink->getItemId()])); + $this->view->assign( + 'usageInfo', + unserialize($publicLink->getUseInfo()) + ); + $this->view->assign( + 'accounts', + SelectItemAdapter::factory($this->dic->get(AccountService::class)->getForUser()) + ->getItemsFromModelSelected([$publicLink->getItemId()]) + ); - $this->view->assign('nextAction', Acl::getActionRoute(Acl::ACCESS_MANAGE)); + $this->view->assign( + 'nextAction', + Acl::getActionRoute(ActionsInterface::ACCESS_MANAGE) + ); if ($this->view->isView === true) { $baseUrl = ($this->configData->getApplicationUrl() ?: Bootstrap::$WEBURI) . Bootstrap::$SUBURI; - $this->view->assign('publicLinkURL', PublicLinkService::getLinkForHash($baseUrl, $publicLink->getHash())); + $this->view->assign( + 'publicLinkURL', + PublicLinkService::getLinkForHash($baseUrl, $publicLink->getHash()) + ); $this->view->assign('disabled', 'disabled'); $this->view->assign('readonly', 'readonly'); } else { @@ -175,25 +210,38 @@ final class PublicLinkController extends ControllerBase implements CrudControlle * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function refreshAction(int $id) + public function refreshAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::PUBLICLINK_REFRESH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PUBLICLINK_REFRESH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->publicLinkService->refresh($id); - $this->eventDispatcher->notifyEvent('edit.publicLink.refresh', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'edit.publicLink.refresh', + new Event($this) + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Link updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Link updated') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -207,12 +255,16 @@ final class PublicLinkController extends ControllerBase implements CrudControlle * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function editAction(int $id) + public function editAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::PUBLICLINK_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PUBLICLINK_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('Edit Public Link')); @@ -221,13 +273,19 @@ final class PublicLinkController extends ControllerBase implements CrudControlle $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.publicLink.edit', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.publicLink.edit', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -241,42 +299,70 @@ final class PublicLinkController extends ControllerBase implements CrudControlle * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): bool { try { - if (!$this->acl->checkUserAccess(Acl::PUBLICLINK_DELETE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PUBLICLINK_DELETE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } if ($id === null) { - $this->publicLinkService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); + $this->publicLinkService + ->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); - $this->deleteCustomFieldsForItem(Acl::PUBLICLINK, $id); - - $this->eventDispatcher->notifyEvent('delete.publicLink.selection', - new Event($this, EventMessage::factory() - ->addDescription(__u('Links deleted'))) + $this->deleteCustomFieldsForItem( + ActionsInterface::PUBLICLINK, + $id ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Links deleted')); - } else { - $this->publicLinkService->delete($id); - - $this->deleteCustomFieldsForItem(Acl::PUBLICLINK, $id); - - $this->eventDispatcher->notifyEvent('delete.publicLink', - new Event($this, EventMessage::factory() - ->addDescription(__u('Link deleted')) - ->addDetail(__u('Link'), $id)) + $this->eventDispatcher->notifyEvent( + 'delete.publicLink.selection', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Links deleted')) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Link deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Links deleted') + ); } + + $this->publicLinkService->delete($id); + + $this->deleteCustomFieldsForItem( + ActionsInterface::PUBLICLINK, + $id + ); + + $this->eventDispatcher->notifyEvent( + 'delete.publicLink', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Link deleted')) + ->addDetail(__u('Link'), $id) + ) + ); + + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Link deleted') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -284,30 +370,43 @@ final class PublicLinkController extends ControllerBase implements CrudControlle /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveCreateAction() + public function saveCreateAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::PUBLICLINK_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PUBLICLINK_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new PublicLinkForm($this->dic); - $form->validate(Acl::PUBLICLINK_CREATE); + $form->validate(ActionsInterface::PUBLICLINK_CREATE); $this->publicLinkService->create($form->getItemData()); - $this->eventDispatcher->notifyEvent('create.publicLink', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'create.publicLink', + new Event($this) + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Link created')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Link created') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -320,14 +419,18 @@ final class PublicLinkController extends ControllerBase implements CrudControlle * @param int $notify * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveCreateFromAccountAction(int $accountId, int $notify) + public function saveCreateFromAccountAction(int $accountId, int $notify): bool { try { - if (!$this->acl->checkUserAccess(Acl::PUBLICLINK_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PUBLICLINK_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $publicLinkData = new PublicLinkData(); @@ -338,13 +441,22 @@ final class PublicLinkController extends ControllerBase implements CrudControlle $this->publicLinkService->create($publicLinkData); - $this->eventDispatcher->notifyEvent('create.publicLink.account', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'create.publicLink.account', + new Event($this) + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Link created')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Link created') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -355,7 +467,7 @@ final class PublicLinkController extends ControllerBase implements CrudControlle * * @param int $id */ - public function saveEditAction(int $id) + public function saveEditAction(int $id): void { throw new RuntimeException('Not implemented'); } @@ -366,14 +478,18 @@ final class PublicLinkController extends ControllerBase implements CrudControlle * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function viewAction(int $id) + public function viewAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::PUBLICLINK_VIEW)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PUBLICLINK_VIEW)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('View Link')); @@ -381,13 +497,19 @@ final class PublicLinkController extends ControllerBase implements CrudControlle $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.publicLink', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.publicLink', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -401,7 +523,7 @@ final class PublicLinkController extends ControllerBase implements CrudControlle * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/ResourceController.php b/app/modules/web/Controllers/ResourceController.php index aad6e3ee..6439283b 100644 --- a/app/modules/web/Controllers/ResourceController.php +++ b/app/modules/web/Controllers/ResourceController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -36,7 +36,7 @@ use SP\Html\Minify; */ final class ResourceController extends SimpleControllerBase { - const CSS_MIN_FILES = [ + private const CSS_MIN_FILES = [ 'reset.min.css', 'jquery-ui.min.css', 'jquery-ui.structure.min.css', @@ -44,7 +44,7 @@ final class ResourceController extends SimpleControllerBase 'toastr.min.css', 'magnific-popup.min.css' ]; - const JS_MIN_FILES = [ + private const JS_MIN_FILES = [ 'jquery-3.3.1.min.js', 'jquery.fileDownload.min.js', 'clipboard.min.js', @@ -58,7 +58,7 @@ final class ResourceController extends SimpleControllerBase 'toastr.min.js', 'jquery.magnific-popup.min.js', 'eventsource.min.js']; - const JS_APP_MIN_FILES = [ + private const JS_APP_MIN_FILES = [ 'app.min.js', 'app-config.min.js', 'app-triggers.min.js', @@ -67,15 +67,12 @@ final class ResourceController extends SimpleControllerBase 'app-util.min.js', 'app-main.min.js']; - /** - * @var Minify - */ - private $minify; + private ?Minify $minify = null; /** * Returns CSS resources */ - public function cssAction() + public function cssAction(): void { $file = $this->request->analyzeString('f'); $base = $this->request->analyzeString('b'); @@ -98,7 +95,7 @@ final class ResourceController extends SimpleControllerBase /** * Returns JS resources */ - public function jsAction() + public function jsAction(): void { $file = $this->request->analyzeString('f'); $base = $this->request->analyzeString('b'); @@ -133,7 +130,7 @@ final class ResourceController extends SimpleControllerBase * @throws DependencyException * @throws NotFoundException */ - protected function initialize() + protected function initialize(): void { $this->request->verifySignature($this->configData->getPasswordSalt()); diff --git a/app/modules/web/Controllers/SecurityManagerController.php b/app/modules/web/Controllers/SecurityManagerController.php index 19427221..5553cf9b 100644 --- a/app/modules/web/Controllers/SecurityManagerController.php +++ b/app/modules/web/Controllers/SecurityManagerController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -27,6 +27,7 @@ namespace SP\Modules\Web\Controllers; use DI\DependencyException; use DI\NotFoundException; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; @@ -47,14 +48,8 @@ use SP\Services\Track\TrackService; */ final class SecurityManagerController extends ControllerBase { - /** - * @var ItemSearchData - */ - protected $itemSearchData; - /** - * @var TabsGridHelper - */ - protected $tabsGridHelper; + protected ?ItemSearchData $itemSearchData = null; + protected ?TabsGridHelper $tabsGridHelper = null; /** * @throws DependencyException @@ -62,7 +57,7 @@ final class SecurityManagerController extends ControllerBase * @throws ConstraintException * @throws QueryException */ - public function indexAction() + public function indexAction(): void { $this->getGridTabs(); } @@ -75,26 +70,32 @@ final class SecurityManagerController extends ControllerBase * @throws ConstraintException * @throws QueryException */ - protected function getGridTabs() + protected function getGridTabs(): void { $this->itemSearchData = new ItemSearchData(); $this->itemSearchData->setLimitCount($this->configData->getAccountCount()); $this->tabsGridHelper = $this->dic->get(TabsGridHelper::class); - if ($this->checkAccess(Acl::EVENTLOG) + if ($this->checkAccess(ActionsInterface::EVENTLOG) && $this->configData->isLogEnabled() ) { $this->tabsGridHelper->addTab($this->getEventlogList()); } - if ($this->checkAccess(Acl::TRACK)) { + if ($this->checkAccess(ActionsInterface::TRACK)) { $this->tabsGridHelper->addTab($this->getTracksList()); } - $this->eventDispatcher->notifyEvent('show.itemlist.security', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.itemlist.security', + new Event($this) + ); - $this->tabsGridHelper->renderTabs(Acl::getActionRoute(Acl::SECURITY_MANAGE), $this->request->analyzeInt('tabIndex', 0)); + $this->tabsGridHelper->renderTabs( + Acl::getActionRoute(ActionsInterface::SECURITY_MANAGE), + $this->request->analyzeInt('tabIndex', 0) + ); $this->view(); } @@ -111,7 +112,8 @@ final class SecurityManagerController extends ControllerBase protected function getEventlogList(): DataGridTab { return $this->dic->get(EventlogGrid::class) - ->getGrid($this->dic->get(EventlogService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(EventlogService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -127,7 +129,8 @@ final class SecurityManagerController extends ControllerBase protected function getTracksList(): DataGridTab { return $this->dic->get(TrackGrid::class) - ->getGrid($this->dic->get(TrackService::class)->search($this->itemSearchData)) + ->getGrid($this->dic->get(TrackService::class) + ->search($this->itemSearchData)) ->updatePager(); } @@ -145,7 +148,7 @@ final class SecurityManagerController extends ControllerBase * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); } diff --git a/app/modules/web/Controllers/SimpleControllerBase.php b/app/modules/web/Controllers/SimpleControllerBase.php index aef42311..3d78cb01 100644 --- a/app/modules/web/Controllers/SimpleControllerBase.php +++ b/app/modules/web/Controllers/SimpleControllerBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,17 +19,15 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; -use DI\Container; -use DI\DependencyException; -use DI\NotFoundException; use Psr\Container\ContainerInterface; use SP\Core\Acl\UnauthorizedPageException; use SP\Core\Exceptions\SessionTimeout; +use SP\Core\Exceptions\SPException; use SP\Modules\Web\Controllers\Traits\WebControllerTrait; /** @@ -41,25 +39,17 @@ abstract class SimpleControllerBase { use WebControllerTrait; - /** - * @var ContainerInterface - */ - protected $dic; - /** - * @var string - */ - protected $previousSk; + protected ContainerInterface $dic; /** * SimpleControllerBase constructor. * - * @param Container $container - * @param $actionName - * - * @throws DependencyException - * @throws NotFoundException + * @throws \JsonException */ - public function __construct(Container $container, $actionName) + public function __construct( + ContainerInterface $container, + string $actionName + ) { $this->dic = $container; $this->actionName = $actionName; @@ -75,18 +65,12 @@ abstract class SimpleControllerBase } } - /** - * @return void - */ - protected abstract function initialize(); + abstract protected function initialize(): void; /** - * @return void - * - * @throws DependencyException - * @throws NotFoundException + * @throws \JsonException */ - public function handleSessionTimeout() + public function handleSessionTimeout(): void { $this->sessionLogout( $this->request, @@ -104,7 +88,7 @@ abstract class SimpleControllerBase * * @throws SessionTimeout */ - protected function checks() + protected function checks(): void { if ($this->session->isLoggedIn() === false || $this->session->getAuthCompleted() !== true @@ -118,16 +102,14 @@ abstract class SimpleControllerBase /** * Comprobar si está permitido el acceso al módulo/página. * - * @param string|null $action La acción a comprobar - * * @throws UnauthorizedPageException */ - protected function checkAccess(?string $action) + protected function checkAccess(int $action): void { - if (!$this->session->getUserData()->getIsAdminApp() - && !$this->acl->checkUserAccess($action) + if (!$this->acl->checkUserAccess($action) + && !$this->session->getUserData()->getIsAdminApp() ) { - throw new UnauthorizedPageException(UnauthorizedPageException::INFO); + throw new UnauthorizedPageException(SPException::INFO); } } } \ No newline at end of file diff --git a/app/modules/web/Controllers/StatusController.php b/app/modules/web/Controllers/StatusController.php index 23a4693c..e2a677e9 100644 --- a/app/modules/web/Controllers/StatusController.php +++ b/app/modules/web/Controllers/StatusController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,13 +19,11 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; -use DI\DependencyException; -use DI\NotFoundException; use GuzzleHttp\Client; use GuzzleHttp\Exception\GuzzleException; use SP\Core\AppInfoInterface; @@ -43,14 +41,15 @@ final class StatusController extends SimpleControllerBase { use JsonTrait; - const TAG_VERSION_REGEX = '/v?(?P\d+)\.(?P\d+)\.(?P\d+)\.(?P\d+)(?P\-[a-z0-9\.]+)?$/'; + private const TAG_VERSION_REGEX = '/v?(?P\d+)\.(?P\d+)\.(?P\d+)\.(?P\d+)(?P\-[a-z0-9\.]+)?$/'; /** * checkReleaseAction * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function checkReleaseAction(): bool { @@ -63,38 +62,41 @@ final class StatusController extends SimpleControllerBase if ($request->getStatusCode() === 200 && strpos($request->getHeaderLine('content-type'), 'application/json') !== false ) { - $requestData = json_decode($request->getBody()); + $requestData = json_decode( + $request->getBody(), + false, + 512, + JSON_THROW_ON_ERROR + ); - if ($requestData !== null && !isset($requestData->message)) { - // $updateInfo[0]->tag_name - // $updateInfo[0]->name - // $updateInfo[0]->body - // $updateInfo[0]->tarball_url - // $updateInfo[0]->zipball_url - // $updateInfo[0]->published_at - // $updateInfo[0]->html_url + if ($requestData !== null && !isset($requestData->message) + && preg_match(self::TAG_VERSION_REGEX, $requestData->tag_name, $matches)) { + $pubVersion = $matches['major'] . + $matches['minor'] . + $matches['patch'] . + '.' . + $matches['build']; - if (preg_match(self::TAG_VERSION_REGEX, $requestData->tag_name, $matches)) { - $pubVersion = $matches['major'] . $matches['minor'] . $matches['patch'] . '.' . $matches['build']; - - if (VersionUtil::checkVersion(VersionUtil::getVersionStringNormalized(), $pubVersion)) { - return $this->returnJsonResponseData([ - 'version' => $requestData->tag_name, - 'url' => $requestData->html_url, - 'title' => $requestData->name, - 'description' => $requestData->body, - 'date' => $requestData->published_at - ]); - } - - return $this->returnJsonResponseData([]); + if (VersionUtil::checkVersion(VersionUtil::getVersionStringNormalized(), $pubVersion)) { + return $this->returnJsonResponseData([ + 'version' => $requestData->tag_name, + 'url' => $requestData->html_url, + 'title' => $requestData->name, + 'description' => $requestData->body, + 'date' => $requestData->published_at + ]); } + + return $this->returnJsonResponseData([]); } logger($requestData->message); } - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Version unavailable')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Version unavailable') + ); } catch (GuzzleException $e) { processException($e); @@ -108,8 +110,9 @@ final class StatusController extends SimpleControllerBase * checkNoticesAction * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function checkNoticesAction(): bool { @@ -122,7 +125,12 @@ final class StatusController extends SimpleControllerBase if ($request->getStatusCode() === 200 && strpos($request->getHeaderLine('content-type'), 'application/json') !== false ) { - $requestData = json_decode($request->getBody()); + $requestData = json_decode( + $request->getBody(), + false, + 512, + JSON_THROW_ON_ERROR + ); if ($requestData !== null && !isset($requestData->message)) { $notices = []; @@ -141,7 +149,10 @@ final class StatusController extends SimpleControllerBase logger($requestData->message); } - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Notifications not available')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Notifications not available') + ); } catch (GuzzleException $e) { processException($e); @@ -154,7 +165,7 @@ final class StatusController extends SimpleControllerBase /** * @return void */ - protected function initialize() + protected function initialize(): void { // TODO: Implement initialize() method. } diff --git a/app/modules/web/Controllers/TagController.php b/app/modules/web/Controllers/TagController.php index e8b1115d..d145118f 100644 --- a/app/modules/web/Controllers/TagController.php +++ b/app/modules/web/Controllers/TagController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -28,6 +28,7 @@ use DI\DependencyException; use DI\NotFoundException; use Exception; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; @@ -55,10 +56,7 @@ final class TagController extends ControllerBase implements CrudControllerInterf { use JsonTrait, ItemTrait; - /** - * @var TagService - */ - protected $tagService; + protected ?TagService $tagService = null; /** * Search action @@ -69,15 +67,22 @@ final class TagController extends ControllerBase implements CrudControllerInterf * @throws ConstraintException * @throws QueryException * @throws SPException + * @throws \JsonException */ - public function searchAction() + public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::TAG_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::TAG_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); - $this->view->assign('index', $this->request->analyzeInt('activetab', 0)); + $this->view->assign( + 'index', + $this->request->analyzeInt('activetab', 0) + ); $this->view->assign('data', $this->getSearchGrid()); return $this->returnJsonResponseData(['html' => $this->render()]); @@ -93,23 +98,33 @@ final class TagController extends ControllerBase implements CrudControllerInterf */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $tagGrid = $this->dic->get(TagGrid::class); - return $tagGrid->updatePager($tagGrid->getGrid($this->tagService->search($itemSearchData)), $itemSearchData); + return $tagGrid->updatePager( + $tagGrid->getGrid($this->tagService->search($itemSearchData)), + $itemSearchData + ); } /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function createAction() + public function createAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::TAG_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::TAG_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('New Tag')); @@ -118,13 +133,19 @@ final class TagController extends ControllerBase implements CrudControllerInterf $this->setViewData(); - $this->eventDispatcher->notifyEvent('show.tag.create', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.tag.create', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -139,15 +160,20 @@ final class TagController extends ControllerBase implements CrudControllerInterf * @throws QueryException * @throws NoSuchItemException */ - protected function setViewData(?int $tagId = null) + protected function setViewData(?int $tagId = null): void { $this->view->addTemplate('tag', 'itemshow'); - $tag = $tagId ? $this->tagService->getById($tagId) : new TagData(); + $tag = $tagId + ? $this->tagService->getById($tagId) + : new TagData(); $this->view->assign('tag', $tag); - $this->view->assign('nextAction', Acl::getActionRoute(Acl::ITEMS_MANAGE)); + $this->view->assign( + 'nextAction', + Acl::getActionRoute(ActionsInterface::ITEMS_MANAGE) + ); if ($this->view->isView === true) { $this->view->assign('disabled', 'disabled'); @@ -164,14 +190,18 @@ final class TagController extends ControllerBase implements CrudControllerInterf * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function editAction(int $id) + public function editAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::TAG_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::TAG_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('Edit Tag')); @@ -180,13 +210,19 @@ final class TagController extends ControllerBase implements CrudControllerInterf $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.tag.edit', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.tag.edit', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -198,37 +234,63 @@ final class TagController extends ControllerBase implements CrudControllerInterf * @param int|null $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): bool { try { - if (!$this->acl->checkUserAccess(Acl::TAG_DELETE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::TAG_DELETE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } if ($id === null) { - $this->tagService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); + $this->tagService + ->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); - $this->deleteCustomFieldsForItem(Acl::TAG, $id); + $this->deleteCustomFieldsForItem( + ActionsInterface::TAG, + $id + ); - $this->eventDispatcher->notifyEvent('delete.tag.selection', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'delete.tag.selection', + new Event($this) + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Tags deleted')); - } else { - $this->tagService->delete($id); - - $this->deleteCustomFieldsForItem(Acl::TAG, $id); - - $this->eventDispatcher->notifyEvent('delete.tag', new Event($this)); - - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Tag removed')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Tags deleted') + ); } + + $this->tagService->delete($id); + + $this->deleteCustomFieldsForItem( + ActionsInterface::TAG, + $id + ); + + $this->eventDispatcher->notifyEvent( + 'delete.tag', + new Event($this) + ); + + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Tag removed') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -236,30 +298,43 @@ final class TagController extends ControllerBase implements CrudControllerInterf /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveCreateAction() + public function saveCreateAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::TAG_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::TAG_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new TagForm($this->dic); - $form->validate(Acl::TAG_CREATE); + $form->validate(ActionsInterface::TAG_CREATE); $this->tagService->create($form->getItemData()); - $this->eventDispatcher->notifyEvent('create.tag', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'create.tag', + new Event($this) + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Tag added')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Tag added') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -271,30 +346,43 @@ final class TagController extends ControllerBase implements CrudControllerInterf * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveEditAction(int $id) + public function saveEditAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::TAG_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::TAG_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new TagForm($this->dic, $id); - $form->validate(Acl::TAG_EDIT); + $form->validate(ActionsInterface::TAG_EDIT); $this->tagService->update($form->getItemData()); - $this->eventDispatcher->notifyEvent('edit.tag', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'edit.tag', + new Event($this) + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Tag updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Tag updated') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -306,14 +394,18 @@ final class TagController extends ControllerBase implements CrudControllerInterf * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function viewAction(int $id) + public function viewAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::TAG_VIEW)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::TAG_VIEW)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('View Tag')); @@ -321,13 +413,19 @@ final class TagController extends ControllerBase implements CrudControllerInterf $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.tag', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.tag', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -341,7 +439,7 @@ final class TagController extends ControllerBase implements CrudControllerInterf * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/TaskController.php b/app/modules/web/Controllers/TaskController.php index 9043d78c..b0581971 100644 --- a/app/modules/web/Controllers/TaskController.php +++ b/app/modules/web/Controllers/TaskController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -60,8 +60,10 @@ final class TaskController /** * @param string $taskId + * + * @throws \JsonException */ - public function trackStatusAction(string $taskId) + public function trackStatusAction(string $taskId): void { $response = $this->router->response(); $response->header('Content-Type', 'text/event-stream'); @@ -89,7 +91,7 @@ final class TaskController * * @throws FileException */ - public function testTaskAction(string $taskId) + public function testTaskAction(string $taskId): void { $task = TaskFactory::create($taskId, $taskId); @@ -99,7 +101,10 @@ final class TaskController while ($count < 60) { TaskFactory::update($task, - TaskFactory::createMessage($task->getTaskId(), "Test Task $count") + TaskFactory::createMessage( + $task->getTaskId(), + "Test Task $count" + ) ); sleep(1); diff --git a/app/modules/web/Controllers/TrackController.php b/app/modules/web/Controllers/TrackController.php index b665e9b1..95f09995 100644 --- a/app/modules/web/Controllers/TrackController.php +++ b/app/modules/web/Controllers/TrackController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -27,7 +27,7 @@ namespace SP\Modules\Web\Controllers; use DI\DependencyException; use DI\NotFoundException; use Exception; -use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Acl\UnauthorizedActionException; use SP\Core\Events\Event; use SP\Core\Exceptions\ConstraintException; @@ -51,10 +51,7 @@ final class TrackController extends ControllerBase { use JsonTrait, ItemTrait; - /** - * @var TrackService - */ - protected $trackService; + protected ?TrackService $trackService = null; /** * Search action @@ -69,12 +66,15 @@ final class TrackController extends ControllerBase */ public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::TRACK_SEARCH)) { - throw new UnauthorizedActionException(UnauthorizedActionException::ERROR); + if (!$this->acl->checkUserAccess(ActionsInterface::TRACK_SEARCH)) { + throw new UnauthorizedActionException(SPException::ERROR); } $this->view->addTemplate('datagrid-table', 'grid'); - $this->view->assign('index', $this->request->analyzeInt('activetab', 0)); + $this->view->assign( + 'index', + $this->request->analyzeInt('activetab', 0) + ); $this->view->assign('data', $this->getSearchGrid()); return $this->returnJsonResponseData(['html' => $this->render()]); @@ -90,11 +90,17 @@ final class TrackController extends ControllerBase */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $itemsGridHelper = $this->dic->get(TrackGrid::class); - return $itemsGridHelper->updatePager($itemsGridHelper->getGrid($this->trackService->search($itemSearchData)), $itemSearchData); + return $itemsGridHelper->updatePager( + $itemsGridHelper->getGrid($this->trackService->search($itemSearchData)), + $itemSearchData + ); } /** @@ -103,25 +109,35 @@ final class TrackController extends ControllerBase * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function unlockAction(int $id) + public function unlockAction(int $id): ?bool { try { - if (!$this->acl->checkUserAccess(Acl::TRACK_UNLOCK)) { - throw new UnauthorizedActionException(UnauthorizedActionException::ERROR); + if (!$this->acl->checkUserAccess(ActionsInterface::TRACK_UNLOCK)) { + throw new UnauthorizedActionException(SPException::ERROR); } $this->trackService->unlock($id); - $this->eventDispatcher->notifyEvent('unlock.track', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'unlock.track', + new Event($this) + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Track unlocked')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Track unlocked') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -131,25 +147,35 @@ final class TrackController extends ControllerBase * Clears tracks * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function clearAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::TRACK_CLEAR)) { - throw new UnauthorizedActionException(UnauthorizedActionException::ERROR); + if (!$this->acl->checkUserAccess(ActionsInterface::TRACK_CLEAR)) { + throw new UnauthorizedActionException(SPException::ERROR); } $this->trackService->clear(); - $this->eventDispatcher->notifyEvent('clear.track', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'clear.track', + new Event($this) + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Tracks cleared out')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Tracks cleared out') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -161,7 +187,7 @@ final class TrackController extends ControllerBase * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/Traits/ConfigTrait.php b/app/modules/web/Controllers/Traits/ConfigTrait.php index 2f535397..4dc068f7 100644 --- a/app/modules/web/Controllers/Traits/ConfigTrait.php +++ b/app/modules/web/Controllers/Traits/ConfigTrait.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Traits; @@ -27,7 +27,7 @@ namespace SP\Modules\Web\Controllers\Traits; use Exception; use SP\Bootstrap; use SP\Config\Config; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Http\JsonResponse; use SP\Util\Util; @@ -43,22 +43,28 @@ trait ConfigTrait /** * Guardar la configuración * - * @param ConfigData $configData - * @param Config $config - * @param callable|null $onSuccess - * - * @return bool + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - protected function saveConfig(ConfigData $configData, Config $config, callable $onSuccess = null): bool + protected function saveConfig( + ConfigDataInterface $configData, + Config $config, + callable $onSuccess = null + ): bool { try { if ($configData->isDemoEnabled()) { - return $this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Ey, this is a DEMO!!')); + return $this->returnJsonResponse( + JsonResponse::JSON_WARNING, + __u('Ey, this is a DEMO!!') + ); } $config->saveConfig($configData); - if ($configData->isMaintenance() === false && Bootstrap::$LOCK !== false) { + if (Bootstrap::$LOCK !== false + && $configData->isMaintenance() === false) { Util::unlockApp(); } @@ -66,11 +72,17 @@ trait ConfigTrait $onSuccess(); } - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Configuration updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Configuration updated') + ); } catch (Exception $e) { processException($e); - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Error while saving the configuration')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Error while saving the configuration') + ); } } } \ No newline at end of file diff --git a/app/modules/web/Controllers/Traits/JsonTrait.php b/app/modules/web/Controllers/Traits/JsonTrait.php index c5f86867..56b01ec5 100644 --- a/app/modules/web/Controllers/Traits/JsonTrait.php +++ b/app/modules/web/Controllers/Traits/JsonTrait.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,13 +19,11 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Traits; -use DI\DependencyException; -use DI\NotFoundException; use Exception; use SP\Core\Context\SessionContext; use SP\Core\Exceptions\SPException; @@ -35,7 +33,6 @@ use SP\Http\JsonResponse; /** * Trait JsonTrait * - * @package SP\Modules\Web\Controllers\Traits * @property SessionContext $session */ trait JsonTrait @@ -47,14 +44,13 @@ trait JsonTrait * @param string $description Untranslated description string * @param array|null $messages Untranslated massages array of strings * - * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \JsonException */ protected function returnJsonResponse( - int $status, + int $status, string $description, - array $messages = null): bool + ?array $messages = null + ): bool { $jsonResponse = new JsonResponse(); $jsonResponse->setStatus($status); @@ -70,20 +66,20 @@ trait JsonTrait /** * Returns JSON response * - * @param mixed $data - * @param int $status Status code - * @param null $description Untranslated description string - * @param array|null $messages + * @param mixed $data + * @param int $status Status code + * @param string|null $description Untranslated description string + * @param array|null $messages * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \JsonException */ protected function returnJsonResponseData( $data, - $status = JsonResponse::JSON_SUCCESS, - $description = null, - array $messages = null): bool + int $status = JsonResponse::JSON_SUCCESS, + ?string $description = null, + ?array $messages = null + ): bool { $jsonResponse = new JsonResponse(); $jsonResponse->setStatus($status); @@ -103,22 +99,20 @@ trait JsonTrait /** * Returns JSON response * - * @param Exception $exception - * @param int $status Status code - * - * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \JsonException */ protected function returnJsonResponseException( Exception $exception, - int $status = JsonResponse::JSON_ERROR): bool + int $status = JsonResponse::JSON_ERROR + ): bool { $jsonResponse = new JsonResponse(); $jsonResponse->setStatus($status); $jsonResponse->setDescription($exception->getMessage()); - if ($exception instanceof SPException && $exception->getHint() !== null) { + if ($exception instanceof SPException + && $exception->getHint() !== null + ) { $jsonResponse->setMessages([$exception->getHint()]); } diff --git a/app/modules/web/Controllers/Traits/WebControllerTrait.php b/app/modules/web/Controllers/Traits/WebControllerTrait.php index 5ceb7b6b..85352544 100644 --- a/app/modules/web/Controllers/Traits/WebControllerTrait.php +++ b/app/modules/web/Controllers/Traits/WebControllerTrait.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers\Traits; @@ -27,7 +27,7 @@ namespace SP\Modules\Web\Controllers\Traits; use Klein\Klein; use Psr\Container\ContainerInterface; use SP\Config\Config; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Acl\Acl; use SP\Core\Context\ContextInterface; use SP\Core\Context\SessionContext; @@ -40,67 +40,27 @@ use SP\Mvc\Controller\ControllerTrait; /** * Trait ControllerTratit - * - * @package SP\Modules\Web\Controllers */ trait WebControllerTrait { use ControllerTrait; - /** - * @var string Nombre del controlador - */ - protected $controllerName; - /** - * @var EventDispatcher - */ - protected $eventDispatcher; - /** - * @var Config - */ - protected $config; - /** - * @var SessionContext - */ - protected $session; - /** - * @var ThemeInterface - */ - protected $theme; - /** - * @var string - */ - protected $actionName; - /** - * @var Klein - */ - protected $router; - /** - * @var Acl - */ - protected $acl; - /** - * @var ConfigData - */ - protected $configData; - /** - * @var Request - */ - protected $request; - /** - * @var PhpExtensionChecker - */ - protected $extensionChecker; - /** - * @var bool - */ - private $setup = false; + protected ?string $controllerName = null; + protected ?EventDispatcher $eventDispatcher = null; + protected ?Config $config = null; + protected ?SessionContext $session = null; + protected ?ThemeInterface $theme = null; + protected ?string $actionName = null; + protected ?Klein $router = null; + protected ?Acl $acl = null; + protected ConfigDataInterface $configData; + protected ?Request $request = null; + protected ?PhpExtensionChecker $extensionChecker = null; + private bool $setup = false; /** * Returns the signed URI component after validating its signature. * This component is used for deep linking - * - * @return null|string */ final protected function getSignedUriFromRequest(): ?string { @@ -112,7 +72,10 @@ trait WebControllerTrait if ($from) { try { - $this->request->verifySignature($this->configData->getPasswordSalt(), 'from'); + $this->request->verifySignature( + $this->configData->getPasswordSalt(), + 'from' + ); } catch (SPException $e) { processException($e); @@ -123,10 +86,7 @@ trait WebControllerTrait return $from; } - /** - * @param ContainerInterface $dic - */ - private function setUp(ContainerInterface $dic) + private function setUp(ContainerInterface $dic): void { $this->controllerName = $this->getControllerName(); diff --git a/app/modules/web/Controllers/UpgradeController.php b/app/modules/web/Controllers/UpgradeController.php index fd7cd005..75d45e93 100644 --- a/app/modules/web/Controllers/UpgradeController.php +++ b/app/modules/web/Controllers/UpgradeController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -51,7 +51,7 @@ final class UpgradeController extends ControllerBase * @throws NotFoundException * @throws FileException */ - public function indexAction() + public function indexAction(): void { $layoutHelper = $this->dic->get(LayoutHelper::class); $layoutHelper->getPublicLayout('index', 'upgrade'); @@ -63,10 +63,11 @@ final class UpgradeController extends ControllerBase /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function upgradeAction() + public function upgradeAction(): bool { if ($this->request->analyzeBool('chkConfirm', false) === false) { return $this->returnJsonResponse( @@ -117,7 +118,7 @@ final class UpgradeController extends ControllerBase /** * @return void */ - protected function initialize() + protected function initialize(): void { // TODO: Implement initialize() method. } diff --git a/app/modules/web/Controllers/UserController.php b/app/modules/web/Controllers/UserController.php index 8c22d872..8ad5dba7 100644 --- a/app/modules/web/Controllers/UserController.php +++ b/app/modules/web/Controllers/UserController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,17 +19,17 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; -use Defuse\Crypto\Exception\EnvironmentIsBrokenException; use DI\DependencyException; use DI\NotFoundException; use Exception; use Psr\Container\ContainerExceptionInterface; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -48,7 +48,6 @@ use SP\Mvc\Controller\ItemTrait; use SP\Mvc\View\Components\SelectItemAdapter; use SP\Services\Auth\AuthException; use SP\Services\Mail\MailService; -use SP\Services\ServiceException; use SP\Services\User\UserService; use SP\Services\UserGroup\UserGroupService; use SP\Services\UserPassRecover\UserPassRecoverService; @@ -64,29 +63,32 @@ final class UserController extends ControllerBase implements CrudControllerInter use JsonTrait; use ItemTrait; - /** - * @var UserService - */ - protected $userService; + protected ?UserService $userService = null; /** * Search action * * @return bool - * @throws DependencyException - * @throws NotFoundException - * @throws ConstraintException - * @throws QueryException - * @throws SPException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function searchAction() + public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::USER_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::USER_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); - $this->view->assign('index', $this->request->analyzeInt('activetab', 0)); + $this->view->assign( + 'index', + $this->request->analyzeInt('activetab', 0) + ); $this->view->assign('data', $this->getSearchGrid()); return $this->returnJsonResponseData(['html' => $this->render()]); @@ -102,23 +104,33 @@ final class UserController extends ControllerBase implements CrudControllerInter */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $userGrid = $this->dic->get(UserGrid::class); - return $userGrid->updatePager($userGrid->getGrid($this->userService->search($itemSearchData)), $itemSearchData); + return $userGrid->updatePager( + $userGrid->getGrid($this->userService->search($itemSearchData)), + $itemSearchData + ); } /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function createAction() + public function createAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::USER_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::USER_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('New User')); @@ -127,13 +139,19 @@ final class UserController extends ControllerBase implements CrudControllerInter $this->setViewData(); - $this->eventDispatcher->notifyEvent('show.user.create', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.user.create', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -147,49 +165,81 @@ final class UserController extends ControllerBase implements CrudControllerInter * @throws SPException * @throws ContainerExceptionInterface */ - protected function setViewData(?int $userId = null) + protected function setViewData(?int $userId = null): void { $this->view->addTemplate('user', 'itemshow'); - $user = $userId ? $this->userService->getById($userId) : new UserData(); + $user = $userId + ? $this->userService->getById($userId) + : new UserData(); $this->view->assign('user', $user); - $this->view->assign('groups', SelectItemAdapter::factory(UserGroupService::getItemsBasic())->getItemsFromModel()); - $this->view->assign('profiles', SelectItemAdapter::factory(UserProfileService::getItemsBasic())->getItemsFromModel()); - $this->view->assign('isUseSSO', $this->configData->isAuthBasicAutoLoginEnabled()); - $this->view->assign('mailEnabled', $this->configData->isMailEnabled()); - $this->view->assign('nextAction', Acl::getActionRoute(Acl::ACCESS_MANAGE)); + $this->view->assign( + 'groups', + SelectItemAdapter::factory(UserGroupService::getItemsBasic()) + ->getItemsFromModel() + ); + $this->view->assign( + 'profiles', + SelectItemAdapter::factory(UserProfileService::getItemsBasic()) + ->getItemsFromModel() + ); + $this->view->assign( + 'isUseSSO', + $this->configData->isAuthBasicAutoLoginEnabled() + ); + $this->view->assign( + 'mailEnabled', + $this->configData->isMailEnabled() + ); + $this->view->assign( + 'nextAction', + Acl::getActionRoute(ActionsInterface::ACCESS_MANAGE) + ); if ($this->view->isView === true - || ($this->configData->isDemoEnabled() && $user->getLogin() === 'demo') + || ($this->configData->isDemoEnabled() + && $user->getLogin() === 'demo') ) { $this->view->assign('disabled', 'disabled'); $this->view->assign('readonly', 'readonly'); - $this->view->assign('usage', array_map(function ($value) { - switch ($value->ref) { - case 'Account': - $value->icon = 'description'; - break; - case 'UserGroup': - $value->icon = 'group'; - break; - case 'PublicLink': - $value->icon = 'link'; - break; - default: - $value->icon = 'info_outline'; - } + $this->view->assign( + 'usage', + array_map( + static function ($value) { + switch ($value->ref) { + case 'Account': + $value->icon = 'description'; + break; + case 'UserGroup': + $value->icon = 'group'; + break; + case 'PublicLink': + $value->icon = 'link'; + break; + default: + $value->icon = 'info_outline'; + } - return $value; - }, $this->userService->getUsageForUser($userId))); + return $value; + }, + $this->userService->getUsageForUser($userId) + ) + ); } else { $this->view->assign('disabled', false); $this->view->assign('readonly', false); } - $this->view->assign('showViewCustomPass', $this->acl->checkUserAccess(Acl::CUSTOMFIELD_VIEW_PASS)); - $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::USER, $userId)); + $this->view->assign( + 'showViewCustomPass', + $this->acl->checkUserAccess(ActionsInterface::CUSTOMFIELD_VIEW_PASS) + ); + $this->view->assign( + 'customFields', + $this->getCustomFieldsForItem(ActionsInterface::USER, $userId) + ); } /** @@ -198,14 +248,18 @@ final class UserController extends ControllerBase implements CrudControllerInter * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function editAction(int $id) + public function editAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::USER_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::USER_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('Edit User')); @@ -214,13 +268,19 @@ final class UserController extends ControllerBase implements CrudControllerInter $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.user.edit', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.user.edit', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -232,15 +292,19 @@ final class UserController extends ControllerBase implements CrudControllerInter * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function editPassAction(int $id) + public function editPassAction(int $id): bool { try { // Comprobar si el usuario a modificar es distinto al de la sesión - if (!$this->acl->checkUserAccess(Acl::USER_EDIT_PASS, $id)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::USER_EDIT_PASS, $id)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('user_pass', 'itemshow'); @@ -249,17 +313,25 @@ final class UserController extends ControllerBase implements CrudControllerInter $this->view->assign('isView', false); $this->view->assign('route', 'user/saveEditPass/' . $id); - $user = $id ? $this->userService->getById($id) : new UserData(); + $user = $id + ? $this->userService->getById($id) + : new UserData(); $this->view->assign('user', $user); - $this->eventDispatcher->notifyEvent('show.user.editPass', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.user.editPass', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -271,47 +343,74 @@ final class UserController extends ControllerBase implements CrudControllerInter * @param int|null $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): bool { try { - if (!$this->acl->checkUserAccess(Acl::USER_DELETE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::USER_DELETE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } if ($id === null) { - $this->userService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); + $this->userService + ->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); $this->eventDispatcher->notifyEvent( 'delete.user.selection', - new Event($this, EventMessage::factory() - ->addDescription(__u('Users deleted')) - ->setExtra('userId', $this->getItemsIdFromRequest($this->request))) + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Users deleted')) + ->setExtra('userId', $this->getItemsIdFromRequest($this->request)) + ) ); - $this->deleteCustomFieldsForItem(Acl::USER, $id); + $this->deleteCustomFieldsForItem( + ActionsInterface::USER, + $id + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Users deleted')); - } else { - $this->userService->delete($id); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Users deleted') + ); + } - $this->deleteCustomFieldsForItem(Acl::USER, $id); + $this->userService->delete($id); - $this->eventDispatcher->notifyEvent('delete.user', - new Event($this, EventMessage::factory() + $this->deleteCustomFieldsForItem( + ActionsInterface::USER, + $id + ); + + $this->eventDispatcher->notifyEvent( + 'delete.user', + new Event( + $this, + EventMessage::factory() ->addDescription(__u('User deleted')) ->addDetail(__u('User'), $id) - ->addExtra('userId', $id)) - ); + ->addExtra('userId', $id) + ) + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('User deleted')); - } + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('User deleted') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -319,14 +418,18 @@ final class UserController extends ControllerBase implements CrudControllerInter /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function saveCreateAction() { try { - if (!$this->acl->checkUserAccess(Acl::USER_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::USER_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new UserForm($this->dic); @@ -336,23 +439,37 @@ final class UserController extends ControllerBase implements CrudControllerInter $id = $this->userService->create($itemData); - $this->eventDispatcher->notifyEvent('create.user', - new Event($this, EventMessage::factory() - ->addDescription(__u('User added')) - ->addDetail(__u('User'), $itemData->getName())) + $this->eventDispatcher->notifyEvent( + 'create.user', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('User added')) + ->addDetail(__u('User'), $itemData->getName()) + ) ); - $this->addCustomFieldsForItem(Acl::USER, $id, $this->request); + $this->addCustomFieldsForItem( + ActionsInterface::USER, + $id, + $this->request + ); $this->checkChangeUserPass($id, $itemData); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('User added')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('User added') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -362,21 +479,26 @@ final class UserController extends ControllerBase implements CrudControllerInter * @param int $userId * @param UserData $userData * - * @throws DependencyException - * @throws NotFoundException - * @throws EnvironmentIsBrokenException - * @throws ConstraintException - * @throws QueryException - * @throws ServiceException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException + * @throws \PHPMailer\PHPMailer\Exception + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException */ - protected function checkChangeUserPass(int $userId, UserData $userData) + protected function checkChangeUserPass(int $userId, UserData $userData): void { if ($userData->isChangePass()) { $hash = $this->dic->get(UserPassRecoverService::class) ->requestForUserId($userId); $this->dic->get(MailService::class) - ->send(__('Password Change'), $userData->getEmail(), UserPassRecoverService::getMailMessage($hash)); + ->send( + __('Password Change'), + $userData->getEmail(), + UserPassRecoverService::getMailMessage($hash) + ); } } @@ -386,41 +508,59 @@ final class UserController extends ControllerBase implements CrudControllerInter * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveEditAction(int $id) + public function saveEditAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::USER_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::USER_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new UserForm($this->dic, $id); - $form->validate(Acl::USER_EDIT); + $form->validate(ActionsInterface::USER_EDIT); $itemData = $form->getItemData(); $this->userService->update($itemData); - $this->eventDispatcher->notifyEvent('edit.user', - new Event($this, EventMessage::factory() - ->addDescription(__u('User updated')) - ->addDetail(__u('User'), $itemData->getName()) - ->addExtra('userId', $id)) + $this->eventDispatcher->notifyEvent( + 'edit.user', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('User updated')) + ->addDetail(__u('User'), $itemData->getName()) + ->addExtra('userId', $id) + ) ); - $this->updateCustomFieldsForItem(Acl::USER, $id, $this->request); + $this->updateCustomFieldsForItem( + ActionsInterface::USER, + $id, + $this->request + ); $this->checkChangeUserPass($id, $itemData); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('User updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('User updated') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -432,36 +572,50 @@ final class UserController extends ControllerBase implements CrudControllerInter * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveEditPassAction(int $id) + public function saveEditPassAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::USER_EDIT_PASS, $id)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::USER_EDIT_PASS, $id)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new UserForm($this->dic, $id); - $form->validate(Acl::USER_EDIT_PASS); + $form->validate(ActionsInterface::USER_EDIT_PASS); $itemData = $form->getItemData(); $this->userService->updatePass($id, $itemData->getPass()); - $this->eventDispatcher->notifyEvent('edit.user.pass', - new Event($this, EventMessage::factory() - ->addDescription(__u('Password updated')) - ->addDetail(__u('User'), $id)) + $this->eventDispatcher->notifyEvent( + 'edit.user.pass', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Password updated')) + ->addDetail(__u('User'), $id) + ) ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Password updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Password updated') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -473,14 +627,18 @@ final class UserController extends ControllerBase implements CrudControllerInter * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function viewAction(int $id) + public function viewAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::USER_VIEW)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::USER_VIEW)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('View User')); @@ -488,13 +646,19 @@ final class UserController extends ControllerBase implements CrudControllerInter $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.user', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.user', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -506,7 +670,7 @@ final class UserController extends ControllerBase implements CrudControllerInter * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/UserGroupController.php b/app/modules/web/Controllers/UserGroupController.php index 503cf939..abf6af6b 100644 --- a/app/modules/web/Controllers/UserGroupController.php +++ b/app/modules/web/Controllers/UserGroupController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -28,6 +28,7 @@ use DI\DependencyException; use DI\NotFoundException; use Exception; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -49,7 +50,6 @@ use SP\Services\Auth\AuthException; use SP\Services\ServiceException; use SP\Services\User\UserService; use SP\Services\UserGroup\UserGroupService; -use SP\Services\UserGroup\UserToUserGroupService; /** * Class GroupController @@ -60,33 +60,32 @@ final class UserGroupController extends ControllerBase implements CrudController { use JsonTrait, ItemTrait; - /** - * @var UserGroupService - */ - protected $userGroupService; - /** - * @var UserToUserGroupService - */ - protected $userToUserGroupService; + protected ?UserGroupService $userGroupService = null; /** * Search action * * @return bool - * @throws ConstraintException - * @throws DependencyException - * @throws NotFoundException - * @throws QueryException - * @throws SPException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function searchAction() + public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::GROUP_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::GROUP_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); - $this->view->assign('index', $this->request->analyzeInt('activetab', 0)); + $this->view->assign( + 'index', + $this->request->analyzeInt('activetab', 0) + ); $this->view->assign('data', $this->getSearchGrid()); return $this->returnJsonResponseData(['html' => $this->render()]); @@ -102,23 +101,33 @@ final class UserGroupController extends ControllerBase implements CrudController */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $userGroupGrid = $this->dic->get(UserGroupGrid::class); - return $userGroupGrid->updatePager($userGroupGrid->getGrid($this->userGroupService->search($itemSearchData)), $itemSearchData); + return $userGroupGrid->updatePager( + $userGroupGrid->getGrid($this->userGroupService->search($itemSearchData)), + $itemSearchData + ); } /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function createAction() + public function createAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::GROUP_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::GROUP_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('New Group')); @@ -127,13 +136,19 @@ final class UserGroupController extends ControllerBase implements CrudController $this->setViewData(); - $this->eventDispatcher->notifyEvent('show.userGroup.create', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.userGroup.create', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -152,22 +167,34 @@ final class UserGroupController extends ControllerBase implements CrudController * @throws SPException * @throws ServiceException */ - protected function setViewData(?int $userGroupId = null) + protected function setViewData(?int $userGroupId = null): void { $this->view->addTemplate('user_group', 'itemshow'); - $userGroupData = $userGroupId ? $this->userGroupService->getById($userGroupId) : new UserGroupData(); + $userGroupData = $userGroupId + ? $this->userGroupService->getById($userGroupId) + : new UserGroupData(); $this->view->assign('group', $userGroupData); $users = $userGroupData->getUsers() ?: []; - $this->view->assign('users', + $this->view->assign( + 'users', SelectItemAdapter::factory(UserService::getItemsBasic()) - ->getItemsFromModelSelected($users)); - $this->view->assign('usedBy', $this->userGroupService->getUsageByUsers($userGroupId)); + ->getItemsFromModelSelected($users) + ); + $this->view->assign( + 'usedBy', + $userGroupId + ? $this->userGroupService->getUsageByUsers($userGroupId) + : [] + ); - $this->view->assign('nextAction', Acl::getActionRoute(Acl::ACCESS_MANAGE)); + $this->view->assign( + 'nextAction', + Acl::getActionRoute(ActionsInterface::ACCESS_MANAGE) + ); if ($this->view->isView === true) { $this->view->assign('disabled', 'disabled'); @@ -177,8 +204,14 @@ final class UserGroupController extends ControllerBase implements CrudController $this->view->assign('readonly', false); } - $this->view->assign('showViewCustomPass', $this->acl->checkUserAccess(Acl::CUSTOMFIELD_VIEW_PASS)); - $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::GROUP, $userGroupId)); + $this->view->assign( + 'showViewCustomPass', + $this->acl->checkUserAccess(ActionsInterface::CUSTOMFIELD_VIEW_PASS) + ); + $this->view->assign( + 'customFields', + $this->getCustomFieldsForItem(ActionsInterface::GROUP, $userGroupId) + ); } /** @@ -187,14 +220,18 @@ final class UserGroupController extends ControllerBase implements CrudController * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function editAction(int $id) + public function editAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::GROUP_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::GROUP_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('Edit Group')); @@ -203,13 +240,19 @@ final class UserGroupController extends ControllerBase implements CrudController $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.userGroup.edit', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.userGroup.edit', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -221,46 +264,73 @@ final class UserGroupController extends ControllerBase implements CrudController * @param int|null $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): bool { try { - if (!$this->acl->checkUserAccess(Acl::GROUP_DELETE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::GROUP_DELETE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } if ($id === null) { - $this->userGroupService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); + $this->userGroupService + ->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); $this->eventDispatcher->notifyEvent( 'delete.userGroup.selection', - new Event($this, EventMessage::factory() - ->addDescription(__u('Groups deleted'))) + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Groups deleted')) + ) ); - $this->deleteCustomFieldsForItem(Acl::GROUP, $id); + $this->deleteCustomFieldsForItem( + ActionsInterface::GROUP, + $id + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Groups deleted')); - } else { - $this->userGroupService->delete($id); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Groups deleted') + ); + } - $this->eventDispatcher->notifyEvent('delete.userGroup', - new Event($this, EventMessage::factory() + $this->userGroupService->delete($id); + + $this->eventDispatcher->notifyEvent( + 'delete.userGroup', + new Event( + $this, + EventMessage::factory() ->addDescription(__u('Group deleted')) ->addDetail(__u('Group'), $id) - ->addExtra('userGroupId', $id)) - ); + ->addExtra('userGroupId', $id) + ) + ); - $this->deleteCustomFieldsForItem(Acl::GROUP, $id); + $this->deleteCustomFieldsForItem( + ActionsInterface::GROUP, + $id + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Group deleted')); - } + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Group deleted') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -268,38 +338,56 @@ final class UserGroupController extends ControllerBase implements CrudController /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveCreateAction() + public function saveCreateAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::GROUP_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::GROUP_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new UserGroupForm($this->dic); - $form->validate(Acl::GROUP_CREATE); + $form->validate(ActionsInterface::GROUP_CREATE); $groupData = $form->getItemData(); $id = $this->userGroupService->create($groupData); - $this->eventDispatcher->notifyEvent('create.userGroup', - new Event($this, EventMessage::factory() - ->addDescription(__u('Group added')) - ->addDetail(__u('Name'), $groupData->getName())) + $this->eventDispatcher->notifyEvent( + 'create.userGroup', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Group added')) + ->addDetail(__u('Name'), $groupData->getName()) + ) ); - $this->addCustomFieldsForItem(Acl::GROUP, $id, $this->request); + $this->addCustomFieldsForItem( + ActionsInterface::GROUP, + $id, + $this->request + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Group added')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Group added') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -311,39 +399,57 @@ final class UserGroupController extends ControllerBase implements CrudController * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveEditAction(int $id) + public function saveEditAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::GROUP_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::GROUP_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new UserGroupForm($this->dic, $id); - $form->validate(Acl::GROUP_EDIT); + $form->validate(ActionsInterface::GROUP_EDIT); $groupData = $form->getItemData(); $this->userGroupService->update($groupData); - $this->eventDispatcher->notifyEvent('edit.userGroup', - new Event($this, EventMessage::factory() - ->addDescription(__u('Group updated')) - ->addDetail(__u('Name'), $groupData->getName()) - ->addExtra('userGroupId', $id)) + $this->eventDispatcher->notifyEvent( + 'edit.userGroup', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Group updated')) + ->addDetail(__u('Name'), $groupData->getName()) + ->addExtra('userGroupId', $id) + ) ); - $this->updateCustomFieldsForItem(Acl::GROUP, $id, $this->request); + $this->updateCustomFieldsForItem( + ActionsInterface::GROUP, + $id, + $this->request + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Group updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Group updated') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -357,12 +463,16 @@ final class UserGroupController extends ControllerBase implements CrudController * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function viewAction(int $id) + public function viewAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::GROUP_VIEW)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::GROUP_VIEW)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('View Group')); @@ -370,13 +480,19 @@ final class UserGroupController extends ControllerBase implements CrudController $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.userGroup', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.userGroup', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -390,7 +506,7 @@ final class UserGroupController extends ControllerBase implements CrudController * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/UserPassResetController.php b/app/modules/web/Controllers/UserPassResetController.php index 0a77a5d2..7aa0ae11 100644 --- a/app/modules/web/Controllers/UserPassResetController.php +++ b/app/modules/web/Controllers/UserPassResetController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -52,14 +52,9 @@ use SP\Util\ErrorUtil; final class UserPassResetController extends ControllerBase { use JsonTrait; - /** - * @var TrackService - */ - protected $trackService; - /** - * @var TrackRequest - */ - protected $trackRequest; + + protected ?TrackService $trackService = null; + protected ?TrackRequest $trackRequest = null; /** * Password reset action @@ -67,13 +62,18 @@ final class UserPassResetController extends ControllerBase * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function indexAction() + public function indexAction(): void { $this->dic->get(LayoutHelper::class) ->getCustomLayout('request', strtolower($this->controllerName)); if (!$this->configData->isMailEnabled()) { - ErrorUtil::showErrorInView($this->view, self::ERR_UNAVAILABLE, true, 'request'); + ErrorUtil::showErrorInView( + $this->view, + self::ERR_UNAVAILABLE, + true, + 'request' + ); } $this->view(); @@ -81,8 +81,9 @@ final class UserPassResetController extends ControllerBase /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function saveRequestAction(): bool { @@ -106,19 +107,25 @@ final class UserPassResetController extends ControllerBase ); } - $hash = $this->dic->get(UserPassRecoverService::class)->requestForUserId($userData->getId()); + $hash = $this->dic->get(UserPassRecoverService::class) + ->requestForUserId($userData->getId()); $this->eventDispatcher->notifyEvent( 'request.user.passReset', - new Event($this, EventMessage::factory() - ->addDescription(__u('Password Recovery')) - ->addDetail(__u('Requested for'), sprintf('%s (%s)', $login, $email))) + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Password Recovery')) + ->addDetail(__u('Requested for'), sprintf('%s (%s)', $login, $email)) + ) ); $this->dic->get(MailService::class) - ->send(__('Password Change'), + ->send( + __('Password Change'), $email, - UserPassRecoverService::getMailMessage($hash)); + UserPassRecoverService::getMailMessage($hash) + ); return $this->returnJsonResponse( JsonResponse::JSON_SUCCESS, @@ -143,17 +150,20 @@ final class UserPassResetController extends ControllerBase * @throws SPException * @throws Exception */ - protected function checkTracking() + protected function checkTracking(): void { if ($this->trackService->checkTracking($this->trackRequest)) { - throw new SPException(__u('Attempts exceeded'), SPException::INFO); + throw new SPException( + __u('Attempts exceeded'), + SPException::INFO + ); } } /** * Añadir un seguimiento */ - private function addTracking() + private function addTracking(): void { try { $this->trackService->add($this->trackRequest); @@ -168,7 +178,7 @@ final class UserPassResetController extends ControllerBase * @throws DependencyException * @throws NotFoundException */ - public function resetAction(?string $hash = null) + public function resetAction(?string $hash = null): void { $this->dic->get(LayoutHelper::class) ->getCustomLayout('reset', strtolower($this->controllerName)); @@ -176,7 +186,12 @@ final class UserPassResetController extends ControllerBase if ($hash && $this->configData->isMailEnabled()) { $this->view->assign('hash', $hash); } else { - ErrorUtil::showErrorInView($this->view, self::ERR_UNAVAILABLE, true, 'reset'); + ErrorUtil::showErrorInView( + $this->view, + self::ERR_UNAVAILABLE, + true, + 'reset' + ); } $this->view(); @@ -184,8 +199,9 @@ final class UserPassResetController extends ControllerBase /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ public function saveResetAction(): bool { @@ -216,11 +232,14 @@ final class UserPassResetController extends ControllerBase $this->eventDispatcher->notifyEvent( 'edit.user.password', - new Event($this, EventMessage::factory() - ->addDescription(__u('Password updated')) - ->addDetail(__u('User'), $user->getLogin()) - ->addExtra('userId', $userId) - ->addExtra('email', $user->getEmail())) + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Password updated')) + ->addDetail(__u('User'), $user->getLogin()) + ->addExtra('userId', $userId) + ->addExtra('email', $user->getEmail()) + ) ); return $this->returnJsonResponse( @@ -232,7 +251,10 @@ final class UserPassResetController extends ControllerBase $this->addTracking(); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -243,7 +265,7 @@ final class UserPassResetController extends ControllerBase * @throws NotFoundException * @throws InvalidArgumentException */ - protected function initialize() + protected function initialize(): void { $this->trackService = $this->dic->get(TrackService::class); $this->trackRequest = $this->trackService->getTrackRequest($this->controllerName); diff --git a/app/modules/web/Controllers/UserProfileController.php b/app/modules/web/Controllers/UserProfileController.php index 5b027375..70a4e773 100644 --- a/app/modules/web/Controllers/UserProfileController.php +++ b/app/modules/web/Controllers/UserProfileController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -28,6 +28,7 @@ use DI\DependencyException; use DI\NotFoundException; use Exception; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -58,29 +59,32 @@ final class UserProfileController extends ControllerBase implements CrudControll { use JsonTrait, ItemTrait; - /** - * @var UserProfileService - */ - protected $userProfileService; + protected ?UserProfileService $userProfileService = null; /** * Search action * * @return bool - * @throws DependencyException - * @throws NotFoundException - * @throws ConstraintException - * @throws QueryException - * @throws SPException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function searchAction() + public function searchAction(): bool { - if (!$this->acl->checkUserAccess(Acl::PROFILE_SEARCH)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PROFILE_SEARCH)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->addTemplate('datagrid-table', 'grid'); - $this->view->assign('index', $this->request->analyzeInt('activetab', 0)); + $this->view->assign( + 'index', + $this->request->analyzeInt('activetab', 0) + ); $this->view->assign('data', $this->getSearchGrid()); return $this->returnJsonResponseData(['html' => $this->render()]); @@ -96,23 +100,33 @@ final class UserProfileController extends ControllerBase implements CrudControll */ protected function getSearchGrid(): DataGridInterface { - $itemSearchData = $this->getSearchData($this->configData->getAccountCount(), $this->request); + $itemSearchData = $this->getSearchData( + $this->configData->getAccountCount(), + $this->request + ); $userProfileGrid = $this->dic->get(UserProfileGrid::class); - return $userProfileGrid->updatePager($userProfileGrid->getGrid($this->userProfileService->search($itemSearchData)), $itemSearchData); + return $userProfileGrid->updatePager( + $userProfileGrid->getGrid($this->userProfileService->search($itemSearchData)), + $itemSearchData + ); } /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function createAction() + public function createAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::PROFILE_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PROFILE_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('New Profile')); @@ -121,13 +135,19 @@ final class UserProfileController extends ControllerBase implements CrudControll $this->setViewData(); - $this->eventDispatcher->notifyEvent('show.userProfile.create', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.userProfile.create', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -146,19 +166,32 @@ final class UserProfileController extends ControllerBase implements CrudControll * @throws SPException * @throws ServiceException */ - protected function setViewData(?int $profileId = null) + protected function setViewData(?int $profileId = null): void { $this->view->addTemplate('user_profile', 'itemshow'); - $profile = $profileId ? $this->userProfileService->getById($profileId) : new UserProfileData(); + $profile = $profileId + ? $this->userProfileService->getById($profileId) + : new UserProfileData(); $this->view->assign('profile', $profile); - $this->view->assign('profileData', $profile->getProfile() ?: new ProfileData()); + $this->view->assign( + 'profileData', + $profile->getProfile() ?: new ProfileData() + ); - $this->view->assign('nextAction', Acl::getActionRoute(Acl::ACCESS_MANAGE)); + $this->view->assign( + 'nextAction', + Acl::getActionRoute(ActionsInterface::ACCESS_MANAGE) + ); if ($this->view->isView === true) { - $this->view->assign('usedBy', $this->userProfileService->getUsersForProfile($profileId)); + $this->view->assign( + 'usedBy', + $profileId + ? $this->userProfileService->getUsersForProfile($profileId) + : [] + ); $this->view->assign('disabled', 'disabled'); $this->view->assign('readonly', 'readonly'); @@ -167,8 +200,14 @@ final class UserProfileController extends ControllerBase implements CrudControll $this->view->assign('readonly', false); } - $this->view->assign('showViewCustomPass', $this->acl->checkUserAccess(Acl::CUSTOMFIELD_VIEW_PASS)); - $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::PROFILE, $profileId)); + $this->view->assign( + 'showViewCustomPass', + $this->acl->checkUserAccess(ActionsInterface::CUSTOMFIELD_VIEW_PASS) + ); + $this->view->assign( + 'customFields', + $this->getCustomFieldsForItem(ActionsInterface::PROFILE, $profileId) + ); } /** @@ -177,14 +216,18 @@ final class UserProfileController extends ControllerBase implements CrudControll * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function editAction(int $id) + public function editAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::PROFILE_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PROFILE_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('Edit Profile')); @@ -193,13 +236,19 @@ final class UserProfileController extends ControllerBase implements CrudControll $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.userProfile.edit', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.userProfile.edit', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -211,28 +260,42 @@ final class UserProfileController extends ControllerBase implements CrudControll * @param int|null $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function deleteAction(?int $id = null) + public function deleteAction(?int $id = null): bool { try { - if (!$this->acl->checkUserAccess(Acl::PROFILE_DELETE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PROFILE_DELETE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } if ($id === null) { - $this->userProfileService->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); + $this->userProfileService + ->deleteByIdBatch($this->getItemsIdFromRequest($this->request)); $this->eventDispatcher->notifyEvent( 'delete.userProfile.selection', - new Event($this, EventMessage::factory() - ->addDescription(__u('Profiles deleted'))) + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Profiles deleted')) + ) ); - $this->deleteCustomFieldsForItem(Acl::PROFILE, $id); + $this->deleteCustomFieldsForItem( + ActionsInterface::PROFILE, + $id + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Profiles deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Profiles deleted') + ); } $this->userProfileService->delete($id); @@ -240,19 +303,31 @@ final class UserProfileController extends ControllerBase implements CrudControll $this->eventDispatcher->notifyEvent( 'delete.userProfile', - new Event($this, EventMessage::factory() - ->addDescription(__u('Profile deleted')) - ->addDetail(__u('Profile'), $id) - ->addExtra('userProfileId', $id)) + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Profile deleted')) + ->addDetail(__u('Profile'), $id) + ->addExtra('userProfileId', $id) + ) ); - $this->deleteCustomFieldsForItem(Acl::PROFILE, $id); + $this->deleteCustomFieldsForItem( + ActionsInterface::PROFILE, + $id + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Profile deleted')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Profile deleted') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -260,38 +335,56 @@ final class UserProfileController extends ControllerBase implements CrudControll /** * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveCreateAction() + public function saveCreateAction(): bool { try { - if (!$this->acl->checkUserAccess(Acl::PROFILE_CREATE)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PROFILE_CREATE)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new UserProfileForm($this->dic); - $form->validate(Acl::PROFILE_CREATE); + $form->validate(ActionsInterface::PROFILE_CREATE); $profileData = $form->getItemData(); $id = $this->userProfileService->create($profileData); - $this->eventDispatcher->notifyEvent('create.userProfile', - new Event($this, EventMessage::factory() - ->addDescription(__u('Profile added')) - ->addDetail(__u('Name'), $profileData->getName())) + $this->eventDispatcher->notifyEvent( + 'create.userProfile', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Profile added')) + ->addDetail(__u('Name'), $profileData->getName()) + ) ); - $this->addCustomFieldsForItem(Acl::PROFILE, $id, $this->request); + $this->addCustomFieldsForItem( + ActionsInterface::PROFILE, + $id, + $this->request + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Profile added')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Profile added') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -303,39 +396,57 @@ final class UserProfileController extends ControllerBase implements CrudControll * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function saveEditAction(int $id) + public function saveEditAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::PROFILE_EDIT)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PROFILE_EDIT)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $form = new UserProfileForm($this->dic, $id); - $form->validate(Acl::PROFILE_EDIT); + $form->validate(ActionsInterface::PROFILE_EDIT); $profileData = $form->getItemData(); $this->userProfileService->update($profileData); - $this->eventDispatcher->notifyEvent('edit.userProfile', - new Event($this, EventMessage::factory() - ->addDescription(__u('Profile updated')) - ->addDetail(__u('Name'), $profileData->getName()) - ->addExtra('userProfileId', $id)) + $this->eventDispatcher->notifyEvent( + 'edit.userProfile', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Profile updated')) + ->addDetail(__u('Name'), $profileData->getName()) + ->addExtra('userProfileId', $id) + ) ); - $this->updateCustomFieldsForItem(Acl::PROFILE, $id, $this->request); + $this->updateCustomFieldsForItem( + ActionsInterface::PROFILE, + $id, + $this->request + ); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Profile updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Profile updated') + ); } catch (ValidationException $e) { return $this->returnJsonResponseException($e); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -347,14 +458,18 @@ final class UserProfileController extends ControllerBase implements CrudControll * @param int $id * * @return bool - * @throws DependencyException - * @throws NotFoundException + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \JsonException */ - public function viewAction(int $id) + public function viewAction(int $id): bool { try { - if (!$this->acl->checkUserAccess(Acl::PROFILE_VIEW)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation')); + if (!$this->acl->checkUserAccess(ActionsInterface::PROFILE_VIEW)) { + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('You don\'t have permission to do this operation') + ); } $this->view->assign('header', __('View Profile')); @@ -362,13 +477,19 @@ final class UserProfileController extends ControllerBase implements CrudControll $this->setViewData($id); - $this->eventDispatcher->notifyEvent('show.userProfile', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.userProfile', + new Event($this) + ); return $this->returnJsonResponseData(['html' => $this->render()]); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -382,7 +503,7 @@ final class UserProfileController extends ControllerBase implements CrudControll * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); diff --git a/app/modules/web/Controllers/UserSettingsGeneralController.php b/app/modules/web/Controllers/UserSettingsGeneralController.php index 86e6f3ee..fd0d7025 100644 --- a/app/modules/web/Controllers/UserSettingsGeneralController.php +++ b/app/modules/web/Controllers/UserSettingsGeneralController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -42,17 +42,15 @@ final class UserSettingsGeneralController extends SimpleControllerBase { use JsonTrait; - /** - * @var UserService - */ - protected $userService; + protected ?UserService $userService = null; /** * @return bool * @throws DependencyException * @throws NotFoundException + * @throws \JsonException */ - public function saveAction() + public function saveAction(): bool { try { $userData = $this->session->getUserData(); @@ -76,11 +74,17 @@ final class UserSettingsGeneralController extends SimpleControllerBase // Guardar las preferencias en la sesión $userData->setPreferences($userPreferencesData); - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Preferences updated')); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS, + __u('Preferences updated') + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); return $this->returnJsonResponseException($e); } @@ -93,7 +97,7 @@ final class UserSettingsGeneralController extends SimpleControllerBase * @throws NotFoundException * @throws SessionTimeout */ - protected function initialize() + protected function initialize(): void { $this->checks(); diff --git a/app/modules/web/Controllers/UserSettingsManagerController.php b/app/modules/web/Controllers/UserSettingsManagerController.php index dcacd75f..467ef098 100644 --- a/app/modules/web/Controllers/UserSettingsManagerController.php +++ b/app/modules/web/Controllers/UserSettingsManagerController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Controllers; @@ -27,6 +27,7 @@ namespace SP\Modules\Web\Controllers; use DI\DependencyException; use DI\NotFoundException; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventDispatcherInterface; use SP\Core\Exceptions\SessionTimeout; @@ -45,16 +46,13 @@ use SP\Services\Auth\AuthException; */ final class UserSettingsManagerController extends ControllerBase implements ExtensibleTabControllerInterface { - /** - * @var TabsHelper - */ - protected $tabsHelper; + protected ?TabsHelper $tabsHelper = null; /** * @throws DependencyException * @throws NotFoundException */ - public function indexAction() + public function indexAction(): void { $this->getTabs(); } @@ -65,15 +63,21 @@ final class UserSettingsManagerController extends ControllerBase implements Exte * @throws DependencyException * @throws NotFoundException */ - protected function getTabs() + protected function getTabs(): void { $this->tabsHelper = $this->dic->get(TabsHelper::class); $this->tabsHelper->addTab($this->getUserPreferences()); - $this->eventDispatcher->notifyEvent('show.userSettings', new Event($this)); + $this->eventDispatcher->notifyEvent( + 'show.userSettings', + new Event($this) + ); - $this->tabsHelper->renderTabs(Acl::getActionRoute(Acl::USERSETTINGS), $this->request->analyzeInt('tabIndex', 0)); + $this->tabsHelper->renderTabs( + Acl::getActionRoute(ActionsInterface::USERSETTINGS), + $this->request->analyzeInt('tabIndex', 0) + ); $this->view(); } @@ -109,7 +113,7 @@ final class UserSettingsManagerController extends ControllerBase implements Exte /** * @param DataTab $tab */ - public function addTab(DataTab $tab) + public function addTab(DataTab $tab): void { $this->tabsHelper->addTab($tab); } @@ -125,7 +129,7 @@ final class UserSettingsManagerController extends ControllerBase implements Exte /** * @return void */ - public function displayView() + public function displayView(): void { $this->view(); } @@ -144,7 +148,7 @@ final class UserSettingsManagerController extends ControllerBase implements Exte * @throws SessionTimeout * @throws AuthException */ - protected function initialize() + protected function initialize(): void { $this->checkLoggedIn(); } diff --git a/app/modules/web/Forms/AccountForm.php b/app/modules/web/Forms/AccountForm.php index e9628838..a172e919 100644 --- a/app/modules/web/Forms/AccountForm.php +++ b/app/modules/web/Forms/AccountForm.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; @@ -40,14 +40,8 @@ use SP\Services\Account\AccountRequest; */ final class AccountForm extends FormBase implements FormInterface { - /** - * @var AccountRequest - */ - protected $accountRequest; - /** - * @var AccountPresetService - */ - private $accountPresetService; + protected ?AccountRequest $accountRequest = null; + private ?AccountPresetService $accountPresetService = null; /** * Validar el formulario @@ -96,7 +90,7 @@ final class AccountForm extends FormBase implements FormInterface * * @return void */ - protected function analyzeRequestData() + protected function analyzeRequestData(): void { $this->accountRequest->id = $this->itemId; $this->accountRequest->name = $this->request->analyzeString('name'); @@ -122,7 +116,7 @@ final class AccountForm extends FormBase implements FormInterface /** * @throws ValidationException */ - private function checkPassword() + private function checkPassword(): void { if ($this->accountRequest->parentId > 0) { return; @@ -137,10 +131,7 @@ final class AccountForm extends FormBase implements FormInterface } } - /** - * analyzeItems - */ - private function analyzeItems() + private function analyzeItems(): void { if ($this->request->analyzeInt('other_users_view_update') === 1) { $this->accountRequest->usersView = $this->request->analyzeArray('other_users_view', null, []); @@ -166,7 +157,7 @@ final class AccountForm extends FormBase implements FormInterface /** * @throws ValidationException */ - private function checkCommon() + private function checkCommon(): void { if (!$this->accountRequest->name) { throw new ValidationException(__u('An account name needed')); @@ -181,10 +172,7 @@ final class AccountForm extends FormBase implements FormInterface } } - /** - * analyzeBulkEdit - */ - private function analyzeBulkEdit() + private function analyzeBulkEdit(): void { if ($this->request->analyzeBool('clear_permission_users_view', false)) { $this->accountRequest->usersView = []; @@ -203,18 +191,12 @@ final class AccountForm extends FormBase implements FormInterface } } - /** - * @return AccountRequest - */ - public function getItemData() + public function getItemData(): ?AccountRequest { return $this->accountRequest; } - /** - * @param ContainerInterface $dic - */ - protected function initialize(ContainerInterface $dic) + protected function initialize(ContainerInterface $dic): void { $this->accountPresetService = $dic->get(AccountPresetService::class); $this->accountRequest = new AccountRequest(); diff --git a/app/modules/web/Forms/AuthTokenForm.php b/app/modules/web/Forms/AuthTokenForm.php index 6046968b..cbe88961 100644 --- a/app/modules/web/Forms/AuthTokenForm.php +++ b/app/modules/web/Forms/AuthTokenForm.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; @@ -36,14 +36,8 @@ use SP\Services\AuthToken\AuthTokenService; */ final class AuthTokenForm extends FormBase implements FormInterface { - /** - * @var AuthTokenData - */ - protected $authTokenData; - /** - * @var bool - */ - protected $refresh = false; + protected ?AuthTokenData $authTokenData = null; + protected bool $refresh = false; /** * Validar el formulario @@ -71,7 +65,7 @@ final class AuthTokenForm extends FormBase implements FormInterface * * @return void */ - protected function analyzeRequestData() + protected function analyzeRequestData(): void { $this->refresh = $this->request->analyzeBool('refreshtoken', false); @@ -85,7 +79,7 @@ final class AuthTokenForm extends FormBase implements FormInterface /** * @throws ValidationException */ - protected function checkCommon() + protected function checkCommon(): void { if (0 === $this->authTokenData->getUserId()) { throw new ValidationException(__u('User not set')); @@ -95,25 +89,19 @@ final class AuthTokenForm extends FormBase implements FormInterface throw new ValidationException(__u('Action not set')); } - if ((AuthTokenService::isSecuredAction($this->authTokenData->getActionId()) || $this->isRefresh()) - && empty($this->authTokenData->getHash()) - ) { + if (empty($this->authTokenData->getHash()) + && (AuthTokenService::isSecuredAction($this->authTokenData->getActionId()) + || $this->isRefresh())) { throw new ValidationException(__u('Password cannot be blank')); } } - /** - * @return bool - */ public function isRefresh(): bool { return $this->refresh; } - /** - * @return AuthTokenData - */ - public function getItemData() + public function getItemData(): ?AuthTokenData { return $this->authTokenData; } diff --git a/app/modules/web/Forms/CategoryForm.php b/app/modules/web/Forms/CategoryForm.php index 38e17bbe..b5f0019a 100644 --- a/app/modules/web/Forms/CategoryForm.php +++ b/app/modules/web/Forms/CategoryForm.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; @@ -35,10 +35,7 @@ use SP\DataModel\CategoryData; */ final class CategoryForm extends FormBase implements FormInterface { - /** - * @var CategoryData - */ - protected $categoryData; + protected ?CategoryData $categoryData = null; /** * Validar el formulario @@ -66,28 +63,28 @@ final class CategoryForm extends FormBase implements FormInterface * * @return void */ - protected function analyzeRequestData() + protected function analyzeRequestData(): void { $this->categoryData = new CategoryData(); - $this->categoryData->setId($this->itemId); - $this->categoryData->setName($this->request->analyzeString('name')); - $this->categoryData->setDescription($this->request->analyzeString('description')); + $this->categoryData + ->setId($this->itemId); + $this->categoryData + ->setName($this->request->analyzeString('name')); + $this->categoryData + ->setDescription($this->request->analyzeString('description')); } /** * @throws ValidationException */ - protected function checkCommon() + protected function checkCommon(): void { if (!$this->categoryData->getName()) { throw new ValidationException(__u('A category name needed')); } } - /** - * @return CategoryData - */ - public function getItemData() + public function getItemData(): ?CategoryData { return $this->categoryData; } diff --git a/app/modules/web/Forms/ClientForm.php b/app/modules/web/Forms/ClientForm.php index adf86ae2..35ad743b 100644 --- a/app/modules/web/Forms/ClientForm.php +++ b/app/modules/web/Forms/ClientForm.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; @@ -35,10 +35,7 @@ use SP\DataModel\ClientData; */ final class ClientForm extends FormBase implements FormInterface { - /** - * @var ClientData - */ - protected $clientData; + protected ?ClientData $clientData = null; /** * Validar el formulario @@ -66,7 +63,7 @@ final class ClientForm extends FormBase implements FormInterface * * @return void */ - protected function analyzeRequestData() + protected function analyzeRequestData(): void { $this->clientData = new ClientData(); $this->clientData->setId($this->itemId); @@ -78,17 +75,14 @@ final class ClientForm extends FormBase implements FormInterface /** * @throws ValidationException */ - protected function checkCommon() + protected function checkCommon(): void { if (!$this->clientData->getName()) { throw new ValidationException(__u('A client name needed')); } } - /** - * @return ClientData - */ - public function getItemData() + public function getItemData(): ?ClientData { return $this->clientData; } diff --git a/app/modules/web/Forms/CustomFieldDefForm.php b/app/modules/web/Forms/CustomFieldDefForm.php index c43ce1cf..b41373a5 100644 --- a/app/modules/web/Forms/CustomFieldDefForm.php +++ b/app/modules/web/Forms/CustomFieldDefForm.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; @@ -35,10 +35,7 @@ use SP\DataModel\CustomFieldDefinitionData; */ final class CustomFieldDefForm extends FormBase implements FormInterface { - /** - * @var CustomFieldDefinitionData - */ - protected $customFieldDefData; + protected ?CustomFieldDefinitionData $customFieldDefData; /** * Validar el formulario @@ -66,7 +63,7 @@ final class CustomFieldDefForm extends FormBase implements FormInterface * * @return void */ - protected function analyzeRequestData() + protected function analyzeRequestData(): void { $this->customFieldDefData = new CustomFieldDefinitionData(); $this->customFieldDefData->setId($this->itemId); @@ -81,7 +78,7 @@ final class CustomFieldDefForm extends FormBase implements FormInterface /** * @throws ValidationException */ - protected function checkCommon() + protected function checkCommon(): void { if (!$this->customFieldDefData->getName()) { throw new ValidationException(__u('Field name not set')); @@ -96,10 +93,7 @@ final class CustomFieldDefForm extends FormBase implements FormInterface } } - /** - * @return CustomFieldDefinitionData - */ - public function getItemData() + public function getItemData(): ?CustomFieldDefinitionData { return $this->customFieldDefData; } diff --git a/app/modules/web/Forms/FormBase.php b/app/modules/web/Forms/FormBase.php index 89136b13..2abf6283 100644 --- a/app/modules/web/Forms/FormBase.php +++ b/app/modules/web/Forms/FormBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,16 +19,15 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; use Psr\Container\ContainerInterface; use SP\Config\Config; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Context\ContextInterface; -use SP\Core\Context\SessionContext; use SP\Http\Request; /** @@ -38,26 +37,11 @@ use SP\Http\Request; */ abstract class FormBase { - /** - * @var int - */ - protected $itemId; - /** - * @var Config - */ - protected $config; - /** - * @var ConfigData - */ - protected $configData; - /** - * @var SessionContext - */ - protected $context; - /** - * @var Request - */ - protected $request; + protected ?int $itemId; + protected Config $config; + protected ConfigDataInterface $configData; + protected ContextInterface $context; + protected Request $request; /** * FormBase constructor. @@ -65,7 +49,10 @@ abstract class FormBase * @param ContainerInterface $container * @param int|null $itemId */ - public function __construct(ContainerInterface $container, ?int $itemId = null) + public function __construct( + ContainerInterface $container, + ?int $itemId = null + ) { $this->config = $container->get(Config::class); $this->configData = $this->config->getConfigData(); @@ -81,8 +68,6 @@ abstract class FormBase /** * Analizar los datos de la petición HTTP - * - * @return void */ abstract protected function analyzeRequestData(); } \ No newline at end of file diff --git a/app/modules/web/Forms/FormInterface.php b/app/modules/web/Forms/FormInterface.php index e2318105..baeab5f4 100644 --- a/app/modules/web/Forms/FormInterface.php +++ b/app/modules/web/Forms/FormInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; diff --git a/app/modules/web/Forms/ItemsPresetForm.php b/app/modules/web/Forms/ItemsPresetForm.php index b57c992a..3bb39599 100644 --- a/app/modules/web/Forms/ItemsPresetForm.php +++ b/app/modules/web/Forms/ItemsPresetForm.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; @@ -43,10 +43,7 @@ use SP\Services\ItemPreset\ItemPresetRequest; */ final class ItemsPresetForm extends FormBase implements FormInterface { - /** - * @var ItemPresetRequest - */ - protected $itemPresetRequest; + protected ?ItemPresetRequest $itemPresetRequest = null; /** * Validar el formulario @@ -75,7 +72,7 @@ final class ItemsPresetForm extends FormBase implements FormInterface * @return void * @throws ValidationException */ - protected function analyzeRequestData() + protected function analyzeRequestData(): void { $itemPresetData = new ItemPresetData(); @@ -101,16 +98,28 @@ final class ItemsPresetForm extends FormBase implements FormInterface switch ($itemPresetData->getType()) { case ItemPresetInterface::ITEM_TYPE_ACCOUNT_PERMISSION: - $this->itemPresetRequest = new ItemPresetRequest($itemPresetData, $this->makePermissionPreset()); + $this->itemPresetRequest = new ItemPresetRequest( + $itemPresetData, + $this->makePermissionPreset() + ); break; case ItemPresetInterface::ITEM_TYPE_ACCOUNT_PRIVATE: - $this->itemPresetRequest = new ItemPresetRequest($itemPresetData, $this->makePrivatePreset()); + $this->itemPresetRequest = new ItemPresetRequest( + $itemPresetData, + $this->makePrivatePreset() + ); break; case ItemPresetInterface::ITEM_TYPE_SESSION_TIMEOUT: - $this->itemPresetRequest = new ItemPresetRequest($itemPresetData, $this->makeSessionTimeoutPreset()); + $this->itemPresetRequest = new ItemPresetRequest( + $itemPresetData, + $this->makeSessionTimeoutPreset() + ); break; case ItemPresetInterface::ITEM_TYPE_ACCOUNT_PASSWORD: - $this->itemPresetRequest = new ItemPresetRequest($itemPresetData, $this->makePasswordPreset()); + $this->itemPresetRequest = new ItemPresetRequest( + $itemPresetData, + $this->makePasswordPreset() + ); break; default: throw new ValidationException(__u('Value type not set or incorrect')); @@ -177,10 +186,8 @@ final class ItemsPresetForm extends FormBase implements FormInterface $regex = $this->request->analyzeUnsafeString('regex'); - if (!empty($regex)) { - if (Validator::isRegex($regex) === false) { - throw new ValidationException(__u('Invalid regular expression')); - } + if (!empty($regex) && Validator::isRegex($regex) === false) { + throw new ValidationException(__u('Invalid regular expression')); } $password->setRegex($regex); @@ -197,7 +204,7 @@ final class ItemsPresetForm extends FormBase implements FormInterface /** * @throws ValidationException */ - protected function checkCommon() + protected function checkCommon(): void { $itemPresetData = $this->itemPresetRequest->getItemPresetData(); @@ -209,10 +216,7 @@ final class ItemsPresetForm extends FormBase implements FormInterface } } - /** - * @return ItemPresetRequest - */ - public function getItemData() + public function getItemData(): ?ItemPresetRequest { return $this->itemPresetRequest; } diff --git a/app/modules/web/Forms/NotificationForm.php b/app/modules/web/Forms/NotificationForm.php index d6134482..e6f2531b 100644 --- a/app/modules/web/Forms/NotificationForm.php +++ b/app/modules/web/Forms/NotificationForm.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; @@ -36,10 +36,7 @@ use SP\DataModel\NotificationData; */ final class NotificationForm extends FormBase implements FormInterface { - /** - * @var NotificationData - */ - protected $notificationData; + protected ?NotificationData $notificationData = null; /** * Validar el formulario @@ -67,7 +64,7 @@ final class NotificationForm extends FormBase implements FormInterface * * @return void */ - protected function analyzeRequestData() + protected function analyzeRequestData(): void { $this->notificationData = new NotificationData(); $this->notificationData->setId($this->itemId); @@ -81,8 +78,8 @@ final class NotificationForm extends FormBase implements FormInterface $this->notificationData->setUserId($this->request->analyzeInt('notification_user')); $this->notificationData->setChecked($this->request->analyzeBool('notification_checkout', false)); - if ($this->context->getUserData()->getIsAdminApp() - && $this->notificationData->getUserId() === 0 + if ($this->notificationData->getUserId() === 0 + && $this->context->getUserData()->getIsAdminApp() ) { $this->notificationData->setOnlyAdmin($this->request->analyzeBool('notification_onlyadmin', false)); $this->notificationData->setSticky($this->request->analyzeBool('notification_sticky', false)); @@ -92,7 +89,7 @@ final class NotificationForm extends FormBase implements FormInterface /** * @throws ValidationException */ - private function checkCommon() + private function checkCommon(): void { if (!$this->notificationData->getComponent()) { throw new ValidationException(__u('A component is needed')); @@ -113,10 +110,7 @@ final class NotificationForm extends FormBase implements FormInterface } } - /** - * @return NotificationData - */ - public function getItemData() + public function getItemData(): ?NotificationData { return $this->notificationData; } diff --git a/app/modules/web/Forms/PublicLinkForm.php b/app/modules/web/Forms/PublicLinkForm.php index a57e56b7..ee1c739a 100644 --- a/app/modules/web/Forms/PublicLinkForm.php +++ b/app/modules/web/Forms/PublicLinkForm.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; @@ -36,10 +36,7 @@ use SP\Services\PublicLink\PublicLinkService; */ final class PublicLinkForm extends FormBase implements FormInterface { - /** - * @var PublicLinkData - */ - protected $publicLinkData; + protected ?PublicLinkData $publicLinkData = null; /** * Validar el formulario @@ -67,7 +64,7 @@ final class PublicLinkForm extends FormBase implements FormInterface * * @return void */ - protected function analyzeRequestData() + protected function analyzeRequestData(): void { $this->publicLinkData = new PublicLinkData(); $this->publicLinkData->setId($this->itemId); @@ -79,17 +76,14 @@ final class PublicLinkForm extends FormBase implements FormInterface /** * @throws ValidationException */ - protected function checkCommon() + protected function checkCommon(): void { if (!$this->publicLinkData->getItemId()) { throw new ValidationException(__u('An account is needed')); } } - /** - * @return mixed - */ - public function getItemData() + public function getItemData(): ?PublicLinkData { return $this->publicLinkData; } diff --git a/app/modules/web/Forms/TagForm.php b/app/modules/web/Forms/TagForm.php index 663bc21e..a113dd42 100644 --- a/app/modules/web/Forms/TagForm.php +++ b/app/modules/web/Forms/TagForm.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; @@ -35,10 +35,7 @@ use SP\DataModel\TagData; */ final class TagForm extends FormBase implements FormInterface { - /** - * @var TagData - */ - protected $tagData; + protected ?TagData $tagData = null; /** * Validar el formulario @@ -66,7 +63,7 @@ final class TagForm extends FormBase implements FormInterface * * @return void */ - protected function analyzeRequestData() + protected function analyzeRequestData(): void { $this->tagData = new TagData(); $this->tagData->setId($this->itemId); @@ -76,17 +73,14 @@ final class TagForm extends FormBase implements FormInterface /** * @throws ValidationException */ - protected function checkCommon() + protected function checkCommon(): void { if (!$this->tagData->getName()) { throw new ValidationException(__u('A tag name is needed')); } } - /** - * @return TagData - */ - public function getItemData() + public function getItemData(): ?TagData { return $this->tagData; } diff --git a/app/modules/web/Forms/UserForm.php b/app/modules/web/Forms/UserForm.php index cc39b487..f88a7b60 100644 --- a/app/modules/web/Forms/UserForm.php +++ b/app/modules/web/Forms/UserForm.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; @@ -35,14 +35,8 @@ use SP\DataModel\UserData; */ final class UserForm extends FormBase implements FormInterface { - /** - * @var UserData - */ - protected $userData; - /** - * @var int - */ - protected $isLdap = 0; + protected ?UserData $userData = null; + protected int $isLdap = 0; /** * Validar el formulario @@ -81,7 +75,7 @@ final class UserForm extends FormBase implements FormInterface * * @return void */ - protected function analyzeRequestData() + protected function analyzeRequestData(): void { $this->isLdap = $this->request->analyzeInt('isLdap', 0); @@ -105,7 +99,7 @@ final class UserForm extends FormBase implements FormInterface /** * @throws ValidationException */ - protected function checkCommon() + protected function checkCommon(): void { if (!$this->isLdap && !$this->userData->getName()) { throw new ValidationException(__u('An username is needed')); @@ -139,13 +133,13 @@ final class UserForm extends FormBase implements FormInterface { return $this->configData->isDemoEnabled() && $this->itemId === 2 // FIXME: Ugly!! - && $this->context->getUserData()->getIsAdminApp() === 0; + && $this->context->getUserData()->getIsAdminApp(); } /** * @throws ValidationException */ - protected function checkPass() + protected function checkPass(): void { $userPassR = $this->request->analyzeEncrypted('password_repeat'); @@ -165,7 +159,7 @@ final class UserForm extends FormBase implements FormInterface /** * @throws ValidationException */ - protected function checkDelete() + protected function checkDelete(): void { if ($this->isDemo()) { throw new ValidationException(__u('Ey, this is a DEMO!!')); @@ -173,25 +167,20 @@ final class UserForm extends FormBase implements FormInterface $userData = $this->context->getUserData(); - if ((is_array($this->itemId) && in_array($userData->getId(), $this->itemId)) - || $this->itemId === $userData->getId() + if ($this->itemId === $userData->getId() + || (is_array($this->itemId) + && in_array($userData->getId(), $this->itemId, true)) ) { throw new ValidationException(__u('Unable to delete, user in use')); } } - /** - * @return UserData - */ - public function getItemData() + public function getItemData(): ?UserData { return $this->userData; } - /** - * @return int - */ - public function getIsLdap() + public function getIsLdap(): int { return $this->isLdap; } diff --git a/app/modules/web/Forms/UserGroupForm.php b/app/modules/web/Forms/UserGroupForm.php index a2866232..229ffadc 100644 --- a/app/modules/web/Forms/UserGroupForm.php +++ b/app/modules/web/Forms/UserGroupForm.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; @@ -35,10 +35,7 @@ use SP\DataModel\UserGroupData; */ final class UserGroupForm extends FormBase implements FormInterface { - /** - * @var UserGroupData - */ - protected $groupData; + protected ?UserGroupData $groupData = null; /** * Validar el formulario @@ -66,7 +63,7 @@ final class UserGroupForm extends FormBase implements FormInterface * * @return void */ - protected function analyzeRequestData() + protected function analyzeRequestData(): void { $this->groupData = new UserGroupData(); $this->groupData->setId($this->itemId); @@ -78,17 +75,14 @@ final class UserGroupForm extends FormBase implements FormInterface /** * @throws ValidationException */ - protected function checkCommon() + protected function checkCommon(): void { if (!$this->groupData->getName()) { throw new ValidationException(__u('A group name is needed')); } } - /** - * @return UserGroupData - */ - public function getItemData() + public function getItemData(): ?UserGroupData { return $this->groupData; } diff --git a/app/modules/web/Forms/UserProfileForm.php b/app/modules/web/Forms/UserProfileForm.php index fec36f6c..19a14d03 100644 --- a/app/modules/web/Forms/UserProfileForm.php +++ b/app/modules/web/Forms/UserProfileForm.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web\Forms; @@ -36,10 +36,7 @@ use SP\DataModel\UserProfileData; */ final class UserProfileForm extends FormBase implements FormInterface { - /** - * @var UserProfileData - */ - protected $userProfileData; + protected ?UserProfileData $userProfileData = null; /** * Validar el formulario @@ -67,7 +64,7 @@ final class UserProfileForm extends FormBase implements FormInterface * * @return void */ - protected function analyzeRequestData() + protected function analyzeRequestData(): void { $profileData = new ProfileData(); $profileData->setAccAdd($this->request->analyzeBool('profile_accadd', false)); @@ -110,17 +107,14 @@ final class UserProfileForm extends FormBase implements FormInterface /** * @throws ValidationException */ - protected function checkCommon() + protected function checkCommon(): void { if (!$this->userProfileData->getName()) { throw new ValidationException(__u('A profile name is needed')); } } - /** - * @return UserProfileData - */ - public function getItemData() + public function getItemData(): ?UserProfileData { return $this->userProfileData; } diff --git a/app/modules/web/Init.php b/app/modules/web/Init.php index 3d92dd85..f2fa060e 100644 --- a/app/modules/web/Init.php +++ b/app/modules/web/Init.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,18 +19,16 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Modules\Web; use Defuse\Crypto\Exception\CryptoException; -use Defuse\Crypto\Exception\EnvironmentIsBrokenException; -use DI\DependencyException; -use DI\NotFoundException; use Exception; use Psr\Container\ContainerInterface; use SP\Bootstrap; +use SP\Core\Context\ContextBase; use SP\Core\Context\ContextInterface; use SP\Core\Context\SessionContext; use SP\Core\Crypt\CryptSessionHandler; @@ -42,14 +40,12 @@ use SP\Core\Exceptions\InitializationException; use SP\Core\Exceptions\InvalidArgumentException; use SP\Core\Exceptions\NoSuchPropertyException; use SP\Core\Exceptions\QueryException; -use SP\Core\Exceptions\SPException; use SP\Core\Language; use SP\Core\ModuleBase; use SP\Core\UI\ThemeInterface; use SP\DataModel\ItemPreset\SessionTimeout; use SP\Http\Address; use SP\Plugin\PluginManager; -use SP\Repositories\NoSuchItemException; use SP\Services\Crypt\SecureSessionService; use SP\Services\ItemPreset\ItemPresetInterface; use SP\Services\ItemPreset\ItemPresetService; @@ -63,9 +59,6 @@ use SP\Util\HttpUtil; /** * Class Init - * - * @property itemPresetService - * @package SP\Modules\Web */ final class Init extends ModuleBase { @@ -73,7 +66,7 @@ final class Init extends ModuleBase * List of controllers that don't need to perform fully initialization * like: install/database checks, session/event handlers initialization */ - const PARTIAL_INIT = [ + private const PARTIAL_INIT = [ 'resource', 'install', 'bootstrap', @@ -85,44 +78,18 @@ final class Init extends ModuleBase /** * List of controllers that don't need to update the user's session activity */ - const NO_SESSION_ACTIVITY = ['items', 'login']; - /** - * @var CSRF - */ - private $csrf; - /** - * @var SessionContext - */ - private $context; - /** - * @var ThemeInterface - */ - private $theme; - /** - * @var Language - */ - private $language; - /** - * @var SecureSessionService - */ - private $secureSessionService; - /** - * @var PluginManager - */ - private $pluginManager; - /** - * @var ItemPresetService - */ - private $itemPresetService; - /** - * @var bool - */ - private $isIndex = false; + private const NO_SESSION_ACTIVITY = ['items', 'login']; + private CSRF $csrf; + private SessionContext $context; + private ThemeInterface $theme; + private Language $language; + private SecureSessionService $secureSessionService; + private PluginManager $pluginManager; + private ItemPresetService $itemPresetService; + private bool $isIndex = false; /** * Init constructor. - * - * @param ContainerInterface $container */ public function __construct(ContainerInterface $container) { @@ -140,18 +107,16 @@ final class Init extends ModuleBase /** * Initialize Web App * - * @param string $controller - * - * @throws DependencyException - * @throws NotFoundException - * @throws EnvironmentIsBrokenException - * @throws ConstraintException - * @throws QueryException - * @throws SPException - * @throws NoSuchItemException - * @throws Exception + * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException + * @throws \JsonException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\InitializationException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + * @throws \SP\Repositories\NoSuchItemException + * @throws \SP\Storage\File\FileException */ - public function initialize(string $controller) + public function initialize(string $controller): void { logger(__METHOD__); @@ -166,7 +131,7 @@ final class Init extends ModuleBase if ($isReload) { logger('Browser reload'); - $this->context->setAppStatus(SessionContext::APP_STATUS_RELOADED); + $this->context->setAppStatus(ContextBase::APP_STATUS_RELOADED); // Cargar la configuración $this->config->loadConfig(true); @@ -253,7 +218,7 @@ final class Init extends ModuleBase $this->pluginManager->loadPlugins(); if ($this->context->isLoggedIn() - && $this->context->getAppStatus() === SessionContext::APP_STATUS_RELOADED + && $this->context->getAppStatus() === ContextBase::APP_STATUS_RELOADED ) { logger('Reload user profile'); @@ -281,11 +246,9 @@ final class Init extends ModuleBase /** * Iniciar la sesión PHP * - * @param bool $encrypt Encriptar la sesión de PHP - * * @throws Exception */ - private function initSession(bool $encrypt = false) + private function initSession(bool $encrypt = false): void { if ($encrypt === true && Bootstrap::$checkPhpVersion @@ -297,7 +260,9 @@ final class Init extends ModuleBase try { $this->context->initialize(); } catch (Exception $e) { - $this->router->response()->header('HTTP/1.1', '500 Internal Server Error'); + $this->router + ->response() + ->header('HTTP/1.1', '500 Internal Server Error'); throw $e; } @@ -331,7 +296,7 @@ final class Init extends ModuleBase * Inicializar la sesión de usuario * */ - private function initUserSession() + private function initUserSession(): void { $lastActivity = $this->context->getLastActivity(); $inMaintenance = $this->configData->isMaintenance(); @@ -342,7 +307,9 @@ final class Init extends ModuleBase && time() > ($lastActivity + $this->getSessionLifeTime()) ) { if ($this->router->request()->cookies()->get(session_name()) !== null) { - $this->router->response()->cookie(session_name(), '', time() - 42000); + $this->router + ->response() + ->cookie(session_name(), '', time() - 42000); } SessionContext::restart(); @@ -382,7 +349,8 @@ final class Init extends ModuleBase try { if ($this->isIndex || $timeout === null) { - $userTimeout = $this->getSessionTimeoutForUser($timeout) ?: $this->configData->getSessionTimeout(); + $userTimeout = $this->getSessionTimeoutForUser($timeout) + ?: $this->configData->getSessionTimeout(); logger('Session timeout: ' . $userTimeout); @@ -396,9 +364,6 @@ final class Init extends ModuleBase } /** - * @param int|null $default - * - * @return int|null * @throws ConstraintException * @throws InvalidArgumentException * @throws NoSuchPropertyException diff --git a/app/modules/web/module.php b/app/modules/web/module.php index 8c98bd55..3e1d65fe 100644 --- a/app/modules/web/module.php +++ b/app/modules/web/module.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,9 +19,9 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ -define('MODULE_PATH', __DIR__); -define('VIEW_PATH', MODULE_PATH . DIRECTORY_SEPARATOR . 'themes'); -define('PLUGINS_PATH', MODULE_PATH . DIRECTORY_SEPARATOR . 'plugins'); +const MODULE_PATH = __DIR__; +const VIEW_PATH = MODULE_PATH . DIRECTORY_SEPARATOR . 'themes'; +const PLUGINS_PATH = MODULE_PATH . DIRECTORY_SEPARATOR . 'plugins'; diff --git a/app/modules/web/themes/material-blue/css/_base.scss b/app/modules/web/themes/material-blue/css/_base.scss index 9bb336fb..208ee0ea 100644 --- a/app/modules/web/themes/material-blue/css/_base.scss +++ b/app/modules/web/themes/material-blue/css/_base.scss @@ -85,8 +85,8 @@ $public-path: 'public'; @mixin flex($values) { -webkit-box-flex: $values; - -moz-box-flex: $values; - -webkit-flex: $values; - -ms-flex: $values; - flex: $values; + -moz-box-flex: $values; + -webkit-flex: $values; + -ms-flex: $values; + flex: $values; } \ No newline at end of file diff --git a/app/modules/web/themes/material-blue/css/_elements.scss b/app/modules/web/themes/material-blue/css/_elements.scss index 6ce9a5eb..1263022d 100644 --- a/app/modules/web/themes/material-blue/css/_elements.scss +++ b/app/modules/web/themes/material-blue/css/_elements.scss @@ -13,6 +13,7 @@ html, body { * { font-family: $font-stack; box-sizing: inherit; + &:before, &:after { box-sizing: inherit; } @@ -21,28 +22,36 @@ html, body { table { font-size: 11px; border-spacing: 0; + th { border-bottom: 2px solid transparent; vertical-align: middle; + .icon { width: 24px; height: 24px; } } + tr { &.odd { background-color: #f9f9f9; } + &.even > td, &.odd > td { border-bottom: 1px solid #d9d9d9 !important; } + &.even:hover, &.odd:hover { background-color: #e8ff99; } + height: 20px; } + td { padding: 3px; + &.txtCliente { font-weight: bold; text-align: center; @@ -68,6 +77,7 @@ input { &.txtFile { width: 200px; } + &.txtLong { width: 300px; } @@ -90,6 +100,7 @@ img { padding: 0; border: 0; cursor: pointer; + &.inputImgMini { background-color: transparent !important; width: 16px !important; @@ -107,6 +118,7 @@ i { form .form-field { display: flex; justify-content: space-between; + > { label { min-width: 12em; @@ -114,6 +126,7 @@ form .form-field { font-size: 16px; align-self: center; } + div { width: 100%; align-self: center; @@ -124,10 +137,12 @@ form .form-field { a { text-decoration: none; color: $color-indigo-fg-accent; + &:visited { text-decoration: none; color: $color-indigo-fg-accent; } + &:hover, &:active, &:focus { text-decoration: none; /*color: rgba(83, 109, 254, .6);*/ diff --git a/app/modules/web/themes/material-blue/css/_login.scss b/app/modules/web/themes/material-blue/css/_login.scss index 0877a68d..abc90a96 100644 --- a/app/modules/web/themes/material-blue/css/_login.scss +++ b/app/modules/web/themes/material-blue/css/_login.scss @@ -2,19 +2,23 @@ #box-login { position: relative; min-height: 14em; + #box-buttons { position: absolute; top: 2em; right: 2em; } + #box-actions { width: 100%; text-align: right; + a { color: #c9c9c9; } } } + #box-updated { width: 350px; margin: 3em auto; @@ -23,16 +27,19 @@ padding: 0.5em; @include color-teal(); } + #demo-info { padding: .5em; margin: 3em auto 0 auto; color: #c9c9c9; border-top: 1px solid #d9d9d9; border-bottom: 1px solid #d9d9d9; + ul { display: flex; justify-content: space-around; list-style: none; + li { > span { padding: 0 1em; @@ -51,19 +58,23 @@ right: 0; text-align: right; } + #box-actions { margin-top: 1em; } } + #demo-info { ul { display: flex; flex-direction: column; align-items: center; list-style: none; + li { width: 11em; text-align: left; + > span { padding: 0 1em; } diff --git a/app/modules/web/themes/material-blue/css/_noheader.scss b/app/modules/web/themes/material-blue/css/_noheader.scss index e2b0fb71..c2be2d2f 100644 --- a/app/modules/web/themes/material-blue/css/_noheader.scss +++ b/app/modules/web/themes/material-blue/css/_noheader.scss @@ -7,14 +7,18 @@ body.login, body.logout, body.userpassreset { background: $color-bluegrey-fg; + #wrap { background: transparent; } + #container { padding-top: 5%; } + footer { background: #78909C; + a { color: #f2f2f2; } @@ -26,15 +30,18 @@ body.userpassreset { width: 40em; min-height: 20em; margin: 0 auto; + > div { width: 100%; padding: 1em; margin: 0 auto; } + .box-spacer { height: 15em; background-color: transparent; } + .box-header { width: 100%; color: #f2f2f2; @@ -45,15 +52,18 @@ body.userpassreset { letter-spacing: .1em; padding: 0.2em 0; } + .box-form { @include shadow-full(); background-color: #f2f2f2; + form { fieldset#box-data { height: 100%; min-height: 14em; text-align: left; background-color: transparent; + legend { width: 100%; color: $color-bluegrey-fg; @@ -64,16 +74,20 @@ body.userpassreset { letter-spacing: .1em; padding: 0.2em 0; } + .form-control > i { margin-right: .5em; opacity: .5; } + .extra-hidden { display: none; } + margin-bottom: 2em; } } + div#box-buttons { margin-top: 2em; text-align: center; @@ -84,9 +98,11 @@ body.userpassreset { @media screen and (max-width: 600px) { #box-pub-noheader { width: 25em; + .box-spacer { height: 10em; } + form { fieldset#box-data { .mdl-textfield { diff --git a/app/modules/web/themes/material-blue/css/fonts.css b/app/modules/web/themes/material-blue/css/fonts.css index 7f82ff0d..7db24269 100644 --- a/app/modules/web/themes/material-blue/css/fonts.css +++ b/app/modules/web/themes/material-blue/css/fonts.css @@ -5,6 +5,7 @@ font-weight: 300; src: local('Roboto Light'), local('Roboto-Light'), url('app/modules/web/themes/material-blue/css/Roboto_300.woff2') format('woff2'); } + @font-face { font-family: 'Roboto Regular'; font-style: normal; @@ -12,12 +13,14 @@ /*src: local('Roboto'), local('Roboto-Regular'), url('app/modules/web/themes/material-blue/css/Roboto_400.woff2') format('woff2');*/ src: url('app/modules/web/themes/material-blue/css/Roboto_400.woff2') format('woff2'); } + @font-face { font-family: 'Roboto Medium'; font-style: normal; font-weight: 500; src: local('Roboto Medium'), local('Roboto-Medium'), url('app/modules/web/themes/material-blue/css/Roboto_500.woff2') format('woff2'); } + @font-face { font-family: 'Roboto Bold'; font-style: normal; diff --git a/app/modules/web/themes/material-blue/css/search-card.css.map b/app/modules/web/themes/material-blue/css/search-card.css.map index 3ef7a4be..058f3147 100644 --- a/app/modules/web/themes/material-blue/css/search-card.css.map +++ b/app/modules/web/themes/material-blue/css/search-card.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": ";AAAA,4DAA4D;AAI1D,qBAAa;EACX,OAAO,EAAE,IAAI;EACb,SAAS,EAAE,IAAI;EACf,eAAe,EAAE,UAAU;EAC3B,UAAU,EAAE,MAAM;EAClB,OAAO,EAAE,OAAO;EAChB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,MAAM;EAEd,oCAAe;IACb,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,aAAa;IAC9B,SAAS,EAAE,IAAI;IACf,KAAK,EAAE,IAAI;IACX,UAAU,EAAE,GAAG;IACf,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,OAAO;IACd,gBAAgB,EAAE,OAAO;IACzB,OAAO,EAAE,MAAM;IAEf;wDACgB;MACd,OAAO,EAAE,IAAI;MACb,SAAS,EAAE,IAAI;MACf,MAAM,EAAE,IAAI;MACZ,UAAU,EAAE,GAAG;MACf,KAAK,EAAE,IAAI;MACX,OAAO,EAAE,OAAO;IAGlB,oDAAgB;MACd,MAAM,EAAE,GAAG;IAGb,gDAAY;MACV,OAAO,EAAE,IAAI;MACb,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,MAAM;MACnB,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,IAAI;IAGd,iDAAa;MACX,OAAO,EAAE,IAAI;MACb,SAAS,EAAE,IAAI;MACf,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,IAAI;MACZ,uDAAQ;QACN,KAAK,EAAE,IAAI;IAIf,iDAAa;MACX,KAAK,EAAE,IAAI;MACX,UAAU,EAAE,GAAG;MACf,MAAM,EAAE,IAAI;MACZ,OAAO,EAAE,MAAM;IAGjB,gDAAY;MACV,SAAS,EAAE,UAAU;MACrB,kDAAE;QACA,KAAK,EC3DG,OAAO;ID+DnB,oDAAgB;MACd,SAAS,EAAE,CAAC;IAGd,gDAAY;MACV,OAAO,EAAE,WAAW;MACpB,KAAK,EAAE,OAAO;MACd,UAAU,EAAE,IAAI;MAChB,aAAa,EAAE,iBACjB;IAEA,uDAAmB;MACjB,OAAO,EAAE,IAAI;IAGf,wDAAoB;MAClB,KAAK,EAAE,KAAK;MACZ,WAAW,EAAE,IAAI;IAGnB;mDACW;MACT,KAAK,EAAE,KAAK;MACZ,WAAW,EAAE,IAAI;EAIrB,mCAAc;IACZ,OAAO,EAAE,aAAa;IACtB,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,GAAG;IACZ,UAAU,EAAE,GAAG;IACf,yCAAQ;MACN,OAAO,EAAE,CAAC;EAId,sCAAiB;IACf,UAAU,EAAE,QAAQ;IACpB,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,KAAK;IACjB,UAAU,EAAE,iBAAiB;IAC7B,wCAAE;MACA,OAAO,EAAE,EAAE;MACX,8CAAQ;QACN,OAAO,EAAE,CAAC;EAKhB,qCAAgB;IACd,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,GAAG;IACX,KAAK,EAAE,GAAG;EAGZ,+BAAU;IACR,OAAO,EAAE,YAAY;IAErB,wCAAS;MACP,MAAM,EAAE,OAAO;MACf,OAAO,EAAE,GAAG;MACZ,8CAAQ;QACN,OAAO,EAAE,CAAC", +"mappings": ";AAAA,4DAA4D;AAI1D,qBAAa;EACX,OAAO,EAAE,IAAI;EACb,SAAS,EAAE,IAAI;EACf,eAAe,EAAE,UAAU;EAC3B,UAAU,EAAE,MAAM;EAClB,OAAO,EAAE,OAAO;EAChB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,MAAM;EAEd,oCAAe;IACb,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,aAAa;IAC9B,SAAS,EAAE,IAAI;IACf,KAAK,EAAE,IAAI;IACX,UAAU,EAAE,GAAG;IACf,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,OAAO;IACd,gBAAgB,EAAE,OAAO;IACzB,OAAO,EAAE,MAAM;IAEf;wDACgB;MACd,OAAO,EAAE,IAAI;MACb,SAAS,EAAE,IAAI;MACf,MAAM,EAAE,IAAI;MACZ,UAAU,EAAE,GAAG;MACf,KAAK,EAAE,IAAI;MACX,OAAO,EAAE,OAAO;IAGlB,oDAAgB;MACd,MAAM,EAAE,GAAG;IAGb,gDAAY;MACV,OAAO,EAAE,IAAI;MACb,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,MAAM;MACnB,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,IAAI;IAGd,iDAAa;MACX,OAAO,EAAE,IAAI;MACb,SAAS,EAAE,IAAI;MACf,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,IAAI;MAEZ,uDAAQ;QACN,KAAK,EAAE,IAAI;IAIf,iDAAa;MACX,KAAK,EAAE,IAAI;MACX,UAAU,EAAE,GAAG;MACf,MAAM,EAAE,IAAI;MACZ,OAAO,EAAE,MAAM;IAGjB,gDAAY;MACV,SAAS,EAAE,UAAU;MAErB,kDAAE;QACA,KAAK,EC7DG,OAAO;IDiEnB,oDAAgB;MACd,SAAS,EAAE,CAAC;IAGd,gDAAY;MACV,OAAO,EAAE,WAAW;MACpB,KAAK,EAAE,OAAO;MACd,UAAU,EAAE,IAAI;MAChB,aAAa,EAAE,iBACjB;IAEA,uDAAmB;MACjB,OAAO,EAAE,IAAI;IAGf,wDAAoB;MAClB,KAAK,EAAE,KAAK;MACZ,WAAW,EAAE,IAAI;IAGnB;mDACW;MACT,KAAK,EAAE,KAAK;MACZ,WAAW,EAAE,IAAI;EAIrB,mCAAc;IACZ,OAAO,EAAE,aAAa;IACtB,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,GAAG;IACZ,UAAU,EAAE,GAAG;IAEf,yCAAQ;MACN,OAAO,EAAE,CAAC;EAId,sCAAiB;IACf,UAAU,EAAE,QAAQ;IACpB,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,KAAK;IACjB,UAAU,EAAE,iBAAiB;IAE7B,wCAAE;MACA,OAAO,EAAE,EAAE;MAEX,8CAAQ;QACN,OAAO,EAAE,CAAC;EAKhB,qCAAgB;IACd,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,GAAG;IACX,KAAK,EAAE,GAAG;EAGZ,+BAAU;IACR,OAAO,EAAE,YAAY;IAErB,wCAAS;MACP,MAAM,EAAE,OAAO;MACf,OAAO,EAAE,GAAG;MAEZ,8CAAQ;QACN,OAAO,EAAE,CAAC", "sources": ["search-card.scss","_base.scss"], "names": [], "file": "search-card.css" diff --git a/app/modules/web/themes/material-blue/css/search-card.scss b/app/modules/web/themes/material-blue/css/search-card.scss index 1549b2a4..026d5083 100644 --- a/app/modules/web/themes/material-blue/css/search-card.scss +++ b/app/modules/web/themes/material-blue/css/search-card.scss @@ -51,6 +51,7 @@ flex-wrap: wrap; width: 100%; height: auto; + & > div { width: 100%; } @@ -65,6 +66,7 @@ .field-text { word-wrap: break-word; + a { color: $color-indigo-fg; } @@ -102,6 +104,7 @@ text-align: left; opacity: 0.3; min-height: 4em; + &:hover { opacity: 1; } @@ -112,8 +115,10 @@ padding: .5em 0; text-align: right; border-top: 1px solid #c9c9c9; + i { opacity: .5; + &:hover { opacity: 1; } @@ -133,6 +138,7 @@ span.tag { cursor: pointer; opacity: 0.3; + &:hover { opacity: 1; } diff --git a/app/modules/web/themes/material-blue/css/search-grid.css.map b/app/modules/web/themes/material-blue/css/search-grid.css.map index 3e792bfb..a84ea129 100644 --- a/app/modules/web/themes/material-blue/css/search-grid.css.map +++ b/app/modules/web/themes/material-blue/css/search-grid.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": ";AAAA,4DAA4D;AAI1D,qBAAa;EACX,UAAU,EAAE,MAAM;EAClB,OAAO,EAAE,OAAO;EAChB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,MAAM;EAEd;4CACqB;IACnB,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,OAAO;EAGjB,oCAAe;IACb,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,aAAa;IAC9B,KAAK,EAAE,IAAI;IACX,UAAU,EAAE,GAAG;IACf,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,OAAO;IACd,gBAAgB,EAAE,OAAO;IACzB,OAAO,EAAE,MAAM;IAEf;wDACgB;MACd,OAAO,EAAE,IAAI;MACb,UAAU,EAAE,GAAG;MACf,MAAM,EAAE,IAAI;MACZ,KAAK,EAAE,IAAI;MACX,OAAO,EAAE,OAAO;IAGlB,oDAAgB;MACd,MAAM,EAAE,GAAG;IAGb,gDAAY;MACV,OAAO,EAAE,IAAI;MACb,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,MAAM;MACnB,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,GAAG;IAGb,iDAAa;MACX,OAAO,EAAE,IAAI;MACb,SAAS,EAAE,IAAI;MACf,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,GAAG;MACX,uDAAQ;QACN,KAAK,EAAE,IAAI;IAIf,iDAAa;MACX,KAAK,EAAE,IAAI;MACX,UAAU,EAAE,GAAG;MACf,MAAM,EAAE,IAAI;MACZ,OAAO,EAAE,MAAM;IAGjB,gDAAY;MACV,SAAS,EAAE,UAAU;MACrB,kDAAE;QACA,KAAK,EC7DG,OAAO;IDiEnB,oDAAgB;MACd,SAAS,EAAE,CAAC;IAGd,gDAAY;MACV,OAAO,EAAE,WAAW;MACpB,KAAK,EAAE,OAAO;MACd,OAAO,EAAE,IAAI;IAGf,uDAAmB;MACjB,OAAO,EAAE,IAAI;IAGf,wDAAoB;MAClB,KAAK,EAAE,KAAK;MACZ,WAAW,EAAE,IAAI;IAGnB;mDACW;MACT,KAAK,EAAE,KAAK;MACZ,WAAW,EAAE,IAAI;EAIrB,mCAAc;IACZ,OAAO,EAAE,aAAa;IACtB,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,GAAG;IACZ,UAAU,EAAE,GAAG;IACf,yCAAQ;MACN,OAAO,EAAE,CAAC;EAId,sCAAiB;IACf,UAAU,EAAE,QAAQ;IACpB,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,KAAK;IACjB,UAAU,EAAE,iBAAiB;EAG/B,qCAAgB;IACd,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,GAAG;IACX,KAAK,EAAE,GAAG;EAGZ,+BAAU;IACR,OAAO,EAAE,YAAY;IAErB,wCAAS;MACP,MAAM,EAAE,OAAO;MACf,OAAO,EAAE,GAAG;MACZ,8CAAQ;QACN,OAAO,EAAE,CAAC;;AAOpB,qCAAsC;EAGhC,oCAAe;IACb,SAAS,EAAE,IAAI;IAEf;wDACgB;MACd,SAAS,EAAE,IAAI;MACf,MAAM,EAAE,IAAI;IAIZ,6DAAY;MACV,OAAO,EAAE,KAAK;MACd,UAAU,EAAE,IAAI;MAChB,aAAa,EAAE,iBAAiB;MAChC,KAAK,EC/IG,OAAO;IDmJnB;qDACa;MACX,MAAM,EAAE,IAAI;IAGd;2DACmB;MACjB,KAAK,EAAE,IAAI;AAOrB,6CAA6C;AAC7C,4CAA4C;AAC5C,4CAA4C;AAC5C,4CAA4C;AAC5C,4CAA4C", +"mappings": ";AAAA,4DAA4D;AAI1D,qBAAa;EACX,UAAU,EAAE,MAAM;EAClB,OAAO,EAAE,OAAO;EAChB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,MAAM;EAEd;4CACqB;IACnB,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,OAAO;EAGjB,oCAAe;IACb,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,aAAa;IAC9B,KAAK,EAAE,IAAI;IACX,UAAU,EAAE,GAAG;IACf,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,OAAO;IACd,gBAAgB,EAAE,OAAO;IACzB,OAAO,EAAE,MAAM;IAEf;wDACgB;MACd,OAAO,EAAE,IAAI;MACb,UAAU,EAAE,GAAG;MACf,MAAM,EAAE,IAAI;MACZ,KAAK,EAAE,IAAI;MACX,OAAO,EAAE,OAAO;IAGlB,oDAAgB;MACd,MAAM,EAAE,GAAG;IAGb,gDAAY;MACV,OAAO,EAAE,IAAI;MACb,SAAS,EAAE,IAAI;MACf,WAAW,EAAE,MAAM;MACnB,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,GAAG;IAGb,iDAAa;MACX,OAAO,EAAE,IAAI;MACb,SAAS,EAAE,IAAI;MACf,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,GAAG;MAEX,uDAAQ;QACN,KAAK,EAAE,IAAI;IAIf,iDAAa;MACX,KAAK,EAAE,IAAI;MACX,UAAU,EAAE,GAAG;MACf,MAAM,EAAE,IAAI;MACZ,OAAO,EAAE,MAAM;IAGjB,gDAAY;MACV,SAAS,EAAE,UAAU;MAErB,kDAAE;QACA,KAAK,EC/DG,OAAO;IDmEnB,oDAAgB;MACd,SAAS,EAAE,CAAC;IAGd,gDAAY;MACV,OAAO,EAAE,WAAW;MACpB,KAAK,EAAE,OAAO;MACd,OAAO,EAAE,IAAI;IAGf,uDAAmB;MACjB,OAAO,EAAE,IAAI;IAGf,wDAAoB;MAClB,KAAK,EAAE,KAAK;MACZ,WAAW,EAAE,IAAI;IAGnB;mDACW;MACT,KAAK,EAAE,KAAK;MACZ,WAAW,EAAE,IAAI;EAIrB,mCAAc;IACZ,OAAO,EAAE,aAAa;IACtB,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,GAAG;IACZ,UAAU,EAAE,GAAG;IAEf,yCAAQ;MACN,OAAO,EAAE,CAAC;EAId,sCAAiB;IACf,UAAU,EAAE,QAAQ;IACpB,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,KAAK;IACjB,UAAU,EAAE,iBAAiB;EAG/B,qCAAgB;IACd,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,GAAG;IACX,KAAK,EAAE,GAAG;EAGZ,+BAAU;IACR,OAAO,EAAE,YAAY;IAErB,wCAAS;MACP,MAAM,EAAE,OAAO;MACf,OAAO,EAAE,GAAG;MAEZ,8CAAQ;QACN,OAAO,EAAE,CAAC;;AAOpB,qCAAsC;EAGhC,oCAAe;IACb,SAAS,EAAE,IAAI;IAEf;wDACgB;MACd,SAAS,EAAE,IAAI;MACf,MAAM,EAAE,IAAI;IAIZ,6DAAY;MACV,OAAO,EAAE,KAAK;MACd,UAAU,EAAE,IAAI;MAChB,aAAa,EAAE,iBAAiB;MAChC,KAAK,ECnJG,OAAO;IDuJnB;qDACa;MACX,MAAM,EAAE,IAAI;IAGd;2DACmB;MACjB,KAAK,EAAE,IAAI;AAOrB,6CAA6C;AAC7C,4CAA4C;AAC5C,4CAA4C;AAC5C,4CAA4C;AAC5C,4CAA4C", "sources": ["search-grid.scss","_base.scss"], "names": [], "file": "search-grid.css" diff --git a/app/modules/web/themes/material-blue/css/search-grid.scss b/app/modules/web/themes/material-blue/css/search-grid.scss index 0a8da08f..ee87f869 100644 --- a/app/modules/web/themes/material-blue/css/search-grid.scss +++ b/app/modules/web/themes/material-blue/css/search-grid.scss @@ -53,6 +53,7 @@ flex-wrap: wrap; width: 18em; height: 4em; + & > div { width: 18em; } @@ -67,6 +68,7 @@ .field-text { word-wrap: break-word; + a { color: $color-indigo-fg; } @@ -103,6 +105,7 @@ text-align: left; opacity: 0.3; min-height: 4em; + &:hover { opacity: 1; } @@ -128,6 +131,7 @@ span.tag { cursor: pointer; opacity: 0.3; + &:hover { opacity: 1; } diff --git a/app/modules/web/themes/material-blue/css/selectize-custom.css b/app/modules/web/themes/material-blue/css/selectize-custom.css index 8f6a5131..c4732bf5 100644 --- a/app/modules/web/themes/material-blue/css/selectize-custom.css +++ b/app/modules/web/themes/material-blue/css/selectize-custom.css @@ -89,7 +89,7 @@ vertical-align: middle; display: inline-block; padding: 1px 0 0 0; - border-left: 1px solid transparent; + border-left: 1px solid rgba(0, 0, 0, 0); -webkit-border-radius: 0 2px 2px 0; -moz-border-radius: 0 2px 2px 0; border-radius: 0 2px 2px 0; @@ -101,7 +101,7 @@ background: rgba(0, 0, 0, 0.05); } .selectize-control.plugin-remove_button [data-value].active .remove { - border-left-color: transparent; } + border-left-color: rgba(0, 0, 0, 0); } .selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { background: none; } @@ -180,12 +180,12 @@ padding: 1px 3px; background: #5c6bc0; color: #fff; - border: 0 solid transparent; } + border: 0 solid rgba(0, 0, 0, 0); } .selectize-control.multi .selectize-input > div.active { background: #607d8b; color: #ffffff; - border: 0 solid transparent; } + border: 0 solid rgba(0, 0, 0, 0); } .selectize-control.multi .selectize-input.disabled > div, .selectize-control.multi .selectize-input.disabled > div.active { diff --git a/app/modules/web/themes/material-blue/css/selectize-custom.css.map b/app/modules/web/themes/material-blue/css/selectize-custom.css.map index b0803da9..e70bcf46 100644 --- a/app/modules/web/themes/material-blue/css/selectize-custom.css.map +++ b/app/modules/web/themes/material-blue/css/selectize-custom.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "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", +"mappings": "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", "sources": ["selectize-custom.scss","_base.scss"], "names": [], "file": "selectize-custom.css" diff --git a/app/modules/web/themes/material-blue/css/selectize-custom.min.css b/app/modules/web/themes/material-blue/css/selectize-custom.min.css index 9a769be7..b559c6ae 100644 --- a/app/modules/web/themes/material-blue/css/selectize-custom.min.css +++ b/app/modules/web/themes/material-blue/css/selectize-custom.min.css @@ -1 +1 @@ -@charset "UTF-8";.selectize-control.plugin-drag_drop.multi>.selectize-input>div.ui-sortable-placeholder{visibility:visible !important;background:#f2f2f2 !important;background:rgba(0,0,0,0.06) !important;border:0 none !important;-webkit-box-shadow:inset 0 0 12px 4px #fff;box-shadow:inset 0 0 12px 4px #fff}.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after{content:'!';visibility:hidden}.selectize-control.plugin-drag_drop .ui-sortable-helper{-webkit-box-shadow:0 2px 5px rgba(0,0,0,0.2);box-shadow:0 2px 5px rgba(0,0,0,0.2)}.selectize-dropdown-header{position:relative;padding:3px 12px;border-bottom:1px solid #d0d0d0;background:#f8f8f8;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.selectize-dropdown-header-close{position:absolute;right:12px;top:50%;color:#333;opacity:.4;margin-top:-12px;line-height:20px;font-size:20px !important}.selectize-dropdown-header-close:hover{color:#000}.selectize-dropdown.plugin-optgroup_columns .optgroup{border-right:1px solid #f2f2f2;border-top:0 none;float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child{border-right:0 none}.selectize-dropdown.plugin-optgroup_columns .optgroup:before{display:none}.selectize-dropdown.plugin-optgroup_columns .optgroup-header{border-top:0 none}.selectize-control.plugin-remove_button [data-value]{position:relative;padding-right:24px !important}.selectize-control.plugin-remove_button [data-value] .remove{z-index:1;position:absolute;top:0;right:0;bottom:0;width:17px;text-align:center;font-weight:bold;font-size:12px;color:inherit;text-decoration:none;vertical-align:middle;display:inline-block;padding:1px 0 0 0;border-left:1px solid transparent;-webkit-border-radius:0 2px 2px 0;-moz-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-control.plugin-remove_button [data-value] .remove:hover{background:rgba(0,0,0,0.05)}.selectize-control.plugin-remove_button [data-value].active .remove{border-left-color:transparent}.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover{background:0}.selectize-control.plugin-remove_button .disabled [data-value] .remove{border-left-color:rgba(77,77,77,0)}.selectize-control{position:relative;padding:20px 0}.selectize-dropdown,.selectize-input,.selectize-input input{color:#333;line-height:20px;-webkit-font-smoothing:inherit}.selectize-control.single{display:inline-block}.selectize-input,.selectize-control.single .selectize-input.input-active{background:#fff;cursor:text;display:inline-block}.selectize-input{border-bottom:1px solid #ccc;padding:3px 0;display:inline-block;width:300px;overflow:hidden;position:relative;z-index:1;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:none;box-shadow:none}.selectize-input.has-items{color:#5c6bc0;font-size:1.3em}.selectize-control.multi .selectize-input.has-items{padding:5px 12px 2px}.selectize-input.full,.selectize-input.not-full{background-color:#fff}.selectize-input.disabled,.selectize-input.disabled *{cursor:default !important}.selectize-input.focus{-webkit-box-shadow:inset 0 -1px 2px rgba(0,0,0,0.15);box-shadow:inset 0 -1px 2px rgba(0,0,0,0.15)}.selectize-input>*{vertical-align:baseline;display:-moz-inline-stack;display:inline-block;zoom:1;*display:inline}.selectize-control.multi .selectize-input{width:95%}.selectize-control.multi .selectize-input>div{cursor:pointer;margin:0 3px 3px 0;padding:1px 3px;background:#5c6bc0;color:#fff;border:0 solid transparent}.selectize-control.multi .selectize-input>div.active{background:#607d8b;color:#fff;border:0 solid transparent}.selectize-control.multi .selectize-input.disabled>div,.selectize-control.multi .selectize-input.disabled>div.active{color:gray;background:#fff;border:0 solid rgba(77,77,77,0)}.selectize-input>input{display:inline-block !important;padding:0 !important;min-height:0 !important;max-height:none !important;max-width:100% !important;margin:0 !important;text-indent:0 !important;border:0 none !important;background:none !important;line-height:inherit !important;-webkit-user-select:auto !important;-webkit-box-shadow:none !important;box-shadow:none !important;font-size:16px;color:#888;color:rgba(0,0,0,0.5)}.selectize-input>input::-ms-clear{display:none}.selectize-input>input:focus{outline:none !important}.selectize-input::after{content:' ';display:block;clear:left}.selectize-input.dropdown-active::before{content:' ';display:block;position:absolute;background:#fff;height:1px;bottom:0;left:0;right:0}.selectize-dropdown{position:absolute;z-index:10;border:1px solid #d0d0d0;background:#fff;margin:-1px 0 0 0;border-top:0 none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1);-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.selectize-dropdown [data-selectable]{cursor:pointer;overflow:hidden}.selectize-dropdown [data-selectable] .highlight{background:rgba(255,237,40,0.4);-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px}.selectize-dropdown [data-selectable],.selectize-dropdown .optgroup-header{padding:3px 12px}.selectize-dropdown .optgroup:first-child .optgroup-header{border-top:0 none}.selectize-dropdown .optgroup-header{color:#777;background:#fff;cursor:default}.selectize-dropdown .active{background-color:#5c6bc0;color:#fff}.selectize-dropdown .active.create{color:#262626}.selectize-dropdown .create{color:rgba(51,51,51,0.5)}.selectize-dropdown-content{overflow-y:auto;overflow-x:hidden;max-height:200px}.selectize-control.single .selectize-input,.selectize-control.single .selectize-input input{cursor:pointer}.selectize-control.single .selectize-input.input-active,.selectize-control.single .selectize-input.input-active input{cursor:text}.selectize-control.single .selectize-input:after{content:' ';display:block;position:absolute;top:50%;right:17px;margin-top:-3px;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:#333 transparent transparent transparent}.selectize-control.single .selectize-input.dropdown-active:after{margin-top:-4px;border-width:0 5px 5px 5px;border-color:transparent transparent #333 transparent}.selectize-control.rtl.single .selectize-input:after{left:17px;right:auto}.selectize-control.rtl .selectize-input>input{margin:0 4px 0 -2px !important}.selectize-control .selectize-input.disabled{background-color:#fff}.selectize-dropdown,.selectize-dropdown.form-control{height:auto;padding:0;margin:2px 0 0 0;z-index:1000;background:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175)}.selectize-dropdown .optgroup-header{font-size:12px;line-height:1.42857143}.selectize-dropdown .optgroup:first-child:before{display:none}.selectize-dropdown .optgroup:before{content:' ';display:block;height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5;margin-left:-12px;margin-right:-12px}.selectize-dropdown-content{padding:5px 0}.selectize-dropdown-header{padding:6px 12px}.selectize-input.dropdown-active::before{display:none}.selectize-input.focus{border-color:#607d8b;outline:0;-webkit-box-shadow:inset 0 -1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 -1px 1px rgba(0,0,0,0.075)}.has-error .selectize-input{border-color:#ef5350;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .selectize-input:focus{border-color:#ef5350;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.selectize-control.multi .selectize-input.has-items{padding-left:9px;padding-right:9px}.selectize-control.multi .selectize-input>div{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.form-control.selectize-control{padding:0;height:auto;border:0;background:0;-webkit-box-shadow:none;box-shadow:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} \ No newline at end of file +@charset "UTF-8";.selectize-control.plugin-drag_drop.multi>.selectize-input>div.ui-sortable-placeholder{visibility:visible !important;background:#f2f2f2 !important;background:rgba(0,0,0,0.06) !important;border:0 none !important;-webkit-box-shadow:inset 0 0 12px 4px #fff;box-shadow:inset 0 0 12px 4px #fff}.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after{content:'!';visibility:hidden}.selectize-control.plugin-drag_drop .ui-sortable-helper{-webkit-box-shadow:0 2px 5px rgba(0,0,0,0.2);box-shadow:0 2px 5px rgba(0,0,0,0.2)}.selectize-dropdown-header{position:relative;padding:3px 12px;border-bottom:1px solid #d0d0d0;background:#f8f8f8;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.selectize-dropdown-header-close{position:absolute;right:12px;top:50%;color:#333;opacity:.4;margin-top:-12px;line-height:20px;font-size:20px !important}.selectize-dropdown-header-close:hover{color:#000}.selectize-dropdown.plugin-optgroup_columns .optgroup{border-right:1px solid #f2f2f2;border-top:0 none;float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child{border-right:0 none}.selectize-dropdown.plugin-optgroup_columns .optgroup:before{display:none}.selectize-dropdown.plugin-optgroup_columns .optgroup-header{border-top:0 none}.selectize-control.plugin-remove_button [data-value]{position:relative;padding-right:24px !important}.selectize-control.plugin-remove_button [data-value] .remove{z-index:1;position:absolute;top:0;right:0;bottom:0;width:17px;text-align:center;font-weight:bold;font-size:12px;color:inherit;text-decoration:none;vertical-align:middle;display:inline-block;padding:1px 0 0 0;border-left:1px solid rgba(0,0,0,0);-webkit-border-radius:0 2px 2px 0;-moz-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-control.plugin-remove_button [data-value] .remove:hover{background:rgba(0,0,0,0.05)}.selectize-control.plugin-remove_button [data-value].active .remove{border-left-color:rgba(0,0,0,0)}.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover{background:0}.selectize-control.plugin-remove_button .disabled [data-value] .remove{border-left-color:rgba(77,77,77,0)}.selectize-control{position:relative;padding:20px 0}.selectize-dropdown,.selectize-input,.selectize-input input{color:#333;line-height:20px;-webkit-font-smoothing:inherit}.selectize-control.single{display:inline-block}.selectize-input,.selectize-control.single .selectize-input.input-active{background:#fff;cursor:text;display:inline-block}.selectize-input{border-bottom:1px solid #ccc;padding:3px 0;display:inline-block;width:300px;overflow:hidden;position:relative;z-index:1;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:none;box-shadow:none}.selectize-input.has-items{color:#5c6bc0;font-size:1.3em}.selectize-control.multi .selectize-input.has-items{padding:5px 12px 2px}.selectize-input.full,.selectize-input.not-full{background-color:#fff}.selectize-input.disabled,.selectize-input.disabled *{cursor:default !important}.selectize-input.focus{-webkit-box-shadow:inset 0 -1px 2px rgba(0,0,0,0.15);box-shadow:inset 0 -1px 2px rgba(0,0,0,0.15)}.selectize-input>*{vertical-align:baseline;display:-moz-inline-stack;display:inline-block;zoom:1;*display:inline}.selectize-control.multi .selectize-input{width:95%}.selectize-control.multi .selectize-input>div{cursor:pointer;margin:0 3px 3px 0;padding:1px 3px;background:#5c6bc0;color:#fff;border:0 solid rgba(0,0,0,0)}.selectize-control.multi .selectize-input>div.active{background:#607d8b;color:#fff;border:0 solid rgba(0,0,0,0)}.selectize-control.multi .selectize-input.disabled>div,.selectize-control.multi .selectize-input.disabled>div.active{color:gray;background:#fff;border:0 solid rgba(77,77,77,0)}.selectize-input>input{display:inline-block !important;padding:0 !important;min-height:0 !important;max-height:none !important;max-width:100% !important;margin:0 !important;text-indent:0 !important;border:0 none !important;background:none !important;line-height:inherit !important;-webkit-user-select:auto !important;-webkit-box-shadow:none !important;box-shadow:none !important;font-size:16px;color:#888;color:rgba(0,0,0,0.5)}.selectize-input>input::-ms-clear{display:none}.selectize-input>input:focus{outline:none !important}.selectize-input::after{content:' ';display:block;clear:left}.selectize-input.dropdown-active::before{content:' ';display:block;position:absolute;background:#fff;height:1px;bottom:0;left:0;right:0}.selectize-dropdown{position:absolute;z-index:10;border:1px solid #d0d0d0;background:#fff;margin:-1px 0 0 0;border-top:0 none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1);-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.selectize-dropdown [data-selectable]{cursor:pointer;overflow:hidden}.selectize-dropdown [data-selectable] .highlight{background:rgba(255,237,40,0.4);-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px}.selectize-dropdown [data-selectable],.selectize-dropdown .optgroup-header{padding:3px 12px}.selectize-dropdown .optgroup:first-child .optgroup-header{border-top:0 none}.selectize-dropdown .optgroup-header{color:#777;background:#fff;cursor:default}.selectize-dropdown .active{background-color:#5c6bc0;color:#fff}.selectize-dropdown .active.create{color:#262626}.selectize-dropdown .create{color:rgba(51,51,51,0.5)}.selectize-dropdown-content{overflow-y:auto;overflow-x:hidden;max-height:200px}.selectize-control.single .selectize-input,.selectize-control.single .selectize-input input{cursor:pointer}.selectize-control.single .selectize-input.input-active,.selectize-control.single .selectize-input.input-active input{cursor:text}.selectize-control.single .selectize-input:after{content:' ';display:block;position:absolute;top:50%;right:17px;margin-top:-3px;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:#333 transparent transparent transparent}.selectize-control.single .selectize-input.dropdown-active:after{margin-top:-4px;border-width:0 5px 5px 5px;border-color:transparent transparent #333 transparent}.selectize-control.rtl.single .selectize-input:after{left:17px;right:auto}.selectize-control.rtl .selectize-input>input{margin:0 4px 0 -2px !important}.selectize-control .selectize-input.disabled{background-color:#fff}.selectize-dropdown,.selectize-dropdown.form-control{height:auto;padding:0;margin:2px 0 0 0;z-index:1000;background:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175)}.selectize-dropdown .optgroup-header{font-size:12px;line-height:1.42857143}.selectize-dropdown .optgroup:first-child:before{display:none}.selectize-dropdown .optgroup:before{content:' ';display:block;height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5;margin-left:-12px;margin-right:-12px}.selectize-dropdown-content{padding:5px 0}.selectize-dropdown-header{padding:6px 12px}.selectize-input.dropdown-active::before{display:none}.selectize-input.focus{border-color:#607d8b;outline:0;-webkit-box-shadow:inset 0 -1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 -1px 1px rgba(0,0,0,0.075)}.has-error .selectize-input{border-color:#ef5350;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .selectize-input:focus{border-color:#ef5350;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.selectize-control.multi .selectize-input.has-items{padding-left:9px;padding-right:9px}.selectize-control.multi .selectize-input>div{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.form-control.selectize-control{padding:0;height:auto;border:0;background:0;-webkit-box-shadow:none;box-shadow:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0} \ No newline at end of file diff --git a/app/modules/web/themes/material-blue/css/styles-wiki.css.map b/app/modules/web/themes/material-blue/css/styles-wiki.css.map index 52c08aad..514fde2e 100644 --- a/app/modules/web/themes/material-blue/css/styles-wiki.css.map +++ b/app/modules/web/themes/material-blue/css/styles-wiki.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "AAGE,oBAAU;EACR,UAAU,EAAE,IAAI;EAChB,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,KAAK;EAEd,oJAAuB;IACrB,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,CAAC;IACV,WAAW,EAAE,GAAG;IAChB,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,OAAO;IACd,aAAa,EAAE,iBAAiB;IAChC,gKAAE;MACA,KAAK,EAAE,IAAI;EAGf,uBAAG;IACD,SAAS,EAAE,GAAG;IACd,MAAM,EAAE,UAAU;EAGpB,uBAAG;IACD,SAAS,EAAE,KAAK;IAChB,MAAM,EAAE,UAAU;EAGpB,uBAAG;IACD,SAAS,EAAE,OAAO;IAClB,MAAM,EAAE,UAAU;EAGpB,uBAAG;IACD,SAAS,EAAE,GAAG;IACd,MAAM,EAAE,OAAO;EAGjB,uBAAG;IACD,SAAS,EAAE,MAAM;IACjB,MAAM,EAAE,YAAY;EAGtB,uBAAG;IACD,SAAS,EAAE,KAAK;IAChB,MAAM,EAAE,WAAW;EAGrB,wBAAI;IACF,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,MAAM;IACjB,MAAM,EAAE,cAAc;IACtB,aAAa,EAAE,GAAG;IAClB,UAAU,EAAE,mBAAmB;IAC/B,OAAO,EAAE,QAAQ;EAGnB,gDAAO;IACL,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,WAAW;EAGrB,0BAAM;IACJ,KAAK,EAAE,IAAI;EAGb,2BAAO;IACL,KAAK,EAAE,IAAI;EAGb,0BAAM;IACJ,KAAK,EAAE,IAAI;AAIf,wBAAc;EACZ,MAAM,EAAE,KAAK;EACb,UAAU,EAAE,iBAA4B;EACxC,KAAK,ECnEW,OAAO;EDqEvB,2BAAG;IACD,UAAU,EAAE,IAAI;EAGlB,2BAAG;IACD,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,IAAI", +"mappings": "AAGE,oBAAU;EACR,UAAU,EAAE,IAAI;EAChB,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,KAAK;EAEd,oJAAuB;IACrB,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,CAAC;IACV,WAAW,EAAE,GAAG;IAChB,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,OAAO;IACd,aAAa,EAAE,iBAAiB;IAEhC,gKAAE;MACA,KAAK,EAAE,IAAI;EAIf,uBAAG;IACD,SAAS,EAAE,GAAG;IACd,MAAM,EAAE,UAAU;EAGpB,uBAAG;IACD,SAAS,EAAE,KAAK;IAChB,MAAM,EAAE,UAAU;EAGpB,uBAAG;IACD,SAAS,EAAE,OAAO;IAClB,MAAM,EAAE,UAAU;EAGpB,uBAAG;IACD,SAAS,EAAE,GAAG;IACd,MAAM,EAAE,OAAO;EAGjB,uBAAG;IACD,SAAS,EAAE,MAAM;IACjB,MAAM,EAAE,YAAY;EAGtB,uBAAG;IACD,SAAS,EAAE,KAAK;IAChB,MAAM,EAAE,WAAW;EAGrB,wBAAI;IACF,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,MAAM;IACjB,MAAM,EAAE,cAAc;IACtB,aAAa,EAAE,GAAG;IAClB,UAAU,EAAE,mBAAmB;IAC/B,OAAO,EAAE,QAAQ;EAGnB,gDAAO;IACL,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,WAAW;EAGrB,0BAAM;IACJ,KAAK,EAAE,IAAI;EAGb,2BAAO;IACL,KAAK,EAAE,IAAI;EAGb,0BAAM;IACJ,KAAK,EAAE,IAAI;AAIf,wBAAc;EACZ,MAAM,EAAE,KAAK;EACb,UAAU,EAAE,iBAA4B;EACxC,KAAK,ECrEW,OAAO;EDuEvB,2BAAG;IACD,UAAU,EAAE,IAAI;EAGlB,2BAAG;IACD,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,IAAI", "sources": ["styles-wiki.scss","_base.scss"], "names": [], "file": "styles-wiki.css" diff --git a/app/modules/web/themes/material-blue/css/styles-wiki.scss b/app/modules/web/themes/material-blue/css/styles-wiki.scss index 90e7f257..49eb1503 100644 --- a/app/modules/web/themes/material-blue/css/styles-wiki.scss +++ b/app/modules/web/themes/material-blue/css/styles-wiki.scss @@ -13,10 +13,12 @@ clear: left; color: #777777; border-bottom: 1px solid #777777; + a { color: #777; } } + h1 { font-size: 2em; margin: 0 0 .444em; diff --git a/app/modules/web/themes/material-blue/css/styles.css.map b/app/modules/web/themes/material-blue/css/styles.css.map index 81766a5e..17d264d3 100644 --- a/app/modules/web/themes/material-blue/css/styles.css.map +++ b/app/modules/web/themes/material-blue/css/styles.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "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", +"mappings": "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", "sources": ["_elements.scss","_base.scss","_noheader.scss","styles.scss","_login.scss"], "names": [], "file": "styles.css" diff --git a/app/modules/web/themes/material-blue/css/toastr.css.map b/app/modules/web/themes/material-blue/css/toastr.css.map index a01ec182..c4c05692 100644 --- a/app/modules/web/themes/material-blue/css/toastr.css.map +++ b/app/modules/web/themes/material-blue/css/toastr.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "AAEA,sBAAuB;EACrB,OAAO,EAAE,CAAC;EACV,UAAU,EAAE,IAAI;EAChB,MAAM,EAAE,IAAI;;AAGd,4BAA6B;EAC3B,UAAU,EAAE,IAAI;EAChB,MAAM,EAAE,IAAI;;AAGd;0CAC2C;EACzC,KAAK,EAAE,GAAG;EACV,WAAW,EAAE,IAAI;EACjB,YAAY,EAAE,IAAI;EAClB,UAAU,EAAE,MAAM;;AAGpB,MAAO;EACL,gBAAgB,EAAE,OAAO;;AAE3B,cAAe;EACb,gBAAgB,ECtBF,OAAO;;ADwBvB,YAAa;EACX,gBAAgB,ECvBH,OAAO;;ADyBtB,WAAY;EACV,gBAAgB,ECjBF,OAAO;;ADmBvB,cAAe;EACb,gBAAgB,EC3BD,OAAO;ED4BtB,KAAK,ECpBM,IAAI", +"mappings": "AAEA,sBAAuB;EACrB,OAAO,EAAE,CAAC;EACV,UAAU,EAAE,IAAI;EAChB,MAAM,EAAE,IAAI;;AAGd,4BAA6B;EAC3B,UAAU,EAAE,IAAI;EAChB,MAAM,EAAE,IAAI;;AAGd;0CAC2C;EACzC,KAAK,EAAE,GAAG;EACV,WAAW,EAAE,IAAI;EACjB,YAAY,EAAE,IAAI;EAClB,UAAU,EAAE,MAAM;;AAGpB,MAAO;EACL,gBAAgB,EAAE,OAAO;;AAG3B,cAAe;EACb,gBAAgB,ECvBF,OAAO;;AD0BvB,YAAa;EACX,gBAAgB,ECzBH,OAAO;;AD4BtB,WAAY;EACV,gBAAgB,ECpBF,OAAO;;ADuBvB,cAAe;EACb,gBAAgB,EC/BD,OAAO;EDgCtB,KAAK,ECxBM,IAAI", "sources": ["toastr.scss","_base.scss"], "names": [], "file": "toastr.css" diff --git a/app/modules/web/themes/material-blue/css/toastr.scss b/app/modules/web/themes/material-blue/css/toastr.scss index 2b9334ab..ae2ec0d6 100644 --- a/app/modules/web/themes/material-blue/css/toastr.scss +++ b/app/modules/web/themes/material-blue/css/toastr.scss @@ -22,15 +22,19 @@ .toast { background-color: #030303; } + .toast-success { background-color: $color-teal-fg; } + .toast-error { background-color: $color-red-fg; } + .toast-info { background-color: $color-blue-fg; } + .toast-warning { background-color: $color-amber-fg; color: $color-grey; diff --git a/app/modules/web/themes/material-blue/index.php b/app/modules/web/themes/material-blue/index.php index 22bf20f1..046a037c 100644 --- a/app/modules/web/themes/material-blue/index.php +++ b/app/modules/web/themes/material-blue/index.php @@ -1,10 +1,10 @@ . + * along with sysPass. If not, see . */ return [ diff --git a/app/modules/web/themes/material-blue/js/app-theme.map b/app/modules/web/themes/material-blue/js/app-theme.map index f5d132df..fd8665ee 100644 --- a/app/modules/web/themes/material-blue/js/app-theme.map +++ b/app/modules/web/themes/material-blue/js/app-theme.map @@ -1,8 +1,175 @@ { -"version":3, -"file":"app-theme.min.js", -"lineCount":20, -"mappings":"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", -"sources":[" [synthetic:base] "," [synthetic:util/findinternal] "," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:util/polyfill] "," [synthetic:es6/array/find] ","app-theme.js"], -"names":["sysPass","Theme","sysPass.Theme","Common","log","loading","elems","$wrap","$","$loading","show","full","undefined","addClass","hide","removeClass","upgradeFull","password","$target","i","chars","genPassword","passwordData","complexity","symbols","numbers","uppercase","numlength","charAt","Math","floor","random","length","min","attr","level","zxcvbn","passLength","$dstParent","parent","$targetR","outputResult","mdl","MaterialTextfield","find","val","CssClasses_","IS_DIRTY","IS_INVALID","encryptFormValue","complexityDialog","content","config","LANG","mdlDialog","title","text","negative","positive","onClick","e","preventDefault","is","parseInt","cancelable","contentStyle","onLoaded","prop","passwordDetect","$container","each","$this","$thisParent","targetId","btnMenu","after","next","prepend","on","checkPassLevel","$passwordActions","focus","$targetIdR","componentHandler","upgradeDom","$icon","data","$clip","setupDatePicker","info","datePickerOpts","format","lang","LOCALE","substr","time","cancelText","okText","clearText","nowText","minDate","Date","triggerEvent","bootstrapMaterialDatePicker","append","moment","tz","TIMEZONE","trigger","unixtime","viewsTriggers","main","layout","document","querySelector","$drawer","click","MaterialLayout","toggleDrawer","search","$frmSearch","$resContent","$searchfav","submit","$tagsSelect","$tagsBar","$showFilter","appActions","account","sort","savefavorite","html","selectize","addItem","slideDown","slideUp","selectedIndex","common","ajax","complete","getList","items","$ul","$li","$span","forEach","value","$spanClone","clone","icon","$item","tabs","add","header","index","isActive","$header","active"] + "version": 3, + "file": "app-theme.min.js", + "lineCount": 20, + "mappings": "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", + "sources": [ + " [synthetic:base] ", + " [synthetic:util/findinternal] ", + " [synthetic:util/defineproperty] ", + " [synthetic:util/global] ", + " [synthetic:util/polyfill] ", + " [synthetic:es6/array/find] ", + "app-theme.js" + ], + "names": [ + "sysPass", + "Theme", + "sysPass.Theme", + "Common", + "log", + "loading", + "elems", + "$wrap", + "$", + "$loading", + "show", + "full", + "undefined", + "addClass", + "hide", + "removeClass", + "upgradeFull", + "password", + "$target", + "i", + "chars", + "genPassword", + "passwordData", + "complexity", + "symbols", + "numbers", + "uppercase", + "numlength", + "charAt", + "Math", + "floor", + "random", + "length", + "min", + "attr", + "level", + "zxcvbn", + "passLength", + "$dstParent", + "parent", + "$targetR", + "outputResult", + "mdl", + "MaterialTextfield", + "find", + "val", + "CssClasses_", + "IS_DIRTY", + "IS_INVALID", + "encryptFormValue", + "complexityDialog", + "content", + "config", + "LANG", + "mdlDialog", + "title", + "text", + "negative", + "positive", + "onClick", + "e", + "preventDefault", + "is", + "parseInt", + "cancelable", + "contentStyle", + "onLoaded", + "prop", + "passwordDetect", + "$container", + "each", + "$this", + "$thisParent", + "targetId", + "btnMenu", + "after", + "next", + "prepend", + "on", + "checkPassLevel", + "$passwordActions", + "focus", + "$targetIdR", + "componentHandler", + "upgradeDom", + "$icon", + "data", + "$clip", + "setupDatePicker", + "info", + "datePickerOpts", + "format", + "lang", + "LOCALE", + "substr", + "time", + "cancelText", + "okText", + "clearText", + "nowText", + "minDate", + "Date", + "triggerEvent", + "bootstrapMaterialDatePicker", + "append", + "moment", + "tz", + "TIMEZONE", + "trigger", + "unixtime", + "viewsTriggers", + "main", + "layout", + "document", + "querySelector", + "$drawer", + "click", + "MaterialLayout", + "toggleDrawer", + "search", + "$frmSearch", + "$resContent", + "$searchfav", + "submit", + "$tagsSelect", + "$tagsBar", + "$showFilter", + "appActions", + "account", + "sort", + "savefavorite", + "html", + "selectize", + "addItem", + "slideDown", + "slideUp", + "selectedIndex", + "common", + "ajax", + "complete", + "getList", + "items", + "$ul", + "$li", + "$span", + "forEach", + "value", + "$spanClone", + "clone", + "icon", + "$item", + "tabs", + "add", + "header", + "index", + "isActive", + "$header", + "active" + ] } diff --git a/app/modules/web/themes/material-blue/js/bootstrap-material-datetimepicker.js b/app/modules/web/themes/material-blue/js/bootstrap-material-datetimepicker.js index 904f059e..7980bf97 100644 --- a/app/modules/web/themes/material-blue/js/bootstrap-material-datetimepicker.js +++ b/app/modules/web/themes/material-blue/js/bootstrap-material-datetimepicker.js @@ -1,4 +1,3 @@ - (function ($, moment) { var pluginName = "bootstrapMaterialDatePicker"; var pluginDataName = "plugin_" + pluginName; @@ -62,334 +61,288 @@ }; Plugin.prototype = - { - init: function () { - this.initDays(); - this.initDates(); + { + init: function () { + this.initDays(); + this.initDates(); - this.initTemplate(); + this.initTemplate(); - this.initButtons(); + this.initButtons(); - this._attachEvent($(window), 'resize', this._centerBox.bind(this)); - this._attachEvent(this.$dtpElement.find('.dtp-content'), 'click', this._onElementClick.bind(this)); - this._attachEvent(this.$dtpElement, 'click', this._onBackgroundClick.bind(this)); - this._attachEvent(this.$dtpElement.find('.dtp-close > a'), 'click', this._onCloseClick.bind(this)); - this._attachEvent(this.$element, this.params.triggerEvent, this._fireCalendar.bind(this)); - }, - initDays: function () { - this.days = []; - for (var i = this.params.weekStart; this.days.length < 7; i++) { - if (i > 6) { - i = 0; + this._attachEvent($(window), 'resize', this._centerBox.bind(this)); + this._attachEvent(this.$dtpElement.find('.dtp-content'), 'click', this._onElementClick.bind(this)); + this._attachEvent(this.$dtpElement, 'click', this._onBackgroundClick.bind(this)); + this._attachEvent(this.$dtpElement.find('.dtp-close > a'), 'click', this._onCloseClick.bind(this)); + this._attachEvent(this.$element, this.params.triggerEvent, this._fireCalendar.bind(this)); + }, + initDays: function () { + this.days = []; + for (var i = this.params.weekStart; this.days.length < 7; i++) { + if (i > 6) { + i = 0; + } + this.days.push(i.toString()); } - this.days.push(i.toString()); - } - }, - initDates: function () { - if (this.$element.val().length > 0) { - if (typeof (this.params.format) !== 'undefined' && this.params.format !== null) { - this.currentDate = moment(this.$element.val(), this.params.format).locale(this.params.lang); - } else { - this.currentDate = moment(this.$element.val()).locale(this.params.lang); - } - } else { - if (typeof (this.$element.attr('value')) !== 'undefined' && this.$element.attr('value') !== null && this.$element.attr('value') !== "") { - if (typeof (this.$element.attr('value')) === 'string') { - if (typeof (this.params.format) !== 'undefined' && this.params.format !== null) { - this.currentDate = moment(this.$element.attr('value'), this.params.format).locale(this.params.lang); - } else { - this.currentDate = moment(this.$element.attr('value')).locale(this.params.lang); - } + }, + initDates: function () { + if (this.$element.val().length > 0) { + if (typeof (this.params.format) !== 'undefined' && this.params.format !== null) { + this.currentDate = moment(this.$element.val(), this.params.format).locale(this.params.lang); + } else { + this.currentDate = moment(this.$element.val()).locale(this.params.lang); } } else { - if (typeof (this.params.currentDate) !== 'undefined' && this.params.currentDate !== null) { - if (typeof (this.params.currentDate) === 'string') { + if (typeof (this.$element.attr('value')) !== 'undefined' && this.$element.attr('value') !== null && this.$element.attr('value') !== "") { + if (typeof (this.$element.attr('value')) === 'string') { if (typeof (this.params.format) !== 'undefined' && this.params.format !== null) { - this.currentDate = moment(this.params.currentDate, this.params.format).locale(this.params.lang); + this.currentDate = moment(this.$element.attr('value'), this.params.format).locale(this.params.lang); } else { - this.currentDate = moment(this.params.currentDate).locale(this.params.lang); - } - } else { - if (typeof (this.params.currentDate.isValid) === 'undefined' || typeof (this.params.currentDate.isValid) !== 'function') { - var x = this.params.currentDate.getTime(); - this.currentDate = moment(x, "x").locale(this.params.lang); - } else { - this.currentDate = this.params.currentDate; + this.currentDate = moment(this.$element.attr('value')).locale(this.params.lang); } } - this.$element.val(this.currentDate.format(this.params.format)); - } else - this.currentDate = moment(); - } - } - - if (typeof (this.params.minDate) !== 'undefined' && this.params.minDate !== null) { - if (typeof (this.params.minDate) === 'string') { - if (typeof (this.params.format) !== 'undefined' && this.params.format !== null) { - this.minDate = moment(this.params.minDate, this.params.format).locale(this.params.lang); } else { - this.minDate = moment(this.params.minDate).locale(this.params.lang); + if (typeof (this.params.currentDate) !== 'undefined' && this.params.currentDate !== null) { + if (typeof (this.params.currentDate) === 'string') { + if (typeof (this.params.format) !== 'undefined' && this.params.format !== null) { + this.currentDate = moment(this.params.currentDate, this.params.format).locale(this.params.lang); + } else { + this.currentDate = moment(this.params.currentDate).locale(this.params.lang); + } + } else { + if (typeof (this.params.currentDate.isValid) === 'undefined' || typeof (this.params.currentDate.isValid) !== 'function') { + var x = this.params.currentDate.getTime(); + this.currentDate = moment(x, "x").locale(this.params.lang); + } else { + this.currentDate = this.params.currentDate; + } + } + this.$element.val(this.currentDate.format(this.params.format)); + } else + this.currentDate = moment(); } + } + + if (typeof (this.params.minDate) !== 'undefined' && this.params.minDate !== null) { + if (typeof (this.params.minDate) === 'string') { + if (typeof (this.params.format) !== 'undefined' && this.params.format !== null) { + this.minDate = moment(this.params.minDate, this.params.format).locale(this.params.lang); + } else { + this.minDate = moment(this.params.minDate).locale(this.params.lang); + } + } else { + if (typeof (this.params.minDate.isValid) === 'undefined' || typeof (this.params.minDate.isValid) !== 'function') { + var x = this.params.minDate.getTime(); + this.minDate = moment(x, "x").locale(this.params.lang); + } else { + this.minDate = this.params.minDate; + } + } + } else if (this.params.minDate === null) { + this.minDate = null; + } + + if (typeof (this.params.maxDate) !== 'undefined' && this.params.maxDate !== null) { + if (typeof (this.params.maxDate) === 'string') { + if (typeof (this.params.format) !== 'undefined' && this.params.format !== null) { + this.maxDate = moment(this.params.maxDate, this.params.format).locale(this.params.lang); + } else { + this.maxDate = moment(this.params.maxDate).locale(this.params.lang); + } + } else { + if (typeof (this.params.maxDate.isValid) === 'undefined' || typeof (this.params.maxDate.isValid) !== 'function') { + var x = this.params.maxDate.getTime(); + this.maxDate = moment(x, "x").locale(this.params.lang); + } else { + this.maxDate = this.params.maxDate; + } + } + } else if (this.params.maxDate === null) { + this.maxDate = null; + } + + if (!this.isAfterMinDate(this.currentDate)) { + this.currentDate = moment(this.minDate); + } + if (!this.isBeforeMaxDate(this.currentDate)) { + this.currentDate = moment(this.maxDate); + } + }, + initTemplate: function () { + this.template = ''; + + var $body = $("body"); + + if ($body.find("#" + this.name).length <= 0) { + $body.append(this.template); + + if (this) + this.dtpElement = $body.find("#" + this.name); + this.$dtpElement = $(this.dtpElement); + } + }, + initButtons: function () { + this._attachEvent(this.$dtpElement.find('.dtp-btn-cancel'), 'click', this._onCancelClick.bind(this)); + this._attachEvent(this.$dtpElement.find('.dtp-btn-ok'), 'click', this._onOKClick.bind(this)); + this._attachEvent(this.$dtpElement.find('a.dtp-select-month-before'), 'click', this._onMonthBeforeClick.bind(this)); + this._attachEvent(this.$dtpElement.find('a.dtp-select-month-after'), 'click', this._onMonthAfterClick.bind(this)); + this._attachEvent(this.$dtpElement.find('a.dtp-select-year-before'), 'click', this._onYearBeforeClick.bind(this)); + this._attachEvent(this.$dtpElement.find('a.dtp-select-year-after'), 'click', this._onYearAfterClick.bind(this)); + + if (this.params.clearButton === true) { + this._attachEvent(this.$dtpElement.find('.dtp-btn-clear'), 'click', this._onClearClick.bind(this)); + this.$dtpElement.find('.dtp-btn-clear').removeClass('hidden'); + } + + if (this.params.nowButton === true) { + this._attachEvent(this.$dtpElement.find('.dtp-btn-now'), 'click', this._onNowClick.bind(this)); + this.$dtpElement.find('.dtp-btn-now').removeClass('hidden'); + } + + if ((this.params.nowButton === true) && (this.params.clearButton === true)) { + this.$dtpElement.find('.dtp-btn-clear, .dtp-btn-now, .dtp-btn-cancel, .dtp-btn-ok').addClass('btn-xs'); + } else if ((this.params.nowButton === true) || (this.params.clearButton === true)) { + this.$dtpElement.find('.dtp-btn-clear, .dtp-btn-now, .dtp-btn-cancel, .dtp-btn-ok').addClass('btn-sm'); + } + }, + initMeridienButtons: function () { + this.$dtpElement.find('a.dtp-meridien-am').off('click').on('click', this._onSelectAM.bind(this)); + this.$dtpElement.find('a.dtp-meridien-pm').off('click').on('click', this._onSelectPM.bind(this)); + }, + initDate: function (d) { + this.currentView = 0; + + this.$dtpElement.find('.dtp-picker-calendar').removeClass('hidden'); + this.$dtpElement.find('.dtp-picker-datetime').addClass('hidden'); + + var _date = ((typeof (this.currentDate) !== 'undefined' && this.currentDate !== null) ? this.currentDate : null); + var _calendar = this.generateCalendar(this.currentDate); + + if (typeof (_calendar.week) !== 'undefined' && typeof (_calendar.days) !== 'undefined') { + var _template = this.constructHTMLCalendar(_date, _calendar); + + this.$dtpElement.find('a.dtp-select-day').off('click'); + this.$dtpElement.find('.dtp-picker-calendar').html(_template); + + this.$dtpElement.find('a.dtp-select-day').on('click', this._onSelectDate.bind(this)); + + this.toggleButtons(_date); + } + + this._centerBox(); + this.showDate(_date); + }, + initHours: function () { + this.currentView = 1; + + this.showTime(this.currentDate); + this.initMeridienButtons(); + + if (this.currentDate.hour() < 12) { + this.$dtpElement.find('a.dtp-meridien-am').click(); } else { - if (typeof (this.params.minDate.isValid) === 'undefined' || typeof (this.params.minDate.isValid) !== 'function') { - var x = this.params.minDate.getTime(); - this.minDate = moment(x, "x").locale(this.params.lang); - } else { - this.minDate = this.params.minDate; - } - } - } else if (this.params.minDate === null) { - this.minDate = null; - } - - if (typeof (this.params.maxDate) !== 'undefined' && this.params.maxDate !== null) { - if (typeof (this.params.maxDate) === 'string') { - if (typeof (this.params.format) !== 'undefined' && this.params.format !== null) { - this.maxDate = moment(this.params.maxDate, this.params.format).locale(this.params.lang); - } else { - this.maxDate = moment(this.params.maxDate).locale(this.params.lang); - } - } else { - if (typeof (this.params.maxDate.isValid) === 'undefined' || typeof (this.params.maxDate.isValid) !== 'function') { - var x = this.params.maxDate.getTime(); - this.maxDate = moment(x, "x").locale(this.params.lang); - } else { - this.maxDate = this.params.maxDate; - } - } - } else if (this.params.maxDate === null) { - this.maxDate = null; - } - - if (!this.isAfterMinDate(this.currentDate)) { - this.currentDate = moment(this.minDate); - } - if (!this.isBeforeMaxDate(this.currentDate)) { - this.currentDate = moment(this.maxDate); - } - }, - initTemplate: function () { - this.template = ''; - - var $body = $("body"); - - if ($body.find("#" + this.name).length <= 0) { - $body.append(this.template); - - if (this) - this.dtpElement = $body.find("#" + this.name); - this.$dtpElement = $(this.dtpElement); - } - }, - initButtons: function () { - this._attachEvent(this.$dtpElement.find('.dtp-btn-cancel'), 'click', this._onCancelClick.bind(this)); - this._attachEvent(this.$dtpElement.find('.dtp-btn-ok'), 'click', this._onOKClick.bind(this)); - this._attachEvent(this.$dtpElement.find('a.dtp-select-month-before'), 'click', this._onMonthBeforeClick.bind(this)); - this._attachEvent(this.$dtpElement.find('a.dtp-select-month-after'), 'click', this._onMonthAfterClick.bind(this)); - this._attachEvent(this.$dtpElement.find('a.dtp-select-year-before'), 'click', this._onYearBeforeClick.bind(this)); - this._attachEvent(this.$dtpElement.find('a.dtp-select-year-after'), 'click', this._onYearAfterClick.bind(this)); - - if (this.params.clearButton === true) { - this._attachEvent(this.$dtpElement.find('.dtp-btn-clear'), 'click', this._onClearClick.bind(this)); - this.$dtpElement.find('.dtp-btn-clear').removeClass('hidden'); - } - - if (this.params.nowButton === true) { - this._attachEvent(this.$dtpElement.find('.dtp-btn-now'), 'click', this._onNowClick.bind(this)); - this.$dtpElement.find('.dtp-btn-now').removeClass('hidden'); - } - - if ((this.params.nowButton === true) && (this.params.clearButton === true)) { - this.$dtpElement.find('.dtp-btn-clear, .dtp-btn-now, .dtp-btn-cancel, .dtp-btn-ok').addClass('btn-xs'); - } else if ((this.params.nowButton === true) || (this.params.clearButton === true)) { - this.$dtpElement.find('.dtp-btn-clear, .dtp-btn-now, .dtp-btn-cancel, .dtp-btn-ok').addClass('btn-sm'); - } - }, - initMeridienButtons: function () { - this.$dtpElement.find('a.dtp-meridien-am').off('click').on('click', this._onSelectAM.bind(this)); - this.$dtpElement.find('a.dtp-meridien-pm').off('click').on('click', this._onSelectPM.bind(this)); - }, - initDate: function (d) { - this.currentView = 0; - - this.$dtpElement.find('.dtp-picker-calendar').removeClass('hidden'); - this.$dtpElement.find('.dtp-picker-datetime').addClass('hidden'); - - var _date = ((typeof (this.currentDate) !== 'undefined' && this.currentDate !== null) ? this.currentDate : null); - var _calendar = this.generateCalendar(this.currentDate); - - if (typeof (_calendar.week) !== 'undefined' && typeof (_calendar.days) !== 'undefined') { - var _template = this.constructHTMLCalendar(_date, _calendar); - - this.$dtpElement.find('a.dtp-select-day').off('click'); - this.$dtpElement.find('.dtp-picker-calendar').html(_template); - - this.$dtpElement.find('a.dtp-select-day').on('click', this._onSelectDate.bind(this)); - - this.toggleButtons(_date); - } - - this._centerBox(); - this.showDate(_date); - }, - initHours: function () { - this.currentView = 1; - - this.showTime(this.currentDate); - this.initMeridienButtons(); - - if (this.currentDate.hour() < 12) { - this.$dtpElement.find('a.dtp-meridien-am').click(); - } else { - this.$dtpElement.find('a.dtp-meridien-pm').click(); - } - - var hFormat = ((this.params.shortTime) ? 'h' : 'H'); - - this.$dtpElement.find('.dtp-picker-datetime').removeClass('hidden'); - this.$dtpElement.find('.dtp-picker-calendar').addClass('hidden'); - - var svgClockElement = this.createSVGClock(true); - - for (var i = 0; i < 12; i++) { - var x = -(162 * (Math.sin(-Math.PI * 2 * (i / 12)))); - var y = -(162 * (Math.cos(-Math.PI * 2 * (i / 12)))); - - var fill = ((this.currentDate.format(hFormat) == i) ? "#8BC34A" : 'transparent'); - var color = ((this.currentDate.format(hFormat) == i) ? "#fff" : '#000'); - - var svgHourCircle = this.createSVGElement("circle", { - 'id': 'h-' + i, - 'class': 'dtp-select-hour', - 'style': 'cursor:pointer', - r: '30', - cx: x, - cy: y, - fill: fill, - 'data-hour': i - }); - - var svgHourText = this.createSVGElement("text", { - 'id': 'th-' + i, - 'class': 'dtp-select-hour-text', - 'text-anchor': 'middle', - 'style': 'cursor:pointer', - 'font-weight': 'bold', - 'font-size': '20', - x: x, - y: y + 7, - fill: color, - 'data-hour': i - }); - svgHourText.textContent = ((i === 0) ? ((this.params.shortTime) ? 12 : i) : i); - - if (!this.toggleTime(i, true)) { - svgHourCircle.className += " disabled"; - svgHourText.className += " disabled"; - svgHourText.setAttribute('fill', '#bdbdbd'); - } else { - svgHourCircle.addEventListener('click', this._onSelectHour.bind(this)); - svgHourText.addEventListener('click', this._onSelectHour.bind(this)); + this.$dtpElement.find('a.dtp-meridien-pm').click(); } - svgClockElement.appendChild(svgHourCircle) - svgClockElement.appendChild(svgHourText) - } + var hFormat = ((this.params.shortTime) ? 'h' : 'H'); + + this.$dtpElement.find('.dtp-picker-datetime').removeClass('hidden'); + this.$dtpElement.find('.dtp-picker-calendar').addClass('hidden'); + + var svgClockElement = this.createSVGClock(true); - if (!this.params.shortTime) { for (var i = 0; i < 12; i++) { - var x = -(110 * (Math.sin(-Math.PI * 2 * (i / 12)))); - var y = -(110 * (Math.cos(-Math.PI * 2 * (i / 12)))); + var x = -(162 * (Math.sin(-Math.PI * 2 * (i / 12)))); + var y = -(162 * (Math.cos(-Math.PI * 2 * (i / 12)))); - var fill = ((this.currentDate.format(hFormat) == (i + 12)) ? "#8BC34A" : 'transparent'); - var color = ((this.currentDate.format(hFormat) == (i + 12)) ? "#fff" : '#000'); + var fill = ((this.currentDate.format(hFormat) == i) ? "#8BC34A" : 'transparent'); + var color = ((this.currentDate.format(hFormat) == i) ? "#fff" : '#000'); var svgHourCircle = this.createSVGElement("circle", { - 'id': 'h-' + (i + 12), + 'id': 'h-' + i, 'class': 'dtp-select-hour', 'style': 'cursor:pointer', r: '30', cx: x, cy: y, fill: fill, - 'data-hour': (i + 12) + 'data-hour': i }); var svgHourText = this.createSVGElement("text", { - 'id': 'th-' + (i + 12), + 'id': 'th-' + i, 'class': 'dtp-select-hour-text', 'text-anchor': 'middle', 'style': 'cursor:pointer', 'font-weight': 'bold', - 'font-size': '22', + 'font-size': '20', x: x, y: y + 7, fill: color, - 'data-hour': (i + 12) + 'data-hour': i }); - svgHourText.textContent = i + 12; + svgHourText.textContent = ((i === 0) ? ((this.params.shortTime) ? 12 : i) : i); - if (!this.toggleTime(i + 12, true)) { + if (!this.toggleTime(i, true)) { svgHourCircle.className += " disabled"; svgHourText.className += " disabled"; svgHourText.setAttribute('fill', '#bdbdbd'); @@ -402,705 +355,757 @@ svgClockElement.appendChild(svgHourText) } - this.$dtpElement.find('a.dtp-meridien-am').addClass('hidden'); - this.$dtpElement.find('a.dtp-meridien-pm').addClass('hidden'); - } + if (!this.params.shortTime) { + for (var i = 0; i < 12; i++) { + var x = -(110 * (Math.sin(-Math.PI * 2 * (i / 12)))); + var y = -(110 * (Math.cos(-Math.PI * 2 * (i / 12)))); - this._centerBox(); - }, - initMinutes: function () { - this.currentView = 2; + var fill = ((this.currentDate.format(hFormat) == (i + 12)) ? "#8BC34A" : 'transparent'); + var color = ((this.currentDate.format(hFormat) == (i + 12)) ? "#fff" : '#000'); - this.showTime(this.currentDate); + var svgHourCircle = this.createSVGElement("circle", { + 'id': 'h-' + (i + 12), + 'class': 'dtp-select-hour', + 'style': 'cursor:pointer', + r: '30', + cx: x, + cy: y, + fill: fill, + 'data-hour': (i + 12) + }); - this.initMeridienButtons(); + var svgHourText = this.createSVGElement("text", { + 'id': 'th-' + (i + 12), + 'class': 'dtp-select-hour-text', + 'text-anchor': 'middle', + 'style': 'cursor:pointer', + 'font-weight': 'bold', + 'font-size': '22', + x: x, + y: y + 7, + fill: color, + 'data-hour': (i + 12) + }); + svgHourText.textContent = i + 12; - if (this.currentDate.hour() < 12) { - this.$dtpElement.find('a.dtp-meridien-am').click(); - } else { - this.$dtpElement.find('a.dtp-meridien-pm').click(); - } + if (!this.toggleTime(i + 12, true)) { + svgHourCircle.className += " disabled"; + svgHourText.className += " disabled"; + svgHourText.setAttribute('fill', '#bdbdbd'); + } else { + svgHourCircle.addEventListener('click', this._onSelectHour.bind(this)); + svgHourText.addEventListener('click', this._onSelectHour.bind(this)); + } - this.$dtpElement.find('.dtp-picker-calendar').addClass('hidden'); - this.$dtpElement.find('.dtp-picker-datetime').removeClass('hidden'); + svgClockElement.appendChild(svgHourCircle) + svgClockElement.appendChild(svgHourText) + } - var svgClockElement = this.createSVGClock(false); - - for (var i = 0; i < 60; i++) { - var s = ((i % 5 === 0) ? 162 : 158); - var r = ((i % 5 === 0) ? 30 : 20); - - var x = -(s * (Math.sin(-Math.PI * 2 * (i / 60)))); - var y = -(s * (Math.cos(-Math.PI * 2 * (i / 60)))); - - var color = ((this.currentDate.format("m") == i) ? "#8BC34A" : 'transparent'); - - var svgMinuteCircle = this.createSVGElement("circle", { - 'id': 'm-' + i, - 'class': 'dtp-select-minute', - 'style': 'cursor:pointer', - r: r, - cx: x, - cy: y, - fill: color, - 'data-minute': i - }); - - if (!this.toggleTime(i, false)) { - svgMinuteCircle.className += " disabled"; - } else { - svgMinuteCircle.addEventListener('click', this._onSelectMinute.bind(this)); + this.$dtpElement.find('a.dtp-meridien-am').addClass('hidden'); + this.$dtpElement.find('a.dtp-meridien-pm').addClass('hidden'); } - svgClockElement.appendChild(svgMinuteCircle) - } + this._centerBox(); + }, + initMinutes: function () { + this.currentView = 2; - for (var i = 0; i < 60; i++) { - if ((i % 5) === 0) { - var x = -(162 * (Math.sin(-Math.PI * 2 * (i / 60)))); - var y = -(162 * (Math.cos(-Math.PI * 2 * (i / 60)))); + this.showTime(this.currentDate); - var color = ((this.currentDate.format("m") == i) ? "#fff" : '#000'); + this.initMeridienButtons(); - var svgMinuteText = this.createSVGElement("text", { - 'id': 'tm-' + i, - 'class': 'dtp-select-minute-text', - 'text-anchor': 'middle', + if (this.currentDate.hour() < 12) { + this.$dtpElement.find('a.dtp-meridien-am').click(); + } else { + this.$dtpElement.find('a.dtp-meridien-pm').click(); + } + + this.$dtpElement.find('.dtp-picker-calendar').addClass('hidden'); + this.$dtpElement.find('.dtp-picker-datetime').removeClass('hidden'); + + var svgClockElement = this.createSVGClock(false); + + for (var i = 0; i < 60; i++) { + var s = ((i % 5 === 0) ? 162 : 158); + var r = ((i % 5 === 0) ? 30 : 20); + + var x = -(s * (Math.sin(-Math.PI * 2 * (i / 60)))); + var y = -(s * (Math.cos(-Math.PI * 2 * (i / 60)))); + + var color = ((this.currentDate.format("m") == i) ? "#8BC34A" : 'transparent'); + + var svgMinuteCircle = this.createSVGElement("circle", { + 'id': 'm-' + i, + 'class': 'dtp-select-minute', 'style': 'cursor:pointer', - 'font-weight': 'bold', - 'font-size': '20', - x: x, - y: y + 7, + r: r, + cx: x, + cy: y, fill: color, 'data-minute': i }); - svgMinuteText.textContent = i; if (!this.toggleTime(i, false)) { - svgMinuteText.className += " disabled"; - svgMinuteText.setAttribute('fill', '#bdbdbd'); + svgMinuteCircle.className += " disabled"; } else { - svgMinuteText.addEventListener('click', this._onSelectMinute.bind(this)); + svgMinuteCircle.addEventListener('click', this._onSelectMinute.bind(this)); } - svgClockElement.appendChild(svgMinuteText) - } - } - - this._centerBox(); - }, - animateHands: function () { - var H = this.currentDate.hour(); - var M = this.currentDate.minute(); - - var hh = this.$dtpElement.find('.hour-hand'); - hh[0].setAttribute('transform', "rotate(" + 360 * H / 12 + ")"); - - var mh = this.$dtpElement.find('.minute-hand'); - mh[0].setAttribute('transform', "rotate(" + 360 * M / 60 + ")"); - }, - createSVGClock: function (isHour) { - var hl = ((this.params.shortTime) ? -120 : -90); - - var svgElement = this.createSVGElement("svg", {class: 'svg-clock', viewBox: '0,0,400,400'}); - var svgGElement = this.createSVGElement("g", {transform: 'translate(200,200) '}); - var svgClockFace = this.createSVGElement("circle", { - r: '192', - fill: '#eee', - stroke: '#bdbdbd', - 'stroke-width': 2 - }); - var svgClockCenter = this.createSVGElement("circle", {r: '15', fill: '#757575'}); - - svgGElement.appendChild(svgClockFace) - - if (isHour) { - var svgMinuteHand = this.createSVGElement("line", { - class: 'minute-hand', - x1: 0, - y1: 0, - x2: 0, - y2: -150, - stroke: '#bdbdbd', - 'stroke-width': 2 - }); - var svgHourHand = this.createSVGElement("line", { - class: 'hour-hand', - x1: 0, - y1: 0, - x2: 0, - y2: hl, - stroke: '#8BC34A', - 'stroke-width': 8 - }); - - svgGElement.appendChild(svgMinuteHand); - svgGElement.appendChild(svgHourHand); - } else { - var svgMinuteHand = this.createSVGElement("line", { - class: 'minute-hand', - x1: 0, - y1: 0, - x2: 0, - y2: -150, - stroke: '#8BC34A', - 'stroke-width': 2 - }); - var svgHourHand = this.createSVGElement("line", { - class: 'hour-hand', - x1: 0, - y1: 0, - x2: 0, - y2: hl, - stroke: '#bdbdbd', - 'stroke-width': 8 - }); - - svgGElement.appendChild(svgHourHand); - svgGElement.appendChild(svgMinuteHand); - } - - svgGElement.appendChild(svgClockCenter) - - svgElement.appendChild(svgGElement) - - this.$dtpElement.find("#dtp-svg-clock").empty(); - this.$dtpElement.find("#dtp-svg-clock")[0].appendChild(svgElement); - - this.animateHands(); - - return svgGElement; - }, - createSVGElement: function (tag, attrs) { - var el = document.createElementNS('http://www.w3.org/2000/svg', tag); - for (var k in attrs) { - el.setAttribute(k, attrs[k]); - } - return el; - }, - isAfterMinDate: function (date, checkHour, checkMinute) { - var _return = true; - - if (typeof (this.minDate) !== 'undefined' && this.minDate !== null) { - var _minDate = moment(this.minDate); - var _date = moment(date); - - if (!checkHour && !checkMinute) { - _minDate.hour(0); - _minDate.minute(0); - - _date.hour(0); - _date.minute(0); + svgClockElement.appendChild(svgMinuteCircle) } - _minDate.second(0); - _date.second(0); - _minDate.millisecond(0); - _date.millisecond(0); + for (var i = 0; i < 60; i++) { + if ((i % 5) === 0) { + var x = -(162 * (Math.sin(-Math.PI * 2 * (i / 60)))); + var y = -(162 * (Math.cos(-Math.PI * 2 * (i / 60)))); - if (!checkMinute) { - _date.minute(0); - _minDate.minute(0); + var color = ((this.currentDate.format("m") == i) ? "#fff" : '#000'); - _return = (parseInt(_date.format("X")) >= parseInt(_minDate.format("X"))); - } else { - _return = (parseInt(_date.format("X")) >= parseInt(_minDate.format("X"))); - } - } + var svgMinuteText = this.createSVGElement("text", { + 'id': 'tm-' + i, + 'class': 'dtp-select-minute-text', + 'text-anchor': 'middle', + 'style': 'cursor:pointer', + 'font-weight': 'bold', + 'font-size': '20', + x: x, + y: y + 7, + fill: color, + 'data-minute': i + }); + svgMinuteText.textContent = i; - return _return; - }, - isBeforeMaxDate: function (date, checkTime, checkMinute) { - var _return = true; - - if (typeof (this.maxDate) !== 'undefined' && this.maxDate !== null) { - var _maxDate = moment(this.maxDate); - var _date = moment(date); - - if (!checkTime && !checkMinute) { - _maxDate.hour(0); - _maxDate.minute(0); - - _date.hour(0); - _date.minute(0); - } - - _maxDate.second(0); - _date.second(0); - _maxDate.millisecond(0); - _date.millisecond(0); - - if (!checkMinute) { - _date.minute(0); - _maxDate.minute(0); - - _return = (parseInt(_date.format("X")) <= parseInt(_maxDate.format("X"))); - } else { - _return = (parseInt(_date.format("X")) <= parseInt(_maxDate.format("X"))); - } - } - - return _return; - }, - rotateElement: function (el, deg) { - $(el).css - ({ - WebkitTransform: 'rotate(' + deg + 'deg)', - '-moz-transform': 'rotate(' + deg + 'deg)' - }); - }, - showDate: function (date) { - if (date) { - this.$dtpElement.find('.dtp-actual-day').html(date.locale(this.params.lang).format('dddd')); - this.$dtpElement.find('.dtp-actual-month').html(date.locale(this.params.lang).format('MMM').toUpperCase()); - this.$dtpElement.find('.dtp-actual-num').html(date.locale(this.params.lang).format('DD')); - this.$dtpElement.find('.dtp-actual-year').html(date.locale(this.params.lang).format('YYYY')); - } - }, - showTime: function (date) { - if (date) { - var minutes = date.minute(); - var content = ((this.params.shortTime) ? date.format('hh') : date.format('HH')) + ':' + ((minutes.toString().length == 2) ? minutes : '0' + minutes) + ((this.params.shortTime) ? ' ' + date.format('A') : ''); - - if (this.params.date) - this.$dtpElement.find('.dtp-actual-time').html(content); - else { - if (this.params.shortTime) - this.$dtpElement.find('.dtp-actual-day').html(date.format('A')); - else - this.$dtpElement.find('.dtp-actual-day').html(' '); - - this.$dtpElement.find('.dtp-actual-maxtime').html(content); - } - } - }, - selectDate: function (date) { - if (date) { - this.currentDate.date(date); - - this.showDate(this.currentDate); - this.$element.trigger('dateSelected', this.currentDate); - } - }, - generateCalendar: function (date) { - var _calendar = {}; - - if (date !== null) { - var startOfMonth = moment(date).locale(this.params.lang).startOf('month'); - var endOfMonth = moment(date).locale(this.params.lang).endOf('month'); - - var iNumDay = startOfMonth.format('d'); - - _calendar.week = this.days; - _calendar.days = []; - - for (var i = startOfMonth.date(); i <= endOfMonth.date(); i++) { - if (i === startOfMonth.date()) { - var iWeek = _calendar.week.indexOf(iNumDay.toString()); - if (iWeek > 0) { - for (var x = 0; x < iWeek; x++) { - _calendar.days.push(0); - } - } - } - _calendar.days.push(moment(startOfMonth).locale(this.params.lang).date(i)); - } - } - - return _calendar; - }, - constructHTMLCalendar: function (date, calendar) { - var _template = ""; - - _template += '
' + date.locale(this.params.lang).format('MMMM YYYY') + '
'; - _template += ''; - for (var i = 0; i < calendar.week.length; i++) { - _template += ''; - } - - _template += ''; - _template += ''; - - for (var i = 0; i < calendar.days.length; i++) { - if (i % 7 == 0) - _template += ''; - _template += ''; } - } - _template += '
' + moment(parseInt(calendar.week[i]), "d").locale(this.params.lang).format("dd").substring(0, 1) + '
'; - if (calendar.days[i] != 0) { - if (this.isBeforeMaxDate(moment(calendar.days[i]), false, false) === false || this.isAfterMinDate(moment(calendar.days[i]), false, false) === false) { - _template += '' + moment(calendar.days[i]).locale(this.params.lang).format("DD") + ''; - } else { - if (moment(calendar.days[i]).locale(this.params.lang).format("DD") === moment(this.currentDate).locale(this.params.lang).format("DD")) { - _template += '' + moment(calendar.days[i]).locale(this.params.lang).format("DD") + ''; + if (!this.toggleTime(i, false)) { + svgMinuteText.className += " disabled"; + svgMinuteText.setAttribute('fill', '#bdbdbd'); } else { - _template += '' + moment(calendar.days[i]).locale(this.params.lang).format("DD") + ''; + svgMinuteText.addEventListener('click', this._onSelectMinute.bind(this)); } + + svgClockElement.appendChild(svgMinuteText) } - - _template += '
'; - return _template; - }, - setName: function () { - var text = ""; - var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + this._centerBox(); + }, + animateHands: function () { + var H = this.currentDate.hour(); + var M = this.currentDate.minute(); - for (var i = 0; i < 5; i++) { - text += possible.charAt(Math.floor(Math.random() * possible.length)); - } + var hh = this.$dtpElement.find('.hour-hand'); + hh[0].setAttribute('transform', "rotate(" + 360 * H / 12 + ")"); - return text; - }, - isPM: function () { - return this.$dtpElement.find('a.dtp-meridien-pm').hasClass('selected'); - }, - setElementValue: function () { - this.$element.trigger('beforeChange', this.currentDate); - if (this.$element.hasClass("mdl-textfield__input")) { - this.$element.removeClass('empty'); - this.$element.parent().addClass("is-dirty"); - } + var mh = this.$dtpElement.find('.minute-hand'); + mh[0].setAttribute('transform', "rotate(" + 360 * M / 60 + ")"); + }, + createSVGClock: function (isHour) { + var hl = ((this.params.shortTime) ? -120 : -90); - this.$element.val(moment(this.currentDate).locale(this.params.lang).format(this.params.format)); + var svgElement = this.createSVGElement("svg", { + class: 'svg-clock', + viewBox: '0,0,400,400' + }); + var svgGElement = this.createSVGElement("g", {transform: 'translate(200,200) '}); + var svgClockFace = this.createSVGElement("circle", { + r: '192', + fill: '#eee', + stroke: '#bdbdbd', + 'stroke-width': 2 + }); + var svgClockCenter = this.createSVGElement("circle", { + r: '15', + fill: '#757575' + }); - this.$element.trigger('change', this.currentDate); - }, - toggleButtons: function (date) { - if (date && date.isValid()) { - var startOfMonth = moment(date).locale(this.params.lang).startOf('month'); - var endOfMonth = moment(date).locale(this.params.lang).endOf('month'); + svgGElement.appendChild(svgClockFace) - if (!this.isAfterMinDate(startOfMonth, false, false)) { - this.$dtpElement.find('a.dtp-select-month-before').addClass('invisible'); + if (isHour) { + var svgMinuteHand = this.createSVGElement("line", { + class: 'minute-hand', + x1: 0, + y1: 0, + x2: 0, + y2: -150, + stroke: '#bdbdbd', + 'stroke-width': 2 + }); + var svgHourHand = this.createSVGElement("line", { + class: 'hour-hand', + x1: 0, + y1: 0, + x2: 0, + y2: hl, + stroke: '#8BC34A', + 'stroke-width': 8 + }); + + svgGElement.appendChild(svgMinuteHand); + svgGElement.appendChild(svgHourHand); } else { - this.$dtpElement.find('a.dtp-select-month-before').removeClass('invisible'); + var svgMinuteHand = this.createSVGElement("line", { + class: 'minute-hand', + x1: 0, + y1: 0, + x2: 0, + y2: -150, + stroke: '#8BC34A', + 'stroke-width': 2 + }); + var svgHourHand = this.createSVGElement("line", { + class: 'hour-hand', + x1: 0, + y1: 0, + x2: 0, + y2: hl, + stroke: '#bdbdbd', + 'stroke-width': 8 + }); + + svgGElement.appendChild(svgHourHand); + svgGElement.appendChild(svgMinuteHand); } - if (!this.isBeforeMaxDate(endOfMonth, false, false)) { - this.$dtpElement.find('a.dtp-select-month-after').addClass('invisible'); - } else { - this.$dtpElement.find('a.dtp-select-month-after').removeClass('invisible'); - } + svgGElement.appendChild(svgClockCenter) - var startOfYear = moment(date).locale(this.params.lang).startOf('year'); - var endOfYear = moment(date).locale(this.params.lang).endOf('year'); + svgElement.appendChild(svgGElement) - if (!this.isAfterMinDate(startOfYear, false, false)) { - this.$dtpElement.find('a.dtp-select-year-before').addClass('invisible'); - } else { - this.$dtpElement.find('a.dtp-select-year-before').removeClass('invisible'); - } - - if (!this.isBeforeMaxDate(endOfYear, false, false)) { - this.$dtpElement.find('a.dtp-select-year-after').addClass('invisible'); - } else { - this.$dtpElement.find('a.dtp-select-year-after').removeClass('invisible'); - } - } - }, - toggleTime: function (value, isHours) { - var result = false; - - if (isHours) { - var _date = moment(this.currentDate); - _date.hour(this.convertHours(value)).minute(0).second(0); - - result = !(this.isAfterMinDate(_date, true, false) === false || this.isBeforeMaxDate(_date, true, false) === false); - } else { - var _date = moment(this.currentDate); - _date.minute(value).second(0); - - result = !(this.isAfterMinDate(_date, true, true) === false || this.isBeforeMaxDate(_date, true, true) === false); - } - - return result; - }, - _attachEvent: function (el, ev, fn) { - el.on(ev, null, null, fn); - this._attachedEvents.push([el, ev, fn]); - }, - _detachEvents: function () { - for (var i = this._attachedEvents.length - 1; i >= 0; i--) { - this._attachedEvents[i][0].off(this._attachedEvents[i][1], this._attachedEvents[i][2]); - this._attachedEvents.splice(i, 1); - } - }, - _fireCalendar: function () { - this.currentView = 0; - this.$element.blur(); - - this.initDates(); - - this.show(); - - if (this.params.date) { - this.$dtpElement.find('.dtp-date').removeClass('hidden'); - this.initDate(); - } else { - if (this.params.time) { - this.$dtpElement.find('.dtp-time').removeClass('hidden'); - this.initHours(); - } - } - }, - _onBackgroundClick: function (e) { - e.stopPropagation(); - this.hide(); - }, - _onElementClick: function (e) { - e.stopPropagation(); - }, - _onKeydown: function (e) { - if (e.which === 27) { - this.hide(); - } - }, - _onCloseClick: function () { - this.hide(); - }, - _onClearClick: function () { - this.currentDate = null; - this.$element.trigger('beforeChange', this.currentDate); - this.hide(); - if (typeof ($.material) !== 'undefined') { - this.$element.addClass('empty'); - } - this.$element.val(''); - this.$element.trigger('change', this.currentDate); - }, - _onNowClick: function () { - this.currentDate = moment(); - - if (this.params.date === true) { - this.showDate(this.currentDate); - - if (this.currentView === 0) { - this.initDate(); - } - } - - if (this.params.time === true) { - this.showTime(this.currentDate); - - switch (this.currentView) { - case 1 : - this.initHours(); - break; - case 2 : - this.initMinutes(); - break; - } + this.$dtpElement.find("#dtp-svg-clock").empty(); + this.$dtpElement.find("#dtp-svg-clock")[0].appendChild(svgElement); this.animateHands(); - } - }, - _onOKClick: function () { - switch (this.currentView) { - case 0: - if (this.params.time === true) { - this.initHours(); - } else { - this.setElementValue(); - this.hide(); + + return svgGElement; + }, + createSVGElement: function (tag, attrs) { + var el = document.createElementNS('http://www.w3.org/2000/svg', tag); + for (var k in attrs) { + el.setAttribute(k, attrs[k]); + } + return el; + }, + isAfterMinDate: function (date, checkHour, checkMinute) { + var _return = true; + + if (typeof (this.minDate) !== 'undefined' && this.minDate !== null) { + var _minDate = moment(this.minDate); + var _date = moment(date); + + if (!checkHour && !checkMinute) { + _minDate.hour(0); + _minDate.minute(0); + + _date.hour(0); + _date.minute(0); } - break; - case 1: - this.initMinutes(); - break; - case 2: - this.setElementValue(); + + _minDate.second(0); + _date.second(0); + _minDate.millisecond(0); + _date.millisecond(0); + + if (!checkMinute) { + _date.minute(0); + _minDate.minute(0); + + _return = (parseInt(_date.format("X")) >= parseInt(_minDate.format("X"))); + } else { + _return = (parseInt(_date.format("X")) >= parseInt(_minDate.format("X"))); + } + } + + return _return; + }, + isBeforeMaxDate: function (date, checkTime, checkMinute) { + var _return = true; + + if (typeof (this.maxDate) !== 'undefined' && this.maxDate !== null) { + var _maxDate = moment(this.maxDate); + var _date = moment(date); + + if (!checkTime && !checkMinute) { + _maxDate.hour(0); + _maxDate.minute(0); + + _date.hour(0); + _date.minute(0); + } + + _maxDate.second(0); + _date.second(0); + _maxDate.millisecond(0); + _date.millisecond(0); + + if (!checkMinute) { + _date.minute(0); + _maxDate.minute(0); + + _return = (parseInt(_date.format("X")) <= parseInt(_maxDate.format("X"))); + } else { + _return = (parseInt(_date.format("X")) <= parseInt(_maxDate.format("X"))); + } + } + + return _return; + }, + rotateElement: function (el, deg) { + $(el).css + ({ + WebkitTransform: 'rotate(' + deg + 'deg)', + '-moz-transform': 'rotate(' + deg + 'deg)' + }); + }, + showDate: function (date) { + if (date) { + this.$dtpElement.find('.dtp-actual-day').html(date.locale(this.params.lang).format('dddd')); + this.$dtpElement.find('.dtp-actual-month').html(date.locale(this.params.lang).format('MMM').toUpperCase()); + this.$dtpElement.find('.dtp-actual-num').html(date.locale(this.params.lang).format('DD')); + this.$dtpElement.find('.dtp-actual-year').html(date.locale(this.params.lang).format('YYYY')); + } + }, + showTime: function (date) { + if (date) { + var minutes = date.minute(); + var content = ((this.params.shortTime) ? date.format('hh') : date.format('HH')) + ':' + ((minutes.toString().length == 2) ? minutes : '0' + minutes) + ((this.params.shortTime) ? ' ' + date.format('A') : ''); + + if (this.params.date) + this.$dtpElement.find('.dtp-actual-time').html(content); + else { + if (this.params.shortTime) + this.$dtpElement.find('.dtp-actual-day').html(date.format('A')); + else + this.$dtpElement.find('.dtp-actual-day').html(' '); + + this.$dtpElement.find('.dtp-actual-maxtime').html(content); + } + } + }, + selectDate: function (date) { + if (date) { + this.currentDate.date(date); + + this.showDate(this.currentDate); + this.$element.trigger('dateSelected', this.currentDate); + } + }, + generateCalendar: function (date) { + var _calendar = {}; + + if (date !== null) { + var startOfMonth = moment(date).locale(this.params.lang).startOf('month'); + var endOfMonth = moment(date).locale(this.params.lang).endOf('month'); + + var iNumDay = startOfMonth.format('d'); + + _calendar.week = this.days; + _calendar.days = []; + + for (var i = startOfMonth.date(); i <= endOfMonth.date(); i++) { + if (i === startOfMonth.date()) { + var iWeek = _calendar.week.indexOf(iNumDay.toString()); + if (iWeek > 0) { + for (var x = 0; x < iWeek; x++) { + _calendar.days.push(0); + } + } + } + _calendar.days.push(moment(startOfMonth).locale(this.params.lang).date(i)); + } + } + + return _calendar; + }, + constructHTMLCalendar: function (date, calendar) { + var _template = ""; + + _template += '
' + date.locale(this.params.lang).format('MMMM YYYY') + '
'; + _template += ''; + for (var i = 0; i < calendar.week.length; i++) { + _template += ''; + } + + _template += ''; + _template += ''; + + for (var i = 0; i < calendar.days.length; i++) { + if (i % 7 == 0) + _template += ''; + _template += ''; + } + } + _template += '
' + moment(parseInt(calendar.week[i]), "d").locale(this.params.lang).format("dd").substring(0, 1) + '
'; + if (calendar.days[i] != 0) { + if (this.isBeforeMaxDate(moment(calendar.days[i]), false, false) === false || this.isAfterMinDate(moment(calendar.days[i]), false, false) === false) { + _template += '' + moment(calendar.days[i]).locale(this.params.lang).format("DD") + ''; + } else { + if (moment(calendar.days[i]).locale(this.params.lang).format("DD") === moment(this.currentDate).locale(this.params.lang).format("DD")) { + _template += '' + moment(calendar.days[i]).locale(this.params.lang).format("DD") + ''; + } else { + _template += '' + moment(calendar.days[i]).locale(this.params.lang).format("DD") + ''; + } + } + + _template += '
'; + + return _template; + }, + setName: function () { + var text = ""; + var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + for (var i = 0; i < 5; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + + return text; + }, + isPM: function () { + return this.$dtpElement.find('a.dtp-meridien-pm').hasClass('selected'); + }, + setElementValue: function () { + this.$element.trigger('beforeChange', this.currentDate); + if (this.$element.hasClass("mdl-textfield__input")) { + this.$element.removeClass('empty'); + this.$element.parent().addClass("is-dirty"); + } + + this.$element.val(moment(this.currentDate).locale(this.params.lang).format(this.params.format)); + + this.$element.trigger('change', this.currentDate); + }, + toggleButtons: function (date) { + if (date && date.isValid()) { + var startOfMonth = moment(date).locale(this.params.lang).startOf('month'); + var endOfMonth = moment(date).locale(this.params.lang).endOf('month'); + + if (!this.isAfterMinDate(startOfMonth, false, false)) { + this.$dtpElement.find('a.dtp-select-month-before').addClass('invisible'); + } else { + this.$dtpElement.find('a.dtp-select-month-before').removeClass('invisible'); + } + + if (!this.isBeforeMaxDate(endOfMonth, false, false)) { + this.$dtpElement.find('a.dtp-select-month-after').addClass('invisible'); + } else { + this.$dtpElement.find('a.dtp-select-month-after').removeClass('invisible'); + } + + var startOfYear = moment(date).locale(this.params.lang).startOf('year'); + var endOfYear = moment(date).locale(this.params.lang).endOf('year'); + + if (!this.isAfterMinDate(startOfYear, false, false)) { + this.$dtpElement.find('a.dtp-select-year-before').addClass('invisible'); + } else { + this.$dtpElement.find('a.dtp-select-year-before').removeClass('invisible'); + } + + if (!this.isBeforeMaxDate(endOfYear, false, false)) { + this.$dtpElement.find('a.dtp-select-year-after').addClass('invisible'); + } else { + this.$dtpElement.find('a.dtp-select-year-after').removeClass('invisible'); + } + } + }, + toggleTime: function (value, isHours) { + var result = false; + + if (isHours) { + var _date = moment(this.currentDate); + _date.hour(this.convertHours(value)).minute(0).second(0); + + result = !(this.isAfterMinDate(_date, true, false) === false || this.isBeforeMaxDate(_date, true, false) === false); + } else { + var _date = moment(this.currentDate); + _date.minute(value).second(0); + + result = !(this.isAfterMinDate(_date, true, true) === false || this.isBeforeMaxDate(_date, true, true) === false); + } + + return result; + }, + _attachEvent: function (el, ev, fn) { + el.on(ev, null, null, fn); + this._attachedEvents.push([el, ev, fn]); + }, + _detachEvents: function () { + for (var i = this._attachedEvents.length - 1; i >= 0; i--) { + this._attachedEvents[i][0].off(this._attachedEvents[i][1], this._attachedEvents[i][2]); + this._attachedEvents.splice(i, 1); + } + }, + _fireCalendar: function () { + this.currentView = 0; + this.$element.blur(); + + this.initDates(); + + this.show(); + + if (this.params.date) { + this.$dtpElement.find('.dtp-date').removeClass('hidden'); + this.initDate(); + } else { + if (this.params.time) { + this.$dtpElement.find('.dtp-time').removeClass('hidden'); + this.initHours(); + } + } + }, + _onBackgroundClick: function (e) { + e.stopPropagation(); + this.hide(); + }, + _onElementClick: function (e) { + e.stopPropagation(); + }, + _onKeydown: function (e) { + if (e.which === 27) { this.hide(); - break; - } - }, - _onCancelClick: function () { - if (this.params.time) { + } + }, + _onCloseClick: function () { + this.hide(); + }, + _onClearClick: function () { + this.currentDate = null; + this.$element.trigger('beforeChange', this.currentDate); + this.hide(); + if (typeof ($.material) !== 'undefined') { + this.$element.addClass('empty'); + } + this.$element.val(''); + this.$element.trigger('change', this.currentDate); + }, + _onNowClick: function () { + this.currentDate = moment(); + + if (this.params.date === true) { + this.showDate(this.currentDate); + + if (this.currentView === 0) { + this.initDate(); + } + } + + if (this.params.time === true) { + this.showTime(this.currentDate); + + switch (this.currentView) { + case 1 : + this.initHours(); + break; + case 2 : + this.initMinutes(); + break; + } + + this.animateHands(); + } + }, + _onOKClick: function () { switch (this.currentView) { case 0: - this.hide(); - break; - case 1: - if (this.params.date) { - this.initDate(); + if (this.params.time === true) { + this.initHours(); } else { + this.setElementValue(); this.hide(); } break; - case 2: - this.initHours(); + case 1: + this.initMinutes(); break; - } - } else { - this.hide(); - } - }, - _onMonthBeforeClick: function () { - this.currentDate.subtract(1, 'months'); - this.initDate(this.currentDate); - }, - _onMonthAfterClick: function () { - this.currentDate.add(1, 'months'); - this.initDate(this.currentDate); - }, - _onYearBeforeClick: function () { - this.currentDate.subtract(1, 'years'); - this.initDate(this.currentDate); - }, - _onYearAfterClick: function () { - this.currentDate.add(1, 'years'); - this.initDate(this.currentDate); - }, - _onSelectDate: function (e) { - this.$dtpElement.find('a.dtp-select-day').removeClass('selected'); - $(e.currentTarget).addClass('selected'); - - this.selectDate($(e.currentTarget).parent().data("date")); - - if (this.params.switchOnClick === true && this.params.time === true) - setTimeout(this.initHours.bind(this), 200); - - if (this.params.switchOnClick === true && this.params.time === false) { - setTimeout(this._onOKClick.bind(this), 200); - } - - }, - _onSelectHour: function (e) { - if (!$(e.target).hasClass('disabled')) { - var value = $(e.target).data('hour'); - var parent = $(e.target).parent(); - - var h = parent.find('.dtp-select-hour'); - for (var i = 0; i < h.length; i++) { - $(h[i]).attr('fill', 'transparent'); - } - var th = parent.find('.dtp-select-hour-text'); - for (var i = 0; i < th.length; i++) { - $(th[i]).attr('fill', '#000'); - } - - $(parent.find('#h-' + value)).attr('fill', '#8BC34A'); - $(parent.find('#th-' + value)).attr('fill', '#fff'); - - this.currentDate.hour(parseInt(value)); - - if (this.params.shortTime === true && this.isPM()) { - this.currentDate.add(12, 'hours'); - } - - this.showTime(this.currentDate); - - this.animateHands(); - - if (this.params.switchOnClick === true) - setTimeout(this.initMinutes.bind(this), 200); - } - }, - _onSelectMinute: function (e) { - if (!$(e.target).hasClass('disabled')) { - var value = $(e.target).data('minute'); - var parent = $(e.target).parent(); - - var m = parent.find('.dtp-select-minute'); - for (var i = 0; i < m.length; i++) { - $(m[i]).attr('fill', 'transparent'); - } - var tm = parent.find('.dtp-select-minute-text'); - for (var i = 0; i < tm.length; i++) { - $(tm[i]).attr('fill', '#000'); - } - - $(parent.find('#m-' + value)).attr('fill', '#8BC34A'); - $(parent.find('#tm-' + value)).attr('fill', '#fff'); - - this.currentDate.minute(parseInt(value)); - this.showTime(this.currentDate); - - this.animateHands(); - - if (this.params.switchOnClick === true) - setTimeout(function () { + case 2: this.setElementValue(); this.hide(); - }.bind(this), 200); - } - }, - _onSelectAM: function (e) { - $('.dtp-actual-meridien').find('a').removeClass('selected'); - $(e.currentTarget).addClass('selected'); + break; + } + }, + _onCancelClick: function () { + if (this.params.time) { + switch (this.currentView) { + case 0: + this.hide(); + break; + case 1: + if (this.params.date) { + this.initDate(); + } else { + this.hide(); + } + break; + case 2: + this.initHours(); + break; + } + } else { + this.hide(); + } + }, + _onMonthBeforeClick: function () { + this.currentDate.subtract(1, 'months'); + this.initDate(this.currentDate); + }, + _onMonthAfterClick: function () { + this.currentDate.add(1, 'months'); + this.initDate(this.currentDate); + }, + _onYearBeforeClick: function () { + this.currentDate.subtract(1, 'years'); + this.initDate(this.currentDate); + }, + _onYearAfterClick: function () { + this.currentDate.add(1, 'years'); + this.initDate(this.currentDate); + }, + _onSelectDate: function (e) { + this.$dtpElement.find('a.dtp-select-day').removeClass('selected'); + $(e.currentTarget).addClass('selected'); + + this.selectDate($(e.currentTarget).parent().data("date")); + + if (this.params.switchOnClick === true && this.params.time === true) + setTimeout(this.initHours.bind(this), 200); + + if (this.params.switchOnClick === true && this.params.time === false) { + setTimeout(this._onOKClick.bind(this), 200); + } + + }, + _onSelectHour: function (e) { + if (!$(e.target).hasClass('disabled')) { + var value = $(e.target).data('hour'); + var parent = $(e.target).parent(); + + var h = parent.find('.dtp-select-hour'); + for (var i = 0; i < h.length; i++) { + $(h[i]).attr('fill', 'transparent'); + } + var th = parent.find('.dtp-select-hour-text'); + for (var i = 0; i < th.length; i++) { + $(th[i]).attr('fill', '#000'); + } + + $(parent.find('#h-' + value)).attr('fill', '#8BC34A'); + $(parent.find('#th-' + value)).attr('fill', '#fff'); + + this.currentDate.hour(parseInt(value)); + + if (this.params.shortTime === true && this.isPM()) { + this.currentDate.add(12, 'hours'); + } - if (this.currentDate.hour() >= 12) { - if (this.currentDate.subtract(12, 'hours')) this.showTime(this.currentDate); - } - this.toggleTime((this.currentView === 1)); - }, - _onSelectPM: function (e) { - $('.dtp-actual-meridien').find('a').removeClass('selected'); - $(e.currentTarget).addClass('selected'); - if (this.currentDate.hour() < 12) { - if (this.currentDate.add(12, 'hours')) + this.animateHands(); + + if (this.params.switchOnClick === true) + setTimeout(this.initMinutes.bind(this), 200); + } + }, + _onSelectMinute: function (e) { + if (!$(e.target).hasClass('disabled')) { + var value = $(e.target).data('minute'); + var parent = $(e.target).parent(); + + var m = parent.find('.dtp-select-minute'); + for (var i = 0; i < m.length; i++) { + $(m[i]).attr('fill', 'transparent'); + } + var tm = parent.find('.dtp-select-minute-text'); + for (var i = 0; i < tm.length; i++) { + $(tm[i]).attr('fill', '#000'); + } + + $(parent.find('#m-' + value)).attr('fill', '#8BC34A'); + $(parent.find('#tm-' + value)).attr('fill', '#fff'); + + this.currentDate.minute(parseInt(value)); this.showTime(this.currentDate); - } - this.toggleTime((this.currentView === 1)); - }, - convertHours: function (h) { - var _return = h; - if (this.params.shortTime === true) { - if ((h < 12) && this.isPM()) { - _return += 12; + this.animateHands(); + + if (this.params.switchOnClick === true) + setTimeout(function () { + this.setElementValue(); + this.hide(); + }.bind(this), 200); + } + }, + _onSelectAM: function (e) { + $('.dtp-actual-meridien').find('a').removeClass('selected'); + $(e.currentTarget).addClass('selected'); + + if (this.currentDate.hour() >= 12) { + if (this.currentDate.subtract(12, 'hours')) + this.showTime(this.currentDate); + } + this.toggleTime((this.currentView === 1)); + }, + _onSelectPM: function (e) { + $('.dtp-actual-meridien').find('a').removeClass('selected'); + $(e.currentTarget).addClass('selected'); + + if (this.currentDate.hour() < 12) { + if (this.currentDate.add(12, 'hours')) + this.showTime(this.currentDate); + } + this.toggleTime((this.currentView === 1)); + }, + convertHours: function (h) { + var _return = h; + + if (this.params.shortTime === true) { + if ((h < 12) && this.isPM()) { + _return += 12; + } + } + + return _return; + }, + setDate: function (date) { + this.params.currentDate = date; + this.initDates(); + }, + setMinDate: function (date) { + this.params.minDate = date; + this.initDates(); + }, + setMaxDate: function (date) { + this.params.maxDate = date; + this.initDates(); + }, + destroy: function () { + this._detachEvents(); + this.$dtpElement.remove(); + }, + show: function () { + this.$dtpElement.removeClass('hidden'); + this._attachEvent($(window), 'keydown', this._onKeydown.bind(this)); + this._centerBox(); + }, + hide: function () { + $(window).off('keydown', null, null, this._onKeydown.bind(this)); + this.$dtpElement.addClass('hidden'); + }, + _centerBox: function () { + var h = (this.$dtpElement.height() - this.$dtpElement.find('.dtp-content').height()) / 2; + this.$dtpElement.find('.dtp-content').css('marginLeft', -(this.$dtpElement.find('.dtp-content').width() / 2) + 'px'); + this.$dtpElement.find('.dtp-content').css('top', h + 'px'); + }, + enableDays: function () { + var enableDays = this.params.enableDays; + if (enableDays) { + $(".dtp-picker-days tbody tr td").each(function () { + if (!(($.inArray($(this).index(), enableDays)) >= 0)) { + $(this).find('a').css({ + "background": "#e3e3e3", + "cursor": "no-drop", + "opacity": "0.5" + }).off("click"); + } + }); } } - return _return; - }, - setDate: function (date) { - this.params.currentDate = date; - this.initDates(); - }, - setMinDate: function (date) { - this.params.minDate = date; - this.initDates(); - }, - setMaxDate: function (date) { - this.params.maxDate = date; - this.initDates(); - }, - destroy: function () { - this._detachEvents(); - this.$dtpElement.remove(); - }, - show: function () { - this.$dtpElement.removeClass('hidden'); - this._attachEvent($(window), 'keydown', this._onKeydown.bind(this)); - this._centerBox(); - }, - hide: function () { - $(window).off('keydown', null, null, this._onKeydown.bind(this)); - this.$dtpElement.addClass('hidden'); - }, - _centerBox: function () { - var h = (this.$dtpElement.height() - this.$dtpElement.find('.dtp-content').height()) / 2; - this.$dtpElement.find('.dtp-content').css('marginLeft', -(this.$dtpElement.find('.dtp-content').width() / 2) + 'px'); - this.$dtpElement.find('.dtp-content').css('top', h + 'px'); - }, - enableDays: function () { - var enableDays = this.params.enableDays; - if (enableDays) { - $(".dtp-picker-days tbody tr td").each(function () { - if (!(($.inArray($(this).index(), enableDays)) >= 0)) { - $(this).find('a').css({ - "background": "#e3e3e3", - "cursor": "no-drop", - "opacity": "0.5" - }).off("click"); - } - }); - } - } - - }; + }; })(jQuery, moment); \ No newline at end of file diff --git a/app/modules/web/themes/material-blue/js/bootstrap-material-datetimepicker.map b/app/modules/web/themes/material-blue/js/bootstrap-material-datetimepicker.map index 76f1256c..a30f6e13 100644 --- a/app/modules/web/themes/material-blue/js/bootstrap-material-datetimepicker.map +++ b/app/modules/web/themes/material-blue/js/bootstrap-material-datetimepicker.map @@ -1,8 +1,246 @@ { -"version":3, -"file":"bootstrap-material-datetimepicker.min.js", -"lineCount":48, -"mappings":"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", -"sources":[" [synthetic:base] "," [synthetic:util/findinternal] "," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:util/polyfill] "," [synthetic:es6/array/find] ","bootstrap-material-datetimepicker.js"], -"names":["$","moment","Plugin","element","options","currentView","minDate","maxDate","_attachedEvents","$element","params","date","time","format","currentDate","lang","weekStart","shortTime","clearButton","nowButton","cancelText","okText","clearText","nowText","switchOnClick","triggerEvent","fn","extend","name","setName","attr","locale","init","p","each","data","pluginDataName","removeData","prototype","initDays","initDates","initTemplate","initButtons","_attachEvent","window","_centerBox","bind","$dtpElement","find","_onElementClick","_onBackgroundClick","_onCloseClick","_fireCalendar","days","i","length","push","toString","val","isValid","x","getTime","isAfterMinDate","isBeforeMaxDate","template","$body","append","dtpElement","_onCancelClick","_onOKClick","_onMonthBeforeClick","_onMonthAfterClick","_onYearBeforeClick","_onYearAfterClick","_onClearClick","removeClass","_onNowClick","addClass","initMeridienButtons","off","on","_onSelectAM","_onSelectPM","initDate","d","_date","_calendar","generateCalendar","week","_template","constructHTMLCalendar","html","_onSelectDate","toggleButtons","showDate","initHours","showTime","hour","click","hFormat","svgClockElement","createSVGClock","Math","sin","PI","y","cos","fill","color","svgHourCircle","createSVGElement","r","cx","cy","svgHourText","textContent","toggleTime","addEventListener","_onSelectHour","className","setAttribute","appendChild","initMinutes","s","svgMinuteCircle","_onSelectMinute","svgMinuteText","animateHands","H","M","minute","hh","mh","isHour","hl","svgElement","class","viewBox","svgGElement","transform","svgClockFace","stroke","svgClockCenter","svgMinuteHand","x1","y1","x2","y2","svgHourHand","empty","tag","attrs","el","document","createElementNS","k","checkHour","checkMinute","_return","_minDate","second","millisecond","parseInt","checkTime","_maxDate","rotateElement","deg","css","WebkitTransform","toUpperCase","minutes","content","selectDate","trigger","startOfMonth","startOf","endOfMonth","endOf","iNumDay","iWeek","indexOf","calendar","substring","text","possible","charAt","floor","random","isPM","hasClass","setElementValue","parent","startOfYear","endOfYear","value","isHours","result","convertHours","ev","_detachEvents","splice","blur","show","e","stopPropagation","hide","_onKeydown","which","material","subtract","add","currentTarget","setTimeout","target","h","th","m","tm","setDate","setMinDate","setMaxDate","destroy","remove","height","width","enableDays","inArray","index","jQuery"] + "version": 3, + "file": "bootstrap-material-datetimepicker.min.js", + "lineCount": 48, + "mappings": "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", + "sources": [ + " [synthetic:base] ", + " [synthetic:util/findinternal] ", + " [synthetic:util/defineproperty] ", + " [synthetic:util/global] ", + " [synthetic:util/polyfill] ", + " [synthetic:es6/array/find] ", + "bootstrap-material-datetimepicker.js" + ], + "names": [ + "$", + "moment", + "Plugin", + "element", + "options", + "currentView", + "minDate", + "maxDate", + "_attachedEvents", + "$element", + "params", + "date", + "time", + "format", + "currentDate", + "lang", + "weekStart", + "shortTime", + "clearButton", + "nowButton", + "cancelText", + "okText", + "clearText", + "nowText", + "switchOnClick", + "triggerEvent", + "fn", + "extend", + "name", + "setName", + "attr", + "locale", + "init", + "p", + "each", + "data", + "pluginDataName", + "removeData", + "prototype", + "initDays", + "initDates", + "initTemplate", + "initButtons", + "_attachEvent", + "window", + "_centerBox", + "bind", + "$dtpElement", + "find", + "_onElementClick", + "_onBackgroundClick", + "_onCloseClick", + "_fireCalendar", + "days", + "i", + "length", + "push", + "toString", + "val", + "isValid", + "x", + "getTime", + "isAfterMinDate", + "isBeforeMaxDate", + "template", + "$body", + "append", + "dtpElement", + "_onCancelClick", + "_onOKClick", + "_onMonthBeforeClick", + "_onMonthAfterClick", + "_onYearBeforeClick", + "_onYearAfterClick", + "_onClearClick", + "removeClass", + "_onNowClick", + "addClass", + "initMeridienButtons", + "off", + "on", + "_onSelectAM", + "_onSelectPM", + "initDate", + "d", + "_date", + "_calendar", + "generateCalendar", + "week", + "_template", + "constructHTMLCalendar", + "html", + "_onSelectDate", + "toggleButtons", + "showDate", + "initHours", + "showTime", + "hour", + "click", + "hFormat", + "svgClockElement", + "createSVGClock", + "Math", + "sin", + "PI", + "y", + "cos", + "fill", + "color", + "svgHourCircle", + "createSVGElement", + "r", + "cx", + "cy", + "svgHourText", + "textContent", + "toggleTime", + "addEventListener", + "_onSelectHour", + "className", + "setAttribute", + "appendChild", + "initMinutes", + "s", + "svgMinuteCircle", + "_onSelectMinute", + "svgMinuteText", + "animateHands", + "H", + "M", + "minute", + "hh", + "mh", + "isHour", + "hl", + "svgElement", + "class", + "viewBox", + "svgGElement", + "transform", + "svgClockFace", + "stroke", + "svgClockCenter", + "svgMinuteHand", + "x1", + "y1", + "x2", + "y2", + "svgHourHand", + "empty", + "tag", + "attrs", + "el", + "document", + "createElementNS", + "k", + "checkHour", + "checkMinute", + "_return", + "_minDate", + "second", + "millisecond", + "parseInt", + "checkTime", + "_maxDate", + "rotateElement", + "deg", + "css", + "WebkitTransform", + "toUpperCase", + "minutes", + "content", + "selectDate", + "trigger", + "startOfMonth", + "startOf", + "endOfMonth", + "endOf", + "iNumDay", + "iWeek", + "indexOf", + "calendar", + "substring", + "text", + "possible", + "charAt", + "floor", + "random", + "isPM", + "hasClass", + "setElementValue", + "parent", + "startOfYear", + "endOfYear", + "value", + "isHours", + "result", + "convertHours", + "ev", + "_detachEvents", + "splice", + "blur", + "show", + "e", + "stopPropagation", + "hide", + "_onKeydown", + "which", + "material", + "subtract", + "add", + "currentTarget", + "setTimeout", + "target", + "h", + "th", + "m", + "tm", + "setDate", + "setMinDate", + "setMaxDate", + "destroy", + "remove", + "height", + "width", + "enableDays", + "inArray", + "index", + "jQuery" + ] } diff --git a/app/modules/web/themes/material-blue/js/material.js b/app/modules/web/themes/material-blue/js/material.js index 994825a4..7783dfa7 100644 --- a/app/modules/web/themes/material-blue/js/material.js +++ b/app/modules/web/themes/material-blue/js/material.js @@ -1,509 +1,518 @@ -;(function() { -"use strict"; +;(function () { + "use strict"; -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -/** - * A component handler interface using the revealing module design pattern. - * More details on this design pattern here: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @author Jason Mayes. - */ -/* exported componentHandler */ + /** + * A component handler interface using the revealing module design pattern. + * More details on this design pattern here: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @author Jason Mayes. + */ + /* exported componentHandler */ // Pre-defining the componentHandler interface, for closure documentation and // static verification. -var componentHandler = { - /** - * Searches existing DOM for elements of our component type and upgrades them - * if they have not already been upgraded. - * - * @param {string=} optJsClass the programatic name of the element class we - * need to create a new instance of. - * @param {string=} optCssClass the name of the CSS class elements of this - * type will have. - */ - upgradeDom: function(optJsClass, optCssClass) {}, - /** - * Upgrades a specific element rather than all in the DOM. - * - * @param {!Element} element The element we wish to upgrade. - * @param {string=} optJsClass Optional name of the class we want to upgrade - * the element to. - */ - upgradeElement: function(element, optJsClass) {}, - /** - * Upgrades a specific list of elements rather than all in the DOM. - * - * @param {!Element|!Array|!NodeList|!HTMLCollection} elements - * The elements we wish to upgrade. - */ - upgradeElements: function(elements) {}, - /** - * Upgrades all registered components found in the current DOM. This is - * automatically called on window load. - */ - upgradeAllRegistered: function() {}, - /** - * Allows user to be alerted to any upgrades that are performed for a given - * component type - * - * @param {string} jsClass The class name of the MDL component we wish - * to hook into for any upgrades performed. - * @param {function(!HTMLElement)} callback The function to call upon an - * upgrade. This function should expect 1 parameter - the HTMLElement which - * got upgraded. - */ - registerUpgradedCallback: function(jsClass, callback) {}, - /** - * Registers a class for future use and attempts to upgrade existing DOM. - * - * @param {componentHandler.ComponentConfigPublic} config the registration configuration - */ - register: function(config) {}, - /** - * Downgrade either a given node, an array of nodes, or a NodeList. - * - * @param {!Node|!Array|!NodeList} nodes - */ - downgradeElements: function(nodes) {} -}; - -componentHandler = (function() { - 'use strict'; - - /** @type {!Array} */ - var registeredComponents_ = []; - - /** @type {!Array} */ - var createdComponents_ = []; - - var componentConfigProperty_ = 'mdlComponentConfigInternal_'; - - /** - * Searches registered components for a class we are interested in using. - * Optionally replaces a match with passed object if specified. - * - * @param {string} name The name of a class we want to use. - * @param {componentHandler.ComponentConfig=} optReplace Optional object to replace match with. - * @return {!Object|boolean} - * @private - */ - function findRegisteredClass_(name, optReplace) { - for (var i = 0; i < registeredComponents_.length; i++) { - if (registeredComponents_[i].className === name) { - if (typeof optReplace !== 'undefined') { - registeredComponents_[i] = optReplace; + var componentHandler = { + /** + * Searches existing DOM for elements of our component type and upgrades them + * if they have not already been upgraded. + * + * @param {string=} optJsClass the programatic name of the element class we + * need to create a new instance of. + * @param {string=} optCssClass the name of the CSS class elements of this + * type will have. + */ + upgradeDom: function (optJsClass, optCssClass) { + }, + /** + * Upgrades a specific element rather than all in the DOM. + * + * @param {!Element} element The element we wish to upgrade. + * @param {string=} optJsClass Optional name of the class we want to upgrade + * the element to. + */ + upgradeElement: function (element, optJsClass) { + }, + /** + * Upgrades a specific list of elements rather than all in the DOM. + * + * @param {!Element|!Array|!NodeList|!HTMLCollection} elements + * The elements we wish to upgrade. + */ + upgradeElements: function (elements) { + }, + /** + * Upgrades all registered components found in the current DOM. This is + * automatically called on window load. + */ + upgradeAllRegistered: function () { + }, + /** + * Allows user to be alerted to any upgrades that are performed for a given + * component type + * + * @param {string} jsClass The class name of the MDL component we wish + * to hook into for any upgrades performed. + * @param {function(!HTMLElement)} callback The function to call upon an + * upgrade. This function should expect 1 parameter - the HTMLElement which + * got upgraded. + */ + registerUpgradedCallback: function (jsClass, callback) { + }, + /** + * Registers a class for future use and attempts to upgrade existing DOM. + * + * @param {componentHandler.ComponentConfigPublic} config the registration configuration + */ + register: function (config) { + }, + /** + * Downgrade either a given node, an array of nodes, or a NodeList. + * + * @param {!Node|!Array|!NodeList} nodes + */ + downgradeElements: function (nodes) { } - return registeredComponents_[i]; - } - } - return false; - } - - /** - * Returns an array of the classNames of the upgraded classes on the element. - * - * @param {!Element} element The element to fetch data from. - * @return {!Array} - * @private - */ - function getUpgradedListOfElement_(element) { - var dataUpgraded = element.getAttribute('data-upgraded'); - // Use `['']` as default value to conform the `,name,name...` style. - return dataUpgraded === null ? [''] : dataUpgraded.split(','); - } - - /** - * Returns true if the given element has already been upgraded for the given - * class. - * - * @param {!Element} element The element we want to check. - * @param {string} jsClass The class to check for. - * @returns {boolean} - * @private - */ - function isElementUpgraded_(element, jsClass) { - var upgradedList = getUpgradedListOfElement_(element); - return upgradedList.indexOf(jsClass) !== -1; - } - - /** - * Create an event object. - * - * @param {string} eventType The type name of the event. - * @param {boolean} bubbles Whether the event should bubble up the DOM. - * @param {boolean} cancelable Whether the event can be canceled. - * @returns {!Event} - */ - function createEvent_(eventType, bubbles, cancelable) { - if ('CustomEvent' in window && typeof window.CustomEvent === 'function') { - return new CustomEvent(eventType, { - bubbles: bubbles, - cancelable: cancelable - }); - } else { - var ev = document.createEvent('Events'); - ev.initEvent(eventType, bubbles, cancelable); - return ev; - } - } - - /** - * Searches existing DOM for elements of our component type and upgrades them - * if they have not already been upgraded. - * - * @param {string=} optJsClass the programatic name of the element class we - * need to create a new instance of. - * @param {string=} optCssClass the name of the CSS class elements of this - * type will have. - */ - function upgradeDomInternal(optJsClass, optCssClass) { - if (typeof optJsClass === 'undefined' && - typeof optCssClass === 'undefined') { - for (var i = 0; i < registeredComponents_.length; i++) { - upgradeDomInternal(registeredComponents_[i].className, - registeredComponents_[i].cssClass); - } - } else { - var jsClass = /** @type {string} */ (optJsClass); - if (typeof optCssClass === 'undefined') { - var registeredClass = findRegisteredClass_(jsClass); - if (registeredClass) { - optCssClass = registeredClass.cssClass; - } - } - - var elements = document.querySelectorAll('.' + optCssClass); - for (var n = 0; n < elements.length; n++) { - upgradeElementInternal(elements[n], jsClass); - } - } - } - - /** - * Upgrades a specific element rather than all in the DOM. - * - * @param {!Element} element The element we wish to upgrade. - * @param {string=} optJsClass Optional name of the class we want to upgrade - * the element to. - */ - function upgradeElementInternal(element, optJsClass) { - // Verify argument type. - if (!(typeof element === 'object' && element instanceof Element)) { - throw new Error('Invalid argument provided to upgrade MDL element.'); - } - // Allow upgrade to be canceled by canceling emitted event. - var upgradingEv = createEvent_('mdl-componentupgrading', true, true); - element.dispatchEvent(upgradingEv); - if (upgradingEv.defaultPrevented) { - return; - } - - var upgradedList = getUpgradedListOfElement_(element); - var classesToUpgrade = []; - // If jsClass is not provided scan the registered components to find the - // ones matching the element's CSS classList. - if (!optJsClass) { - var classList = element.classList; - registeredComponents_.forEach(function(component) { - // Match CSS & Not to be upgraded & Not upgraded. - if (classList.contains(component.cssClass) && - classesToUpgrade.indexOf(component) === -1 && - !isElementUpgraded_(element, component.className)) { - classesToUpgrade.push(component); - } - }); - } else if (!isElementUpgraded_(element, optJsClass)) { - classesToUpgrade.push(findRegisteredClass_(optJsClass)); - } - - // Upgrade the element for each classes. - for (var i = 0, n = classesToUpgrade.length, registeredClass; i < n; i++) { - registeredClass = classesToUpgrade[i]; - if (registeredClass) { - // Mark element as upgraded. - upgradedList.push(registeredClass.className); - element.setAttribute('data-upgraded', upgradedList.join(',')); - var instance = new registeredClass.classConstructor(element); - instance[componentConfigProperty_] = registeredClass; - createdComponents_.push(instance); - // Call any callbacks the user has registered with this component type. - for (var j = 0, m = registeredClass.callbacks.length; j < m; j++) { - registeredClass.callbacks[j](element); - } - - if (registeredClass.widget) { - // Assign per element instance for control over API - element[registeredClass.className] = instance; - } - } else { - throw new Error( - 'Unable to find a registered component for the given class.'); - } - - var upgradedEv = createEvent_('mdl-componentupgraded', true, false); - element.dispatchEvent(upgradedEv); - } - } - - /** - * Upgrades a specific list of elements rather than all in the DOM. - * - * @param {!Element|!Array|!NodeList|!HTMLCollection} elements - * The elements we wish to upgrade. - */ - function upgradeElementsInternal(elements) { - if (!Array.isArray(elements)) { - if (elements instanceof Element) { - elements = [elements]; - } else { - elements = Array.prototype.slice.call(elements); - } - } - for (var i = 0, n = elements.length, element; i < n; i++) { - element = elements[i]; - if (element instanceof HTMLElement) { - upgradeElementInternal(element); - if (element.children.length > 0) { - upgradeElementsInternal(element.children); - } - } - } - } - - /** - * Registers a class for future use and attempts to upgrade existing DOM. - * - * @param {componentHandler.ComponentConfigPublic} config - */ - function registerInternal(config) { - // In order to support both Closure-compiled and uncompiled code accessing - // this method, we need to allow for both the dot and array syntax for - // property access. You'll therefore see the `foo.bar || foo['bar']` - // pattern repeated across this method. - var widgetMissing = (typeof config.widget === 'undefined' && - typeof config['widget'] === 'undefined'); - var widget = true; - - if (!widgetMissing) { - widget = config.widget || config['widget']; - } - - var newConfig = /** @type {componentHandler.ComponentConfig} */ ({ - classConstructor: config.constructor || config['constructor'], - className: config.classAsString || config['classAsString'], - cssClass: config.cssClass || config['cssClass'], - widget: widget, - callbacks: [] - }); - - registeredComponents_.forEach(function(item) { - if (item.cssClass === newConfig.cssClass) { - throw new Error('The provided cssClass has already been registered: ' + item.cssClass); - } - if (item.className === newConfig.className) { - throw new Error('The provided className has already been registered'); - } - }); - - if (config.constructor.prototype - .hasOwnProperty(componentConfigProperty_)) { - throw new Error( - 'MDL component classes must not have ' + componentConfigProperty_ + - ' defined as a property.'); - } - - var found = findRegisteredClass_(config.classAsString, newConfig); - - if (!found) { - registeredComponents_.push(newConfig); - } - } - - /** - * Allows user to be alerted to any upgrades that are performed for a given - * component type - * - * @param {string} jsClass The class name of the MDL component we wish - * to hook into for any upgrades performed. - * @param {function(!HTMLElement)} callback The function to call upon an - * upgrade. This function should expect 1 parameter - the HTMLElement which - * got upgraded. - */ - function registerUpgradedCallbackInternal(jsClass, callback) { - var regClass = findRegisteredClass_(jsClass); - if (regClass) { - regClass.callbacks.push(callback); - } - } - - /** - * Upgrades all registered components found in the current DOM. This is - * automatically called on window load. - */ - function upgradeAllRegisteredInternal() { - for (var n = 0; n < registeredComponents_.length; n++) { - upgradeDomInternal(registeredComponents_[n].className); - } - } - - /** - * Check the component for the downgrade method. - * Execute if found. - * Remove component from createdComponents list. - * - * @param {?componentHandler.Component} component - */ - function deconstructComponentInternal(component) { - if (component) { - var componentIndex = createdComponents_.indexOf(component); - createdComponents_.splice(componentIndex, 1); - - var upgrades = component.element_.getAttribute('data-upgraded').split(','); - var componentPlace = upgrades.indexOf(component[componentConfigProperty_].classAsString); - upgrades.splice(componentPlace, 1); - component.element_.setAttribute('data-upgraded', upgrades.join(',')); - - var ev = createEvent_('mdl-componentdowngraded', true, false); - component.element_.dispatchEvent(ev); - } - } - - /** - * Downgrade either a given node, an array of nodes, or a NodeList. - * - * @param {!Node|!Array|!NodeList} nodes - */ - function downgradeNodesInternal(nodes) { - /** - * Auxiliary function to downgrade a single node. - * @param {!Node} node the node to be downgraded - */ - var downgradeNode = function(node) { - createdComponents_.filter(function(item) { - return item.element_ === node; - }).forEach(deconstructComponentInternal); }; - if (nodes instanceof Array || nodes instanceof NodeList) { - for (var n = 0; n < nodes.length; n++) { - downgradeNode(nodes[n]); - } - } else if (nodes instanceof Node) { - downgradeNode(nodes); - } else { - throw new Error('Invalid argument provided to downgrade MDL nodes.'); - } - } - // Now return the functions that should be made public with their publicly - // facing names... - return { - upgradeDom: upgradeDomInternal, - upgradeElement: upgradeElementInternal, - upgradeElements: upgradeElementsInternal, - upgradeAllRegistered: upgradeAllRegisteredInternal, - registerUpgradedCallback: registerUpgradedCallbackInternal, - register: registerInternal, - downgradeElements: downgradeNodesInternal - }; -})(); + componentHandler = (function () { + 'use strict'; -/** - * Describes the type of a registered component type managed by - * componentHandler. Provided for benefit of the Closure compiler. - * - * @typedef {{ - * constructor: Function, - * classAsString: string, - * cssClass: string, - * widget: (string|boolean|undefined) - * }} - */ -componentHandler.ComponentConfigPublic; // jshint ignore:line + /** @type {!Array} */ + var registeredComponents_ = []; -/** - * Describes the type of a registered component type managed by - * componentHandler. Provided for benefit of the Closure compiler. - * - * @typedef {{ - * constructor: !Function, - * className: string, - * cssClass: string, - * widget: (string|boolean), - * callbacks: !Array - * }} - */ -componentHandler.ComponentConfig; // jshint ignore:line + /** @type {!Array} */ + var createdComponents_ = []; -/** - * Created component (i.e., upgraded element) type as managed by - * componentHandler. Provided for benefit of the Closure compiler. - * - * @typedef {{ - * element_: !HTMLElement, - * className: string, - * classAsString: string, - * cssClass: string, - * widget: string - * }} - */ -componentHandler.Component; // jshint ignore:line + var componentConfigProperty_ = 'mdlComponentConfigInternal_'; + + /** + * Searches registered components for a class we are interested in using. + * Optionally replaces a match with passed object if specified. + * + * @param {string} name The name of a class we want to use. + * @param {componentHandler.ComponentConfig=} optReplace Optional object to replace match with. + * @return {!Object|boolean} + * @private + */ + function findRegisteredClass_(name, optReplace) { + for (var i = 0; i < registeredComponents_.length; i++) { + if (registeredComponents_[i].className === name) { + if (typeof optReplace !== 'undefined') { + registeredComponents_[i] = optReplace; + } + return registeredComponents_[i]; + } + } + return false; + } + + /** + * Returns an array of the classNames of the upgraded classes on the element. + * + * @param {!Element} element The element to fetch data from. + * @return {!Array} + * @private + */ + function getUpgradedListOfElement_(element) { + var dataUpgraded = element.getAttribute('data-upgraded'); + // Use `['']` as default value to conform the `,name,name...` style. + return dataUpgraded === null ? [''] : dataUpgraded.split(','); + } + + /** + * Returns true if the given element has already been upgraded for the given + * class. + * + * @param {!Element} element The element we want to check. + * @param {string} jsClass The class to check for. + * @returns {boolean} + * @private + */ + function isElementUpgraded_(element, jsClass) { + var upgradedList = getUpgradedListOfElement_(element); + return upgradedList.indexOf(jsClass) !== -1; + } + + /** + * Create an event object. + * + * @param {string} eventType The type name of the event. + * @param {boolean} bubbles Whether the event should bubble up the DOM. + * @param {boolean} cancelable Whether the event can be canceled. + * @returns {!Event} + */ + function createEvent_(eventType, bubbles, cancelable) { + if ('CustomEvent' in window && typeof window.CustomEvent === 'function') { + return new CustomEvent(eventType, { + bubbles: bubbles, + cancelable: cancelable + }); + } else { + var ev = document.createEvent('Events'); + ev.initEvent(eventType, bubbles, cancelable); + return ev; + } + } + + /** + * Searches existing DOM for elements of our component type and upgrades them + * if they have not already been upgraded. + * + * @param {string=} optJsClass the programatic name of the element class we + * need to create a new instance of. + * @param {string=} optCssClass the name of the CSS class elements of this + * type will have. + */ + function upgradeDomInternal(optJsClass, optCssClass) { + if (typeof optJsClass === 'undefined' && + typeof optCssClass === 'undefined') { + for (var i = 0; i < registeredComponents_.length; i++) { + upgradeDomInternal(registeredComponents_[i].className, + registeredComponents_[i].cssClass); + } + } else { + var jsClass = /** @type {string} */ (optJsClass); + if (typeof optCssClass === 'undefined') { + var registeredClass = findRegisteredClass_(jsClass); + if (registeredClass) { + optCssClass = registeredClass.cssClass; + } + } + + var elements = document.querySelectorAll('.' + optCssClass); + for (var n = 0; n < elements.length; n++) { + upgradeElementInternal(elements[n], jsClass); + } + } + } + + /** + * Upgrades a specific element rather than all in the DOM. + * + * @param {!Element} element The element we wish to upgrade. + * @param {string=} optJsClass Optional name of the class we want to upgrade + * the element to. + */ + function upgradeElementInternal(element, optJsClass) { + // Verify argument type. + if (!(typeof element === 'object' && element instanceof Element)) { + throw new Error('Invalid argument provided to upgrade MDL element.'); + } + // Allow upgrade to be canceled by canceling emitted event. + var upgradingEv = createEvent_('mdl-componentupgrading', true, true); + element.dispatchEvent(upgradingEv); + if (upgradingEv.defaultPrevented) { + return; + } + + var upgradedList = getUpgradedListOfElement_(element); + var classesToUpgrade = []; + // If jsClass is not provided scan the registered components to find the + // ones matching the element's CSS classList. + if (!optJsClass) { + var classList = element.classList; + registeredComponents_.forEach(function (component) { + // Match CSS & Not to be upgraded & Not upgraded. + if (classList.contains(component.cssClass) && + classesToUpgrade.indexOf(component) === -1 && + !isElementUpgraded_(element, component.className)) { + classesToUpgrade.push(component); + } + }); + } else if (!isElementUpgraded_(element, optJsClass)) { + classesToUpgrade.push(findRegisteredClass_(optJsClass)); + } + + // Upgrade the element for each classes. + for (var i = 0, n = classesToUpgrade.length, registeredClass; i < n; i++) { + registeredClass = classesToUpgrade[i]; + if (registeredClass) { + // Mark element as upgraded. + upgradedList.push(registeredClass.className); + element.setAttribute('data-upgraded', upgradedList.join(',')); + var instance = new registeredClass.classConstructor(element); + instance[componentConfigProperty_] = registeredClass; + createdComponents_.push(instance); + // Call any callbacks the user has registered with this component type. + for (var j = 0, m = registeredClass.callbacks.length; j < m; j++) { + registeredClass.callbacks[j](element); + } + + if (registeredClass.widget) { + // Assign per element instance for control over API + element[registeredClass.className] = instance; + } + } else { + throw new Error( + 'Unable to find a registered component for the given class.'); + } + + var upgradedEv = createEvent_('mdl-componentupgraded', true, false); + element.dispatchEvent(upgradedEv); + } + } + + /** + * Upgrades a specific list of elements rather than all in the DOM. + * + * @param {!Element|!Array|!NodeList|!HTMLCollection} elements + * The elements we wish to upgrade. + */ + function upgradeElementsInternal(elements) { + if (!Array.isArray(elements)) { + if (elements instanceof Element) { + elements = [elements]; + } else { + elements = Array.prototype.slice.call(elements); + } + } + for (var i = 0, n = elements.length, element; i < n; i++) { + element = elements[i]; + if (element instanceof HTMLElement) { + upgradeElementInternal(element); + if (element.children.length > 0) { + upgradeElementsInternal(element.children); + } + } + } + } + + /** + * Registers a class for future use and attempts to upgrade existing DOM. + * + * @param {componentHandler.ComponentConfigPublic} config + */ + function registerInternal(config) { + // In order to support both Closure-compiled and uncompiled code accessing + // this method, we need to allow for both the dot and array syntax for + // property access. You'll therefore see the `foo.bar || foo['bar']` + // pattern repeated across this method. + var widgetMissing = (typeof config.widget === 'undefined' && + typeof config['widget'] === 'undefined'); + var widget = true; + + if (!widgetMissing) { + widget = config.widget || config['widget']; + } + + var newConfig = /** @type {componentHandler.ComponentConfig} */ ({ + classConstructor: config.constructor || config['constructor'], + className: config.classAsString || config['classAsString'], + cssClass: config.cssClass || config['cssClass'], + widget: widget, + callbacks: [] + }); + + registeredComponents_.forEach(function (item) { + if (item.cssClass === newConfig.cssClass) { + throw new Error('The provided cssClass has already been registered: ' + item.cssClass); + } + if (item.className === newConfig.className) { + throw new Error('The provided className has already been registered'); + } + }); + + if (config.constructor.prototype + .hasOwnProperty(componentConfigProperty_)) { + throw new Error( + 'MDL component classes must not have ' + componentConfigProperty_ + + ' defined as a property.'); + } + + var found = findRegisteredClass_(config.classAsString, newConfig); + + if (!found) { + registeredComponents_.push(newConfig); + } + } + + /** + * Allows user to be alerted to any upgrades that are performed for a given + * component type + * + * @param {string} jsClass The class name of the MDL component we wish + * to hook into for any upgrades performed. + * @param {function(!HTMLElement)} callback The function to call upon an + * upgrade. This function should expect 1 parameter - the HTMLElement which + * got upgraded. + */ + function registerUpgradedCallbackInternal(jsClass, callback) { + var regClass = findRegisteredClass_(jsClass); + if (regClass) { + regClass.callbacks.push(callback); + } + } + + /** + * Upgrades all registered components found in the current DOM. This is + * automatically called on window load. + */ + function upgradeAllRegisteredInternal() { + for (var n = 0; n < registeredComponents_.length; n++) { + upgradeDomInternal(registeredComponents_[n].className); + } + } + + /** + * Check the component for the downgrade method. + * Execute if found. + * Remove component from createdComponents list. + * + * @param {?componentHandler.Component} component + */ + function deconstructComponentInternal(component) { + if (component) { + var componentIndex = createdComponents_.indexOf(component); + createdComponents_.splice(componentIndex, 1); + + var upgrades = component.element_.getAttribute('data-upgraded').split(','); + var componentPlace = upgrades.indexOf(component[componentConfigProperty_].classAsString); + upgrades.splice(componentPlace, 1); + component.element_.setAttribute('data-upgraded', upgrades.join(',')); + + var ev = createEvent_('mdl-componentdowngraded', true, false); + component.element_.dispatchEvent(ev); + } + } + + /** + * Downgrade either a given node, an array of nodes, or a NodeList. + * + * @param {!Node|!Array|!NodeList} nodes + */ + function downgradeNodesInternal(nodes) { + /** + * Auxiliary function to downgrade a single node. + * @param {!Node} node the node to be downgraded + */ + var downgradeNode = function (node) { + createdComponents_.filter(function (item) { + return item.element_ === node; + }).forEach(deconstructComponentInternal); + }; + if (nodes instanceof Array || nodes instanceof NodeList) { + for (var n = 0; n < nodes.length; n++) { + downgradeNode(nodes[n]); + } + } else if (nodes instanceof Node) { + downgradeNode(nodes); + } else { + throw new Error('Invalid argument provided to downgrade MDL nodes.'); + } + } + + // Now return the functions that should be made public with their publicly + // facing names... + return { + upgradeDom: upgradeDomInternal, + upgradeElement: upgradeElementInternal, + upgradeElements: upgradeElementsInternal, + upgradeAllRegistered: upgradeAllRegisteredInternal, + registerUpgradedCallback: registerUpgradedCallbackInternal, + register: registerInternal, + downgradeElements: downgradeNodesInternal + }; + })(); + + /** + * Describes the type of a registered component type managed by + * componentHandler. Provided for benefit of the Closure compiler. + * + * @typedef {{ + * constructor: Function, + * classAsString: string, + * cssClass: string, + * widget: (string|boolean|undefined) + * }} + */ + componentHandler.ComponentConfigPublic; // jshint ignore:line + + /** + * Describes the type of a registered component type managed by + * componentHandler. Provided for benefit of the Closure compiler. + * + * @typedef {{ + * constructor: !Function, + * className: string, + * cssClass: string, + * widget: (string|boolean), + * callbacks: !Array + * }} + */ + componentHandler.ComponentConfig; // jshint ignore:line + + /** + * Created component (i.e., upgraded element) type as managed by + * componentHandler. Provided for benefit of the Closure compiler. + * + * @typedef {{ + * element_: !HTMLElement, + * className: string, + * classAsString: string, + * cssClass: string, + * widget: string + * }} + */ + componentHandler.Component; // jshint ignore:line // Export all symbols, for the benefit of Closure compiler. // No effect on uncompiled code. -componentHandler['upgradeDom'] = componentHandler.upgradeDom; -componentHandler['upgradeElement'] = componentHandler.upgradeElement; -componentHandler['upgradeElements'] = componentHandler.upgradeElements; -componentHandler['upgradeAllRegistered'] = - componentHandler.upgradeAllRegistered; -componentHandler['registerUpgradedCallback'] = - componentHandler.registerUpgradedCallback; -componentHandler['register'] = componentHandler.register; -componentHandler['downgradeElements'] = componentHandler.downgradeElements; -window.componentHandler = componentHandler; -window['componentHandler'] = componentHandler; + componentHandler['upgradeDom'] = componentHandler.upgradeDom; + componentHandler['upgradeElement'] = componentHandler.upgradeElement; + componentHandler['upgradeElements'] = componentHandler.upgradeElements; + componentHandler['upgradeAllRegistered'] = + componentHandler.upgradeAllRegistered; + componentHandler['registerUpgradedCallback'] = + componentHandler.registerUpgradedCallback; + componentHandler['register'] = componentHandler.register; + componentHandler['downgradeElements'] = componentHandler.downgradeElements; + window.componentHandler = componentHandler; + window['componentHandler'] = componentHandler; -window.addEventListener('load', function() { - 'use strict'; + window.addEventListener('load', function () { + 'use strict'; - /** - * Performs a "Cutting the mustard" test. If the browser supports the features - * tested, adds a mdl-js class to the element. It then upgrades all MDL - * components requiring JavaScript. - */ - if ('classList' in document.createElement('div') && - 'querySelector' in document && - 'addEventListener' in window && Array.prototype.forEach) { - document.documentElement.classList.add('mdl-js'); - componentHandler.upgradeAllRegistered(); - } else { - /** - * Dummy function to avoid JS errors. - */ - componentHandler.upgradeElement = function() {}; - /** - * Dummy function to avoid JS errors. - */ - componentHandler.register = function() {}; - } -}); + /** + * Performs a "Cutting the mustard" test. If the browser supports the features + * tested, adds a mdl-js class to the element. It then upgrades all MDL + * components requiring JavaScript. + */ + if ('classList' in document.createElement('div') && + 'querySelector' in document && + 'addEventListener' in window && Array.prototype.forEach) { + document.documentElement.classList.add('mdl-js'); + componentHandler.upgradeAllRegistered(); + } else { + /** + * Dummy function to avoid JS errors. + */ + componentHandler.upgradeElement = function () { + }; + /** + * Dummy function to avoid JS errors. + */ + componentHandler.register = function () { + }; + } + }); // Source: https://github.com/darius/requestAnimationFrame/blob/master/requestAnimationFrame.js // Adapted from https://gist.github.com/paulirish/1579671 which derived from @@ -512,3485 +521,3490 @@ window.addEventListener('load', function() { // requestAnimationFrame polyfill by Erik Möller. // Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon // MIT license -if (!Date.now) { + if (!Date.now) { + /** + * Date.now polyfill. + * @return {number} the current Date + */ + Date.now = function () { + return new Date().getTime(); + }; + Date['now'] = Date.now; + } + var vendors = [ + 'webkit', + 'moz' + ]; + for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { + var vp = vendors[i]; + window.requestAnimationFrame = window[vp + 'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vp + 'CancelAnimationFrame'] || window[vp + 'CancelRequestAnimationFrame']; + window['requestAnimationFrame'] = window.requestAnimationFrame; + window['cancelAnimationFrame'] = window.cancelAnimationFrame; + } + if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) { + var lastTime = 0; + /** + * requestAnimationFrame polyfill. + * @param {!Function} callback the callback function. + */ + window.requestAnimationFrame = function (callback) { + var now = Date.now(); + var nextTime = Math.max(lastTime + 16, now); + return setTimeout(function () { + callback(lastTime = nextTime); + }, nextTime - now); + }; + window.cancelAnimationFrame = clearTimeout; + window['requestAnimationFrame'] = window.requestAnimationFrame; + window['cancelAnimationFrame'] = window.cancelAnimationFrame; + } /** - * Date.now polyfill. - * @return {number} the current Date + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ - Date.now = function () { - return new Date().getTime(); - }; - Date['now'] = Date.now; -} -var vendors = [ - 'webkit', - 'moz' -]; -for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) { - var vp = vendors[i]; - window.requestAnimationFrame = window[vp + 'RequestAnimationFrame']; - window.cancelAnimationFrame = window[vp + 'CancelAnimationFrame'] || window[vp + 'CancelRequestAnimationFrame']; - window['requestAnimationFrame'] = window.requestAnimationFrame; - window['cancelAnimationFrame'] = window.cancelAnimationFrame; -} -if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) { - var lastTime = 0; /** - * requestAnimationFrame polyfill. - * @param {!Function} callback the callback function. + * Class constructor for Button MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @param {HTMLElement} element The element that will be upgraded. */ - window.requestAnimationFrame = function (callback) { - var now = Date.now(); - var nextTime = Math.max(lastTime + 16, now); - return setTimeout(function () { - callback(lastTime = nextTime); - }, nextTime - now); + var MaterialButton = function MaterialButton(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialButton'] = MaterialButton; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialButton.prototype.Constant_ = {}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialButton.prototype.CssClasses_ = { + RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_CONTAINER: 'mdl-button__ripple-container', + RIPPLE: 'mdl-ripple' + }; + /** + * Handle blur of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialButton.prototype.blurHandler_ = function (event) { + if (event) { + this.element_.blur(); + } }; - window.cancelAnimationFrame = clearTimeout; - window['requestAnimationFrame'] = window.requestAnimationFrame; - window['cancelAnimationFrame'] = window.cancelAnimationFrame; -} -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Button MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @param {HTMLElement} element The element that will be upgraded. - */ -var MaterialButton = function MaterialButton(element) { - this.element_ = element; - // Initialize instance. - this.init(); -}; -window['MaterialButton'] = MaterialButton; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialButton.prototype.Constant_ = {}; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialButton.prototype.CssClasses_ = { - RIPPLE_EFFECT: 'mdl-js-ripple-effect', - RIPPLE_CONTAINER: 'mdl-button__ripple-container', - RIPPLE: 'mdl-ripple' -}; -/** - * Handle blur of element. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialButton.prototype.blurHandler_ = function (event) { - if (event) { - this.element_.blur(); - } -}; // Public methods. -/** - * Disable button. - * - * @public - */ -MaterialButton.prototype.disable = function () { - this.element_.disabled = true; -}; -MaterialButton.prototype['disable'] = MaterialButton.prototype.disable; -/** - * Enable button. - * - * @public - */ -MaterialButton.prototype.enable = function () { - this.element_.disabled = false; -}; -MaterialButton.prototype['enable'] = MaterialButton.prototype.enable; -/** - * Initialize element. - */ -MaterialButton.prototype.init = function () { - if (this.element_) { - if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { - var rippleContainer = document.createElement('span'); - rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER); - this.rippleElement_ = document.createElement('span'); - this.rippleElement_.classList.add(this.CssClasses_.RIPPLE); - rippleContainer.appendChild(this.rippleElement_); - this.boundRippleBlurHandler = this.blurHandler_.bind(this); - this.rippleElement_.addEventListener('mouseup', this.boundRippleBlurHandler); - this.element_.appendChild(rippleContainer); - } - this.boundButtonBlurHandler = this.blurHandler_.bind(this); - this.element_.addEventListener('mouseup', this.boundButtonBlurHandler); - this.element_.addEventListener('mouseleave', this.boundButtonBlurHandler); - } -}; -// The component registers itself. It can assume componentHandler is available -// in the global scope. -componentHandler.register({ - constructor: MaterialButton, - classAsString: 'MaterialButton', - cssClass: 'mdl-js-button', - widget: true -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Checkbox MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {HTMLElement} element The element that will be upgraded. - */ -var MaterialCheckbox = function MaterialCheckbox(element) { - this.element_ = element; - // Initialize instance. - this.init(); -}; -window['MaterialCheckbox'] = MaterialCheckbox; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialCheckbox.prototype.Constant_ = { TINY_TIMEOUT: 0.001 }; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialCheckbox.prototype.CssClasses_ = { - INPUT: 'mdl-checkbox__input', - BOX_OUTLINE: 'mdl-checkbox__box-outline', - FOCUS_HELPER: 'mdl-checkbox__focus-helper', - TICK_OUTLINE: 'mdl-checkbox__tick-outline', - RIPPLE_EFFECT: 'mdl-js-ripple-effect', - RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', - RIPPLE_CONTAINER: 'mdl-checkbox__ripple-container', - RIPPLE_CENTER: 'mdl-ripple--center', - RIPPLE: 'mdl-ripple', - IS_FOCUSED: 'is-focused', - IS_DISABLED: 'is-disabled', - IS_CHECKED: 'is-checked', - IS_UPGRADED: 'is-upgraded' -}; -/** - * Handle change of state. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialCheckbox.prototype.onChange_ = function (event) { - this.updateClasses_(); -}; -/** - * Handle focus of element. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialCheckbox.prototype.onFocus_ = function (event) { - this.element_.classList.add(this.CssClasses_.IS_FOCUSED); -}; -/** - * Handle lost focus of element. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialCheckbox.prototype.onBlur_ = function (event) { - this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); -}; -/** - * Handle mouseup. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialCheckbox.prototype.onMouseUp_ = function (event) { - this.blur_(); -}; -/** - * Handle class updates. - * - * @private - */ -MaterialCheckbox.prototype.updateClasses_ = function () { - this.checkDisabled(); - this.checkToggleState(); -}; -/** - * Add blur. - * - * @private - */ -MaterialCheckbox.prototype.blur_ = function () { - // TODO: figure out why there's a focus event being fired after our blur, - // so that we can avoid this hack. - window.setTimeout(function () { - this.inputElement_.blur(); - }.bind(this), this.Constant_.TINY_TIMEOUT); -}; -// Public methods. -/** - * Check the inputs toggle state and update display. - * - * @public - */ -MaterialCheckbox.prototype.checkToggleState = function () { - if (this.inputElement_.checked) { - this.element_.classList.add(this.CssClasses_.IS_CHECKED); - } else { - this.element_.classList.remove(this.CssClasses_.IS_CHECKED); - } -}; -MaterialCheckbox.prototype['checkToggleState'] = MaterialCheckbox.prototype.checkToggleState; -/** - * Check the inputs disabled state and update display. - * - * @public - */ -MaterialCheckbox.prototype.checkDisabled = function () { - if (this.inputElement_.disabled) { - this.element_.classList.add(this.CssClasses_.IS_DISABLED); - } else { - this.element_.classList.remove(this.CssClasses_.IS_DISABLED); - } -}; -MaterialCheckbox.prototype['checkDisabled'] = MaterialCheckbox.prototype.checkDisabled; -/** - * Disable checkbox. - * - * @public - */ -MaterialCheckbox.prototype.disable = function () { - this.inputElement_.disabled = true; - this.updateClasses_(); -}; -MaterialCheckbox.prototype['disable'] = MaterialCheckbox.prototype.disable; -/** - * Enable checkbox. - * - * @public - */ -MaterialCheckbox.prototype.enable = function () { - this.inputElement_.disabled = false; - this.updateClasses_(); -}; -MaterialCheckbox.prototype['enable'] = MaterialCheckbox.prototype.enable; -/** - * Check checkbox. - * - * @public - */ -MaterialCheckbox.prototype.check = function () { - this.inputElement_.checked = true; - this.updateClasses_(); -}; -MaterialCheckbox.prototype['check'] = MaterialCheckbox.prototype.check; -/** - * Uncheck checkbox. - * - * @public - */ -MaterialCheckbox.prototype.uncheck = function () { - this.inputElement_.checked = false; - this.updateClasses_(); -}; -MaterialCheckbox.prototype['uncheck'] = MaterialCheckbox.prototype.uncheck; -/** - * Initialize element. - */ -MaterialCheckbox.prototype.init = function () { - if (this.element_) { - this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT); - var boxOutline = document.createElement('span'); - boxOutline.classList.add(this.CssClasses_.BOX_OUTLINE); - var tickContainer = document.createElement('span'); - tickContainer.classList.add(this.CssClasses_.FOCUS_HELPER); - var tickOutline = document.createElement('span'); - tickOutline.classList.add(this.CssClasses_.TICK_OUTLINE); - boxOutline.appendChild(tickOutline); - this.element_.appendChild(tickContainer); - this.element_.appendChild(boxOutline); - if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { - this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); - this.rippleContainerElement_ = document.createElement('span'); - this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER); - this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT); - this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER); - this.boundRippleMouseUp = this.onMouseUp_.bind(this); - this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp); - var ripple = document.createElement('span'); - ripple.classList.add(this.CssClasses_.RIPPLE); - this.rippleContainerElement_.appendChild(ripple); - this.element_.appendChild(this.rippleContainerElement_); - } - this.boundInputOnChange = this.onChange_.bind(this); - this.boundInputOnFocus = this.onFocus_.bind(this); - this.boundInputOnBlur = this.onBlur_.bind(this); - this.boundElementMouseUp = this.onMouseUp_.bind(this); - this.inputElement_.addEventListener('change', this.boundInputOnChange); - this.inputElement_.addEventListener('focus', this.boundInputOnFocus); - this.inputElement_.addEventListener('blur', this.boundInputOnBlur); - this.element_.addEventListener('mouseup', this.boundElementMouseUp); - this.updateClasses_(); - this.element_.classList.add(this.CssClasses_.IS_UPGRADED); - } -}; -// The component registers itself. It can assume componentHandler is available -// in the global scope. -componentHandler.register({ - constructor: MaterialCheckbox, - classAsString: 'MaterialCheckbox', - cssClass: 'mdl-js-checkbox', - widget: true -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for icon toggle MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {HTMLElement} element The element that will be upgraded. - */ -var MaterialIconToggle = function MaterialIconToggle(element) { - this.element_ = element; - // Initialize instance. - this.init(); -}; -window['MaterialIconToggle'] = MaterialIconToggle; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialIconToggle.prototype.Constant_ = { TINY_TIMEOUT: 0.001 }; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialIconToggle.prototype.CssClasses_ = { - INPUT: 'mdl-icon-toggle__input', - JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect', - RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', - RIPPLE_CONTAINER: 'mdl-icon-toggle__ripple-container', - RIPPLE_CENTER: 'mdl-ripple--center', - RIPPLE: 'mdl-ripple', - IS_FOCUSED: 'is-focused', - IS_DISABLED: 'is-disabled', - IS_CHECKED: 'is-checked' -}; -/** - * Handle change of state. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialIconToggle.prototype.onChange_ = function (event) { - this.updateClasses_(); -}; -/** - * Handle focus of element. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialIconToggle.prototype.onFocus_ = function (event) { - this.element_.classList.add(this.CssClasses_.IS_FOCUSED); -}; -/** - * Handle lost focus of element. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialIconToggle.prototype.onBlur_ = function (event) { - this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); -}; -/** - * Handle mouseup. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialIconToggle.prototype.onMouseUp_ = function (event) { - this.blur_(); -}; -/** - * Handle class updates. - * - * @private - */ -MaterialIconToggle.prototype.updateClasses_ = function () { - this.checkDisabled(); - this.checkToggleState(); -}; -/** - * Add blur. - * - * @private - */ -MaterialIconToggle.prototype.blur_ = function () { - // TODO: figure out why there's a focus event being fired after our blur, - // so that we can avoid this hack. - window.setTimeout(function () { - this.inputElement_.blur(); - }.bind(this), this.Constant_.TINY_TIMEOUT); -}; -// Public methods. -/** - * Check the inputs toggle state and update display. - * - * @public - */ -MaterialIconToggle.prototype.checkToggleState = function () { - if (this.inputElement_.checked) { - this.element_.classList.add(this.CssClasses_.IS_CHECKED); - } else { - this.element_.classList.remove(this.CssClasses_.IS_CHECKED); - } -}; -MaterialIconToggle.prototype['checkToggleState'] = MaterialIconToggle.prototype.checkToggleState; -/** - * Check the inputs disabled state and update display. - * - * @public - */ -MaterialIconToggle.prototype.checkDisabled = function () { - if (this.inputElement_.disabled) { - this.element_.classList.add(this.CssClasses_.IS_DISABLED); - } else { - this.element_.classList.remove(this.CssClasses_.IS_DISABLED); - } -}; -MaterialIconToggle.prototype['checkDisabled'] = MaterialIconToggle.prototype.checkDisabled; -/** - * Disable icon toggle. - * - * @public - */ -MaterialIconToggle.prototype.disable = function () { - this.inputElement_.disabled = true; - this.updateClasses_(); -}; -MaterialIconToggle.prototype['disable'] = MaterialIconToggle.prototype.disable; -/** - * Enable icon toggle. - * - * @public - */ -MaterialIconToggle.prototype.enable = function () { - this.inputElement_.disabled = false; - this.updateClasses_(); -}; -MaterialIconToggle.prototype['enable'] = MaterialIconToggle.prototype.enable; -/** - * Check icon toggle. - * - * @public - */ -MaterialIconToggle.prototype.check = function () { - this.inputElement_.checked = true; - this.updateClasses_(); -}; -MaterialIconToggle.prototype['check'] = MaterialIconToggle.prototype.check; -/** - * Uncheck icon toggle. - * - * @public - */ -MaterialIconToggle.prototype.uncheck = function () { - this.inputElement_.checked = false; - this.updateClasses_(); -}; -MaterialIconToggle.prototype['uncheck'] = MaterialIconToggle.prototype.uncheck; -/** - * Initialize element. - */ -MaterialIconToggle.prototype.init = function () { - if (this.element_) { - this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT); - if (this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) { - this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); - this.rippleContainerElement_ = document.createElement('span'); - this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER); - this.rippleContainerElement_.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT); - this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER); - this.boundRippleMouseUp = this.onMouseUp_.bind(this); - this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp); - var ripple = document.createElement('span'); - ripple.classList.add(this.CssClasses_.RIPPLE); - this.rippleContainerElement_.appendChild(ripple); - this.element_.appendChild(this.rippleContainerElement_); - } - this.boundInputOnChange = this.onChange_.bind(this); - this.boundInputOnFocus = this.onFocus_.bind(this); - this.boundInputOnBlur = this.onBlur_.bind(this); - this.boundElementOnMouseUp = this.onMouseUp_.bind(this); - this.inputElement_.addEventListener('change', this.boundInputOnChange); - this.inputElement_.addEventListener('focus', this.boundInputOnFocus); - this.inputElement_.addEventListener('blur', this.boundInputOnBlur); - this.element_.addEventListener('mouseup', this.boundElementOnMouseUp); - this.updateClasses_(); - this.element_.classList.add('is-upgraded'); - } -}; -// The component registers itself. It can assume componentHandler is available -// in the global scope. -componentHandler.register({ - constructor: MaterialIconToggle, - classAsString: 'MaterialIconToggle', - cssClass: 'mdl-js-icon-toggle', - widget: true -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for dropdown MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {HTMLElement} element The element that will be upgraded. - */ -var MaterialMenu = function MaterialMenu(element) { - this.element_ = element; - // Initialize instance. - this.init(); -}; -window['MaterialMenu'] = MaterialMenu; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialMenu.prototype.Constant_ = { - // Total duration of the menu animation. - TRANSITION_DURATION_SECONDS: 0.3, - // The fraction of the total duration we want to use for menu item animations. - TRANSITION_DURATION_FRACTION: 0.8, - // How long the menu stays open after choosing an option (so the user can see - // the ripple). - CLOSE_TIMEOUT: 150 -}; -/** - * Keycodes, for code readability. - * - * @enum {number} - * @private - */ -MaterialMenu.prototype.Keycodes_ = { - ENTER: 13, - ESCAPE: 27, - SPACE: 32, - UP_ARROW: 38, - DOWN_ARROW: 40 -}; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialMenu.prototype.CssClasses_ = { - CONTAINER: 'mdl-menu__container', - OUTLINE: 'mdl-menu__outline', - ITEM: 'mdl-menu__item', - ITEM_RIPPLE_CONTAINER: 'mdl-menu__item-ripple-container', - RIPPLE_EFFECT: 'mdl-js-ripple-effect', - RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', - RIPPLE: 'mdl-ripple', - // Statuses - IS_UPGRADED: 'is-upgraded', - IS_VISIBLE: 'is-visible', - IS_ANIMATING: 'is-animating', - // Alignment options - BOTTOM_LEFT: 'mdl-menu--bottom-left', - // This is the default. - BOTTOM_RIGHT: 'mdl-menu--bottom-right', - TOP_LEFT: 'mdl-menu--top-left', - TOP_RIGHT: 'mdl-menu--top-right', - UNALIGNED: 'mdl-menu--unaligned' -}; -/** - * Initialize element. - */ -MaterialMenu.prototype.init = function () { - if (this.element_) { - // Create container for the menu. - var container = document.createElement('div'); - container.classList.add(this.CssClasses_.CONTAINER); - this.element_.parentElement.insertBefore(container, this.element_); - this.element_.parentElement.removeChild(this.element_); - container.appendChild(this.element_); - this.container_ = container; - // Create outline for the menu (shadow and background). - var outline = document.createElement('div'); - outline.classList.add(this.CssClasses_.OUTLINE); - this.outline_ = outline; - container.insertBefore(outline, this.element_); - // Find the "for" element and bind events to it. - var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for'); - var forEl = null; - if (forElId) { - forEl = document.getElementById(forElId); - if (forEl) { - this.forElement_ = forEl; - forEl.addEventListener('click', this.handleForClick_.bind(this)); - forEl.addEventListener('keydown', this.handleForKeyboardEvent_.bind(this)); - } - } - var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM); - this.boundItemKeydown_ = this.handleItemKeyboardEvent_.bind(this); - this.boundItemClick_ = this.handleItemClick_.bind(this); - for (var i = 0; i < items.length; i++) { - // Add a listener to each menu item. - items[i].addEventListener('click', this.boundItemClick_); - // Add a tab index to each menu item. - items[i].tabIndex = '-1'; - // Add a keyboard listener to each menu item. - items[i].addEventListener('keydown', this.boundItemKeydown_); - } - // Add ripple classes to each item, if the user has enabled ripples. - if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { - this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); - for (i = 0; i < items.length; i++) { - var item = items[i]; + /** + * Disable button. + * + * @public + */ + MaterialButton.prototype.disable = function () { + this.element_.disabled = true; + }; + MaterialButton.prototype['disable'] = MaterialButton.prototype.disable; + /** + * Enable button. + * + * @public + */ + MaterialButton.prototype.enable = function () { + this.element_.disabled = false; + }; + MaterialButton.prototype['enable'] = MaterialButton.prototype.enable; + /** + * Initialize element. + */ + MaterialButton.prototype.init = function () { + if (this.element_) { + if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { var rippleContainer = document.createElement('span'); - rippleContainer.classList.add(this.CssClasses_.ITEM_RIPPLE_CONTAINER); + rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER); + this.rippleElement_ = document.createElement('span'); + this.rippleElement_.classList.add(this.CssClasses_.RIPPLE); + rippleContainer.appendChild(this.rippleElement_); + this.boundRippleBlurHandler = this.blurHandler_.bind(this); + this.rippleElement_.addEventListener('mouseup', this.boundRippleBlurHandler); + this.element_.appendChild(rippleContainer); + } + this.boundButtonBlurHandler = this.blurHandler_.bind(this); + this.element_.addEventListener('mouseup', this.boundButtonBlurHandler); + this.element_.addEventListener('mouseleave', this.boundButtonBlurHandler); + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialButton, + classAsString: 'MaterialButton', + cssClass: 'mdl-js-button', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for Checkbox MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialCheckbox = function MaterialCheckbox(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialCheckbox'] = MaterialCheckbox; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialCheckbox.prototype.Constant_ = {TINY_TIMEOUT: 0.001}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialCheckbox.prototype.CssClasses_ = { + INPUT: 'mdl-checkbox__input', + BOX_OUTLINE: 'mdl-checkbox__box-outline', + FOCUS_HELPER: 'mdl-checkbox__focus-helper', + TICK_OUTLINE: 'mdl-checkbox__tick-outline', + RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + RIPPLE_CONTAINER: 'mdl-checkbox__ripple-container', + RIPPLE_CENTER: 'mdl-ripple--center', + RIPPLE: 'mdl-ripple', + IS_FOCUSED: 'is-focused', + IS_DISABLED: 'is-disabled', + IS_CHECKED: 'is-checked', + IS_UPGRADED: 'is-upgraded' + }; + /** + * Handle change of state. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialCheckbox.prototype.onChange_ = function (event) { + this.updateClasses_(); + }; + /** + * Handle focus of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialCheckbox.prototype.onFocus_ = function (event) { + this.element_.classList.add(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle lost focus of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialCheckbox.prototype.onBlur_ = function (event) { + this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle mouseup. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialCheckbox.prototype.onMouseUp_ = function (event) { + this.blur_(); + }; + /** + * Handle class updates. + * + * @private + */ + MaterialCheckbox.prototype.updateClasses_ = function () { + this.checkDisabled(); + this.checkToggleState(); + }; + /** + * Add blur. + * + * @private + */ + MaterialCheckbox.prototype.blur_ = function () { + // TODO: figure out why there's a focus event being fired after our blur, + // so that we can avoid this hack. + window.setTimeout(function () { + this.inputElement_.blur(); + }.bind(this), this.Constant_.TINY_TIMEOUT); + }; +// Public methods. + /** + * Check the inputs toggle state and update display. + * + * @public + */ + MaterialCheckbox.prototype.checkToggleState = function () { + if (this.inputElement_.checked) { + this.element_.classList.add(this.CssClasses_.IS_CHECKED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_CHECKED); + } + }; + MaterialCheckbox.prototype['checkToggleState'] = MaterialCheckbox.prototype.checkToggleState; + /** + * Check the inputs disabled state and update display. + * + * @public + */ + MaterialCheckbox.prototype.checkDisabled = function () { + if (this.inputElement_.disabled) { + this.element_.classList.add(this.CssClasses_.IS_DISABLED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_DISABLED); + } + }; + MaterialCheckbox.prototype['checkDisabled'] = MaterialCheckbox.prototype.checkDisabled; + /** + * Disable checkbox. + * + * @public + */ + MaterialCheckbox.prototype.disable = function () { + this.inputElement_.disabled = true; + this.updateClasses_(); + }; + MaterialCheckbox.prototype['disable'] = MaterialCheckbox.prototype.disable; + /** + * Enable checkbox. + * + * @public + */ + MaterialCheckbox.prototype.enable = function () { + this.inputElement_.disabled = false; + this.updateClasses_(); + }; + MaterialCheckbox.prototype['enable'] = MaterialCheckbox.prototype.enable; + /** + * Check checkbox. + * + * @public + */ + MaterialCheckbox.prototype.check = function () { + this.inputElement_.checked = true; + this.updateClasses_(); + }; + MaterialCheckbox.prototype['check'] = MaterialCheckbox.prototype.check; + /** + * Uncheck checkbox. + * + * @public + */ + MaterialCheckbox.prototype.uncheck = function () { + this.inputElement_.checked = false; + this.updateClasses_(); + }; + MaterialCheckbox.prototype['uncheck'] = MaterialCheckbox.prototype.uncheck; + /** + * Initialize element. + */ + MaterialCheckbox.prototype.init = function () { + if (this.element_) { + this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT); + var boxOutline = document.createElement('span'); + boxOutline.classList.add(this.CssClasses_.BOX_OUTLINE); + var tickContainer = document.createElement('span'); + tickContainer.classList.add(this.CssClasses_.FOCUS_HELPER); + var tickOutline = document.createElement('span'); + tickOutline.classList.add(this.CssClasses_.TICK_OUTLINE); + boxOutline.appendChild(tickOutline); + this.element_.appendChild(tickContainer); + this.element_.appendChild(boxOutline); + if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { + this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); + this.rippleContainerElement_ = document.createElement('span'); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER); + this.boundRippleMouseUp = this.onMouseUp_.bind(this); + this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp); var ripple = document.createElement('span'); ripple.classList.add(this.CssClasses_.RIPPLE); - rippleContainer.appendChild(ripple); - item.appendChild(rippleContainer); - item.classList.add(this.CssClasses_.RIPPLE_EFFECT); + this.rippleContainerElement_.appendChild(ripple); + this.element_.appendChild(this.rippleContainerElement_); } + this.boundInputOnChange = this.onChange_.bind(this); + this.boundInputOnFocus = this.onFocus_.bind(this); + this.boundInputOnBlur = this.onBlur_.bind(this); + this.boundElementMouseUp = this.onMouseUp_.bind(this); + this.inputElement_.addEventListener('change', this.boundInputOnChange); + this.inputElement_.addEventListener('focus', this.boundInputOnFocus); + this.inputElement_.addEventListener('blur', this.boundInputOnBlur); + this.element_.addEventListener('mouseup', this.boundElementMouseUp); + this.updateClasses_(); + this.element_.classList.add(this.CssClasses_.IS_UPGRADED); } - // Copy alignment classes to the container, so the outline can use them. - if (this.element_.classList.contains(this.CssClasses_.BOTTOM_LEFT)) { - this.outline_.classList.add(this.CssClasses_.BOTTOM_LEFT); - } - if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) { - this.outline_.classList.add(this.CssClasses_.BOTTOM_RIGHT); - } - if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) { - this.outline_.classList.add(this.CssClasses_.TOP_LEFT); - } - if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) { - this.outline_.classList.add(this.CssClasses_.TOP_RIGHT); - } - if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) { - this.outline_.classList.add(this.CssClasses_.UNALIGNED); - } - container.classList.add(this.CssClasses_.IS_UPGRADED); - } -}; -/** - * Handles a click on the "for" element, by positioning the menu and then - * toggling it. - * - * @param {Event} evt The event that fired. - * @private - */ -MaterialMenu.prototype.handleForClick_ = function (evt) { - if (this.element_ && this.forElement_) { - var rect = this.forElement_.getBoundingClientRect(); - var forRect = this.forElement_.parentElement.getBoundingClientRect(); - if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) { - } else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) { - // Position below the "for" element, aligned to its right. - this.container_.style.right = forRect.right - rect.right + 'px'; - this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px'; - } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) { - // Position above the "for" element, aligned to its left. - this.container_.style.left = this.forElement_.offsetLeft + 'px'; - this.container_.style.bottom = forRect.bottom - rect.top + 'px'; - } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) { - // Position above the "for" element, aligned to its right. - this.container_.style.right = forRect.right - rect.right + 'px'; - this.container_.style.bottom = forRect.bottom - rect.top + 'px'; - } else { - // Default: position below the "for" element, aligned to its left. - this.container_.style.left = this.forElement_.offsetLeft + 'px'; - this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px'; - } - } - this.toggle(evt); -}; -/** - * Handles a keyboard event on the "for" element. - * - * @param {Event} evt The event that fired. - * @private - */ -MaterialMenu.prototype.handleForKeyboardEvent_ = function (evt) { - if (this.element_ && this.container_ && this.forElement_) { - var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])'); - if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) { - if (evt.keyCode === this.Keycodes_.UP_ARROW) { - evt.preventDefault(); - items[items.length - 1].focus(); - } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) { - evt.preventDefault(); - items[0].focus(); - } - } - } -}; -/** - * Handles a keyboard event on an item. - * - * @param {Event} evt The event that fired. - * @private - */ -MaterialMenu.prototype.handleItemKeyboardEvent_ = function (evt) { - if (this.element_ && this.container_) { - var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])'); - if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) { - var currentIndex = Array.prototype.slice.call(items).indexOf(evt.target); - if (evt.keyCode === this.Keycodes_.UP_ARROW) { - evt.preventDefault(); - if (currentIndex > 0) { - items[currentIndex - 1].focus(); - } else { - items[items.length - 1].focus(); - } - } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) { - evt.preventDefault(); - if (items.length > currentIndex + 1) { - items[currentIndex + 1].focus(); - } else { - items[0].focus(); - } - } else if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) { - evt.preventDefault(); - // Send mousedown and mouseup to trigger ripple. - var e = new MouseEvent('mousedown'); - evt.target.dispatchEvent(e); - e = new MouseEvent('mouseup'); - evt.target.dispatchEvent(e); - // Send click. - evt.target.click(); - } else if (evt.keyCode === this.Keycodes_.ESCAPE) { - evt.preventDefault(); - this.hide(); - } - } - } -}; -/** - * Handles a click event on an item. - * - * @param {Event} evt The event that fired. - * @private - */ -MaterialMenu.prototype.handleItemClick_ = function (evt) { - if (evt.target.hasAttribute('disabled')) { - evt.stopPropagation(); - } else { - // Wait some time before closing menu, so the user can see the ripple. - this.closing_ = true; - window.setTimeout(function (evt) { - this.hide(); - this.closing_ = false; - }.bind(this), this.Constant_.CLOSE_TIMEOUT); - } -}; -/** - * Calculates the initial clip (for opening the menu) or final clip (for closing - * it), and applies it. This allows us to animate from or to the correct point, - * that is, the point it's aligned to in the "for" element. - * - * @param {number} height Height of the clip rectangle - * @param {number} width Width of the clip rectangle - * @private - */ -MaterialMenu.prototype.applyClip_ = function (height, width) { - if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) { - // Do not clip. - this.element_.style.clip = ''; - } else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) { - // Clip to the top right corner of the menu. - this.element_.style.clip = 'rect(0 ' + width + 'px ' + '0 ' + width + 'px)'; - } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) { - // Clip to the bottom left corner of the menu. - this.element_.style.clip = 'rect(' + height + 'px 0 ' + height + 'px 0)'; - } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) { - // Clip to the bottom right corner of the menu. - this.element_.style.clip = 'rect(' + height + 'px ' + width + 'px ' + height + 'px ' + width + 'px)'; - } else { - // Default: do not clip (same as clipping to the top left corner). - this.element_.style.clip = ''; - } -}; -/** - * Cleanup function to remove animation listeners. - * - * @param {Event} evt - * @private - */ -MaterialMenu.prototype.removeAnimationEndListener_ = function (evt) { - evt.target.classList.remove(MaterialMenu.prototype.CssClasses_.IS_ANIMATING); -}; -/** - * Adds an event listener to clean up after the animation ends. - * - * @private - */ -MaterialMenu.prototype.addAnimationEndListener_ = function () { - this.element_.addEventListener('transitionend', this.removeAnimationEndListener_); - this.element_.addEventListener('webkitTransitionEnd', this.removeAnimationEndListener_); -}; -/** - * Displays the menu. - * - * @public - */ -MaterialMenu.prototype.show = function (evt) { - if (this.element_ && this.container_ && this.outline_) { - // Measure the inner element. - var height = this.element_.getBoundingClientRect().height; - var width = this.element_.getBoundingClientRect().width; - // Apply the inner element's size to the container and outline. - this.container_.style.width = width + 'px'; - this.container_.style.height = height + 'px'; - this.outline_.style.width = width + 'px'; - this.outline_.style.height = height + 'px'; - var transitionDuration = this.Constant_.TRANSITION_DURATION_SECONDS * this.Constant_.TRANSITION_DURATION_FRACTION; - // Calculate transition delays for individual menu items, so that they fade - // in one at a time. - var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM); - for (var i = 0; i < items.length; i++) { - var itemDelay = null; - if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT) || this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) { - itemDelay = (height - items[i].offsetTop - items[i].offsetHeight) / height * transitionDuration + 's'; - } else { - itemDelay = items[i].offsetTop / height * transitionDuration + 's'; - } - items[i].style.transitionDelay = itemDelay; - } - // Apply the initial clip to the text before we start animating. - this.applyClip_(height, width); - // Wait for the next frame, turn on animation, and apply the final clip. - // Also make it visible. This triggers the transitions. - window.requestAnimationFrame(function () { - this.element_.classList.add(this.CssClasses_.IS_ANIMATING); - this.element_.style.clip = 'rect(0 ' + width + 'px ' + height + 'px 0)'; - this.container_.classList.add(this.CssClasses_.IS_VISIBLE); - }.bind(this)); - // Clean up after the animation is complete. - this.addAnimationEndListener_(); - // Add a click listener to the document, to close the menu. - var callback = function (e) { - // Check to see if the document is processing the same event that - // displayed the menu in the first place. If so, do nothing. - // Also check to see if the menu is in the process of closing itself, and - // do nothing in that case. - // Also check if the clicked element is a menu item - // if so, do nothing. - if (e !== evt && !this.closing_ && e.target.parentNode !== this.element_) { - document.removeEventListener('click', callback); - this.hide(); - } - }.bind(this); - document.addEventListener('click', callback); - } -}; -MaterialMenu.prototype['show'] = MaterialMenu.prototype.show; -/** - * Hides the menu. - * - * @public - */ -MaterialMenu.prototype.hide = function () { - if (this.element_ && this.container_ && this.outline_) { - var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM); - // Remove all transition delays; menu items fade out concurrently. - for (var i = 0; i < items.length; i++) { - items[i].style.removeProperty('transition-delay'); - } - // Measure the inner element. - var rect = this.element_.getBoundingClientRect(); - var height = rect.height; - var width = rect.width; - // Turn on animation, and apply the final clip. Also make invisible. - // This triggers the transitions. - this.element_.classList.add(this.CssClasses_.IS_ANIMATING); - this.applyClip_(height, width); - this.container_.classList.remove(this.CssClasses_.IS_VISIBLE); - // Clean up after the animation is complete. - this.addAnimationEndListener_(); - } -}; -MaterialMenu.prototype['hide'] = MaterialMenu.prototype.hide; -/** - * Displays or hides the menu, depending on current state. - * - * @public - */ -MaterialMenu.prototype.toggle = function (evt) { - if (this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) { - this.hide(); - } else { - this.show(evt); - } -}; -MaterialMenu.prototype['toggle'] = MaterialMenu.prototype.toggle; + }; // The component registers itself. It can assume componentHandler is available // in the global scope. -componentHandler.register({ - constructor: MaterialMenu, - classAsString: 'MaterialMenu', - cssClass: 'mdl-js-menu', - widget: true -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Progress MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {HTMLElement} element The element that will be upgraded. - */ -var MaterialProgress = function MaterialProgress(element) { - this.element_ = element; - // Initialize instance. - this.init(); -}; -window['MaterialProgress'] = MaterialProgress; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialProgress.prototype.Constant_ = {}; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialProgress.prototype.CssClasses_ = { INDETERMINATE_CLASS: 'mdl-progress__indeterminate' }; -/** - * Set the current progress of the progressbar. - * - * @param {number} p Percentage of the progress (0-100) - * @public - */ -MaterialProgress.prototype.setProgress = function (p) { - if (this.element_.classList.contains(this.CssClasses_.INDETERMINATE_CLASS)) { - return; - } - this.progressbar_.style.width = p + '%'; -}; -MaterialProgress.prototype['setProgress'] = MaterialProgress.prototype.setProgress; -/** - * Set the current progress of the buffer. - * - * @param {number} p Percentage of the buffer (0-100) - * @public - */ -MaterialProgress.prototype.setBuffer = function (p) { - this.bufferbar_.style.width = p + '%'; - this.auxbar_.style.width = 100 - p + '%'; -}; -MaterialProgress.prototype['setBuffer'] = MaterialProgress.prototype.setBuffer; -/** - * Initialize element. - */ -MaterialProgress.prototype.init = function () { - if (this.element_) { - var el = document.createElement('div'); - el.className = 'progressbar bar bar1'; - this.element_.appendChild(el); - this.progressbar_ = el; - el = document.createElement('div'); - el.className = 'bufferbar bar bar2'; - this.element_.appendChild(el); - this.bufferbar_ = el; - el = document.createElement('div'); - el.className = 'auxbar bar bar3'; - this.element_.appendChild(el); - this.auxbar_ = el; - this.progressbar_.style.width = '0%'; - this.bufferbar_.style.width = '100%'; - this.auxbar_.style.width = '0%'; - this.element_.classList.add('is-upgraded'); - } -}; -// The component registers itself. It can assume componentHandler is available -// in the global scope. -componentHandler.register({ - constructor: MaterialProgress, - classAsString: 'MaterialProgress', - cssClass: 'mdl-js-progress', - widget: true -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Radio MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {HTMLElement} element The element that will be upgraded. - */ -var MaterialRadio = function MaterialRadio(element) { - this.element_ = element; - // Initialize instance. - this.init(); -}; -window['MaterialRadio'] = MaterialRadio; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialRadio.prototype.Constant_ = { TINY_TIMEOUT: 0.001 }; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialRadio.prototype.CssClasses_ = { - IS_FOCUSED: 'is-focused', - IS_DISABLED: 'is-disabled', - IS_CHECKED: 'is-checked', - IS_UPGRADED: 'is-upgraded', - JS_RADIO: 'mdl-js-radio', - RADIO_BTN: 'mdl-radio__button', - RADIO_OUTER_CIRCLE: 'mdl-radio__outer-circle', - RADIO_INNER_CIRCLE: 'mdl-radio__inner-circle', - RIPPLE_EFFECT: 'mdl-js-ripple-effect', - RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', - RIPPLE_CONTAINER: 'mdl-radio__ripple-container', - RIPPLE_CENTER: 'mdl-ripple--center', - RIPPLE: 'mdl-ripple' -}; -/** - * Handle change of state. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialRadio.prototype.onChange_ = function (event) { - // Since other radio buttons don't get change events, we need to look for - // them to update their classes. - var radios = document.getElementsByClassName(this.CssClasses_.JS_RADIO); - for (var i = 0; i < radios.length; i++) { - var button = radios[i].querySelector('.' + this.CssClasses_.RADIO_BTN); - // Different name == different group, so no point updating those. - if (button.getAttribute('name') === this.btnElement_.getAttribute('name')) { - if (typeof radios[i]['MaterialRadio'] !== 'undefined') { - radios[i]['MaterialRadio'].updateClasses_(); - } - } - } -}; -/** - * Handle focus. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialRadio.prototype.onFocus_ = function (event) { - this.element_.classList.add(this.CssClasses_.IS_FOCUSED); -}; -/** - * Handle lost focus. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialRadio.prototype.onBlur_ = function (event) { - this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); -}; -/** - * Handle mouseup. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialRadio.prototype.onMouseup_ = function (event) { - this.blur_(); -}; -/** - * Update classes. - * - * @private - */ -MaterialRadio.prototype.updateClasses_ = function () { - this.checkDisabled(); - this.checkToggleState(); -}; -/** - * Add blur. - * - * @private - */ -MaterialRadio.prototype.blur_ = function () { - // TODO: figure out why there's a focus event being fired after our blur, - // so that we can avoid this hack. - window.setTimeout(function () { - this.btnElement_.blur(); - }.bind(this), this.Constant_.TINY_TIMEOUT); -}; -// Public methods. -/** - * Check the components disabled state. - * - * @public - */ -MaterialRadio.prototype.checkDisabled = function () { - if (this.btnElement_.disabled) { - this.element_.classList.add(this.CssClasses_.IS_DISABLED); - } else { - this.element_.classList.remove(this.CssClasses_.IS_DISABLED); - } -}; -MaterialRadio.prototype['checkDisabled'] = MaterialRadio.prototype.checkDisabled; -/** - * Check the components toggled state. - * - * @public - */ -MaterialRadio.prototype.checkToggleState = function () { - if (this.btnElement_.checked) { - this.element_.classList.add(this.CssClasses_.IS_CHECKED); - } else { - this.element_.classList.remove(this.CssClasses_.IS_CHECKED); - } -}; -MaterialRadio.prototype['checkToggleState'] = MaterialRadio.prototype.checkToggleState; -/** - * Disable radio. - * - * @public - */ -MaterialRadio.prototype.disable = function () { - this.btnElement_.disabled = true; - this.updateClasses_(); -}; -MaterialRadio.prototype['disable'] = MaterialRadio.prototype.disable; -/** - * Enable radio. - * - * @public - */ -MaterialRadio.prototype.enable = function () { - this.btnElement_.disabled = false; - this.updateClasses_(); -}; -MaterialRadio.prototype['enable'] = MaterialRadio.prototype.enable; -/** - * Check radio. - * - * @public - */ -MaterialRadio.prototype.check = function () { - this.btnElement_.checked = true; - this.onChange_(null); -}; -MaterialRadio.prototype['check'] = MaterialRadio.prototype.check; -/** - * Uncheck radio. - * - * @public - */ -MaterialRadio.prototype.uncheck = function () { - this.btnElement_.checked = false; - this.onChange_(null); -}; -MaterialRadio.prototype['uncheck'] = MaterialRadio.prototype.uncheck; -/** - * Initialize element. - */ -MaterialRadio.prototype.init = function () { - if (this.element_) { - this.btnElement_ = this.element_.querySelector('.' + this.CssClasses_.RADIO_BTN); - this.boundChangeHandler_ = this.onChange_.bind(this); - this.boundFocusHandler_ = this.onChange_.bind(this); - this.boundBlurHandler_ = this.onBlur_.bind(this); - this.boundMouseUpHandler_ = this.onMouseup_.bind(this); - var outerCircle = document.createElement('span'); - outerCircle.classList.add(this.CssClasses_.RADIO_OUTER_CIRCLE); - var innerCircle = document.createElement('span'); - innerCircle.classList.add(this.CssClasses_.RADIO_INNER_CIRCLE); - this.element_.appendChild(outerCircle); - this.element_.appendChild(innerCircle); - var rippleContainer; - if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { - this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); - rippleContainer = document.createElement('span'); - rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER); - rippleContainer.classList.add(this.CssClasses_.RIPPLE_EFFECT); - rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER); - rippleContainer.addEventListener('mouseup', this.boundMouseUpHandler_); - var ripple = document.createElement('span'); - ripple.classList.add(this.CssClasses_.RIPPLE); - rippleContainer.appendChild(ripple); - this.element_.appendChild(rippleContainer); - } - this.btnElement_.addEventListener('change', this.boundChangeHandler_); - this.btnElement_.addEventListener('focus', this.boundFocusHandler_); - this.btnElement_.addEventListener('blur', this.boundBlurHandler_); - this.element_.addEventListener('mouseup', this.boundMouseUpHandler_); - this.updateClasses_(); - this.element_.classList.add(this.CssClasses_.IS_UPGRADED); - } -}; -// The component registers itself. It can assume componentHandler is available -// in the global scope. -componentHandler.register({ - constructor: MaterialRadio, - classAsString: 'MaterialRadio', - cssClass: 'mdl-js-radio', - widget: true -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Slider MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {HTMLElement} element The element that will be upgraded. - */ -var MaterialSlider = function MaterialSlider(element) { - this.element_ = element; - // Browser feature detection. - this.isIE_ = window.navigator.msPointerEnabled; - // Initialize instance. - this.init(); -}; -window['MaterialSlider'] = MaterialSlider; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialSlider.prototype.Constant_ = {}; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialSlider.prototype.CssClasses_ = { - IE_CONTAINER: 'mdl-slider__ie-container', - SLIDER_CONTAINER: 'mdl-slider__container', - BACKGROUND_FLEX: 'mdl-slider__background-flex', - BACKGROUND_LOWER: 'mdl-slider__background-lower', - BACKGROUND_UPPER: 'mdl-slider__background-upper', - IS_LOWEST_VALUE: 'is-lowest-value', - IS_UPGRADED: 'is-upgraded' -}; -/** - * Handle input on element. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialSlider.prototype.onInput_ = function (event) { - this.updateValueStyles_(); -}; -/** - * Handle change on element. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialSlider.prototype.onChange_ = function (event) { - this.updateValueStyles_(); -}; -/** - * Handle mouseup on element. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialSlider.prototype.onMouseUp_ = function (event) { - event.target.blur(); -}; -/** - * Handle mousedown on container element. - * This handler is purpose is to not require the use to click - * exactly on the 2px slider element, as FireFox seems to be very - * strict about this. - * - * @param {Event} event The event that fired. - * @private - * @suppress {missingProperties} - */ -MaterialSlider.prototype.onContainerMouseDown_ = function (event) { - // If this click is not on the parent element (but rather some child) - // ignore. It may still bubble up. - if (event.target !== this.element_.parentElement) { - return; - } - // Discard the original event and create a new event that - // is on the slider element. - event.preventDefault(); - var newEvent = new MouseEvent('mousedown', { - target: event.target, - buttons: event.buttons, - clientX: event.clientX, - clientY: this.element_.getBoundingClientRect().y + componentHandler.register({ + constructor: MaterialCheckbox, + classAsString: 'MaterialCheckbox', + cssClass: 'mdl-js-checkbox', + widget: true }); - this.element_.dispatchEvent(newEvent); -}; -/** - * Handle updating of values. - * - * @private - */ -MaterialSlider.prototype.updateValueStyles_ = function () { - // Calculate and apply percentages to div structure behind slider. - var fraction = (this.element_.value - this.element_.min) / (this.element_.max - this.element_.min); - if (fraction === 0) { - this.element_.classList.add(this.CssClasses_.IS_LOWEST_VALUE); - } else { - this.element_.classList.remove(this.CssClasses_.IS_LOWEST_VALUE); - } - if (!this.isIE_) { - this.backgroundLower_.style.flex = fraction; - this.backgroundLower_.style.webkitFlex = fraction; - this.backgroundUpper_.style.flex = 1 - fraction; - this.backgroundUpper_.style.webkitFlex = 1 - fraction; - } -}; + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for icon toggle MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialIconToggle = function MaterialIconToggle(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialIconToggle'] = MaterialIconToggle; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialIconToggle.prototype.Constant_ = {TINY_TIMEOUT: 0.001}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialIconToggle.prototype.CssClasses_ = { + INPUT: 'mdl-icon-toggle__input', + JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + RIPPLE_CONTAINER: 'mdl-icon-toggle__ripple-container', + RIPPLE_CENTER: 'mdl-ripple--center', + RIPPLE: 'mdl-ripple', + IS_FOCUSED: 'is-focused', + IS_DISABLED: 'is-disabled', + IS_CHECKED: 'is-checked' + }; + /** + * Handle change of state. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialIconToggle.prototype.onChange_ = function (event) { + this.updateClasses_(); + }; + /** + * Handle focus of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialIconToggle.prototype.onFocus_ = function (event) { + this.element_.classList.add(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle lost focus of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialIconToggle.prototype.onBlur_ = function (event) { + this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle mouseup. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialIconToggle.prototype.onMouseUp_ = function (event) { + this.blur_(); + }; + /** + * Handle class updates. + * + * @private + */ + MaterialIconToggle.prototype.updateClasses_ = function () { + this.checkDisabled(); + this.checkToggleState(); + }; + /** + * Add blur. + * + * @private + */ + MaterialIconToggle.prototype.blur_ = function () { + // TODO: figure out why there's a focus event being fired after our blur, + // so that we can avoid this hack. + window.setTimeout(function () { + this.inputElement_.blur(); + }.bind(this), this.Constant_.TINY_TIMEOUT); + }; // Public methods. -/** - * Disable slider. - * - * @public - */ -MaterialSlider.prototype.disable = function () { - this.element_.disabled = true; -}; -MaterialSlider.prototype['disable'] = MaterialSlider.prototype.disable; -/** - * Enable slider. - * - * @public - */ -MaterialSlider.prototype.enable = function () { - this.element_.disabled = false; -}; -MaterialSlider.prototype['enable'] = MaterialSlider.prototype.enable; -/** - * Update slider value. - * - * @param {number} value The value to which to set the control (optional). - * @public - */ -MaterialSlider.prototype.change = function (value) { - if (typeof value !== 'undefined') { - this.element_.value = value; - } - this.updateValueStyles_(); -}; -MaterialSlider.prototype['change'] = MaterialSlider.prototype.change; -/** - * Initialize element. - */ -MaterialSlider.prototype.init = function () { - if (this.element_) { - if (this.isIE_) { - // Since we need to specify a very large height in IE due to - // implementation limitations, we add a parent here that trims it down to - // a reasonable size. - var containerIE = document.createElement('div'); - containerIE.classList.add(this.CssClasses_.IE_CONTAINER); - this.element_.parentElement.insertBefore(containerIE, this.element_); - this.element_.parentElement.removeChild(this.element_); - containerIE.appendChild(this.element_); + /** + * Check the inputs toggle state and update display. + * + * @public + */ + MaterialIconToggle.prototype.checkToggleState = function () { + if (this.inputElement_.checked) { + this.element_.classList.add(this.CssClasses_.IS_CHECKED); } else { - // For non-IE browsers, we need a div structure that sits behind the - // slider and allows us to style the left and right sides of it with - // different colors. + this.element_.classList.remove(this.CssClasses_.IS_CHECKED); + } + }; + MaterialIconToggle.prototype['checkToggleState'] = MaterialIconToggle.prototype.checkToggleState; + /** + * Check the inputs disabled state and update display. + * + * @public + */ + MaterialIconToggle.prototype.checkDisabled = function () { + if (this.inputElement_.disabled) { + this.element_.classList.add(this.CssClasses_.IS_DISABLED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_DISABLED); + } + }; + MaterialIconToggle.prototype['checkDisabled'] = MaterialIconToggle.prototype.checkDisabled; + /** + * Disable icon toggle. + * + * @public + */ + MaterialIconToggle.prototype.disable = function () { + this.inputElement_.disabled = true; + this.updateClasses_(); + }; + MaterialIconToggle.prototype['disable'] = MaterialIconToggle.prototype.disable; + /** + * Enable icon toggle. + * + * @public + */ + MaterialIconToggle.prototype.enable = function () { + this.inputElement_.disabled = false; + this.updateClasses_(); + }; + MaterialIconToggle.prototype['enable'] = MaterialIconToggle.prototype.enable; + /** + * Check icon toggle. + * + * @public + */ + MaterialIconToggle.prototype.check = function () { + this.inputElement_.checked = true; + this.updateClasses_(); + }; + MaterialIconToggle.prototype['check'] = MaterialIconToggle.prototype.check; + /** + * Uncheck icon toggle. + * + * @public + */ + MaterialIconToggle.prototype.uncheck = function () { + this.inputElement_.checked = false; + this.updateClasses_(); + }; + MaterialIconToggle.prototype['uncheck'] = MaterialIconToggle.prototype.uncheck; + /** + * Initialize element. + */ + MaterialIconToggle.prototype.init = function () { + if (this.element_) { + this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT); + if (this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) { + this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); + this.rippleContainerElement_ = document.createElement('span'); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER); + this.rippleContainerElement_.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER); + this.boundRippleMouseUp = this.onMouseUp_.bind(this); + this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp); + var ripple = document.createElement('span'); + ripple.classList.add(this.CssClasses_.RIPPLE); + this.rippleContainerElement_.appendChild(ripple); + this.element_.appendChild(this.rippleContainerElement_); + } + this.boundInputOnChange = this.onChange_.bind(this); + this.boundInputOnFocus = this.onFocus_.bind(this); + this.boundInputOnBlur = this.onBlur_.bind(this); + this.boundElementOnMouseUp = this.onMouseUp_.bind(this); + this.inputElement_.addEventListener('change', this.boundInputOnChange); + this.inputElement_.addEventListener('focus', this.boundInputOnFocus); + this.inputElement_.addEventListener('blur', this.boundInputOnBlur); + this.element_.addEventListener('mouseup', this.boundElementOnMouseUp); + this.updateClasses_(); + this.element_.classList.add('is-upgraded'); + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialIconToggle, + classAsString: 'MaterialIconToggle', + cssClass: 'mdl-js-icon-toggle', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for dropdown MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialMenu = function MaterialMenu(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialMenu'] = MaterialMenu; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialMenu.prototype.Constant_ = { + // Total duration of the menu animation. + TRANSITION_DURATION_SECONDS: 0.3, + // The fraction of the total duration we want to use for menu item animations. + TRANSITION_DURATION_FRACTION: 0.8, + // How long the menu stays open after choosing an option (so the user can see + // the ripple). + CLOSE_TIMEOUT: 150 + }; + /** + * Keycodes, for code readability. + * + * @enum {number} + * @private + */ + MaterialMenu.prototype.Keycodes_ = { + ENTER: 13, + ESCAPE: 27, + SPACE: 32, + UP_ARROW: 38, + DOWN_ARROW: 40 + }; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialMenu.prototype.CssClasses_ = { + CONTAINER: 'mdl-menu__container', + OUTLINE: 'mdl-menu__outline', + ITEM: 'mdl-menu__item', + ITEM_RIPPLE_CONTAINER: 'mdl-menu__item-ripple-container', + RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + RIPPLE: 'mdl-ripple', + // Statuses + IS_UPGRADED: 'is-upgraded', + IS_VISIBLE: 'is-visible', + IS_ANIMATING: 'is-animating', + // Alignment options + BOTTOM_LEFT: 'mdl-menu--bottom-left', + // This is the default. + BOTTOM_RIGHT: 'mdl-menu--bottom-right', + TOP_LEFT: 'mdl-menu--top-left', + TOP_RIGHT: 'mdl-menu--top-right', + UNALIGNED: 'mdl-menu--unaligned' + }; + /** + * Initialize element. + */ + MaterialMenu.prototype.init = function () { + if (this.element_) { + // Create container for the menu. var container = document.createElement('div'); - container.classList.add(this.CssClasses_.SLIDER_CONTAINER); + container.classList.add(this.CssClasses_.CONTAINER); this.element_.parentElement.insertBefore(container, this.element_); this.element_.parentElement.removeChild(this.element_); container.appendChild(this.element_); - var backgroundFlex = document.createElement('div'); - backgroundFlex.classList.add(this.CssClasses_.BACKGROUND_FLEX); - container.appendChild(backgroundFlex); - this.backgroundLower_ = document.createElement('div'); - this.backgroundLower_.classList.add(this.CssClasses_.BACKGROUND_LOWER); - backgroundFlex.appendChild(this.backgroundLower_); - this.backgroundUpper_ = document.createElement('div'); - this.backgroundUpper_.classList.add(this.CssClasses_.BACKGROUND_UPPER); - backgroundFlex.appendChild(this.backgroundUpper_); + this.container_ = container; + // Create outline for the menu (shadow and background). + var outline = document.createElement('div'); + outline.classList.add(this.CssClasses_.OUTLINE); + this.outline_ = outline; + container.insertBefore(outline, this.element_); + // Find the "for" element and bind events to it. + var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for'); + var forEl = null; + if (forElId) { + forEl = document.getElementById(forElId); + if (forEl) { + this.forElement_ = forEl; + forEl.addEventListener('click', this.handleForClick_.bind(this)); + forEl.addEventListener('keydown', this.handleForKeyboardEvent_.bind(this)); + } + } + var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM); + this.boundItemKeydown_ = this.handleItemKeyboardEvent_.bind(this); + this.boundItemClick_ = this.handleItemClick_.bind(this); + for (var i = 0; i < items.length; i++) { + // Add a listener to each menu item. + items[i].addEventListener('click', this.boundItemClick_); + // Add a tab index to each menu item. + items[i].tabIndex = '-1'; + // Add a keyboard listener to each menu item. + items[i].addEventListener('keydown', this.boundItemKeydown_); + } + // Add ripple classes to each item, if the user has enabled ripples. + if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { + this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); + for (i = 0; i < items.length; i++) { + var item = items[i]; + var rippleContainer = document.createElement('span'); + rippleContainer.classList.add(this.CssClasses_.ITEM_RIPPLE_CONTAINER); + var ripple = document.createElement('span'); + ripple.classList.add(this.CssClasses_.RIPPLE); + rippleContainer.appendChild(ripple); + item.appendChild(rippleContainer); + item.classList.add(this.CssClasses_.RIPPLE_EFFECT); + } + } + // Copy alignment classes to the container, so the outline can use them. + if (this.element_.classList.contains(this.CssClasses_.BOTTOM_LEFT)) { + this.outline_.classList.add(this.CssClasses_.BOTTOM_LEFT); + } + if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) { + this.outline_.classList.add(this.CssClasses_.BOTTOM_RIGHT); + } + if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) { + this.outline_.classList.add(this.CssClasses_.TOP_LEFT); + } + if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) { + this.outline_.classList.add(this.CssClasses_.TOP_RIGHT); + } + if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) { + this.outline_.classList.add(this.CssClasses_.UNALIGNED); + } + container.classList.add(this.CssClasses_.IS_UPGRADED); } - this.boundInputHandler = this.onInput_.bind(this); - this.boundChangeHandler = this.onChange_.bind(this); - this.boundMouseUpHandler = this.onMouseUp_.bind(this); - this.boundContainerMouseDownHandler = this.onContainerMouseDown_.bind(this); - this.element_.addEventListener('input', this.boundInputHandler); - this.element_.addEventListener('change', this.boundChangeHandler); - this.element_.addEventListener('mouseup', this.boundMouseUpHandler); - this.element_.parentElement.addEventListener('mousedown', this.boundContainerMouseDownHandler); - this.updateValueStyles_(); - this.element_.classList.add(this.CssClasses_.IS_UPGRADED); - } -}; + }; + /** + * Handles a click on the "for" element, by positioning the menu and then + * toggling it. + * + * @param {Event} evt The event that fired. + * @private + */ + MaterialMenu.prototype.handleForClick_ = function (evt) { + if (this.element_ && this.forElement_) { + var rect = this.forElement_.getBoundingClientRect(); + var forRect = this.forElement_.parentElement.getBoundingClientRect(); + if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) { + } else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) { + // Position below the "for" element, aligned to its right. + this.container_.style.right = forRect.right - rect.right + 'px'; + this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px'; + } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) { + // Position above the "for" element, aligned to its left. + this.container_.style.left = this.forElement_.offsetLeft + 'px'; + this.container_.style.bottom = forRect.bottom - rect.top + 'px'; + } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) { + // Position above the "for" element, aligned to its right. + this.container_.style.right = forRect.right - rect.right + 'px'; + this.container_.style.bottom = forRect.bottom - rect.top + 'px'; + } else { + // Default: position below the "for" element, aligned to its left. + this.container_.style.left = this.forElement_.offsetLeft + 'px'; + this.container_.style.top = this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px'; + } + } + this.toggle(evt); + }; + /** + * Handles a keyboard event on the "for" element. + * + * @param {Event} evt The event that fired. + * @private + */ + MaterialMenu.prototype.handleForKeyboardEvent_ = function (evt) { + if (this.element_ && this.container_ && this.forElement_) { + var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])'); + if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) { + if (evt.keyCode === this.Keycodes_.UP_ARROW) { + evt.preventDefault(); + items[items.length - 1].focus(); + } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) { + evt.preventDefault(); + items[0].focus(); + } + } + } + }; + /** + * Handles a keyboard event on an item. + * + * @param {Event} evt The event that fired. + * @private + */ + MaterialMenu.prototype.handleItemKeyboardEvent_ = function (evt) { + if (this.element_ && this.container_) { + var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM + ':not([disabled])'); + if (items && items.length > 0 && this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) { + var currentIndex = Array.prototype.slice.call(items).indexOf(evt.target); + if (evt.keyCode === this.Keycodes_.UP_ARROW) { + evt.preventDefault(); + if (currentIndex > 0) { + items[currentIndex - 1].focus(); + } else { + items[items.length - 1].focus(); + } + } else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) { + evt.preventDefault(); + if (items.length > currentIndex + 1) { + items[currentIndex + 1].focus(); + } else { + items[0].focus(); + } + } else if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) { + evt.preventDefault(); + // Send mousedown and mouseup to trigger ripple. + var e = new MouseEvent('mousedown'); + evt.target.dispatchEvent(e); + e = new MouseEvent('mouseup'); + evt.target.dispatchEvent(e); + // Send click. + evt.target.click(); + } else if (evt.keyCode === this.Keycodes_.ESCAPE) { + evt.preventDefault(); + this.hide(); + } + } + } + }; + /** + * Handles a click event on an item. + * + * @param {Event} evt The event that fired. + * @private + */ + MaterialMenu.prototype.handleItemClick_ = function (evt) { + if (evt.target.hasAttribute('disabled')) { + evt.stopPropagation(); + } else { + // Wait some time before closing menu, so the user can see the ripple. + this.closing_ = true; + window.setTimeout(function (evt) { + this.hide(); + this.closing_ = false; + }.bind(this), this.Constant_.CLOSE_TIMEOUT); + } + }; + /** + * Calculates the initial clip (for opening the menu) or final clip (for closing + * it), and applies it. This allows us to animate from or to the correct point, + * that is, the point it's aligned to in the "for" element. + * + * @param {number} height Height of the clip rectangle + * @param {number} width Width of the clip rectangle + * @private + */ + MaterialMenu.prototype.applyClip_ = function (height, width) { + if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) { + // Do not clip. + this.element_.style.clip = ''; + } else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) { + // Clip to the top right corner of the menu. + this.element_.style.clip = 'rect(0 ' + width + 'px ' + '0 ' + width + 'px)'; + } else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) { + // Clip to the bottom left corner of the menu. + this.element_.style.clip = 'rect(' + height + 'px 0 ' + height + 'px 0)'; + } else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) { + // Clip to the bottom right corner of the menu. + this.element_.style.clip = 'rect(' + height + 'px ' + width + 'px ' + height + 'px ' + width + 'px)'; + } else { + // Default: do not clip (same as clipping to the top left corner). + this.element_.style.clip = ''; + } + }; + /** + * Cleanup function to remove animation listeners. + * + * @param {Event} evt + * @private + */ + MaterialMenu.prototype.removeAnimationEndListener_ = function (evt) { + evt.target.classList.remove(MaterialMenu.prototype.CssClasses_.IS_ANIMATING); + }; + /** + * Adds an event listener to clean up after the animation ends. + * + * @private + */ + MaterialMenu.prototype.addAnimationEndListener_ = function () { + this.element_.addEventListener('transitionend', this.removeAnimationEndListener_); + this.element_.addEventListener('webkitTransitionEnd', this.removeAnimationEndListener_); + }; + /** + * Displays the menu. + * + * @public + */ + MaterialMenu.prototype.show = function (evt) { + if (this.element_ && this.container_ && this.outline_) { + // Measure the inner element. + var height = this.element_.getBoundingClientRect().height; + var width = this.element_.getBoundingClientRect().width; + // Apply the inner element's size to the container and outline. + this.container_.style.width = width + 'px'; + this.container_.style.height = height + 'px'; + this.outline_.style.width = width + 'px'; + this.outline_.style.height = height + 'px'; + var transitionDuration = this.Constant_.TRANSITION_DURATION_SECONDS * this.Constant_.TRANSITION_DURATION_FRACTION; + // Calculate transition delays for individual menu items, so that they fade + // in one at a time. + var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM); + for (var i = 0; i < items.length; i++) { + var itemDelay = null; + if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT) || this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) { + itemDelay = (height - items[i].offsetTop - items[i].offsetHeight) / height * transitionDuration + 's'; + } else { + itemDelay = items[i].offsetTop / height * transitionDuration + 's'; + } + items[i].style.transitionDelay = itemDelay; + } + // Apply the initial clip to the text before we start animating. + this.applyClip_(height, width); + // Wait for the next frame, turn on animation, and apply the final clip. + // Also make it visible. This triggers the transitions. + window.requestAnimationFrame(function () { + this.element_.classList.add(this.CssClasses_.IS_ANIMATING); + this.element_.style.clip = 'rect(0 ' + width + 'px ' + height + 'px 0)'; + this.container_.classList.add(this.CssClasses_.IS_VISIBLE); + }.bind(this)); + // Clean up after the animation is complete. + this.addAnimationEndListener_(); + // Add a click listener to the document, to close the menu. + var callback = function (e) { + // Check to see if the document is processing the same event that + // displayed the menu in the first place. If so, do nothing. + // Also check to see if the menu is in the process of closing itself, and + // do nothing in that case. + // Also check if the clicked element is a menu item + // if so, do nothing. + if (e !== evt && !this.closing_ && e.target.parentNode !== this.element_) { + document.removeEventListener('click', callback); + this.hide(); + } + }.bind(this); + document.addEventListener('click', callback); + } + }; + MaterialMenu.prototype['show'] = MaterialMenu.prototype.show; + /** + * Hides the menu. + * + * @public + */ + MaterialMenu.prototype.hide = function () { + if (this.element_ && this.container_ && this.outline_) { + var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM); + // Remove all transition delays; menu items fade out concurrently. + for (var i = 0; i < items.length; i++) { + items[i].style.removeProperty('transition-delay'); + } + // Measure the inner element. + var rect = this.element_.getBoundingClientRect(); + var height = rect.height; + var width = rect.width; + // Turn on animation, and apply the final clip. Also make invisible. + // This triggers the transitions. + this.element_.classList.add(this.CssClasses_.IS_ANIMATING); + this.applyClip_(height, width); + this.container_.classList.remove(this.CssClasses_.IS_VISIBLE); + // Clean up after the animation is complete. + this.addAnimationEndListener_(); + } + }; + MaterialMenu.prototype['hide'] = MaterialMenu.prototype.hide; + /** + * Displays or hides the menu, depending on current state. + * + * @public + */ + MaterialMenu.prototype.toggle = function (evt) { + if (this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) { + this.hide(); + } else { + this.show(evt); + } + }; + MaterialMenu.prototype['toggle'] = MaterialMenu.prototype.toggle; // The component registers itself. It can assume componentHandler is available // in the global scope. -componentHandler.register({ - constructor: MaterialSlider, - classAsString: 'MaterialSlider', - cssClass: 'mdl-js-slider', - widget: true -}); -/** - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Snackbar MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {HTMLElement} element The element that will be upgraded. - */ -var MaterialSnackbar = function MaterialSnackbar(element) { - this.element_ = element; - this.textElement_ = this.element_.querySelector('.' + this.cssClasses_.MESSAGE); - this.actionElement_ = this.element_.querySelector('.' + this.cssClasses_.ACTION); - if (!this.textElement_) { - throw new Error('There must be a message element for a snackbar.'); - } - if (!this.actionElement_) { - throw new Error('There must be an action element for a snackbar.'); - } - this.active = false; - this.actionHandler_ = undefined; - this.message_ = undefined; - this.actionText_ = undefined; - this.queuedNotifications_ = []; - this.setActionHidden_(true); -}; -window['MaterialSnackbar'] = MaterialSnackbar; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialSnackbar.prototype.Constant_ = { - // The duration of the snackbar show/hide animation, in ms. - ANIMATION_LENGTH: 250 -}; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialSnackbar.prototype.cssClasses_ = { - SNACKBAR: 'mdl-snackbar', - MESSAGE: 'mdl-snackbar__text', - ACTION: 'mdl-snackbar__action', - ACTIVE: 'mdl-snackbar--active' -}; -/** - * Display the snackbar. - * - * @private - */ -MaterialSnackbar.prototype.displaySnackbar_ = function () { - this.element_.setAttribute('aria-hidden', 'true'); - if (this.actionHandler_) { - this.actionElement_.textContent = this.actionText_; - this.actionElement_.addEventListener('click', this.actionHandler_); - this.setActionHidden_(false); - } - this.textElement_.textContent = this.message_; - this.element_.classList.add(this.cssClasses_.ACTIVE); - this.element_.setAttribute('aria-hidden', 'false'); - setTimeout(this.cleanup_.bind(this), this.timeout_); -}; -/** - * Show the snackbar. - * - * @param {Object} data The data for the notification. - * @public - */ -MaterialSnackbar.prototype.showSnackbar = function (data) { - if (data === undefined) { - throw new Error('Please provide a data object with at least a message to display.'); - } - if (data['message'] === undefined) { - throw new Error('Please provide a message to be displayed.'); - } - if (data['actionHandler'] && !data['actionText']) { - throw new Error('Please provide action text with the handler.'); - } - if (this.active) { - this.queuedNotifications_.push(data); - } else { - this.active = true; - this.message_ = data['message']; - if (data['timeout']) { - this.timeout_ = data['timeout']; + componentHandler.register({ + constructor: MaterialMenu, + classAsString: 'MaterialMenu', + cssClass: 'mdl-js-menu', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for Progress MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialProgress = function MaterialProgress(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialProgress'] = MaterialProgress; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialProgress.prototype.Constant_ = {}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialProgress.prototype.CssClasses_ = {INDETERMINATE_CLASS: 'mdl-progress__indeterminate'}; + /** + * Set the current progress of the progressbar. + * + * @param {number} p Percentage of the progress (0-100) + * @public + */ + MaterialProgress.prototype.setProgress = function (p) { + if (this.element_.classList.contains(this.CssClasses_.INDETERMINATE_CLASS)) { + return; + } + this.progressbar_.style.width = p + '%'; + }; + MaterialProgress.prototype['setProgress'] = MaterialProgress.prototype.setProgress; + /** + * Set the current progress of the buffer. + * + * @param {number} p Percentage of the buffer (0-100) + * @public + */ + MaterialProgress.prototype.setBuffer = function (p) { + this.bufferbar_.style.width = p + '%'; + this.auxbar_.style.width = 100 - p + '%'; + }; + MaterialProgress.prototype['setBuffer'] = MaterialProgress.prototype.setBuffer; + /** + * Initialize element. + */ + MaterialProgress.prototype.init = function () { + if (this.element_) { + var el = document.createElement('div'); + el.className = 'progressbar bar bar1'; + this.element_.appendChild(el); + this.progressbar_ = el; + el = document.createElement('div'); + el.className = 'bufferbar bar bar2'; + this.element_.appendChild(el); + this.bufferbar_ = el; + el = document.createElement('div'); + el.className = 'auxbar bar bar3'; + this.element_.appendChild(el); + this.auxbar_ = el; + this.progressbar_.style.width = '0%'; + this.bufferbar_.style.width = '100%'; + this.auxbar_.style.width = '0%'; + this.element_.classList.add('is-upgraded'); + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialProgress, + classAsString: 'MaterialProgress', + cssClass: 'mdl-js-progress', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for Radio MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialRadio = function MaterialRadio(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialRadio'] = MaterialRadio; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialRadio.prototype.Constant_ = {TINY_TIMEOUT: 0.001}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialRadio.prototype.CssClasses_ = { + IS_FOCUSED: 'is-focused', + IS_DISABLED: 'is-disabled', + IS_CHECKED: 'is-checked', + IS_UPGRADED: 'is-upgraded', + JS_RADIO: 'mdl-js-radio', + RADIO_BTN: 'mdl-radio__button', + RADIO_OUTER_CIRCLE: 'mdl-radio__outer-circle', + RADIO_INNER_CIRCLE: 'mdl-radio__inner-circle', + RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + RIPPLE_CONTAINER: 'mdl-radio__ripple-container', + RIPPLE_CENTER: 'mdl-ripple--center', + RIPPLE: 'mdl-ripple' + }; + /** + * Handle change of state. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialRadio.prototype.onChange_ = function (event) { + // Since other radio buttons don't get change events, we need to look for + // them to update their classes. + var radios = document.getElementsByClassName(this.CssClasses_.JS_RADIO); + for (var i = 0; i < radios.length; i++) { + var button = radios[i].querySelector('.' + this.CssClasses_.RADIO_BTN); + // Different name == different group, so no point updating those. + if (button.getAttribute('name') === this.btnElement_.getAttribute('name')) { + if (typeof radios[i]['MaterialRadio'] !== 'undefined') { + radios[i]['MaterialRadio'].updateClasses_(); + } + } + } + }; + /** + * Handle focus. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialRadio.prototype.onFocus_ = function (event) { + this.element_.classList.add(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle lost focus. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialRadio.prototype.onBlur_ = function (event) { + this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle mouseup. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialRadio.prototype.onMouseup_ = function (event) { + this.blur_(); + }; + /** + * Update classes. + * + * @private + */ + MaterialRadio.prototype.updateClasses_ = function () { + this.checkDisabled(); + this.checkToggleState(); + }; + /** + * Add blur. + * + * @private + */ + MaterialRadio.prototype.blur_ = function () { + // TODO: figure out why there's a focus event being fired after our blur, + // so that we can avoid this hack. + window.setTimeout(function () { + this.btnElement_.blur(); + }.bind(this), this.Constant_.TINY_TIMEOUT); + }; +// Public methods. + /** + * Check the components disabled state. + * + * @public + */ + MaterialRadio.prototype.checkDisabled = function () { + if (this.btnElement_.disabled) { + this.element_.classList.add(this.CssClasses_.IS_DISABLED); } else { - this.timeout_ = 2750; + this.element_.classList.remove(this.CssClasses_.IS_DISABLED); } - if (data['actionHandler']) { - this.actionHandler_ = data['actionHandler']; + }; + MaterialRadio.prototype['checkDisabled'] = MaterialRadio.prototype.checkDisabled; + /** + * Check the components toggled state. + * + * @public + */ + MaterialRadio.prototype.checkToggleState = function () { + if (this.btnElement_.checked) { + this.element_.classList.add(this.CssClasses_.IS_CHECKED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_CHECKED); } - if (data['actionText']) { - this.actionText_ = data['actionText']; + }; + MaterialRadio.prototype['checkToggleState'] = MaterialRadio.prototype.checkToggleState; + /** + * Disable radio. + * + * @public + */ + MaterialRadio.prototype.disable = function () { + this.btnElement_.disabled = true; + this.updateClasses_(); + }; + MaterialRadio.prototype['disable'] = MaterialRadio.prototype.disable; + /** + * Enable radio. + * + * @public + */ + MaterialRadio.prototype.enable = function () { + this.btnElement_.disabled = false; + this.updateClasses_(); + }; + MaterialRadio.prototype['enable'] = MaterialRadio.prototype.enable; + /** + * Check radio. + * + * @public + */ + MaterialRadio.prototype.check = function () { + this.btnElement_.checked = true; + this.onChange_(null); + }; + MaterialRadio.prototype['check'] = MaterialRadio.prototype.check; + /** + * Uncheck radio. + * + * @public + */ + MaterialRadio.prototype.uncheck = function () { + this.btnElement_.checked = false; + this.onChange_(null); + }; + MaterialRadio.prototype['uncheck'] = MaterialRadio.prototype.uncheck; + /** + * Initialize element. + */ + MaterialRadio.prototype.init = function () { + if (this.element_) { + this.btnElement_ = this.element_.querySelector('.' + this.CssClasses_.RADIO_BTN); + this.boundChangeHandler_ = this.onChange_.bind(this); + this.boundFocusHandler_ = this.onChange_.bind(this); + this.boundBlurHandler_ = this.onBlur_.bind(this); + this.boundMouseUpHandler_ = this.onMouseup_.bind(this); + var outerCircle = document.createElement('span'); + outerCircle.classList.add(this.CssClasses_.RADIO_OUTER_CIRCLE); + var innerCircle = document.createElement('span'); + innerCircle.classList.add(this.CssClasses_.RADIO_INNER_CIRCLE); + this.element_.appendChild(outerCircle); + this.element_.appendChild(innerCircle); + var rippleContainer; + if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { + this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); + rippleContainer = document.createElement('span'); + rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER); + rippleContainer.classList.add(this.CssClasses_.RIPPLE_EFFECT); + rippleContainer.classList.add(this.CssClasses_.RIPPLE_CENTER); + rippleContainer.addEventListener('mouseup', this.boundMouseUpHandler_); + var ripple = document.createElement('span'); + ripple.classList.add(this.CssClasses_.RIPPLE); + rippleContainer.appendChild(ripple); + this.element_.appendChild(rippleContainer); + } + this.btnElement_.addEventListener('change', this.boundChangeHandler_); + this.btnElement_.addEventListener('focus', this.boundFocusHandler_); + this.btnElement_.addEventListener('blur', this.boundBlurHandler_); + this.element_.addEventListener('mouseup', this.boundMouseUpHandler_); + this.updateClasses_(); + this.element_.classList.add(this.CssClasses_.IS_UPGRADED); } - this.displaySnackbar_(); - } -}; -MaterialSnackbar.prototype['showSnackbar'] = MaterialSnackbar.prototype.showSnackbar; -/** - * Check if the queue has items within it. - * If it does, display the next entry. - * - * @private - */ -MaterialSnackbar.prototype.checkQueue_ = function () { - if (this.queuedNotifications_.length > 0) { - this.showSnackbar(this.queuedNotifications_.shift()); - } -}; -/** - * Cleanup the snackbar event listeners and accessiblity attributes. - * - * @private - */ -MaterialSnackbar.prototype.cleanup_ = function () { - this.element_.classList.remove(this.cssClasses_.ACTIVE); - setTimeout(function () { - this.element_.setAttribute('aria-hidden', 'true'); - this.textElement_.textContent = ''; - if (!Boolean(this.actionElement_.getAttribute('aria-hidden'))) { - this.setActionHidden_(true); - this.actionElement_.textContent = ''; - this.actionElement_.removeEventListener('click', this.actionHandler_); + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialRadio, + classAsString: 'MaterialRadio', + cssClass: 'mdl-js-radio', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for Slider MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialSlider = function MaterialSlider(element) { + this.element_ = element; + // Browser feature detection. + this.isIE_ = window.navigator.msPointerEnabled; + // Initialize instance. + this.init(); + }; + window['MaterialSlider'] = MaterialSlider; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialSlider.prototype.Constant_ = {}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialSlider.prototype.CssClasses_ = { + IE_CONTAINER: 'mdl-slider__ie-container', + SLIDER_CONTAINER: 'mdl-slider__container', + BACKGROUND_FLEX: 'mdl-slider__background-flex', + BACKGROUND_LOWER: 'mdl-slider__background-lower', + BACKGROUND_UPPER: 'mdl-slider__background-upper', + IS_LOWEST_VALUE: 'is-lowest-value', + IS_UPGRADED: 'is-upgraded' + }; + /** + * Handle input on element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSlider.prototype.onInput_ = function (event) { + this.updateValueStyles_(); + }; + /** + * Handle change on element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSlider.prototype.onChange_ = function (event) { + this.updateValueStyles_(); + }; + /** + * Handle mouseup on element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSlider.prototype.onMouseUp_ = function (event) { + event.target.blur(); + }; + /** + * Handle mousedown on container element. + * This handler is purpose is to not require the use to click + * exactly on the 2px slider element, as FireFox seems to be very + * strict about this. + * + * @param {Event} event The event that fired. + * @private + * @suppress {missingProperties} + */ + MaterialSlider.prototype.onContainerMouseDown_ = function (event) { + // If this click is not on the parent element (but rather some child) + // ignore. It may still bubble up. + if (event.target !== this.element_.parentElement) { + return; } + // Discard the original event and create a new event that + // is on the slider element. + event.preventDefault(); + var newEvent = new MouseEvent('mousedown', { + target: event.target, + buttons: event.buttons, + clientX: event.clientX, + clientY: this.element_.getBoundingClientRect().y + }); + this.element_.dispatchEvent(newEvent); + }; + /** + * Handle updating of values. + * + * @private + */ + MaterialSlider.prototype.updateValueStyles_ = function () { + // Calculate and apply percentages to div structure behind slider. + var fraction = (this.element_.value - this.element_.min) / (this.element_.max - this.element_.min); + if (fraction === 0) { + this.element_.classList.add(this.CssClasses_.IS_LOWEST_VALUE); + } else { + this.element_.classList.remove(this.CssClasses_.IS_LOWEST_VALUE); + } + if (!this.isIE_) { + this.backgroundLower_.style.flex = fraction; + this.backgroundLower_.style.webkitFlex = fraction; + this.backgroundUpper_.style.flex = 1 - fraction; + this.backgroundUpper_.style.webkitFlex = 1 - fraction; + } + }; +// Public methods. + /** + * Disable slider. + * + * @public + */ + MaterialSlider.prototype.disable = function () { + this.element_.disabled = true; + }; + MaterialSlider.prototype['disable'] = MaterialSlider.prototype.disable; + /** + * Enable slider. + * + * @public + */ + MaterialSlider.prototype.enable = function () { + this.element_.disabled = false; + }; + MaterialSlider.prototype['enable'] = MaterialSlider.prototype.enable; + /** + * Update slider value. + * + * @param {number} value The value to which to set the control (optional). + * @public + */ + MaterialSlider.prototype.change = function (value) { + if (typeof value !== 'undefined') { + this.element_.value = value; + } + this.updateValueStyles_(); + }; + MaterialSlider.prototype['change'] = MaterialSlider.prototype.change; + /** + * Initialize element. + */ + MaterialSlider.prototype.init = function () { + if (this.element_) { + if (this.isIE_) { + // Since we need to specify a very large height in IE due to + // implementation limitations, we add a parent here that trims it down to + // a reasonable size. + var containerIE = document.createElement('div'); + containerIE.classList.add(this.CssClasses_.IE_CONTAINER); + this.element_.parentElement.insertBefore(containerIE, this.element_); + this.element_.parentElement.removeChild(this.element_); + containerIE.appendChild(this.element_); + } else { + // For non-IE browsers, we need a div structure that sits behind the + // slider and allows us to style the left and right sides of it with + // different colors. + var container = document.createElement('div'); + container.classList.add(this.CssClasses_.SLIDER_CONTAINER); + this.element_.parentElement.insertBefore(container, this.element_); + this.element_.parentElement.removeChild(this.element_); + container.appendChild(this.element_); + var backgroundFlex = document.createElement('div'); + backgroundFlex.classList.add(this.CssClasses_.BACKGROUND_FLEX); + container.appendChild(backgroundFlex); + this.backgroundLower_ = document.createElement('div'); + this.backgroundLower_.classList.add(this.CssClasses_.BACKGROUND_LOWER); + backgroundFlex.appendChild(this.backgroundLower_); + this.backgroundUpper_ = document.createElement('div'); + this.backgroundUpper_.classList.add(this.CssClasses_.BACKGROUND_UPPER); + backgroundFlex.appendChild(this.backgroundUpper_); + } + this.boundInputHandler = this.onInput_.bind(this); + this.boundChangeHandler = this.onChange_.bind(this); + this.boundMouseUpHandler = this.onMouseUp_.bind(this); + this.boundContainerMouseDownHandler = this.onContainerMouseDown_.bind(this); + this.element_.addEventListener('input', this.boundInputHandler); + this.element_.addEventListener('change', this.boundChangeHandler); + this.element_.addEventListener('mouseup', this.boundMouseUpHandler); + this.element_.parentElement.addEventListener('mousedown', this.boundContainerMouseDownHandler); + this.updateValueStyles_(); + this.element_.classList.add(this.CssClasses_.IS_UPGRADED); + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialSlider, + classAsString: 'MaterialSlider', + cssClass: 'mdl-js-slider', + widget: true + }); + /** + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for Snackbar MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialSnackbar = function MaterialSnackbar(element) { + this.element_ = element; + this.textElement_ = this.element_.querySelector('.' + this.cssClasses_.MESSAGE); + this.actionElement_ = this.element_.querySelector('.' + this.cssClasses_.ACTION); + if (!this.textElement_) { + throw new Error('There must be a message element for a snackbar.'); + } + if (!this.actionElement_) { + throw new Error('There must be an action element for a snackbar.'); + } + this.active = false; this.actionHandler_ = undefined; this.message_ = undefined; this.actionText_ = undefined; - this.active = false; - this.checkQueue_(); - }.bind(this), this.Constant_.ANIMATION_LENGTH); -}; -/** - * Set the action handler hidden state. - * - * @param {boolean} value - * @private - */ -MaterialSnackbar.prototype.setActionHidden_ = function (value) { - if (value) { - this.actionElement_.setAttribute('aria-hidden', 'true'); - } else { - this.actionElement_.removeAttribute('aria-hidden'); - } -}; + this.queuedNotifications_ = []; + this.setActionHidden_(true); + }; + window['MaterialSnackbar'] = MaterialSnackbar; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialSnackbar.prototype.Constant_ = { + // The duration of the snackbar show/hide animation, in ms. + ANIMATION_LENGTH: 250 + }; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialSnackbar.prototype.cssClasses_ = { + SNACKBAR: 'mdl-snackbar', + MESSAGE: 'mdl-snackbar__text', + ACTION: 'mdl-snackbar__action', + ACTIVE: 'mdl-snackbar--active' + }; + /** + * Display the snackbar. + * + * @private + */ + MaterialSnackbar.prototype.displaySnackbar_ = function () { + this.element_.setAttribute('aria-hidden', 'true'); + if (this.actionHandler_) { + this.actionElement_.textContent = this.actionText_; + this.actionElement_.addEventListener('click', this.actionHandler_); + this.setActionHidden_(false); + } + this.textElement_.textContent = this.message_; + this.element_.classList.add(this.cssClasses_.ACTIVE); + this.element_.setAttribute('aria-hidden', 'false'); + setTimeout(this.cleanup_.bind(this), this.timeout_); + }; + /** + * Show the snackbar. + * + * @param {Object} data The data for the notification. + * @public + */ + MaterialSnackbar.prototype.showSnackbar = function (data) { + if (data === undefined) { + throw new Error('Please provide a data object with at least a message to display.'); + } + if (data['message'] === undefined) { + throw new Error('Please provide a message to be displayed.'); + } + if (data['actionHandler'] && !data['actionText']) { + throw new Error('Please provide action text with the handler.'); + } + if (this.active) { + this.queuedNotifications_.push(data); + } else { + this.active = true; + this.message_ = data['message']; + if (data['timeout']) { + this.timeout_ = data['timeout']; + } else { + this.timeout_ = 2750; + } + if (data['actionHandler']) { + this.actionHandler_ = data['actionHandler']; + } + if (data['actionText']) { + this.actionText_ = data['actionText']; + } + this.displaySnackbar_(); + } + }; + MaterialSnackbar.prototype['showSnackbar'] = MaterialSnackbar.prototype.showSnackbar; + /** + * Check if the queue has items within it. + * If it does, display the next entry. + * + * @private + */ + MaterialSnackbar.prototype.checkQueue_ = function () { + if (this.queuedNotifications_.length > 0) { + this.showSnackbar(this.queuedNotifications_.shift()); + } + }; + /** + * Cleanup the snackbar event listeners and accessiblity attributes. + * + * @private + */ + MaterialSnackbar.prototype.cleanup_ = function () { + this.element_.classList.remove(this.cssClasses_.ACTIVE); + setTimeout(function () { + this.element_.setAttribute('aria-hidden', 'true'); + this.textElement_.textContent = ''; + if (!Boolean(this.actionElement_.getAttribute('aria-hidden'))) { + this.setActionHidden_(true); + this.actionElement_.textContent = ''; + this.actionElement_.removeEventListener('click', this.actionHandler_); + } + this.actionHandler_ = undefined; + this.message_ = undefined; + this.actionText_ = undefined; + this.active = false; + this.checkQueue_(); + }.bind(this), this.Constant_.ANIMATION_LENGTH); + }; + /** + * Set the action handler hidden state. + * + * @param {boolean} value + * @private + */ + MaterialSnackbar.prototype.setActionHidden_ = function (value) { + if (value) { + this.actionElement_.setAttribute('aria-hidden', 'true'); + } else { + this.actionElement_.removeAttribute('aria-hidden'); + } + }; // The component registers itself. It can assume componentHandler is available // in the global scope. -componentHandler.register({ - constructor: MaterialSnackbar, - classAsString: 'MaterialSnackbar', - cssClass: 'mdl-js-snackbar', - widget: true -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Spinner MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @param {HTMLElement} element The element that will be upgraded. - * @constructor - */ -var MaterialSpinner = function MaterialSpinner(element) { - this.element_ = element; - // Initialize instance. - this.init(); -}; -window['MaterialSpinner'] = MaterialSpinner; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialSpinner.prototype.Constant_ = { MDL_SPINNER_LAYER_COUNT: 4 }; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialSpinner.prototype.CssClasses_ = { - MDL_SPINNER_LAYER: 'mdl-spinner__layer', - MDL_SPINNER_CIRCLE_CLIPPER: 'mdl-spinner__circle-clipper', - MDL_SPINNER_CIRCLE: 'mdl-spinner__circle', - MDL_SPINNER_GAP_PATCH: 'mdl-spinner__gap-patch', - MDL_SPINNER_LEFT: 'mdl-spinner__left', - MDL_SPINNER_RIGHT: 'mdl-spinner__right' -}; -/** - * Auxiliary method to create a spinner layer. - * - * @param {number} index Index of the layer to be created. - * @public - */ -MaterialSpinner.prototype.createLayer = function (index) { - var layer = document.createElement('div'); - layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER); - layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER + '-' + index); - var leftClipper = document.createElement('div'); - leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER); - leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_LEFT); - var gapPatch = document.createElement('div'); - gapPatch.classList.add(this.CssClasses_.MDL_SPINNER_GAP_PATCH); - var rightClipper = document.createElement('div'); - rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER); - rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_RIGHT); - var circleOwners = [ - leftClipper, - gapPatch, - rightClipper - ]; - for (var i = 0; i < circleOwners.length; i++) { - var circle = document.createElement('div'); - circle.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE); - circleOwners[i].appendChild(circle); - } - layer.appendChild(leftClipper); - layer.appendChild(gapPatch); - layer.appendChild(rightClipper); - this.element_.appendChild(layer); -}; -MaterialSpinner.prototype['createLayer'] = MaterialSpinner.prototype.createLayer; -/** - * Stops the spinner animation. - * Public method for users who need to stop the spinner for any reason. - * - * @public - */ -MaterialSpinner.prototype.stop = function () { - this.element_.classList.remove('is-active'); -}; -MaterialSpinner.prototype['stop'] = MaterialSpinner.prototype.stop; -/** - * Starts the spinner animation. - * Public method for users who need to manually start the spinner for any reason - * (instead of just adding the 'is-active' class to their markup). - * - * @public - */ -MaterialSpinner.prototype.start = function () { - this.element_.classList.add('is-active'); -}; -MaterialSpinner.prototype['start'] = MaterialSpinner.prototype.start; -/** - * Initialize element. - */ -MaterialSpinner.prototype.init = function () { - if (this.element_) { - for (var i = 1; i <= this.Constant_.MDL_SPINNER_LAYER_COUNT; i++) { - this.createLayer(i); + componentHandler.register({ + constructor: MaterialSnackbar, + classAsString: 'MaterialSnackbar', + cssClass: 'mdl-js-snackbar', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for Spinner MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @param {HTMLElement} element The element that will be upgraded. + * @constructor + */ + var MaterialSpinner = function MaterialSpinner(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialSpinner'] = MaterialSpinner; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialSpinner.prototype.Constant_ = {MDL_SPINNER_LAYER_COUNT: 4}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialSpinner.prototype.CssClasses_ = { + MDL_SPINNER_LAYER: 'mdl-spinner__layer', + MDL_SPINNER_CIRCLE_CLIPPER: 'mdl-spinner__circle-clipper', + MDL_SPINNER_CIRCLE: 'mdl-spinner__circle', + MDL_SPINNER_GAP_PATCH: 'mdl-spinner__gap-patch', + MDL_SPINNER_LEFT: 'mdl-spinner__left', + MDL_SPINNER_RIGHT: 'mdl-spinner__right' + }; + /** + * Auxiliary method to create a spinner layer. + * + * @param {number} index Index of the layer to be created. + * @public + */ + MaterialSpinner.prototype.createLayer = function (index) { + var layer = document.createElement('div'); + layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER); + layer.classList.add(this.CssClasses_.MDL_SPINNER_LAYER + '-' + index); + var leftClipper = document.createElement('div'); + leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER); + leftClipper.classList.add(this.CssClasses_.MDL_SPINNER_LEFT); + var gapPatch = document.createElement('div'); + gapPatch.classList.add(this.CssClasses_.MDL_SPINNER_GAP_PATCH); + var rightClipper = document.createElement('div'); + rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE_CLIPPER); + rightClipper.classList.add(this.CssClasses_.MDL_SPINNER_RIGHT); + var circleOwners = [ + leftClipper, + gapPatch, + rightClipper + ]; + for (var i = 0; i < circleOwners.length; i++) { + var circle = document.createElement('div'); + circle.classList.add(this.CssClasses_.MDL_SPINNER_CIRCLE); + circleOwners[i].appendChild(circle); } - this.element_.classList.add('is-upgraded'); - } -}; + layer.appendChild(leftClipper); + layer.appendChild(gapPatch); + layer.appendChild(rightClipper); + this.element_.appendChild(layer); + }; + MaterialSpinner.prototype['createLayer'] = MaterialSpinner.prototype.createLayer; + /** + * Stops the spinner animation. + * Public method for users who need to stop the spinner for any reason. + * + * @public + */ + MaterialSpinner.prototype.stop = function () { + this.element_.classList.remove('is-active'); + }; + MaterialSpinner.prototype['stop'] = MaterialSpinner.prototype.stop; + /** + * Starts the spinner animation. + * Public method for users who need to manually start the spinner for any reason + * (instead of just adding the 'is-active' class to their markup). + * + * @public + */ + MaterialSpinner.prototype.start = function () { + this.element_.classList.add('is-active'); + }; + MaterialSpinner.prototype['start'] = MaterialSpinner.prototype.start; + /** + * Initialize element. + */ + MaterialSpinner.prototype.init = function () { + if (this.element_) { + for (var i = 1; i <= this.Constant_.MDL_SPINNER_LAYER_COUNT; i++) { + this.createLayer(i); + } + this.element_.classList.add('is-upgraded'); + } + }; // The component registers itself. It can assume componentHandler is available // in the global scope. -componentHandler.register({ - constructor: MaterialSpinner, - classAsString: 'MaterialSpinner', - cssClass: 'mdl-js-spinner', - widget: true -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Checkbox MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {HTMLElement} element The element that will be upgraded. - */ -var MaterialSwitch = function MaterialSwitch(element) { - this.element_ = element; - // Initialize instance. - this.init(); -}; -window['MaterialSwitch'] = MaterialSwitch; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialSwitch.prototype.Constant_ = { TINY_TIMEOUT: 0.001 }; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialSwitch.prototype.CssClasses_ = { - INPUT: 'mdl-switch__input', - TRACK: 'mdl-switch__track', - THUMB: 'mdl-switch__thumb', - FOCUS_HELPER: 'mdl-switch__focus-helper', - RIPPLE_EFFECT: 'mdl-js-ripple-effect', - RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', - RIPPLE_CONTAINER: 'mdl-switch__ripple-container', - RIPPLE_CENTER: 'mdl-ripple--center', - RIPPLE: 'mdl-ripple', - IS_FOCUSED: 'is-focused', - IS_DISABLED: 'is-disabled', - IS_CHECKED: 'is-checked' -}; -/** - * Handle change of state. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialSwitch.prototype.onChange_ = function (event) { - this.updateClasses_(); -}; -/** - * Handle focus of element. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialSwitch.prototype.onFocus_ = function (event) { - this.element_.classList.add(this.CssClasses_.IS_FOCUSED); -}; -/** - * Handle lost focus of element. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialSwitch.prototype.onBlur_ = function (event) { - this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); -}; -/** - * Handle mouseup. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialSwitch.prototype.onMouseUp_ = function (event) { - this.blur_(); -}; -/** - * Handle class updates. - * - * @private - */ -MaterialSwitch.prototype.updateClasses_ = function () { - this.checkDisabled(); - this.checkToggleState(); -}; -/** - * Add blur. - * - * @private - */ -MaterialSwitch.prototype.blur_ = function () { - // TODO: figure out why there's a focus event being fired after our blur, - // so that we can avoid this hack. - window.setTimeout(function () { - this.inputElement_.blur(); - }.bind(this), this.Constant_.TINY_TIMEOUT); -}; -// Public methods. -/** - * Check the components disabled state. - * - * @public - */ -MaterialSwitch.prototype.checkDisabled = function () { - if (this.inputElement_.disabled) { - this.element_.classList.add(this.CssClasses_.IS_DISABLED); - } else { - this.element_.classList.remove(this.CssClasses_.IS_DISABLED); - } -}; -MaterialSwitch.prototype['checkDisabled'] = MaterialSwitch.prototype.checkDisabled; -/** - * Check the components toggled state. - * - * @public - */ -MaterialSwitch.prototype.checkToggleState = function () { - if (this.inputElement_.checked) { - this.element_.classList.add(this.CssClasses_.IS_CHECKED); - } else { - this.element_.classList.remove(this.CssClasses_.IS_CHECKED); - } -}; -MaterialSwitch.prototype['checkToggleState'] = MaterialSwitch.prototype.checkToggleState; -/** - * Disable switch. - * - * @public - */ -MaterialSwitch.prototype.disable = function () { - this.inputElement_.disabled = true; - this.updateClasses_(); -}; -MaterialSwitch.prototype['disable'] = MaterialSwitch.prototype.disable; -/** - * Enable switch. - * - * @public - */ -MaterialSwitch.prototype.enable = function () { - this.inputElement_.disabled = false; - this.updateClasses_(); -}; -MaterialSwitch.prototype['enable'] = MaterialSwitch.prototype.enable; -/** - * Activate switch. - * - * @public - */ -MaterialSwitch.prototype.on = function () { - this.inputElement_.checked = true; - this.updateClasses_(); -}; -MaterialSwitch.prototype['on'] = MaterialSwitch.prototype.on; -/** - * Deactivate switch. - * - * @public - */ -MaterialSwitch.prototype.off = function () { - this.inputElement_.checked = false; - this.updateClasses_(); -}; -MaterialSwitch.prototype['off'] = MaterialSwitch.prototype.off; -/** - * Initialize element. - */ -MaterialSwitch.prototype.init = function () { - if (this.element_) { - this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT); - var track = document.createElement('div'); - track.classList.add(this.CssClasses_.TRACK); - var thumb = document.createElement('div'); - thumb.classList.add(this.CssClasses_.THUMB); - var focusHelper = document.createElement('span'); - focusHelper.classList.add(this.CssClasses_.FOCUS_HELPER); - thumb.appendChild(focusHelper); - this.element_.appendChild(track); - this.element_.appendChild(thumb); - this.boundMouseUpHandler = this.onMouseUp_.bind(this); - if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { - this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); - this.rippleContainerElement_ = document.createElement('span'); - this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER); - this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT); - this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER); - this.rippleContainerElement_.addEventListener('mouseup', this.boundMouseUpHandler); - var ripple = document.createElement('span'); - ripple.classList.add(this.CssClasses_.RIPPLE); - this.rippleContainerElement_.appendChild(ripple); - this.element_.appendChild(this.rippleContainerElement_); - } - this.boundChangeHandler = this.onChange_.bind(this); - this.boundFocusHandler = this.onFocus_.bind(this); - this.boundBlurHandler = this.onBlur_.bind(this); - this.inputElement_.addEventListener('change', this.boundChangeHandler); - this.inputElement_.addEventListener('focus', this.boundFocusHandler); - this.inputElement_.addEventListener('blur', this.boundBlurHandler); - this.element_.addEventListener('mouseup', this.boundMouseUpHandler); + componentHandler.register({ + constructor: MaterialSpinner, + classAsString: 'MaterialSpinner', + cssClass: 'mdl-js-spinner', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for Checkbox MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialSwitch = function MaterialSwitch(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialSwitch'] = MaterialSwitch; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialSwitch.prototype.Constant_ = {TINY_TIMEOUT: 0.001}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialSwitch.prototype.CssClasses_ = { + INPUT: 'mdl-switch__input', + TRACK: 'mdl-switch__track', + THUMB: 'mdl-switch__thumb', + FOCUS_HELPER: 'mdl-switch__focus-helper', + RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + RIPPLE_CONTAINER: 'mdl-switch__ripple-container', + RIPPLE_CENTER: 'mdl-ripple--center', + RIPPLE: 'mdl-ripple', + IS_FOCUSED: 'is-focused', + IS_DISABLED: 'is-disabled', + IS_CHECKED: 'is-checked' + }; + /** + * Handle change of state. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSwitch.prototype.onChange_ = function (event) { this.updateClasses_(); - this.element_.classList.add('is-upgraded'); - } -}; + }; + /** + * Handle focus of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSwitch.prototype.onFocus_ = function (event) { + this.element_.classList.add(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle lost focus of element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSwitch.prototype.onBlur_ = function (event) { + this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle mouseup. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialSwitch.prototype.onMouseUp_ = function (event) { + this.blur_(); + }; + /** + * Handle class updates. + * + * @private + */ + MaterialSwitch.prototype.updateClasses_ = function () { + this.checkDisabled(); + this.checkToggleState(); + }; + /** + * Add blur. + * + * @private + */ + MaterialSwitch.prototype.blur_ = function () { + // TODO: figure out why there's a focus event being fired after our blur, + // so that we can avoid this hack. + window.setTimeout(function () { + this.inputElement_.blur(); + }.bind(this), this.Constant_.TINY_TIMEOUT); + }; +// Public methods. + /** + * Check the components disabled state. + * + * @public + */ + MaterialSwitch.prototype.checkDisabled = function () { + if (this.inputElement_.disabled) { + this.element_.classList.add(this.CssClasses_.IS_DISABLED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_DISABLED); + } + }; + MaterialSwitch.prototype['checkDisabled'] = MaterialSwitch.prototype.checkDisabled; + /** + * Check the components toggled state. + * + * @public + */ + MaterialSwitch.prototype.checkToggleState = function () { + if (this.inputElement_.checked) { + this.element_.classList.add(this.CssClasses_.IS_CHECKED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_CHECKED); + } + }; + MaterialSwitch.prototype['checkToggleState'] = MaterialSwitch.prototype.checkToggleState; + /** + * Disable switch. + * + * @public + */ + MaterialSwitch.prototype.disable = function () { + this.inputElement_.disabled = true; + this.updateClasses_(); + }; + MaterialSwitch.prototype['disable'] = MaterialSwitch.prototype.disable; + /** + * Enable switch. + * + * @public + */ + MaterialSwitch.prototype.enable = function () { + this.inputElement_.disabled = false; + this.updateClasses_(); + }; + MaterialSwitch.prototype['enable'] = MaterialSwitch.prototype.enable; + /** + * Activate switch. + * + * @public + */ + MaterialSwitch.prototype.on = function () { + this.inputElement_.checked = true; + this.updateClasses_(); + }; + MaterialSwitch.prototype['on'] = MaterialSwitch.prototype.on; + /** + * Deactivate switch. + * + * @public + */ + MaterialSwitch.prototype.off = function () { + this.inputElement_.checked = false; + this.updateClasses_(); + }; + MaterialSwitch.prototype['off'] = MaterialSwitch.prototype.off; + /** + * Initialize element. + */ + MaterialSwitch.prototype.init = function () { + if (this.element_) { + this.inputElement_ = this.element_.querySelector('.' + this.CssClasses_.INPUT); + var track = document.createElement('div'); + track.classList.add(this.CssClasses_.TRACK); + var thumb = document.createElement('div'); + thumb.classList.add(this.CssClasses_.THUMB); + var focusHelper = document.createElement('span'); + focusHelper.classList.add(this.CssClasses_.FOCUS_HELPER); + thumb.appendChild(focusHelper); + this.element_.appendChild(track); + this.element_.appendChild(thumb); + this.boundMouseUpHandler = this.onMouseUp_.bind(this); + if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) { + this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); + this.rippleContainerElement_ = document.createElement('span'); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT); + this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER); + this.rippleContainerElement_.addEventListener('mouseup', this.boundMouseUpHandler); + var ripple = document.createElement('span'); + ripple.classList.add(this.CssClasses_.RIPPLE); + this.rippleContainerElement_.appendChild(ripple); + this.element_.appendChild(this.rippleContainerElement_); + } + this.boundChangeHandler = this.onChange_.bind(this); + this.boundFocusHandler = this.onFocus_.bind(this); + this.boundBlurHandler = this.onBlur_.bind(this); + this.inputElement_.addEventListener('change', this.boundChangeHandler); + this.inputElement_.addEventListener('focus', this.boundFocusHandler); + this.inputElement_.addEventListener('blur', this.boundBlurHandler); + this.element_.addEventListener('mouseup', this.boundMouseUpHandler); + this.updateClasses_(); + this.element_.classList.add('is-upgraded'); + } + }; // The component registers itself. It can assume componentHandler is available // in the global scope. -componentHandler.register({ - constructor: MaterialSwitch, - classAsString: 'MaterialSwitch', - cssClass: 'mdl-js-switch', - widget: true -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Tabs MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {Element} element The element that will be upgraded. - */ -var MaterialTabs = function MaterialTabs(element) { - // Stores the HTML element. - this.element_ = element; - // Initialize instance. - this.init(); -}; -window['MaterialTabs'] = MaterialTabs; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string} - * @private - */ -MaterialTabs.prototype.Constant_ = {}; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialTabs.prototype.CssClasses_ = { - TAB_CLASS: 'mdl-tabs__tab', - PANEL_CLASS: 'mdl-tabs__panel', - ACTIVE_CLASS: 'is-active', - UPGRADED_CLASS: 'is-upgraded', - MDL_JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect', - MDL_RIPPLE_CONTAINER: 'mdl-tabs__ripple-container', - MDL_RIPPLE: 'mdl-ripple', - MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events' -}; -/** - * Handle clicks to a tabs component - * - * @private - */ -MaterialTabs.prototype.initTabs_ = function () { - if (this.element_.classList.contains(this.CssClasses_.MDL_JS_RIPPLE_EFFECT)) { - this.element_.classList.add(this.CssClasses_.MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS); + componentHandler.register({ + constructor: MaterialSwitch, + classAsString: 'MaterialSwitch', + cssClass: 'mdl-js-switch', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for Tabs MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {Element} element The element that will be upgraded. + */ + var MaterialTabs = function MaterialTabs(element) { + // Stores the HTML element. + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialTabs'] = MaterialTabs; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string} + * @private + */ + MaterialTabs.prototype.Constant_ = {}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialTabs.prototype.CssClasses_ = { + TAB_CLASS: 'mdl-tabs__tab', + PANEL_CLASS: 'mdl-tabs__panel', + ACTIVE_CLASS: 'is-active', + UPGRADED_CLASS: 'is-upgraded', + MDL_JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect', + MDL_RIPPLE_CONTAINER: 'mdl-tabs__ripple-container', + MDL_RIPPLE: 'mdl-ripple', + MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events' + }; + /** + * Handle clicks to a tabs component + * + * @private + */ + MaterialTabs.prototype.initTabs_ = function () { + if (this.element_.classList.contains(this.CssClasses_.MDL_JS_RIPPLE_EFFECT)) { + this.element_.classList.add(this.CssClasses_.MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS); + } + // Select element tabs, document panels + this.tabs_ = this.element_.querySelectorAll('.' + this.CssClasses_.TAB_CLASS); + this.panels_ = this.element_.querySelectorAll('.' + this.CssClasses_.PANEL_CLASS); + // Create new tabs for each tab element + for (var i = 0; i < this.tabs_.length; i++) { + new MaterialTab(this.tabs_[i], this); + } + this.element_.classList.add(this.CssClasses_.UPGRADED_CLASS); + }; + /** + * Reset tab state, dropping active classes + * + * @private + */ + MaterialTabs.prototype.resetTabState_ = function () { + for (var k = 0; k < this.tabs_.length; k++) { + this.tabs_[k].classList.remove(this.CssClasses_.ACTIVE_CLASS); + } + }; + /** + * Reset panel state, droping active classes + * + * @private + */ + MaterialTabs.prototype.resetPanelState_ = function () { + for (var j = 0; j < this.panels_.length; j++) { + this.panels_[j].classList.remove(this.CssClasses_.ACTIVE_CLASS); + } + }; + /** + * Initialize element. + */ + MaterialTabs.prototype.init = function () { + if (this.element_) { + this.initTabs_(); + } + }; + + /** + * Constructor for an individual tab. + * + * @constructor + * @param {Element} tab The HTML element for the tab. + * @param {MaterialTabs} ctx The MaterialTabs object that owns the tab. + */ + function MaterialTab(tab, ctx) { + if (tab) { + if (ctx.element_.classList.contains(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT)) { + var rippleContainer = document.createElement('span'); + rippleContainer.classList.add(ctx.CssClasses_.MDL_RIPPLE_CONTAINER); + rippleContainer.classList.add(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT); + var ripple = document.createElement('span'); + ripple.classList.add(ctx.CssClasses_.MDL_RIPPLE); + rippleContainer.appendChild(ripple); + tab.appendChild(rippleContainer); + } + tab.addEventListener('click', function (e) { + if (tab.getAttribute('href').charAt(0) === '#') { + e.preventDefault(); + var href = tab.href.split('#')[1]; + var panel = ctx.element_.querySelector('#' + href); + ctx.resetTabState_(); + ctx.resetPanelState_(); + tab.classList.add(ctx.CssClasses_.ACTIVE_CLASS); + panel.classList.add(ctx.CssClasses_.ACTIVE_CLASS); + } + }); + } } - // Select element tabs, document panels - this.tabs_ = this.element_.querySelectorAll('.' + this.CssClasses_.TAB_CLASS); - this.panels_ = this.element_.querySelectorAll('.' + this.CssClasses_.PANEL_CLASS); - // Create new tabs for each tab element - for (var i = 0; i < this.tabs_.length; i++) { - new MaterialTab(this.tabs_[i], this); - } - this.element_.classList.add(this.CssClasses_.UPGRADED_CLASS); -}; -/** - * Reset tab state, dropping active classes - * - * @private - */ -MaterialTabs.prototype.resetTabState_ = function () { - for (var k = 0; k < this.tabs_.length; k++) { - this.tabs_[k].classList.remove(this.CssClasses_.ACTIVE_CLASS); - } -}; -/** - * Reset panel state, droping active classes - * - * @private - */ -MaterialTabs.prototype.resetPanelState_ = function () { - for (var j = 0; j < this.panels_.length; j++) { - this.panels_[j].classList.remove(this.CssClasses_.ACTIVE_CLASS); - } -}; -/** - * Initialize element. - */ -MaterialTabs.prototype.init = function () { - if (this.element_) { - this.initTabs_(); - } -}; -/** - * Constructor for an individual tab. - * - * @constructor - * @param {Element} tab The HTML element for the tab. - * @param {MaterialTabs} ctx The MaterialTabs object that owns the tab. - */ -function MaterialTab(tab, ctx) { - if (tab) { - if (ctx.element_.classList.contains(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT)) { + +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialTabs, + classAsString: 'MaterialTabs', + cssClass: 'mdl-js-tabs' + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for Textfield MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialTextfield = function MaterialTextfield(element) { + this.element_ = element; + this.maxRows = this.Constant_.NO_MAX_ROWS; + // Initialize instance. + this.init(); + }; + window['MaterialTextfield'] = MaterialTextfield; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialTextfield.prototype.Constant_ = { + NO_MAX_ROWS: -1, + MAX_ROWS_ATTRIBUTE: 'maxrows' + }; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialTextfield.prototype.CssClasses_ = { + LABEL: 'mdl-textfield__label', + INPUT: 'mdl-textfield__input', + IS_DIRTY: 'is-dirty', + IS_FOCUSED: 'is-focused', + IS_DISABLED: 'is-disabled', + IS_INVALID: 'is-invalid', + IS_UPGRADED: 'is-upgraded', + HAS_PLACEHOLDER: 'has-placeholder' + }; + /** + * Handle input being entered. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialTextfield.prototype.onKeyDown_ = function (event) { + var currentRowCount = event.target.value.split('\n').length; + if (event.keyCode === 13) { + if (currentRowCount >= this.maxRows) { + event.preventDefault(); + } + } + }; + /** + * Handle focus. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialTextfield.prototype.onFocus_ = function (event) { + this.element_.classList.add(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle lost focus. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialTextfield.prototype.onBlur_ = function (event) { + this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); + }; + /** + * Handle reset event from out side. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialTextfield.prototype.onReset_ = function (event) { + this.updateClasses_(); + }; + /** + * Handle class updates. + * + * @private + */ + MaterialTextfield.prototype.updateClasses_ = function () { + this.checkDisabled(); + this.checkValidity(); + this.checkDirty(); + this.checkFocus(); + }; +// Public methods. + /** + * Check the disabled state and update field accordingly. + * + * @public + */ + MaterialTextfield.prototype.checkDisabled = function () { + if (this.input_.disabled) { + this.element_.classList.add(this.CssClasses_.IS_DISABLED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_DISABLED); + } + }; + MaterialTextfield.prototype['checkDisabled'] = MaterialTextfield.prototype.checkDisabled; + /** + * Check the focus state and update field accordingly. + * + * @public + */ + MaterialTextfield.prototype.checkFocus = function () { + if (Boolean(this.element_.querySelector(':focus'))) { + this.element_.classList.add(this.CssClasses_.IS_FOCUSED); + } else { + this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); + } + }; + MaterialTextfield.prototype['checkFocus'] = MaterialTextfield.prototype.checkFocus; + /** + * Check the validity state and update field accordingly. + * + * @public + */ + MaterialTextfield.prototype.checkValidity = function () { + if (this.input_.validity) { + if (this.input_.validity.valid) { + this.element_.classList.remove(this.CssClasses_.IS_INVALID); + } else { + this.element_.classList.add(this.CssClasses_.IS_INVALID); + } + } + }; + MaterialTextfield.prototype['checkValidity'] = MaterialTextfield.prototype.checkValidity; + /** + * Check the dirty state and update field accordingly. + * + * @public + */ + MaterialTextfield.prototype.checkDirty = function () { + if (this.input_.value && this.input_.value.length > 0) { + this.element_.classList.add(this.CssClasses_.IS_DIRTY); + } else { + this.element_.classList.remove(this.CssClasses_.IS_DIRTY); + } + }; + MaterialTextfield.prototype['checkDirty'] = MaterialTextfield.prototype.checkDirty; + /** + * Disable text field. + * + * @public + */ + MaterialTextfield.prototype.disable = function () { + this.input_.disabled = true; + this.updateClasses_(); + }; + MaterialTextfield.prototype['disable'] = MaterialTextfield.prototype.disable; + /** + * Enable text field. + * + * @public + */ + MaterialTextfield.prototype.enable = function () { + this.input_.disabled = false; + this.updateClasses_(); + }; + MaterialTextfield.prototype['enable'] = MaterialTextfield.prototype.enable; + /** + * Update text field value. + * + * @param {string} value The value to which to set the control (optional). + * @public + */ + MaterialTextfield.prototype.change = function (value) { + this.input_.value = value || ''; + this.updateClasses_(); + }; + MaterialTextfield.prototype['change'] = MaterialTextfield.prototype.change; + /** + * Initialize element. + */ + MaterialTextfield.prototype.init = function () { + if (this.element_) { + this.label_ = this.element_.querySelector('.' + this.CssClasses_.LABEL); + this.input_ = this.element_.querySelector('.' + this.CssClasses_.INPUT); + if (this.input_) { + if (this.input_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)) { + this.maxRows = parseInt(this.input_.getAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE), 10); + if (isNaN(this.maxRows)) { + this.maxRows = this.Constant_.NO_MAX_ROWS; + } + } + if (this.input_.hasAttribute('placeholder')) { + this.element_.classList.add(this.CssClasses_.HAS_PLACEHOLDER); + } + this.boundUpdateClassesHandler = this.updateClasses_.bind(this); + this.boundFocusHandler = this.onFocus_.bind(this); + this.boundBlurHandler = this.onBlur_.bind(this); + this.boundResetHandler = this.onReset_.bind(this); + this.input_.addEventListener('input', this.boundUpdateClassesHandler); + this.input_.addEventListener('focus', this.boundFocusHandler); + this.input_.addEventListener('blur', this.boundBlurHandler); + this.input_.addEventListener('reset', this.boundResetHandler); + if (this.maxRows !== this.Constant_.NO_MAX_ROWS) { + // TODO: This should handle pasting multi line text. + // Currently doesn't. + this.boundKeyDownHandler = this.onKeyDown_.bind(this); + this.input_.addEventListener('keydown', this.boundKeyDownHandler); + } + var invalid = this.element_.classList.contains(this.CssClasses_.IS_INVALID); + this.updateClasses_(); + this.element_.classList.add(this.CssClasses_.IS_UPGRADED); + if (invalid) { + this.element_.classList.add(this.CssClasses_.IS_INVALID); + } + if (this.input_.hasAttribute('autofocus')) { + this.element_.focus(); + this.checkFocus(); + } + } + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialTextfield, + classAsString: 'MaterialTextfield', + cssClass: 'mdl-js-textfield', + widget: true + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for Tooltip MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialTooltip = function MaterialTooltip(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialTooltip'] = MaterialTooltip; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialTooltip.prototype.Constant_ = {}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialTooltip.prototype.CssClasses_ = { + IS_ACTIVE: 'is-active', + BOTTOM: 'mdl-tooltip--bottom', + LEFT: 'mdl-tooltip--left', + RIGHT: 'mdl-tooltip--right', + TOP: 'mdl-tooltip--top' + }; + /** + * Handle mouseenter for tooltip. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialTooltip.prototype.handleMouseEnter_ = function (event) { + var props = event.target.getBoundingClientRect(); + var left = props.left + props.width / 2; + var top = props.top + props.height / 2; + var marginLeft = -1 * (this.element_.offsetWidth / 2); + var marginTop = -1 * (this.element_.offsetHeight / 2); + if (this.element_.classList.contains(this.CssClasses_.LEFT) || this.element_.classList.contains(this.CssClasses_.RIGHT)) { + left = props.width / 2; + if (top + marginTop < 0) { + this.element_.style.top = '0'; + this.element_.style.marginTop = '0'; + } else { + this.element_.style.top = top + 'px'; + this.element_.style.marginTop = marginTop + 'px'; + } + } else { + if (left + marginLeft < 0) { + this.element_.style.left = '0'; + this.element_.style.marginLeft = '0'; + } else { + this.element_.style.left = left + 'px'; + this.element_.style.marginLeft = marginLeft + 'px'; + } + } + if (this.element_.classList.contains(this.CssClasses_.TOP)) { + this.element_.style.top = props.top - this.element_.offsetHeight - 10 + 'px'; + } else if (this.element_.classList.contains(this.CssClasses_.RIGHT)) { + this.element_.style.left = props.left + props.width + 10 + 'px'; + } else if (this.element_.classList.contains(this.CssClasses_.LEFT)) { + this.element_.style.left = props.left - this.element_.offsetWidth - 10 + 'px'; + } else { + this.element_.style.top = props.top + props.height + 10 + 'px'; + } + this.element_.classList.add(this.CssClasses_.IS_ACTIVE); + }; + /** + * Hide tooltip on mouseleave or scroll + * + * @private + */ + MaterialTooltip.prototype.hideTooltip_ = function () { + this.element_.classList.remove(this.CssClasses_.IS_ACTIVE); + }; + /** + * Initialize element. + */ + MaterialTooltip.prototype.init = function () { + if (this.element_) { + var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for'); + if (forElId) { + this.forElement_ = document.getElementById(forElId); + } + if (this.forElement_) { + // It's left here because it prevents accidental text selection on Android + if (!this.forElement_.hasAttribute('tabindex')) { + this.forElement_.setAttribute('tabindex', '0'); + } + this.boundMouseEnterHandler = this.handleMouseEnter_.bind(this); + this.boundMouseLeaveAndScrollHandler = this.hideTooltip_.bind(this); + this.forElement_.addEventListener('mouseenter', this.boundMouseEnterHandler, false); + this.forElement_.addEventListener('touchend', this.boundMouseEnterHandler, false); + this.forElement_.addEventListener('mouseleave', this.boundMouseLeaveAndScrollHandler, false); + window.addEventListener('scroll', this.boundMouseLeaveAndScrollHandler, true); + window.addEventListener('touchstart', this.boundMouseLeaveAndScrollHandler); + } + } + }; +// The component registers itself. It can assume componentHandler is available +// in the global scope. + componentHandler.register({ + constructor: MaterialTooltip, + classAsString: 'MaterialTooltip', + cssClass: 'mdl-tooltip' + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for Layout MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialLayout = function MaterialLayout(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialLayout'] = MaterialLayout; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialLayout.prototype.Constant_ = { + MAX_WIDTH: '(max-width: 1024px)', + TAB_SCROLL_PIXELS: 100, + RESIZE_TIMEOUT: 100, + MENU_ICON: '', + CHEVRON_LEFT: 'chevron_left', + CHEVRON_RIGHT: 'chevron_right' + }; + /** + * Keycodes, for code readability. + * + * @enum {number} + * @private + */ + MaterialLayout.prototype.Keycodes_ = { + ENTER: 13, + ESCAPE: 27, + SPACE: 32 + }; + /** + * Modes. + * + * @enum {number} + * @private + */ + MaterialLayout.prototype.Mode_ = { + STANDARD: 0, + SEAMED: 1, + WATERFALL: 2, + SCROLL: 3 + }; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialLayout.prototype.CssClasses_ = { + CONTAINER: 'mdl-layout__container', + HEADER: 'mdl-layout__header', + DRAWER: 'mdl-layout__drawer', + CONTENT: 'mdl-layout__content', + DRAWER_BTN: 'mdl-layout__drawer-button', + ICON: 'material-icons', + JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect', + RIPPLE_CONTAINER: 'mdl-layout__tab-ripple-container', + RIPPLE: 'mdl-ripple', + RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + HEADER_SEAMED: 'mdl-layout__header--seamed', + HEADER_WATERFALL: 'mdl-layout__header--waterfall', + HEADER_SCROLL: 'mdl-layout__header--scroll', + FIXED_HEADER: 'mdl-layout--fixed-header', + OBFUSCATOR: 'mdl-layout__obfuscator', + TAB_BAR: 'mdl-layout__tab-bar', + TAB_CONTAINER: 'mdl-layout__tab-bar-container', + TAB: 'mdl-layout__tab', + TAB_BAR_BUTTON: 'mdl-layout__tab-bar-button', + TAB_BAR_LEFT_BUTTON: 'mdl-layout__tab-bar-left-button', + TAB_BAR_RIGHT_BUTTON: 'mdl-layout__tab-bar-right-button', + TAB_MANUAL_SWITCH: 'mdl-layout__tab-manual-switch', + PANEL: 'mdl-layout__tab-panel', + HAS_DRAWER: 'has-drawer', + HAS_TABS: 'has-tabs', + HAS_SCROLLING_HEADER: 'has-scrolling-header', + CASTING_SHADOW: 'is-casting-shadow', + IS_COMPACT: 'is-compact', + IS_SMALL_SCREEN: 'is-small-screen', + IS_DRAWER_OPEN: 'is-visible', + IS_ACTIVE: 'is-active', + IS_UPGRADED: 'is-upgraded', + IS_ANIMATING: 'is-animating', + ON_LARGE_SCREEN: 'mdl-layout--large-screen-only', + ON_SMALL_SCREEN: 'mdl-layout--small-screen-only' + }; + /** + * Handles scrolling on the content. + * + * @private + */ + MaterialLayout.prototype.contentScrollHandler_ = function () { + if (this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)) { + return; + } + var headerVisible = !this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN) || this.element_.classList.contains(this.CssClasses_.FIXED_HEADER); + if (this.content_.scrollTop > 0 && !this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) { + this.header_.classList.add(this.CssClasses_.CASTING_SHADOW); + this.header_.classList.add(this.CssClasses_.IS_COMPACT); + if (headerVisible) { + this.header_.classList.add(this.CssClasses_.IS_ANIMATING); + } + } else if (this.content_.scrollTop <= 0 && this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) { + this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW); + this.header_.classList.remove(this.CssClasses_.IS_COMPACT); + if (headerVisible) { + this.header_.classList.add(this.CssClasses_.IS_ANIMATING); + } + } + }; + /** + * Handles a keyboard event on the drawer. + * + * @param {Event} evt The event that fired. + * @private + */ + MaterialLayout.prototype.keyboardEventHandler_ = function (evt) { + // Only react when the drawer is open. + if (evt.keyCode === this.Keycodes_.ESCAPE && this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) { + this.toggleDrawer(); + } + }; + /** + * Handles changes in screen size. + * + * @private + */ + MaterialLayout.prototype.screenSizeHandler_ = function () { + if (this.screenSizeMediaQuery_.matches) { + this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN); + } else { + this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN); + // Collapse drawer (if any) when moving to a large screen size. + if (this.drawer_) { + this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN); + this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN); + } + } + }; + /** + * Handles events of drawer button. + * + * @param {Event} evt The event that fired. + * @private + */ + MaterialLayout.prototype.drawerToggleHandler_ = function (evt) { + if (evt && evt.type === 'keydown') { + if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) { + // prevent scrolling in drawer nav + evt.preventDefault(); + } else { + // prevent other keys + return; + } + } + this.toggleDrawer(); + }; + /** + * Handles (un)setting the `is-animating` class + * + * @private + */ + MaterialLayout.prototype.headerTransitionEndHandler_ = function () { + this.header_.classList.remove(this.CssClasses_.IS_ANIMATING); + }; + /** + * Handles expanding the header on click + * + * @private + */ + MaterialLayout.prototype.headerClickHandler_ = function () { + if (this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) { + this.header_.classList.remove(this.CssClasses_.IS_COMPACT); + this.header_.classList.add(this.CssClasses_.IS_ANIMATING); + } + }; + /** + * Reset tab state, dropping active classes + * + * @private + */ + MaterialLayout.prototype.resetTabState_ = function (tabBar) { + for (var k = 0; k < tabBar.length; k++) { + tabBar[k].classList.remove(this.CssClasses_.IS_ACTIVE); + } + }; + /** + * Reset panel state, droping active classes + * + * @private + */ + MaterialLayout.prototype.resetPanelState_ = function (panels) { + for (var j = 0; j < panels.length; j++) { + panels[j].classList.remove(this.CssClasses_.IS_ACTIVE); + } + }; + /** + * Toggle drawer state + * + * @public + */ + MaterialLayout.prototype.toggleDrawer = function () { + var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN); + this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN); + this.obfuscator_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN); + // Set accessibility properties. + if (this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) { + this.drawer_.setAttribute('aria-hidden', 'false'); + drawerButton.setAttribute('aria-expanded', 'true'); + } else { + this.drawer_.setAttribute('aria-hidden', 'true'); + drawerButton.setAttribute('aria-expanded', 'false'); + } + }; + MaterialLayout.prototype['toggleDrawer'] = MaterialLayout.prototype.toggleDrawer; + /** + * Initialize element. + */ + MaterialLayout.prototype.init = function () { + if (this.element_) { + var container = document.createElement('div'); + container.classList.add(this.CssClasses_.CONTAINER); + var focusedElement = this.element_.querySelector(':focus'); + this.element_.parentElement.insertBefore(container, this.element_); + this.element_.parentElement.removeChild(this.element_); + container.appendChild(this.element_); + if (focusedElement) { + focusedElement.focus(); + } + var directChildren = this.element_.childNodes; + var numChildren = directChildren.length; + for (var c = 0; c < numChildren; c++) { + var child = directChildren[c]; + if (child.classList && child.classList.contains(this.CssClasses_.HEADER)) { + this.header_ = child; + } + if (child.classList && child.classList.contains(this.CssClasses_.DRAWER)) { + this.drawer_ = child; + } + if (child.classList && child.classList.contains(this.CssClasses_.CONTENT)) { + this.content_ = child; + } + } + window.addEventListener('pageshow', function (e) { + if (e.persisted) { + // when page is loaded from back/forward cache + // trigger repaint to let layout scroll in safari + this.element_.style.overflowY = 'hidden'; + requestAnimationFrame(function () { + this.element_.style.overflowY = ''; + }.bind(this)); + } + }.bind(this), false); + if (this.header_) { + this.tabBar_ = this.header_.querySelector('.' + this.CssClasses_.TAB_BAR); + } + var mode = this.Mode_.STANDARD; + if (this.header_) { + if (this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)) { + mode = this.Mode_.SEAMED; + } else if (this.header_.classList.contains(this.CssClasses_.HEADER_WATERFALL)) { + mode = this.Mode_.WATERFALL; + this.header_.addEventListener('transitionend', this.headerTransitionEndHandler_.bind(this)); + this.header_.addEventListener('click', this.headerClickHandler_.bind(this)); + } else if (this.header_.classList.contains(this.CssClasses_.HEADER_SCROLL)) { + mode = this.Mode_.SCROLL; + container.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER); + } + if (mode === this.Mode_.STANDARD) { + this.header_.classList.add(this.CssClasses_.CASTING_SHADOW); + if (this.tabBar_) { + this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW); + } + } else if (mode === this.Mode_.SEAMED || mode === this.Mode_.SCROLL) { + this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW); + if (this.tabBar_) { + this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW); + } + } else if (mode === this.Mode_.WATERFALL) { + // Add and remove shadows depending on scroll position. + // Also add/remove auxiliary class for styling of the compact version of + // the header. + this.content_.addEventListener('scroll', this.contentScrollHandler_.bind(this)); + this.contentScrollHandler_(); + } + } + // Add drawer toggling button to our layout, if we have an openable drawer. + if (this.drawer_) { + var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN); + if (!drawerButton) { + drawerButton = document.createElement('div'); + drawerButton.setAttribute('aria-expanded', 'false'); + drawerButton.setAttribute('role', 'button'); + drawerButton.setAttribute('tabindex', '0'); + drawerButton.classList.add(this.CssClasses_.DRAWER_BTN); + var drawerButtonIcon = document.createElement('i'); + drawerButtonIcon.classList.add(this.CssClasses_.ICON); + drawerButtonIcon.innerHTML = this.Constant_.MENU_ICON; + drawerButton.appendChild(drawerButtonIcon); + } + if (this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)) { + //If drawer has ON_LARGE_SCREEN class then add it to the drawer toggle button as well. + drawerButton.classList.add(this.CssClasses_.ON_LARGE_SCREEN); + } else if (this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)) { + //If drawer has ON_SMALL_SCREEN class then add it to the drawer toggle button as well. + drawerButton.classList.add(this.CssClasses_.ON_SMALL_SCREEN); + } + drawerButton.addEventListener('click', this.drawerToggleHandler_.bind(this)); + drawerButton.addEventListener('keydown', this.drawerToggleHandler_.bind(this)); + // Add a class if the layout has a drawer, for altering the left padding. + // Adds the HAS_DRAWER to the elements since this.header_ may or may + // not be present. + this.element_.classList.add(this.CssClasses_.HAS_DRAWER); + // If we have a fixed header, add the button to the header rather than + // the layout. + if (this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)) { + this.header_.insertBefore(drawerButton, this.header_.firstChild); + } else { + this.element_.insertBefore(drawerButton, this.content_); + } + var obfuscator = document.createElement('div'); + obfuscator.classList.add(this.CssClasses_.OBFUSCATOR); + this.element_.appendChild(obfuscator); + obfuscator.addEventListener('click', this.drawerToggleHandler_.bind(this)); + this.obfuscator_ = obfuscator; + this.drawer_.addEventListener('keydown', this.keyboardEventHandler_.bind(this)); + this.drawer_.setAttribute('aria-hidden', 'true'); + } + // Keep an eye on screen size, and add/remove auxiliary class for styling + // of small screens. + this.screenSizeMediaQuery_ = window.matchMedia(this.Constant_.MAX_WIDTH); + this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this)); + this.screenSizeHandler_(); + // Initialize tabs, if any. + if (this.header_ && this.tabBar_) { + this.element_.classList.add(this.CssClasses_.HAS_TABS); + var tabContainer = document.createElement('div'); + tabContainer.classList.add(this.CssClasses_.TAB_CONTAINER); + this.header_.insertBefore(tabContainer, this.tabBar_); + this.header_.removeChild(this.tabBar_); + var leftButton = document.createElement('div'); + leftButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON); + leftButton.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON); + var leftButtonIcon = document.createElement('i'); + leftButtonIcon.classList.add(this.CssClasses_.ICON); + leftButtonIcon.textContent = this.Constant_.CHEVRON_LEFT; + leftButton.appendChild(leftButtonIcon); + leftButton.addEventListener('click', function () { + this.tabBar_.scrollLeft -= this.Constant_.TAB_SCROLL_PIXELS; + }.bind(this)); + var rightButton = document.createElement('div'); + rightButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON); + rightButton.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON); + var rightButtonIcon = document.createElement('i'); + rightButtonIcon.classList.add(this.CssClasses_.ICON); + rightButtonIcon.textContent = this.Constant_.CHEVRON_RIGHT; + rightButton.appendChild(rightButtonIcon); + rightButton.addEventListener('click', function () { + this.tabBar_.scrollLeft += this.Constant_.TAB_SCROLL_PIXELS; + }.bind(this)); + tabContainer.appendChild(leftButton); + tabContainer.appendChild(this.tabBar_); + tabContainer.appendChild(rightButton); + // Add and remove tab buttons depending on scroll position and total + // window size. + var tabUpdateHandler = function () { + if (this.tabBar_.scrollLeft > 0) { + leftButton.classList.add(this.CssClasses_.IS_ACTIVE); + } else { + leftButton.classList.remove(this.CssClasses_.IS_ACTIVE); + } + if (this.tabBar_.scrollLeft < this.tabBar_.scrollWidth - this.tabBar_.offsetWidth) { + rightButton.classList.add(this.CssClasses_.IS_ACTIVE); + } else { + rightButton.classList.remove(this.CssClasses_.IS_ACTIVE); + } + }.bind(this); + this.tabBar_.addEventListener('scroll', tabUpdateHandler); + tabUpdateHandler(); + // Update tabs when the window resizes. + var windowResizeHandler = function () { + // Use timeouts to make sure it doesn't happen too often. + if (this.resizeTimeoutId_) { + clearTimeout(this.resizeTimeoutId_); + } + this.resizeTimeoutId_ = setTimeout(function () { + tabUpdateHandler(); + this.resizeTimeoutId_ = null; + }.bind(this), this.Constant_.RESIZE_TIMEOUT); + }.bind(this); + window.addEventListener('resize', windowResizeHandler); + if (this.tabBar_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) { + this.tabBar_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); + } + // Select element tabs, document panels + var tabs = this.tabBar_.querySelectorAll('.' + this.CssClasses_.TAB); + var panels = this.content_.querySelectorAll('.' + this.CssClasses_.PANEL); + // Create new tabs for each tab element + for (var i = 0; i < tabs.length; i++) { + new MaterialLayoutTab(tabs[i], tabs, panels, this); + } + } + this.element_.classList.add(this.CssClasses_.IS_UPGRADED); + } + }; + + /** + * Constructor for an individual tab. + * + * @constructor + * @param {HTMLElement} tab The HTML element for the tab. + * @param {!Array} tabs Array with HTML elements for all tabs. + * @param {!Array} panels Array with HTML elements for all panels. + * @param {MaterialLayout} layout The MaterialLayout object that owns the tab. + */ + function MaterialLayoutTab(tab, tabs, panels, layout) { + /** + * Auxiliary method to programmatically select a tab in the UI. + */ + function selectTab() { + var href = tab.href.split('#')[1]; + var panel = layout.content_.querySelector('#' + href); + layout.resetTabState_(tabs); + layout.resetPanelState_(panels); + tab.classList.add(layout.CssClasses_.IS_ACTIVE); + panel.classList.add(layout.CssClasses_.IS_ACTIVE); + } + + if (layout.tabBar_.classList.contains(layout.CssClasses_.JS_RIPPLE_EFFECT)) { var rippleContainer = document.createElement('span'); - rippleContainer.classList.add(ctx.CssClasses_.MDL_RIPPLE_CONTAINER); - rippleContainer.classList.add(ctx.CssClasses_.MDL_JS_RIPPLE_EFFECT); + rippleContainer.classList.add(layout.CssClasses_.RIPPLE_CONTAINER); + rippleContainer.classList.add(layout.CssClasses_.JS_RIPPLE_EFFECT); var ripple = document.createElement('span'); - ripple.classList.add(ctx.CssClasses_.MDL_RIPPLE); + ripple.classList.add(layout.CssClasses_.RIPPLE); rippleContainer.appendChild(ripple); tab.appendChild(rippleContainer); } - tab.addEventListener('click', function (e) { - if (tab.getAttribute('href').charAt(0) === '#') { - e.preventDefault(); - var href = tab.href.split('#')[1]; - var panel = ctx.element_.querySelector('#' + href); - ctx.resetTabState_(); - ctx.resetPanelState_(); - tab.classList.add(ctx.CssClasses_.ACTIVE_CLASS); - panel.classList.add(ctx.CssClasses_.ACTIVE_CLASS); - } - }); + if (!layout.tabBar_.classList.contains(layout.CssClasses_.TAB_MANUAL_SWITCH)) { + tab.addEventListener('click', function (e) { + if (tab.getAttribute('href').charAt(0) === '#') { + e.preventDefault(); + selectTab(); + } + }); + } + tab.show = selectTab; } -} + + window['MaterialLayoutTab'] = MaterialLayoutTab; // The component registers itself. It can assume componentHandler is available // in the global scope. -componentHandler.register({ - constructor: MaterialTabs, - classAsString: 'MaterialTabs', - cssClass: 'mdl-js-tabs' -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Textfield MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {HTMLElement} element The element that will be upgraded. - */ -var MaterialTextfield = function MaterialTextfield(element) { - this.element_ = element; - this.maxRows = this.Constant_.NO_MAX_ROWS; - // Initialize instance. - this.init(); -}; -window['MaterialTextfield'] = MaterialTextfield; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialTextfield.prototype.Constant_ = { - NO_MAX_ROWS: -1, - MAX_ROWS_ATTRIBUTE: 'maxrows' -}; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialTextfield.prototype.CssClasses_ = { - LABEL: 'mdl-textfield__label', - INPUT: 'mdl-textfield__input', - IS_DIRTY: 'is-dirty', - IS_FOCUSED: 'is-focused', - IS_DISABLED: 'is-disabled', - IS_INVALID: 'is-invalid', - IS_UPGRADED: 'is-upgraded', - HAS_PLACEHOLDER: 'has-placeholder' -}; -/** - * Handle input being entered. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialTextfield.prototype.onKeyDown_ = function (event) { - var currentRowCount = event.target.value.split('\n').length; - if (event.keyCode === 13) { - if (currentRowCount >= this.maxRows) { - event.preventDefault(); - } - } -}; -/** - * Handle focus. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialTextfield.prototype.onFocus_ = function (event) { - this.element_.classList.add(this.CssClasses_.IS_FOCUSED); -}; -/** - * Handle lost focus. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialTextfield.prototype.onBlur_ = function (event) { - this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); -}; -/** - * Handle reset event from out side. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialTextfield.prototype.onReset_ = function (event) { - this.updateClasses_(); -}; -/** - * Handle class updates. - * - * @private - */ -MaterialTextfield.prototype.updateClasses_ = function () { - this.checkDisabled(); - this.checkValidity(); - this.checkDirty(); - this.checkFocus(); -}; -// Public methods. -/** - * Check the disabled state and update field accordingly. - * - * @public - */ -MaterialTextfield.prototype.checkDisabled = function () { - if (this.input_.disabled) { - this.element_.classList.add(this.CssClasses_.IS_DISABLED); - } else { - this.element_.classList.remove(this.CssClasses_.IS_DISABLED); - } -}; -MaterialTextfield.prototype['checkDisabled'] = MaterialTextfield.prototype.checkDisabled; -/** - * Check the focus state and update field accordingly. - * - * @public - */ -MaterialTextfield.prototype.checkFocus = function () { - if (Boolean(this.element_.querySelector(':focus'))) { - this.element_.classList.add(this.CssClasses_.IS_FOCUSED); - } else { - this.element_.classList.remove(this.CssClasses_.IS_FOCUSED); - } -}; -MaterialTextfield.prototype['checkFocus'] = MaterialTextfield.prototype.checkFocus; -/** - * Check the validity state and update field accordingly. - * - * @public - */ -MaterialTextfield.prototype.checkValidity = function () { - if (this.input_.validity) { - if (this.input_.validity.valid) { - this.element_.classList.remove(this.CssClasses_.IS_INVALID); - } else { - this.element_.classList.add(this.CssClasses_.IS_INVALID); - } - } -}; -MaterialTextfield.prototype['checkValidity'] = MaterialTextfield.prototype.checkValidity; -/** - * Check the dirty state and update field accordingly. - * - * @public - */ -MaterialTextfield.prototype.checkDirty = function () { - if (this.input_.value && this.input_.value.length > 0) { - this.element_.classList.add(this.CssClasses_.IS_DIRTY); - } else { - this.element_.classList.remove(this.CssClasses_.IS_DIRTY); - } -}; -MaterialTextfield.prototype['checkDirty'] = MaterialTextfield.prototype.checkDirty; -/** - * Disable text field. - * - * @public - */ -MaterialTextfield.prototype.disable = function () { - this.input_.disabled = true; - this.updateClasses_(); -}; -MaterialTextfield.prototype['disable'] = MaterialTextfield.prototype.disable; -/** - * Enable text field. - * - * @public - */ -MaterialTextfield.prototype.enable = function () { - this.input_.disabled = false; - this.updateClasses_(); -}; -MaterialTextfield.prototype['enable'] = MaterialTextfield.prototype.enable; -/** - * Update text field value. - * - * @param {string} value The value to which to set the control (optional). - * @public - */ -MaterialTextfield.prototype.change = function (value) { - this.input_.value = value || ''; - this.updateClasses_(); -}; -MaterialTextfield.prototype['change'] = MaterialTextfield.prototype.change; -/** - * Initialize element. - */ -MaterialTextfield.prototype.init = function () { - if (this.element_) { - this.label_ = this.element_.querySelector('.' + this.CssClasses_.LABEL); - this.input_ = this.element_.querySelector('.' + this.CssClasses_.INPUT); - if (this.input_) { - if (this.input_.hasAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE)) { - this.maxRows = parseInt(this.input_.getAttribute(this.Constant_.MAX_ROWS_ATTRIBUTE), 10); - if (isNaN(this.maxRows)) { - this.maxRows = this.Constant_.NO_MAX_ROWS; - } - } - if (this.input_.hasAttribute('placeholder')) { - this.element_.classList.add(this.CssClasses_.HAS_PLACEHOLDER); - } - this.boundUpdateClassesHandler = this.updateClasses_.bind(this); - this.boundFocusHandler = this.onFocus_.bind(this); - this.boundBlurHandler = this.onBlur_.bind(this); - this.boundResetHandler = this.onReset_.bind(this); - this.input_.addEventListener('input', this.boundUpdateClassesHandler); - this.input_.addEventListener('focus', this.boundFocusHandler); - this.input_.addEventListener('blur', this.boundBlurHandler); - this.input_.addEventListener('reset', this.boundResetHandler); - if (this.maxRows !== this.Constant_.NO_MAX_ROWS) { - // TODO: This should handle pasting multi line text. - // Currently doesn't. - this.boundKeyDownHandler = this.onKeyDown_.bind(this); - this.input_.addEventListener('keydown', this.boundKeyDownHandler); - } - var invalid = this.element_.classList.contains(this.CssClasses_.IS_INVALID); - this.updateClasses_(); - this.element_.classList.add(this.CssClasses_.IS_UPGRADED); - if (invalid) { - this.element_.classList.add(this.CssClasses_.IS_INVALID); - } - if (this.input_.hasAttribute('autofocus')) { - this.element_.focus(); - this.checkFocus(); - } - } - } -}; -// The component registers itself. It can assume componentHandler is available -// in the global scope. -componentHandler.register({ - constructor: MaterialTextfield, - classAsString: 'MaterialTextfield', - cssClass: 'mdl-js-textfield', - widget: true -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Tooltip MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {HTMLElement} element The element that will be upgraded. - */ -var MaterialTooltip = function MaterialTooltip(element) { - this.element_ = element; - // Initialize instance. - this.init(); -}; -window['MaterialTooltip'] = MaterialTooltip; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialTooltip.prototype.Constant_ = {}; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialTooltip.prototype.CssClasses_ = { - IS_ACTIVE: 'is-active', - BOTTOM: 'mdl-tooltip--bottom', - LEFT: 'mdl-tooltip--left', - RIGHT: 'mdl-tooltip--right', - TOP: 'mdl-tooltip--top' -}; -/** - * Handle mouseenter for tooltip. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialTooltip.prototype.handleMouseEnter_ = function (event) { - var props = event.target.getBoundingClientRect(); - var left = props.left + props.width / 2; - var top = props.top + props.height / 2; - var marginLeft = -1 * (this.element_.offsetWidth / 2); - var marginTop = -1 * (this.element_.offsetHeight / 2); - if (this.element_.classList.contains(this.CssClasses_.LEFT) || this.element_.classList.contains(this.CssClasses_.RIGHT)) { - left = props.width / 2; - if (top + marginTop < 0) { - this.element_.style.top = '0'; - this.element_.style.marginTop = '0'; - } else { - this.element_.style.top = top + 'px'; - this.element_.style.marginTop = marginTop + 'px'; - } - } else { - if (left + marginLeft < 0) { - this.element_.style.left = '0'; - this.element_.style.marginLeft = '0'; - } else { - this.element_.style.left = left + 'px'; - this.element_.style.marginLeft = marginLeft + 'px'; - } - } - if (this.element_.classList.contains(this.CssClasses_.TOP)) { - this.element_.style.top = props.top - this.element_.offsetHeight - 10 + 'px'; - } else if (this.element_.classList.contains(this.CssClasses_.RIGHT)) { - this.element_.style.left = props.left + props.width + 10 + 'px'; - } else if (this.element_.classList.contains(this.CssClasses_.LEFT)) { - this.element_.style.left = props.left - this.element_.offsetWidth - 10 + 'px'; - } else { - this.element_.style.top = props.top + props.height + 10 + 'px'; - } - this.element_.classList.add(this.CssClasses_.IS_ACTIVE); -}; -/** - * Hide tooltip on mouseleave or scroll - * - * @private - */ -MaterialTooltip.prototype.hideTooltip_ = function () { - this.element_.classList.remove(this.CssClasses_.IS_ACTIVE); -}; -/** - * Initialize element. - */ -MaterialTooltip.prototype.init = function () { - if (this.element_) { - var forElId = this.element_.getAttribute('for') || this.element_.getAttribute('data-mdl-for'); - if (forElId) { - this.forElement_ = document.getElementById(forElId); - } - if (this.forElement_) { - // It's left here because it prevents accidental text selection on Android - if (!this.forElement_.hasAttribute('tabindex')) { - this.forElement_.setAttribute('tabindex', '0'); - } - this.boundMouseEnterHandler = this.handleMouseEnter_.bind(this); - this.boundMouseLeaveAndScrollHandler = this.hideTooltip_.bind(this); - this.forElement_.addEventListener('mouseenter', this.boundMouseEnterHandler, false); - this.forElement_.addEventListener('touchend', this.boundMouseEnterHandler, false); - this.forElement_.addEventListener('mouseleave', this.boundMouseLeaveAndScrollHandler, false); - window.addEventListener('scroll', this.boundMouseLeaveAndScrollHandler, true); - window.addEventListener('touchstart', this.boundMouseLeaveAndScrollHandler); - } - } -}; -// The component registers itself. It can assume componentHandler is available -// in the global scope. -componentHandler.register({ - constructor: MaterialTooltip, - classAsString: 'MaterialTooltip', - cssClass: 'mdl-tooltip' -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Layout MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {HTMLElement} element The element that will be upgraded. - */ -var MaterialLayout = function MaterialLayout(element) { - this.element_ = element; - // Initialize instance. - this.init(); -}; -window['MaterialLayout'] = MaterialLayout; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialLayout.prototype.Constant_ = { - MAX_WIDTH: '(max-width: 1024px)', - TAB_SCROLL_PIXELS: 100, - RESIZE_TIMEOUT: 100, - MENU_ICON: '', - CHEVRON_LEFT: 'chevron_left', - CHEVRON_RIGHT: 'chevron_right' -}; -/** - * Keycodes, for code readability. - * - * @enum {number} - * @private - */ -MaterialLayout.prototype.Keycodes_ = { - ENTER: 13, - ESCAPE: 27, - SPACE: 32 -}; -/** - * Modes. - * - * @enum {number} - * @private - */ -MaterialLayout.prototype.Mode_ = { - STANDARD: 0, - SEAMED: 1, - WATERFALL: 2, - SCROLL: 3 -}; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialLayout.prototype.CssClasses_ = { - CONTAINER: 'mdl-layout__container', - HEADER: 'mdl-layout__header', - DRAWER: 'mdl-layout__drawer', - CONTENT: 'mdl-layout__content', - DRAWER_BTN: 'mdl-layout__drawer-button', - ICON: 'material-icons', - JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect', - RIPPLE_CONTAINER: 'mdl-layout__tab-ripple-container', - RIPPLE: 'mdl-ripple', - RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', - HEADER_SEAMED: 'mdl-layout__header--seamed', - HEADER_WATERFALL: 'mdl-layout__header--waterfall', - HEADER_SCROLL: 'mdl-layout__header--scroll', - FIXED_HEADER: 'mdl-layout--fixed-header', - OBFUSCATOR: 'mdl-layout__obfuscator', - TAB_BAR: 'mdl-layout__tab-bar', - TAB_CONTAINER: 'mdl-layout__tab-bar-container', - TAB: 'mdl-layout__tab', - TAB_BAR_BUTTON: 'mdl-layout__tab-bar-button', - TAB_BAR_LEFT_BUTTON: 'mdl-layout__tab-bar-left-button', - TAB_BAR_RIGHT_BUTTON: 'mdl-layout__tab-bar-right-button', - TAB_MANUAL_SWITCH: 'mdl-layout__tab-manual-switch', - PANEL: 'mdl-layout__tab-panel', - HAS_DRAWER: 'has-drawer', - HAS_TABS: 'has-tabs', - HAS_SCROLLING_HEADER: 'has-scrolling-header', - CASTING_SHADOW: 'is-casting-shadow', - IS_COMPACT: 'is-compact', - IS_SMALL_SCREEN: 'is-small-screen', - IS_DRAWER_OPEN: 'is-visible', - IS_ACTIVE: 'is-active', - IS_UPGRADED: 'is-upgraded', - IS_ANIMATING: 'is-animating', - ON_LARGE_SCREEN: 'mdl-layout--large-screen-only', - ON_SMALL_SCREEN: 'mdl-layout--small-screen-only' -}; -/** - * Handles scrolling on the content. - * - * @private - */ -MaterialLayout.prototype.contentScrollHandler_ = function () { - if (this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)) { - return; - } - var headerVisible = !this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN) || this.element_.classList.contains(this.CssClasses_.FIXED_HEADER); - if (this.content_.scrollTop > 0 && !this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) { - this.header_.classList.add(this.CssClasses_.CASTING_SHADOW); - this.header_.classList.add(this.CssClasses_.IS_COMPACT); - if (headerVisible) { - this.header_.classList.add(this.CssClasses_.IS_ANIMATING); - } - } else if (this.content_.scrollTop <= 0 && this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) { - this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW); - this.header_.classList.remove(this.CssClasses_.IS_COMPACT); - if (headerVisible) { - this.header_.classList.add(this.CssClasses_.IS_ANIMATING); - } - } -}; -/** - * Handles a keyboard event on the drawer. - * - * @param {Event} evt The event that fired. - * @private - */ -MaterialLayout.prototype.keyboardEventHandler_ = function (evt) { - // Only react when the drawer is open. - if (evt.keyCode === this.Keycodes_.ESCAPE && this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) { - this.toggleDrawer(); - } -}; -/** - * Handles changes in screen size. - * - * @private - */ -MaterialLayout.prototype.screenSizeHandler_ = function () { - if (this.screenSizeMediaQuery_.matches) { - this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN); - } else { - this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN); - // Collapse drawer (if any) when moving to a large screen size. - if (this.drawer_) { - this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN); - this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN); - } - } -}; -/** - * Handles events of drawer button. - * - * @param {Event} evt The event that fired. - * @private - */ -MaterialLayout.prototype.drawerToggleHandler_ = function (evt) { - if (evt && evt.type === 'keydown') { - if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) { - // prevent scrolling in drawer nav - evt.preventDefault(); - } else { - // prevent other keys - return; - } - } - this.toggleDrawer(); -}; -/** - * Handles (un)setting the `is-animating` class - * - * @private - */ -MaterialLayout.prototype.headerTransitionEndHandler_ = function () { - this.header_.classList.remove(this.CssClasses_.IS_ANIMATING); -}; -/** - * Handles expanding the header on click - * - * @private - */ -MaterialLayout.prototype.headerClickHandler_ = function () { - if (this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) { - this.header_.classList.remove(this.CssClasses_.IS_COMPACT); - this.header_.classList.add(this.CssClasses_.IS_ANIMATING); - } -}; -/** - * Reset tab state, dropping active classes - * - * @private - */ -MaterialLayout.prototype.resetTabState_ = function (tabBar) { - for (var k = 0; k < tabBar.length; k++) { - tabBar[k].classList.remove(this.CssClasses_.IS_ACTIVE); - } -}; -/** - * Reset panel state, droping active classes - * - * @private - */ -MaterialLayout.prototype.resetPanelState_ = function (panels) { - for (var j = 0; j < panels.length; j++) { - panels[j].classList.remove(this.CssClasses_.IS_ACTIVE); - } -}; -/** - * Toggle drawer state - * - * @public - */ -MaterialLayout.prototype.toggleDrawer = function () { - var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN); - this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN); - this.obfuscator_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN); - // Set accessibility properties. - if (this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) { - this.drawer_.setAttribute('aria-hidden', 'false'); - drawerButton.setAttribute('aria-expanded', 'true'); - } else { - this.drawer_.setAttribute('aria-hidden', 'true'); - drawerButton.setAttribute('aria-expanded', 'false'); - } -}; -MaterialLayout.prototype['toggleDrawer'] = MaterialLayout.prototype.toggleDrawer; -/** - * Initialize element. - */ -MaterialLayout.prototype.init = function () { - if (this.element_) { - var container = document.createElement('div'); - container.classList.add(this.CssClasses_.CONTAINER); - var focusedElement = this.element_.querySelector(':focus'); - this.element_.parentElement.insertBefore(container, this.element_); - this.element_.parentElement.removeChild(this.element_); - container.appendChild(this.element_); - if (focusedElement) { - focusedElement.focus(); - } - var directChildren = this.element_.childNodes; - var numChildren = directChildren.length; - for (var c = 0; c < numChildren; c++) { - var child = directChildren[c]; - if (child.classList && child.classList.contains(this.CssClasses_.HEADER)) { - this.header_ = child; - } - if (child.classList && child.classList.contains(this.CssClasses_.DRAWER)) { - this.drawer_ = child; - } - if (child.classList && child.classList.contains(this.CssClasses_.CONTENT)) { - this.content_ = child; - } - } - window.addEventListener('pageshow', function (e) { - if (e.persisted) { - // when page is loaded from back/forward cache - // trigger repaint to let layout scroll in safari - this.element_.style.overflowY = 'hidden'; - requestAnimationFrame(function () { - this.element_.style.overflowY = ''; - }.bind(this)); - } - }.bind(this), false); - if (this.header_) { - this.tabBar_ = this.header_.querySelector('.' + this.CssClasses_.TAB_BAR); - } - var mode = this.Mode_.STANDARD; - if (this.header_) { - if (this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)) { - mode = this.Mode_.SEAMED; - } else if (this.header_.classList.contains(this.CssClasses_.HEADER_WATERFALL)) { - mode = this.Mode_.WATERFALL; - this.header_.addEventListener('transitionend', this.headerTransitionEndHandler_.bind(this)); - this.header_.addEventListener('click', this.headerClickHandler_.bind(this)); - } else if (this.header_.classList.contains(this.CssClasses_.HEADER_SCROLL)) { - mode = this.Mode_.SCROLL; - container.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER); - } - if (mode === this.Mode_.STANDARD) { - this.header_.classList.add(this.CssClasses_.CASTING_SHADOW); - if (this.tabBar_) { - this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW); - } - } else if (mode === this.Mode_.SEAMED || mode === this.Mode_.SCROLL) { - this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW); - if (this.tabBar_) { - this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW); - } - } else if (mode === this.Mode_.WATERFALL) { - // Add and remove shadows depending on scroll position. - // Also add/remove auxiliary class for styling of the compact version of - // the header. - this.content_.addEventListener('scroll', this.contentScrollHandler_.bind(this)); - this.contentScrollHandler_(); - } - } - // Add drawer toggling button to our layout, if we have an openable drawer. - if (this.drawer_) { - var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN); - if (!drawerButton) { - drawerButton = document.createElement('div'); - drawerButton.setAttribute('aria-expanded', 'false'); - drawerButton.setAttribute('role', 'button'); - drawerButton.setAttribute('tabindex', '0'); - drawerButton.classList.add(this.CssClasses_.DRAWER_BTN); - var drawerButtonIcon = document.createElement('i'); - drawerButtonIcon.classList.add(this.CssClasses_.ICON); - drawerButtonIcon.innerHTML = this.Constant_.MENU_ICON; - drawerButton.appendChild(drawerButtonIcon); - } - if (this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)) { - //If drawer has ON_LARGE_SCREEN class then add it to the drawer toggle button as well. - drawerButton.classList.add(this.CssClasses_.ON_LARGE_SCREEN); - } else if (this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)) { - //If drawer has ON_SMALL_SCREEN class then add it to the drawer toggle button as well. - drawerButton.classList.add(this.CssClasses_.ON_SMALL_SCREEN); - } - drawerButton.addEventListener('click', this.drawerToggleHandler_.bind(this)); - drawerButton.addEventListener('keydown', this.drawerToggleHandler_.bind(this)); - // Add a class if the layout has a drawer, for altering the left padding. - // Adds the HAS_DRAWER to the elements since this.header_ may or may - // not be present. - this.element_.classList.add(this.CssClasses_.HAS_DRAWER); - // If we have a fixed header, add the button to the header rather than - // the layout. - if (this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)) { - this.header_.insertBefore(drawerButton, this.header_.firstChild); - } else { - this.element_.insertBefore(drawerButton, this.content_); - } - var obfuscator = document.createElement('div'); - obfuscator.classList.add(this.CssClasses_.OBFUSCATOR); - this.element_.appendChild(obfuscator); - obfuscator.addEventListener('click', this.drawerToggleHandler_.bind(this)); - this.obfuscator_ = obfuscator; - this.drawer_.addEventListener('keydown', this.keyboardEventHandler_.bind(this)); - this.drawer_.setAttribute('aria-hidden', 'true'); - } - // Keep an eye on screen size, and add/remove auxiliary class for styling - // of small screens. - this.screenSizeMediaQuery_ = window.matchMedia(this.Constant_.MAX_WIDTH); - this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this)); - this.screenSizeHandler_(); - // Initialize tabs, if any. - if (this.header_ && this.tabBar_) { - this.element_.classList.add(this.CssClasses_.HAS_TABS); - var tabContainer = document.createElement('div'); - tabContainer.classList.add(this.CssClasses_.TAB_CONTAINER); - this.header_.insertBefore(tabContainer, this.tabBar_); - this.header_.removeChild(this.tabBar_); - var leftButton = document.createElement('div'); - leftButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON); - leftButton.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON); - var leftButtonIcon = document.createElement('i'); - leftButtonIcon.classList.add(this.CssClasses_.ICON); - leftButtonIcon.textContent = this.Constant_.CHEVRON_LEFT; - leftButton.appendChild(leftButtonIcon); - leftButton.addEventListener('click', function () { - this.tabBar_.scrollLeft -= this.Constant_.TAB_SCROLL_PIXELS; - }.bind(this)); - var rightButton = document.createElement('div'); - rightButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON); - rightButton.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON); - var rightButtonIcon = document.createElement('i'); - rightButtonIcon.classList.add(this.CssClasses_.ICON); - rightButtonIcon.textContent = this.Constant_.CHEVRON_RIGHT; - rightButton.appendChild(rightButtonIcon); - rightButton.addEventListener('click', function () { - this.tabBar_.scrollLeft += this.Constant_.TAB_SCROLL_PIXELS; - }.bind(this)); - tabContainer.appendChild(leftButton); - tabContainer.appendChild(this.tabBar_); - tabContainer.appendChild(rightButton); - // Add and remove tab buttons depending on scroll position and total - // window size. - var tabUpdateHandler = function () { - if (this.tabBar_.scrollLeft > 0) { - leftButton.classList.add(this.CssClasses_.IS_ACTIVE); - } else { - leftButton.classList.remove(this.CssClasses_.IS_ACTIVE); - } - if (this.tabBar_.scrollLeft < this.tabBar_.scrollWidth - this.tabBar_.offsetWidth) { - rightButton.classList.add(this.CssClasses_.IS_ACTIVE); - } else { - rightButton.classList.remove(this.CssClasses_.IS_ACTIVE); - } - }.bind(this); - this.tabBar_.addEventListener('scroll', tabUpdateHandler); - tabUpdateHandler(); - // Update tabs when the window resizes. - var windowResizeHandler = function () { - // Use timeouts to make sure it doesn't happen too often. - if (this.resizeTimeoutId_) { - clearTimeout(this.resizeTimeoutId_); - } - this.resizeTimeoutId_ = setTimeout(function () { - tabUpdateHandler(); - this.resizeTimeoutId_ = null; - }.bind(this), this.Constant_.RESIZE_TIMEOUT); - }.bind(this); - window.addEventListener('resize', windowResizeHandler); - if (this.tabBar_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) { - this.tabBar_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS); - } - // Select element tabs, document panels - var tabs = this.tabBar_.querySelectorAll('.' + this.CssClasses_.TAB); - var panels = this.content_.querySelectorAll('.' + this.CssClasses_.PANEL); - // Create new tabs for each tab element - for (var i = 0; i < tabs.length; i++) { - new MaterialLayoutTab(tabs[i], tabs, panels, this); - } - } - this.element_.classList.add(this.CssClasses_.IS_UPGRADED); - } -}; -/** - * Constructor for an individual tab. - * - * @constructor - * @param {HTMLElement} tab The HTML element for the tab. - * @param {!Array} tabs Array with HTML elements for all tabs. - * @param {!Array} panels Array with HTML elements for all panels. - * @param {MaterialLayout} layout The MaterialLayout object that owns the tab. - */ -function MaterialLayoutTab(tab, tabs, panels, layout) { + componentHandler.register({ + constructor: MaterialLayout, + classAsString: 'MaterialLayout', + cssClass: 'mdl-js-layout' + }); /** - * Auxiliary method to programmatically select a tab in the UI. + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ - function selectTab() { - var href = tab.href.split('#')[1]; - var panel = layout.content_.querySelector('#' + href); - layout.resetTabState_(tabs); - layout.resetPanelState_(panels); - tab.classList.add(layout.CssClasses_.IS_ACTIVE); - panel.classList.add(layout.CssClasses_.IS_ACTIVE); - } - if (layout.tabBar_.classList.contains(layout.CssClasses_.JS_RIPPLE_EFFECT)) { - var rippleContainer = document.createElement('span'); - rippleContainer.classList.add(layout.CssClasses_.RIPPLE_CONTAINER); - rippleContainer.classList.add(layout.CssClasses_.JS_RIPPLE_EFFECT); - var ripple = document.createElement('span'); - ripple.classList.add(layout.CssClasses_.RIPPLE); - rippleContainer.appendChild(ripple); - tab.appendChild(rippleContainer); - } - if (!layout.tabBar_.classList.contains(layout.CssClasses_.TAB_MANUAL_SWITCH)) { - tab.addEventListener('click', function (e) { - if (tab.getAttribute('href').charAt(0) === '#') { - e.preventDefault(); - selectTab(); - } - }); - } - tab.show = selectTab; -} -window['MaterialLayoutTab'] = MaterialLayoutTab; -// The component registers itself. It can assume componentHandler is available -// in the global scope. -componentHandler.register({ - constructor: MaterialLayout, - classAsString: 'MaterialLayout', - cssClass: 'mdl-js-layout' -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Data Table Card MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {Element} element The element that will be upgraded. - */ -var MaterialDataTable = function MaterialDataTable(element) { - this.element_ = element; - // Initialize instance. - this.init(); -}; -window['MaterialDataTable'] = MaterialDataTable; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialDataTable.prototype.Constant_ = {}; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialDataTable.prototype.CssClasses_ = { - DATA_TABLE: 'mdl-data-table', - SELECTABLE: 'mdl-data-table--selectable', - SELECT_ELEMENT: 'mdl-data-table__select', - IS_SELECTED: 'is-selected', - IS_UPGRADED: 'is-upgraded' -}; -/** - * Generates and returns a function that toggles the selection state of a - * single row (or multiple rows). - * - * @param {Element} checkbox Checkbox that toggles the selection state. - * @param {Element} row Row to toggle when checkbox changes. - * @param {(Array|NodeList)=} opt_rows Rows to toggle when checkbox changes. - * @private - */ -MaterialDataTable.prototype.selectRow_ = function (checkbox, row, opt_rows) { - if (row) { - return function () { - if (checkbox.checked) { - row.classList.add(this.CssClasses_.IS_SELECTED); - } else { - row.classList.remove(this.CssClasses_.IS_SELECTED); - } - }.bind(this); - } - if (opt_rows) { - return function () { - var i; - var el; - if (checkbox.checked) { - for (i = 0; i < opt_rows.length; i++) { - el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox'); - el['MaterialCheckbox'].check(); - opt_rows[i].classList.add(this.CssClasses_.IS_SELECTED); + /** + * Class constructor for Data Table Card MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {Element} element The element that will be upgraded. + */ + var MaterialDataTable = function MaterialDataTable(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialDataTable'] = MaterialDataTable; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialDataTable.prototype.Constant_ = {}; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialDataTable.prototype.CssClasses_ = { + DATA_TABLE: 'mdl-data-table', + SELECTABLE: 'mdl-data-table--selectable', + SELECT_ELEMENT: 'mdl-data-table__select', + IS_SELECTED: 'is-selected', + IS_UPGRADED: 'is-upgraded' + }; + /** + * Generates and returns a function that toggles the selection state of a + * single row (or multiple rows). + * + * @param {Element} checkbox Checkbox that toggles the selection state. + * @param {Element} row Row to toggle when checkbox changes. + * @param {(Array|NodeList)=} opt_rows Rows to toggle when checkbox changes. + * @private + */ + MaterialDataTable.prototype.selectRow_ = function (checkbox, row, opt_rows) { + if (row) { + return function () { + if (checkbox.checked) { + row.classList.add(this.CssClasses_.IS_SELECTED); + } else { + row.classList.remove(this.CssClasses_.IS_SELECTED); } - } else { - for (i = 0; i < opt_rows.length; i++) { - el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox'); - el['MaterialCheckbox'].uncheck(); - opt_rows[i].classList.remove(this.CssClasses_.IS_SELECTED); - } - } - }.bind(this); - } -}; -/** - * Creates a checkbox for a single or or multiple rows and hooks up the - * event handling. - * - * @param {Element} row Row to toggle when checkbox changes. - * @param {(Array|NodeList)=} opt_rows Rows to toggle when checkbox changes. - * @private - */ -MaterialDataTable.prototype.createCheckbox_ = function (row, opt_rows) { - var label = document.createElement('label'); - var labelClasses = [ - 'mdl-checkbox', - 'mdl-js-checkbox', - 'mdl-js-ripple-effect', - this.CssClasses_.SELECT_ELEMENT - ]; - label.className = labelClasses.join(' '); - var checkbox = document.createElement('input'); - checkbox.type = 'checkbox'; - checkbox.classList.add('mdl-checkbox__input'); - if (row) { - checkbox.checked = row.classList.contains(this.CssClasses_.IS_SELECTED); - checkbox.addEventListener('change', this.selectRow_(checkbox, row)); - } else if (opt_rows) { - checkbox.addEventListener('change', this.selectRow_(checkbox, null, opt_rows)); - } - label.appendChild(checkbox); - componentHandler.upgradeElement(label, 'MaterialCheckbox'); - return label; -}; -/** - * Initialize element. - */ -MaterialDataTable.prototype.init = function () { - if (this.element_) { - var firstHeader = this.element_.querySelector('th'); - var bodyRows = Array.prototype.slice.call(this.element_.querySelectorAll('tbody tr')); - var footRows = Array.prototype.slice.call(this.element_.querySelectorAll('tfoot tr')); - var rows = bodyRows.concat(footRows); - if (this.element_.classList.contains(this.CssClasses_.SELECTABLE)) { - var th = document.createElement('th'); - var headerCheckbox = this.createCheckbox_(null, rows); - th.appendChild(headerCheckbox); - firstHeader.parentElement.insertBefore(th, firstHeader); - for (var i = 0; i < rows.length; i++) { - var firstCell = rows[i].querySelector('td'); - if (firstCell) { - var td = document.createElement('td'); - if (rows[i].parentNode.nodeName.toUpperCase() === 'TBODY') { - var rowCheckbox = this.createCheckbox_(rows[i]); - td.appendChild(rowCheckbox); + }.bind(this); + } + if (opt_rows) { + return function () { + var i; + var el; + if (checkbox.checked) { + for (i = 0; i < opt_rows.length; i++) { + el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox'); + el['MaterialCheckbox'].check(); + opt_rows[i].classList.add(this.CssClasses_.IS_SELECTED); + } + } else { + for (i = 0; i < opt_rows.length; i++) { + el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox'); + el['MaterialCheckbox'].uncheck(); + opt_rows[i].classList.remove(this.CssClasses_.IS_SELECTED); } - rows[i].insertBefore(td, firstCell); } - } - this.element_.classList.add(this.CssClasses_.IS_UPGRADED); + }.bind(this); } - } -}; + }; + /** + * Creates a checkbox for a single or or multiple rows and hooks up the + * event handling. + * + * @param {Element} row Row to toggle when checkbox changes. + * @param {(Array|NodeList)=} opt_rows Rows to toggle when checkbox changes. + * @private + */ + MaterialDataTable.prototype.createCheckbox_ = function (row, opt_rows) { + var label = document.createElement('label'); + var labelClasses = [ + 'mdl-checkbox', + 'mdl-js-checkbox', + 'mdl-js-ripple-effect', + this.CssClasses_.SELECT_ELEMENT + ]; + label.className = labelClasses.join(' '); + var checkbox = document.createElement('input'); + checkbox.type = 'checkbox'; + checkbox.classList.add('mdl-checkbox__input'); + if (row) { + checkbox.checked = row.classList.contains(this.CssClasses_.IS_SELECTED); + checkbox.addEventListener('change', this.selectRow_(checkbox, row)); + } else if (opt_rows) { + checkbox.addEventListener('change', this.selectRow_(checkbox, null, opt_rows)); + } + label.appendChild(checkbox); + componentHandler.upgradeElement(label, 'MaterialCheckbox'); + return label; + }; + /** + * Initialize element. + */ + MaterialDataTable.prototype.init = function () { + if (this.element_) { + var firstHeader = this.element_.querySelector('th'); + var bodyRows = Array.prototype.slice.call(this.element_.querySelectorAll('tbody tr')); + var footRows = Array.prototype.slice.call(this.element_.querySelectorAll('tfoot tr')); + var rows = bodyRows.concat(footRows); + if (this.element_.classList.contains(this.CssClasses_.SELECTABLE)) { + var th = document.createElement('th'); + var headerCheckbox = this.createCheckbox_(null, rows); + th.appendChild(headerCheckbox); + firstHeader.parentElement.insertBefore(th, firstHeader); + for (var i = 0; i < rows.length; i++) { + var firstCell = rows[i].querySelector('td'); + if (firstCell) { + var td = document.createElement('td'); + if (rows[i].parentNode.nodeName.toUpperCase() === 'TBODY') { + var rowCheckbox = this.createCheckbox_(rows[i]); + td.appendChild(rowCheckbox); + } + rows[i].insertBefore(td, firstCell); + } + } + this.element_.classList.add(this.CssClasses_.IS_UPGRADED); + } + } + }; // The component registers itself. It can assume componentHandler is available // in the global scope. -componentHandler.register({ - constructor: MaterialDataTable, - classAsString: 'MaterialDataTable', - cssClass: 'mdl-js-data-table' -}); -/** - * @license - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * Class constructor for Ripple MDL component. - * Implements MDL component design pattern defined at: - * https://github.com/jasonmayes/mdl-component-design-pattern - * - * @constructor - * @param {HTMLElement} element The element that will be upgraded. - */ -var MaterialRipple = function MaterialRipple(element) { - this.element_ = element; - // Initialize instance. - this.init(); -}; -window['MaterialRipple'] = MaterialRipple; -/** - * Store constants in one place so they can be updated easily. - * - * @enum {string | number} - * @private - */ -MaterialRipple.prototype.Constant_ = { - INITIAL_SCALE: 'scale(0.0001, 0.0001)', - INITIAL_SIZE: '1px', - INITIAL_OPACITY: '0.4', - FINAL_OPACITY: '0', - FINAL_SCALE: '' -}; -/** - * Store strings for class names defined by this component that are used in - * JavaScript. This allows us to simply change it in one place should we - * decide to modify at a later date. - * - * @enum {string} - * @private - */ -MaterialRipple.prototype.CssClasses_ = { - RIPPLE_CENTER: 'mdl-ripple--center', - RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', - RIPPLE: 'mdl-ripple', - IS_ANIMATING: 'is-animating', - IS_VISIBLE: 'is-visible' -}; -/** - * Handle mouse / finger down on element. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialRipple.prototype.downHandler_ = function (event) { - if (!this.rippleElement_.style.width && !this.rippleElement_.style.height) { - var rect = this.element_.getBoundingClientRect(); - this.boundHeight = rect.height; - this.boundWidth = rect.width; - this.rippleSize_ = Math.sqrt(rect.width * rect.width + rect.height * rect.height) * 2 + 2; - this.rippleElement_.style.width = this.rippleSize_ + 'px'; - this.rippleElement_.style.height = this.rippleSize_ + 'px'; - } - this.rippleElement_.classList.add(this.CssClasses_.IS_VISIBLE); - if (event.type === 'mousedown' && this.ignoringMouseDown_) { - this.ignoringMouseDown_ = false; - } else { - if (event.type === 'touchstart') { - this.ignoringMouseDown_ = true; + componentHandler.register({ + constructor: MaterialDataTable, + classAsString: 'MaterialDataTable', + cssClass: 'mdl-js-data-table' + }); + /** + * @license + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** + * Class constructor for Ripple MDL component. + * Implements MDL component design pattern defined at: + * https://github.com/jasonmayes/mdl-component-design-pattern + * + * @constructor + * @param {HTMLElement} element The element that will be upgraded. + */ + var MaterialRipple = function MaterialRipple(element) { + this.element_ = element; + // Initialize instance. + this.init(); + }; + window['MaterialRipple'] = MaterialRipple; + /** + * Store constants in one place so they can be updated easily. + * + * @enum {string | number} + * @private + */ + MaterialRipple.prototype.Constant_ = { + INITIAL_SCALE: 'scale(0.0001, 0.0001)', + INITIAL_SIZE: '1px', + INITIAL_OPACITY: '0.4', + FINAL_OPACITY: '0', + FINAL_SCALE: '' + }; + /** + * Store strings for class names defined by this component that are used in + * JavaScript. This allows us to simply change it in one place should we + * decide to modify at a later date. + * + * @enum {string} + * @private + */ + MaterialRipple.prototype.CssClasses_ = { + RIPPLE_CENTER: 'mdl-ripple--center', + RIPPLE_EFFECT_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events', + RIPPLE: 'mdl-ripple', + IS_ANIMATING: 'is-animating', + IS_VISIBLE: 'is-visible' + }; + /** + * Handle mouse / finger down on element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialRipple.prototype.downHandler_ = function (event) { + if (!this.rippleElement_.style.width && !this.rippleElement_.style.height) { + var rect = this.element_.getBoundingClientRect(); + this.boundHeight = rect.height; + this.boundWidth = rect.width; + this.rippleSize_ = Math.sqrt(rect.width * rect.width + rect.height * rect.height) * 2 + 2; + this.rippleElement_.style.width = this.rippleSize_ + 'px'; + this.rippleElement_.style.height = this.rippleSize_ + 'px'; } - var frameCount = this.getFrameCount(); - if (frameCount > 0) { - return; - } - this.setFrameCount(1); - var bound = event.currentTarget.getBoundingClientRect(); - var x; - var y; - // Check if we are handling a keyboard click. - if (event.clientX === 0 && event.clientY === 0) { - x = Math.round(bound.width / 2); - y = Math.round(bound.height / 2); - } else { - var clientX = event.clientX !== undefined ? event.clientX : event.touches[0].clientX; - var clientY = event.clientY !== undefined ? event.clientY : event.touches[0].clientY; - x = Math.round(clientX - bound.left); - y = Math.round(clientY - bound.top); - } - this.setRippleXY(x, y); - this.setRippleStyles(true); - window.requestAnimationFrame(this.animFrameHandler.bind(this)); - } -}; -/** - * Handle mouse / finger up on element. - * - * @param {Event} event The event that fired. - * @private - */ -MaterialRipple.prototype.upHandler_ = function (event) { - // Don't fire for the artificial "mouseup" generated by a double-click. - if (event && event.detail !== 2) { - // Allow a repaint to occur before removing this class, so the animation - // shows for tap events, which seem to trigger a mouseup too soon after - // mousedown. - window.setTimeout(function () { - this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE); - }.bind(this), 0); - } -}; -/** - * Initialize element. - */ -MaterialRipple.prototype.init = function () { - if (this.element_) { - var recentering = this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER); - if (!this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)) { - this.rippleElement_ = this.element_.querySelector('.' + this.CssClasses_.RIPPLE); - this.frameCount_ = 0; - this.rippleSize_ = 0; - this.x_ = 0; - this.y_ = 0; - // Touch start produces a compat mouse down event, which would cause a - // second ripples. To avoid that, we use this property to ignore the first - // mouse down after a touch start. + this.rippleElement_.classList.add(this.CssClasses_.IS_VISIBLE); + if (event.type === 'mousedown' && this.ignoringMouseDown_) { this.ignoringMouseDown_ = false; - this.boundDownHandler = this.downHandler_.bind(this); - this.element_.addEventListener('mousedown', this.boundDownHandler); - this.element_.addEventListener('touchstart', this.boundDownHandler); - this.boundUpHandler = this.upHandler_.bind(this); - this.element_.addEventListener('mouseup', this.boundUpHandler); - this.element_.addEventListener('mouseleave', this.boundUpHandler); - this.element_.addEventListener('touchend', this.boundUpHandler); - this.element_.addEventListener('blur', this.boundUpHandler); - /** - * Getter for frameCount_. - * @return {number} the frame count. - */ - this.getFrameCount = function () { - return this.frameCount_; - }; - /** - * Setter for frameCount_. - * @param {number} fC the frame count. - */ - this.setFrameCount = function (fC) { - this.frameCount_ = fC; - }; - /** - * Getter for rippleElement_. - * @return {Element} the ripple element. - */ - this.getRippleElement = function () { - return this.rippleElement_; - }; - /** - * Sets the ripple X and Y coordinates. - * @param {number} newX the new X coordinate - * @param {number} newY the new Y coordinate - */ - this.setRippleXY = function (newX, newY) { - this.x_ = newX; - this.y_ = newY; - }; - /** - * Sets the ripple styles. - * @param {boolean} start whether or not this is the start frame. - */ - this.setRippleStyles = function (start) { - if (this.rippleElement_ !== null) { - var transformString; - var scale; - var size; - var offset = 'translate(' + this.x_ + 'px, ' + this.y_ + 'px)'; - if (start) { - scale = this.Constant_.INITIAL_SCALE; - size = this.Constant_.INITIAL_SIZE; - } else { - scale = this.Constant_.FINAL_SCALE; - size = this.rippleSize_ + 'px'; - if (recentering) { - offset = 'translate(' + this.boundWidth / 2 + 'px, ' + this.boundHeight / 2 + 'px)'; + } else { + if (event.type === 'touchstart') { + this.ignoringMouseDown_ = true; + } + var frameCount = this.getFrameCount(); + if (frameCount > 0) { + return; + } + this.setFrameCount(1); + var bound = event.currentTarget.getBoundingClientRect(); + var x; + var y; + // Check if we are handling a keyboard click. + if (event.clientX === 0 && event.clientY === 0) { + x = Math.round(bound.width / 2); + y = Math.round(bound.height / 2); + } else { + var clientX = event.clientX !== undefined ? event.clientX : event.touches[0].clientX; + var clientY = event.clientY !== undefined ? event.clientY : event.touches[0].clientY; + x = Math.round(clientX - bound.left); + y = Math.round(clientY - bound.top); + } + this.setRippleXY(x, y); + this.setRippleStyles(true); + window.requestAnimationFrame(this.animFrameHandler.bind(this)); + } + }; + /** + * Handle mouse / finger up on element. + * + * @param {Event} event The event that fired. + * @private + */ + MaterialRipple.prototype.upHandler_ = function (event) { + // Don't fire for the artificial "mouseup" generated by a double-click. + if (event && event.detail !== 2) { + // Allow a repaint to occur before removing this class, so the animation + // shows for tap events, which seem to trigger a mouseup too soon after + // mousedown. + window.setTimeout(function () { + this.rippleElement_.classList.remove(this.CssClasses_.IS_VISIBLE); + }.bind(this), 0); + } + }; + /** + * Initialize element. + */ + MaterialRipple.prototype.init = function () { + if (this.element_) { + var recentering = this.element_.classList.contains(this.CssClasses_.RIPPLE_CENTER); + if (!this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT_IGNORE_EVENTS)) { + this.rippleElement_ = this.element_.querySelector('.' + this.CssClasses_.RIPPLE); + this.frameCount_ = 0; + this.rippleSize_ = 0; + this.x_ = 0; + this.y_ = 0; + // Touch start produces a compat mouse down event, which would cause a + // second ripples. To avoid that, we use this property to ignore the first + // mouse down after a touch start. + this.ignoringMouseDown_ = false; + this.boundDownHandler = this.downHandler_.bind(this); + this.element_.addEventListener('mousedown', this.boundDownHandler); + this.element_.addEventListener('touchstart', this.boundDownHandler); + this.boundUpHandler = this.upHandler_.bind(this); + this.element_.addEventListener('mouseup', this.boundUpHandler); + this.element_.addEventListener('mouseleave', this.boundUpHandler); + this.element_.addEventListener('touchend', this.boundUpHandler); + this.element_.addEventListener('blur', this.boundUpHandler); + /** + * Getter for frameCount_. + * @return {number} the frame count. + */ + this.getFrameCount = function () { + return this.frameCount_; + }; + /** + * Setter for frameCount_. + * @param {number} fC the frame count. + */ + this.setFrameCount = function (fC) { + this.frameCount_ = fC; + }; + /** + * Getter for rippleElement_. + * @return {Element} the ripple element. + */ + this.getRippleElement = function () { + return this.rippleElement_; + }; + /** + * Sets the ripple X and Y coordinates. + * @param {number} newX the new X coordinate + * @param {number} newY the new Y coordinate + */ + this.setRippleXY = function (newX, newY) { + this.x_ = newX; + this.y_ = newY; + }; + /** + * Sets the ripple styles. + * @param {boolean} start whether or not this is the start frame. + */ + this.setRippleStyles = function (start) { + if (this.rippleElement_ !== null) { + var transformString; + var scale; + var size; + var offset = 'translate(' + this.x_ + 'px, ' + this.y_ + 'px)'; + if (start) { + scale = this.Constant_.INITIAL_SCALE; + size = this.Constant_.INITIAL_SIZE; + } else { + scale = this.Constant_.FINAL_SCALE; + size = this.rippleSize_ + 'px'; + if (recentering) { + offset = 'translate(' + this.boundWidth / 2 + 'px, ' + this.boundHeight / 2 + 'px)'; + } + } + transformString = 'translate(-50%, -50%) ' + offset + scale; + this.rippleElement_.style.webkitTransform = transformString; + this.rippleElement_.style.msTransform = transformString; + this.rippleElement_.style.transform = transformString; + if (start) { + this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING); + } else { + this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING); } } - transformString = 'translate(-50%, -50%) ' + offset + scale; - this.rippleElement_.style.webkitTransform = transformString; - this.rippleElement_.style.msTransform = transformString; - this.rippleElement_.style.transform = transformString; - if (start) { - this.rippleElement_.classList.remove(this.CssClasses_.IS_ANIMATING); + }; + /** + * Handles an animation frame. + */ + this.animFrameHandler = function () { + if (this.frameCount_-- > 0) { + window.requestAnimationFrame(this.animFrameHandler.bind(this)); } else { - this.rippleElement_.classList.add(this.CssClasses_.IS_ANIMATING); + this.setRippleStyles(false); } - } - }; - /** - * Handles an animation frame. - */ - this.animFrameHandler = function () { - if (this.frameCount_-- > 0) { - window.requestAnimationFrame(this.animFrameHandler.bind(this)); - } else { - this.setRippleStyles(false); - } - }; + }; + } } - } -}; + }; // The component registers itself. It can assume componentHandler is available // in the global scope. -componentHandler.register({ - constructor: MaterialRipple, - classAsString: 'MaterialRipple', - cssClass: 'mdl-js-ripple-effect', - widget: false -}); + componentHandler.register({ + constructor: MaterialRipple, + classAsString: 'MaterialRipple', + cssClass: 'mdl-js-ripple-effect', + widget: false + }); }()); diff --git a/app/modules/web/themes/material-blue/js/material.map b/app/modules/web/themes/material-blue/js/material.map index 6b0a0075..819b4c52 100644 --- a/app/modules/web/themes/material-blue/js/material.map +++ b/app/modules/web/themes/material-blue/js/material.map @@ -1,8 +1,721 @@ { -"version":3, -"file":"material.min.js", -"lineCount":345, -"mappings":"A;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAE,SAAQ,EAAG,CAiqFbA,QAASA,EAAW,CAACC,CAAD,CAAMC,CAAN,CAAW,CAC3B,GAAID,CAAJ,CAAS,CACL,GAAIC,CAAAC,SAAAC,UAAAC,SAAA,CAAgCH,CAAAI,YAAAC,qBAAhC,CAAJ,CAA2E,CACvE,IAAIC,EAAkBC,QAAAC,cAAA,CAAuB,MAAvB,CACtBF,EAAAJ,UAAAO,IAAA,CAA8BT,CAAAI,YAAAM,qBAA9B,CACAJ,EAAAJ,UAAAO,IAAA,CAA8BT,CAAAI,YAAAC,qBAA9B,CACA,KAAIM,EAASJ,QAAAC,cAAA,CAAuB,MAAvB,CACbG,EAAAT,UAAAO,IAAA,CAAqBT,CAAAI,YAAAQ,WAArB,CACAN,EAAAO,YAAA,CAA4BF,CAA5B,CACAZ,EAAAc,YAAA,CAAgBP,CAAhB,CAPuE,CAS3EP,CAAAe,iBAAA,CAAqB,OAArB,CAA8B,QAAS,CAACC,CAAD,CAAI,CACI,GAA3C,GAAIhB,CAAAiB,aAAA,CAAiB,MAAjB,CAAAC,OAAA,CAAgC,CAAhC,CAAJ,GACIF,CAAAG,eAAA,EAMA,CALIC,CAKJ,CALWpB,CAAAoB,KAAAC,MAAA,CAAe,GAAf,CAAA,CAAoB,CAApB,CAKX,CAJIC,CAIJ,CAJYrB,CAAAC,SAAAqB,cAAA,CAA2B,GAA3B;AAAiCH,CAAjC,CAIZ,CAHAnB,CAAAuB,eAAA,EAGA,CAFAvB,CAAAwB,iBAAA,EAEA,CADAzB,CAAAG,UAAAO,IAAA,CAAkBT,CAAAI,YAAAqB,aAAlB,CACA,CAAAJ,CAAAnB,UAAAO,IAAA,CAAoBT,CAAAI,YAAAqB,aAApB,CAPJ,CADuC,CAA3C,CAVK,CADkB,CAo1B/BC,QAASA,EAAiB,CAAC3B,CAAD,CAAM4B,CAAN,CAAYC,CAAZ,CAAoBC,CAApB,CAA4B,CAIlDC,QAASA,EAAS,EAAG,CACjB,IAAIX,EAAOpB,CAAAoB,KAAAC,MAAA,CAAe,GAAf,CAAA,CAAoB,CAApB,CAAX,CACIC,EAAQQ,CAAAE,SAAAT,cAAA,CAA8B,GAA9B,CAAoCH,CAApC,CACZU,EAAAN,eAAA,CAAsBI,CAAtB,CACAE,EAAAL,iBAAA,CAAwBI,CAAxB,CACA7B,EAAAG,UAAAO,IAAA,CAAkBoB,CAAAzB,YAAA4B,UAAlB,CACAX,EAAAnB,UAAAO,IAAA,CAAoBoB,CAAAzB,YAAA4B,UAApB,CANiB,CAQrB,GAAIH,CAAAI,QAAA/B,UAAAC,SAAA,CAAkC0B,CAAAzB,YAAA8B,iBAAlC,CAAJ,CAA4E,CACxE,IAAI5B,EAAkBC,QAAAC,cAAA,CAAuB,MAAvB,CACtBF,EAAAJ,UAAAO,IAAA,CAA8BoB,CAAAzB,YAAA+B,iBAA9B,CACA7B;CAAAJ,UAAAO,IAAA,CAA8BoB,CAAAzB,YAAA8B,iBAA9B,CACA,KAAIvB,EAASJ,QAAAC,cAAA,CAAuB,MAAvB,CACbG,EAAAT,UAAAO,IAAA,CAAqBoB,CAAAzB,YAAAgC,OAArB,CACA9B,EAAAO,YAAA,CAA4BF,CAA5B,CACAZ,EAAAc,YAAA,CAAgBP,CAAhB,CAPwE,CASvEuB,CAAAI,QAAA/B,UAAAC,SAAA,CAAkC0B,CAAAzB,YAAAiC,kBAAlC,CAAL,EACItC,CAAAe,iBAAA,CAAqB,OAArB,CAA8B,QAAS,CAACC,CAAD,CAAI,CACI,GAA3C,GAAIhB,CAAAiB,aAAA,CAAiB,MAAjB,CAAAC,OAAA,CAAgC,CAAhC,CAAJ,GACIF,CAAAG,eAAA,EACA,CAAAY,CAAA,EAFJ,CADuC,CAA3C,CAOJ/B,EAAAuC,KAAA,CAAWR,CA7BuC,CAt9GtD,IAAIS,EAAmB,CAUrBC,WAAYA,QAAQ,CAACC,CAAD,CAAaC,CAAb,CAA0B,EAVzB,CAkBrBC,eAAgBA,QAAQ,CAACC,CAAD,CAAUH,CAAV,CAAsB,EAlBzB,CAyBrBI,gBAAiBA,QAAQ,CAACC,CAAD,CAAW,EAzBf,CA8BrBC,qBAAsBA,QAAQ,EAAG,EA9BZ,CAyCrBC,yBAA0BA,QAAQ,CAACC,CAAD,CAAUC,CAAV,CAAoB,EAzCjC;AA+CrBC,SAAUA,QAAQ,CAACC,CAAD,CAAS,EA/CN,CAqDrBC,kBAAmBA,QAAQ,CAACC,CAAD,CAAQ,EArDd,CAAvB,CAwDAf,EAAoB,QAAQ,EAAG,CAoB7BgB,QAASA,EAAoB,CAACC,CAAD,CAAOC,CAAP,CAAmB,CAC9C,IAAK,IAAIC,EAAI,CAAb,CAAgBA,CAAhB,CAAoBC,CAAAC,OAApB,CAAkDF,CAAA,EAAlD,CACE,GAAIC,CAAA,CAAsBD,CAAtB,CAAAG,UAAJ,GAA2CL,CAA3C,CAIE,MAH0B,WAGnB,GAHH,MAAOC,EAGJ,GAFLE,CAAA,CAAsBD,CAAtB,CAEK,CAFsBD,CAEtB,EAAAE,CAAA,CAAsBD,CAAtB,CAGX,OAAO,CAAA,CATuC,CAmBhDI,QAASA,EAAyB,CAAClB,CAAD,CAAU,CACtCmB,CAAAA,CAAenB,CAAA5B,aAAA,CAAqB,eAArB,CAEnB,OAAwB,KAAjB,GAAA+C,CAAA,CAAwB,CAAC,EAAD,CAAxB,CAA+BA,CAAA3C,MAAA,CAAmB,GAAnB,CAHI,CAe5C4C,QAASA,EAAkB,CAACpB,CAAD,CAAUK,CAAV,CAAmB,CAE5C,MAA0C,EAA1C,GADmBa,CAAAG,CAA0BrB,CAA1BqB,CACZC,QAAA,CAAqBjB,CAArB,CAFqC,CAa9CkB,QAASA,EAAY,CAACC,CAAD,CAAYC,CAAZ,CAAqBC,CAArB,CAAiC,CACpD,GAAI,aAAJ,EAAqBC,OAArB,EAA6D,UAA7D,GAA+B,MAAOA,OAAAC,YAAtC,CACE,MAAO,KAAIA,WAAJ,CAAgBJ,CAAhB,CAA2B,CAChCC,QAASA,CADuB,CAEhCC,WAAYA,CAFoB,CAA3B,CAKP,KAAIG,EAAKlE,QAAAmE,YAAA,CAAqB,QAArB,CACTD,EAAAE,UAAA,CAAaP,CAAb,CAAwBC,CAAxB,CAAiCC,CAAjC,CACA;MAAOG,EAT2C,CAsBtDG,QAASA,EAAkB,CAACnC,CAAD,CAAaC,CAAb,CAA0B,CACnD,GAA0B,WAA1B,GAAI,MAAOD,EAAX,EAC2B,WAD3B,GACI,MAAOC,EADX,CAEE,IAAK,IAAIgB,EAAI,CAAb,CAAgBA,CAAhB,CAAoBC,CAAAC,OAApB,CAAkDF,CAAA,EAAlD,CACEkB,CAAA,CAAmBjB,CAAA,CAAsBD,CAAtB,CAAAG,UAAnB,CACIF,CAAA,CAAsBD,CAAtB,CAAAmB,SADJ,CAHJ,KAMO,CAEsB,WAA3B,GAAI,MAAOnC,EAAX,GACMoC,CADN,CACwBvB,CAAA,CAFad,CAEb,CADxB,IAGIC,CAHJ,CAGkBoC,CAAAD,SAHlB,CAQA,KADI/B,IAAAA,EAAWvC,QAAAwE,iBAAA,CAA0B,GAA1B,CAAgCrC,CAAhC,CAAXI,CACKkC,EAAI,CAAb,CAAgBA,CAAhB,CAAoBlC,CAAAc,OAApB,CAAqCoB,CAAA,EAArC,CACEC,CAAA,CAAuBnC,CAAA,CAASkC,CAAT,CAAvB,CAVmCvC,CAUnC,CAXG,CAP4C,CA8BrDwC,QAASA,EAAsB,CAACrC,CAAD,CAAUH,CAAV,CAAsB,CAEnD,GAAM,EAAmB,QAAnB,GAAA,MAAOG,EAAP,EAA+BA,CAA/B,WAAkDsC,QAAlD,CAAN,CACE,KAAUC,MAAJ,CAAU,mDAAV,CAAN,CAGF,IAAIC,EAAcjB,CAAA,CAAa,wBAAb,CAAuC,CAAA,CAAvC,CAA6C,CAAA,CAA7C,CAClBvB,EAAAyC,cAAA,CAAsBD,CAAtB,CACA,IAAIE,CAAAF,CAAAE,iBAAJ,CAAA,CAIIrB,IAAAA,EAAeH,CAAA,CAA0BlB,CAA1B,CAAfqB,CACAsB,EAAmB,EAGvB,IAAK9C,CAAL,CAUYuB,CAAA,CAAmBpB,CAAnB,CAA4BH,CAA5B,CAAL;AACL8C,CAAAC,KAAA,CAAsBjC,CAAA,CAAqBd,CAArB,CAAtB,CAXF,KAAiB,CACf,IAAIvC,EAAY0C,CAAA1C,UAChByD,EAAA8B,QAAA,CAA8B,QAAQ,CAACC,CAAD,CAAY,CAE5CxF,CAAAC,SAAA,CAAmBuF,CAAAb,SAAnB,CAAJ,EAC6C,EAD7C,GACIU,CAAArB,QAAA,CAAyBwB,CAAzB,CADJ,EAEK,CAAA1B,CAAA,CAAmBpB,CAAnB,CAA4B8C,CAAA7B,UAA5B,CAFL,EAGE0B,CAAAC,KAAA,CAAsBE,CAAtB,CAL8C,CAAlD,CAFe,CAejB,IA/BmD,IA+B1ChC,EAAI,CA/BsC,CA+BnCsB,EAAIO,CAAA3B,OA/B+B,CA+BNkB,CAA7C,CAA8DpB,CAA9D,CAAkEsB,CAAlE,CAAqEtB,CAAA,EAArE,CAA0E,CAExE,GADAoB,CACA,CADkBS,CAAA,CAAiB7B,CAAjB,CAClB,CAAqB,CAEnBO,CAAAuB,KAAA,CAAkBV,CAAAjB,UAAlB,CACAjB,EAAA+C,aAAA,CAAqB,eAArB,CAAsC1B,CAAA2B,KAAA,CAAkB,GAAlB,CAAtC,CACA,KAAIC,EAAW,IAAIf,CAAAgB,iBAAJ,CAAqClD,CAArC,CACfiD,EAAA,4BAAA,CAAqCf,CACrCiB,EAAAP,KAAA,CAAwBK,CAAxB,CAEA,KARmB,IAQVG,EAAI,CARM,CAQHC,EAAInB,CAAAoB,UAAAtC,OAApB,CAAsDoC,CAAtD,CAA0DC,CAA1D,CAA6DD,CAAA,EAA7D,CACElB,CAAAoB,UAAA,CAA0BF,CAA1B,CAAA,CAA6BpD,CAA7B,CAGEkC,EAAAqB,OAAJ,GAEEvD,CAAA,CAAQkC,CAAAjB,UAAR,CAFF,CAEuCgC,CAFvC,CAZmB,CAArB,IAiBE,MAAUV,MAAJ,CACJ,4DADI,CAAN,CAIEiB,CAAAA,CAAajC,CAAA,CAAa,uBAAb;AAAsC,CAAA,CAAtC,CAA4C,CAAA,CAA5C,CACjBvB,EAAAyC,cAAA,CAAsBe,CAAtB,CAxBwE,CAvB1E,CARmD,CAiErDC,QAASA,EAAuB,CAACvD,CAAD,CAAW,CACpCwD,KAAAC,QAAA,CAAczD,CAAd,CAAL,GAEIA,CAFJ,CACMA,CAAJ,WAAwBoC,QAAxB,CACa,CAACpC,CAAD,CADb,CAGawD,KAAAE,UAAAC,MAAAC,KAAA,CAA2B5D,CAA3B,CAJf,CAOA,KARyC,IAQhCY,EAAI,CAR4B,CAQzBsB,EAAIlC,CAAAc,OARqB,CAQJhB,CAArC,CAA8Cc,CAA9C,CAAkDsB,CAAlD,CAAqDtB,CAAA,EAArD,CACEd,CACA,CADUE,CAAA,CAASY,CAAT,CACV,CAAId,CAAJ,WAAuB+D,YAAvB,GACE1B,CAAA,CAAuBrC,CAAvB,CACA,CAA8B,CAA9B,CAAIA,CAAAgE,SAAAhD,OAAJ,EACEyC,CAAA,CAAwBzD,CAAAgE,SAAxB,CAHJ,CAVuC,CAsG3CC,QAASA,EAA4B,CAACnB,CAAD,CAAY,CAC/C,GAAIA,CAAJ,CAAe,CACb,IAAIoB,EAAiBf,CAAA7B,QAAA,CAA2BwB,CAA3B,CACrBK,EAAAgB,OAAA,CAA0BD,CAA1B,CAA0C,CAA1C,CAEIE,KAAAA,EAAWtB,CAAAzF,SAAAe,aAAA,CAAgC,eAAhC,CAAAI,MAAA,CAAuD,GAAvD,CAAX4F,CACAC,EAAiBD,CAAA9C,QAAA,CAAiBwB,CAAA,4BAAAwB,cAAjB,CACrBF,EAAAD,OAAA,CAAgBE,CAAhB,CAAgC,CAAhC,CACAvB,EAAAzF,SAAA0F,aAAA,CAAgC,eAAhC,CAAiDqB,CAAApB,KAAA,CAAc,GAAd,CAAjD,CAEInB,EAAAA,CAAKN,CAAA,CAAa,yBAAb,CAAwC,CAAA,CAAxC,CAA8C,CAAA,CAA9C,CACTuB,EAAAzF,SAAAoF,cAAA,CAAiCZ,CAAjC,CAVa,CADgC,CA9RpB;AAI7B,IAAId,EAAwB,EAA5B,CAGIoC,EAAqB,EAkUzB,OAAO,CACLvD,WAAYoC,CADP,CAELjC,eAAgBsC,CAFX,CAGLpC,gBAAiBwD,CAHZ,CAILtD,qBA5DFoE,QAAqC,EAAG,CACtC,IAAK,IAAInC,EAAI,CAAb,CAAgBA,CAAhB,CAAoBrB,CAAAC,OAApB,CAAkDoB,CAAA,EAAlD,CACEJ,CAAA,CAAmBjB,CAAA,CAAsBqB,CAAtB,CAAAnB,UAAnB,CAFoC,CAwDjC,CAKLb,yBAxEFoE,QAAyC,CAACnE,CAAD,CAAUC,CAAV,CAAoB,CAC3D,IAAImE,EAAW9D,CAAA,CAAqBN,CAArB,CACXoE,EAAJ,EACEA,CAAAnB,UAAAV,KAAA,CAAwBtC,CAAxB,CAHyD,CAmEtD,CAMLC,SA/HFmE,QAAyB,CAAClE,CAAD,CAAS,CAOhC,IAAI+C,EAAS,CAAA,CAEb,IAJ8C,WAI9C,GAJqB,MAAO/C,EAAA+C,OAI5B,EAHgC,WAGhC,GAHI,MAAO/C,EAAA,OAGX,CACE+C,CAAA,CAAS/C,CAAA+C,OAAT,EAA0B/C,CAAA,OAG5B,KAAImE,EAA6D,CAC/DzB,iBAAkB1C,CAAAoE,YAAlB1B,EAAwC1C,CAAA,YADuB,CAE/DS,UAAWT,CAAA8D,cAAXrD,EAAmCT,CAAA,cAF4B,CAG/DyB,SAAUzB,CAAAyB,SAAVA,EAA6BzB,CAAA,SAHkC,CAI/D+C,OAAQA,CAJuD,CAK/DD,UAAW,EALoD,CAQjEvC,EAAA8B,QAAA,CAA8B,QAAQ,CAACgC,CAAD,CAAO,CAC3C,GAAIA,CAAA5C,SAAJ;AAAsB0C,CAAA1C,SAAtB,CACE,KAAUM,MAAJ,CAAU,qDAAV,CAAkEsC,CAAA5C,SAAlE,CAAN,CAEF,GAAI4C,CAAA5D,UAAJ,GAAuB0D,CAAA1D,UAAvB,CACE,KAAUsB,MAAJ,CAAU,oDAAV,CAAN,CALyC,CAA7C,CASA,IAAI/B,CAAAoE,YAAAhB,UAAAkB,eAAA,CArOyBC,6BAqOzB,CAAJ,CAEE,KAAUxC,MAAJ,CACF,wFADE,CAAN,CAKU5B,CAAAqE,CAAqBxE,CAAA8D,cAArBU,CAA2CL,CAA3CK,CAEZ,EACEjE,CAAA6B,KAAA,CAA2B+B,CAA3B,CAxC8B,CAyH3B,CAOLlE,kBA9BFwE,QAA+B,CAACvE,CAAD,CAAQ,CAKrC,IAAIwE,EAAgBA,QAAQ,CAACC,CAAD,CAAO,CACjChC,CAAAiC,OAAA,CAA0B,QAAQ,CAACP,CAAD,CAAO,CACvC,MAAOA,EAAAxH,SAAP,GAAyB8H,CADc,CAAzC,CAAAtC,QAAA,CAEWoB,CAFX,CADiC,CAKnC,IAAIvD,CAAJ;AAAqBgD,KAArB,EAA8BhD,CAA9B,WAA+C2E,SAA/C,CACE,IAAK,IAAIjD,EAAI,CAAb,CAAgBA,CAAhB,CAAoB1B,CAAAM,OAApB,CAAkCoB,CAAA,EAAlC,CACE8C,CAAA,CAAcxE,CAAA,CAAM0B,CAAN,CAAd,CAFJ,KAIO,IAAI1B,CAAJ,WAAqB4E,KAArB,CACLJ,CAAA,CAAcxE,CAAd,CADK,KAGL,MAAU6B,MAAJ,CAAU,mDAAV,CAAN,CAjBmC,CAuBhC,CAzUsB,CAAZ,EA+XnB5C,EAAA,WAAA,CAAiCA,CAAAC,WACjCD,EAAA,eAAA,CAAqCA,CAAAI,eACrCJ,EAAA,gBAAA,CAAsCA,CAAAM,gBACtCN,EAAA,qBAAA,CACIA,CAAAQ,qBACJR,EAAA,yBAAA,CACIA,CAAAS,yBACJT,EAAA,SAAA,CAA+BA,CAAAY,SAC/BZ,EAAA,kBAAA,CAAwCA,CAAAc,kBACxCkB,OAAAhC,iBAAA,CAA0BA,CAC1BgC,OAAA,iBAAA,CAA6BhC,CAE7BgC,OAAAzD,iBAAA,CAAwB,MAAxB;AAAgC,QAAQ,EAAG,CAQrC,WAAJ,EAAmBP,SAAAC,cAAA,CAAuB,KAAvB,CAAnB,EACI,eADJ,EACuBD,SADvB,EAEI,kBAFJ,EAE0BgE,OAF1B,EAEoC+B,KAAAE,UAAAf,QAFpC,EAGElF,QAAA4H,gBAAAjI,UAAAO,IAAA,CAAuC,QAAvC,CACA,CAAA8B,CAAAQ,qBAAA,EAJF,GASER,CAAAI,eAIA,CAJkCyF,QAAQ,EAAG,EAI7C,CAAA7F,CAAAY,SAAA,CAA4BkF,QAAQ,EAAG,EAbzC,CARyC,CAA3C,CAgCKC,KAAAC,IAAL,GAKID,IAAAC,IAGA,CAHWC,QAAS,EAAG,CACnB,MAAOC,CAAA,IAAIH,IAAJG,SAAA,EADY,CAGvB,CAAAH,IAAA,IAAA,CAAcA,IAAAC,IARlB,CAcA,KAJA,IAAIG,EAAU,CACV,QADU,CAEV,KAFU,CAAd,CAIShF,EAAI,CAAb,CAAgBA,CAAhB,CAAoBgF,CAAA9E,OAApB,EAAuC+E,CAAApE,MAAAoE,sBAAvC,CAAqE,EAAEjF,CAAvE,CAA0E,CACtE,IAAIkF,EAAKF,CAAA,CAAQhF,CAAR,CACTa,OAAAoE,sBAAA,CAA+BpE,MAAA,CAAOqE,CAAP,CAAY,uBAAZ,CAC/BrE;MAAAsE,qBAAA,CAA8BtE,MAAA,CAAOqE,CAAP,CAAY,sBAAZ,CAA9B,EAAqErE,MAAA,CAAOqE,CAAP,CAAY,6BAAZ,CACrErE,OAAA,sBAAA,CAAkCA,MAAAoE,sBAClCpE,OAAA,qBAAA,CAAiCA,MAAAsE,qBALqC,CAO1E,GAAI,sBAAAC,KAAA,CAA4BvE,MAAAwE,UAAAC,UAA5B,CAAJ,EAAgEL,CAAApE,MAAAoE,sBAAhE,EAAiGE,CAAAtE,MAAAsE,qBAAjG,CAA8H,CAC1H,IAAII,EAAW,CAKf1E,OAAAoE,sBAAA,CAA+BO,QAAS,CAAChG,CAAD,CAAW,CAC/C,IAAIqF,EAAMD,IAAAC,IAAA,EAAV,CACIY,EAAWC,IAAAC,IAAA,CAASJ,CAAT,CAAoB,EAApB,CAAwBV,CAAxB,CACf,OAAOe,WAAA,CAAW,QAAS,EAAG,CAC1BpG,CAAA,CAAS+F,CAAT,CAAoBE,CAApB,CAD0B,CAAvB,CAEJA,CAFI,CAEOZ,CAFP,CAHwC,CAOnDhE,OAAAsE,qBAAA,CAA8BU,YAC9BhF;MAAA,sBAAA,CAAkCA,MAAAoE,sBAClCpE,OAAA,qBAAA,CAAiCA,MAAAsE,qBAfyF,CAwC1HW,CAAAA,CAAiBA,QAAuB,CAAC5G,CAAD,CAAU,CAClD,IAAA3C,SAAA,CAAgB2C,CAEhB,KAAA6G,KAAA,EAHkD,CAKtDlF,OAAA,eAAA,CAA2BiF,CAO3BA,EAAAhD,UAAAkD,UAAA,CAAqC,EASrCF,EAAAhD,UAAApG,YAAA,CAAuC,CACnCuJ,cAAe,sBADoB,CAEnCxH,iBAAkB,8BAFiB,CAGnCC,OAAQ,YAH2B,CAWvCoH,EAAAhD,UAAAoD,aAAA,CAAwCC,QAAS,CAACC,CAAD,CAAQ,CACjDA,CAAJ,EACI,IAAA7J,SAAA8J,KAAA,EAFiD,CAWzDP,EAAAhD,UAAAwD,QAAA,CAAmCC,QAAS,EAAG,CAC3C,IAAAhK,SAAAiK,SAAA,CAAyB,CAAA,CADkB,CAG/CV,EAAAhD,UAAA,QAAA,CAAsCgD,CAAAhD,UAAAwD,QAMtCR,EAAAhD,UAAA2D,OAAA;AAAkCC,QAAS,EAAG,CAC1C,IAAAnK,SAAAiK,SAAA,CAAyB,CAAA,CADiB,CAG9CV,EAAAhD,UAAA,OAAA,CAAqCgD,CAAAhD,UAAA2D,OAIrCX,EAAAhD,UAAAiD,KAAA,CAAgCY,QAAS,EAAG,CACxC,GAAI,IAAApK,SAAJ,CAAmB,CACf,GAAI,IAAAA,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAuJ,cAAjC,CAAJ,CAAsE,CAClE,IAAIrJ,EAAkBC,QAAAC,cAAA,CAAuB,MAAvB,CACtBF,EAAAJ,UAAAO,IAAA,CAA8B,IAAAL,YAAA+B,iBAA9B,CACA,KAAAmI,eAAA,CAAsB/J,QAAAC,cAAA,CAAuB,MAAvB,CACtB,KAAA8J,eAAApK,UAAAO,IAAA,CAAkC,IAAAL,YAAAgC,OAAlC,CACA9B,EAAAO,YAAA,CAA4B,IAAAyJ,eAA5B,CACA,KAAAC,uBAAA,CAA8B,IAAAX,aAAAY,KAAA,CAAuB,IAAvB,CAC9B,KAAAF,eAAAxJ,iBAAA,CAAqC,SAArC;AAAgD,IAAAyJ,uBAAhD,CACA,KAAAtK,SAAAY,YAAA,CAA0BP,CAA1B,CARkE,CAUtE,IAAAmK,uBAAA,CAA8B,IAAAb,aAAAY,KAAA,CAAuB,IAAvB,CAC9B,KAAAvK,SAAAa,iBAAA,CAA+B,SAA/B,CAA0C,IAAA2J,uBAA1C,CACA,KAAAxK,SAAAa,iBAAA,CAA+B,YAA/B,CAA6C,IAAA2J,uBAA7C,CAbe,CADqB,CAmB5ClI,EAAAY,SAAA,CAA0B,CACtBqE,YAAagC,CADS,CAEtBtC,cAAe,gBAFO,CAGtBrC,SAAU,eAHY,CAItBsB,OAAQ,CAAA,CAJc,CAA1B,CA8BIuE,EAAAA,CAAmBA,QAAyB,CAAC9H,CAAD,CAAU,CACtD,IAAA3C,SAAA,CAAgB2C,CAEhB,KAAA6G,KAAA,EAHsD,CAK1DlF,OAAA,iBAAA,CAA6BmG,CAO7BA,EAAAlE,UAAAkD,UAAA,CAAuC,CAAEiB,aAAc,IAAhB,CASvCD,EAAAlE,UAAApG,YAAA,CAAyC,CACrCwK,MAAO,qBAD8B;AAErCC,YAAa,2BAFwB,CAGrCC,aAAc,4BAHuB,CAIrCC,aAAc,4BAJuB,CAKrCpB,cAAe,sBALsB,CAMrCqB,qBAAsB,qCANe,CAOrC7I,iBAAkB,gCAPmB,CAQrC8I,cAAe,oBARsB,CASrC7I,OAAQ,YAT6B,CAUrC8I,WAAY,YAVyB,CAWrCC,YAAa,aAXwB,CAYrCC,WAAY,YAZyB,CAarCC,YAAa,aAbwB,CAqBzCX,EAAAlE,UAAA8E,UAAA,CAAuCC,QAAS,CAACzB,CAAD,CAAQ,CACpD,IAAA0B,eAAA,EADoD,CASxDd,EAAAlE,UAAAiF,SAAA;AAAsCC,QAAS,CAAC5B,CAAD,CAAQ,CACnD,IAAA7J,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA8K,WAA5B,CADmD,CASvDR,EAAAlE,UAAAmF,QAAA,CAAqCC,QAAS,CAAC9B,CAAD,CAAQ,CAClD,IAAA7J,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA8K,WAA/B,CADkD,CAStDR,EAAAlE,UAAAsF,WAAA,CAAwCC,QAAS,CAACjC,CAAD,CAAQ,CACrD,IAAAkC,MAAA,EADqD,CAQzDtB,EAAAlE,UAAAgF,eAAA,CAA4CS,QAAS,EAAG,CACpD,IAAAC,cAAA,EACA,KAAAC,iBAAA,EAFoD,CASxDzB,EAAAlE,UAAAwF,MAAA,CAAmCI,QAAS,EAAG,CAG3C7H,MAAA+E,WAAA,CAAkB,QAAS,EAAG,CAC1B,IAAA+C,cAAAtC,KAAA,EAD0B,CAAZS,KAAA,CAEX,IAFW,CAAlB,CAEc,IAAAd,UAAAiB,aAFd,CAH2C,CAa/CD,EAAAlE,UAAA2F,iBAAA,CAA8CG,QAAS,EAAG,CAClD,IAAAD,cAAAE,QAAJ,CACI,IAAAtM,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAgL,WAA5B,CADJ;AAGI,IAAAnL,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAAgL,WAA/B,CAJkD,CAO1DV,EAAAlE,UAAA,iBAAA,CAAiDkE,CAAAlE,UAAA2F,iBAMjDzB,EAAAlE,UAAA0F,cAAA,CAA2CM,QAAS,EAAG,CAC/C,IAAAH,cAAAnC,SAAJ,CACI,IAAAjK,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA+K,YAA5B,CADJ,CAGI,IAAAlL,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA+K,YAA/B,CAJ+C,CAOvDT,EAAAlE,UAAA,cAAA,CAA8CkE,CAAAlE,UAAA0F,cAM9CxB,EAAAlE,UAAAwD,QAAA,CAAqCyC,QAAS,EAAG,CAC7C,IAAAJ,cAAAnC,SAAA,CAA8B,CAAA,CAC9B,KAAAsB,eAAA,EAF6C,CAIjDd,EAAAlE,UAAA,QAAA,CAAwCkE,CAAAlE,UAAAwD,QAMxCU,EAAAlE,UAAA2D,OAAA,CAAoCuC,QAAS,EAAG,CAC5C,IAAAL,cAAAnC,SAAA;AAA8B,CAAA,CAC9B,KAAAsB,eAAA,EAF4C,CAIhDd,EAAAlE,UAAA,OAAA,CAAuCkE,CAAAlE,UAAA2D,OAMvCO,EAAAlE,UAAAmG,MAAA,CAAmCC,QAAS,EAAG,CAC3C,IAAAP,cAAAE,QAAA,CAA6B,CAAA,CAC7B,KAAAf,eAAA,EAF2C,CAI/Cd,EAAAlE,UAAA,MAAA,CAAsCkE,CAAAlE,UAAAmG,MAMtCjC,EAAAlE,UAAAqG,QAAA,CAAqCC,QAAS,EAAG,CAC7C,IAAAT,cAAAE,QAAA,CAA6B,CAAA,CAC7B,KAAAf,eAAA,EAF6C,CAIjDd,EAAAlE,UAAA,QAAA,CAAwCkE,CAAAlE,UAAAqG,QAIxCnC,EAAAlE,UAAAiD,KAAA,CAAkCsD,QAAS,EAAG,CAC1C,GAAI,IAAA9M,SAAJ,CAAmB,CACf,IAAAoM,cAAA,CAAqB,IAAApM,SAAAqB,cAAA,CAA4B,GAA5B,CAAkC,IAAAlB,YAAAwK,MAAlC,CACrB,KAAIoC,EAAazM,QAAAC,cAAA,CAAuB,MAAvB,CACjBwM,EAAA9M,UAAAO,IAAA,CAAyB,IAAAL,YAAAyK,YAAzB,CACA;IAAIoC,EAAgB1M,QAAAC,cAAA,CAAuB,MAAvB,CACpByM,EAAA/M,UAAAO,IAAA,CAA4B,IAAAL,YAAA0K,aAA5B,CACA,KAAIoC,EAAc3M,QAAAC,cAAA,CAAuB,MAAvB,CAClB0M,EAAAhN,UAAAO,IAAA,CAA0B,IAAAL,YAAA2K,aAA1B,CACAiC,EAAAnM,YAAA,CAAuBqM,CAAvB,CACA,KAAAjN,SAAAY,YAAA,CAA0BoM,CAA1B,CACA,KAAAhN,SAAAY,YAAA,CAA0BmM,CAA1B,CACI,KAAA/M,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAuJ,cAAjC,CAAJ,GACI,IAAA1J,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA4K,qBAA5B,CAUA,CATA,IAAAmC,wBASA,CAT+B5M,QAAAC,cAAA,CAAuB,MAAvB,CAS/B,CARA,IAAA2M,wBAAAjN,UAAAO,IAAA,CAA2C,IAAAL,YAAA+B,iBAA3C,CAQA;AAPA,IAAAgL,wBAAAjN,UAAAO,IAAA,CAA2C,IAAAL,YAAAuJ,cAA3C,CAOA,CANA,IAAAwD,wBAAAjN,UAAAO,IAAA,CAA2C,IAAAL,YAAA6K,cAA3C,CAMA,CALA,IAAAmC,mBAKA,CAL0B,IAAAtB,WAAAtB,KAAA,CAAqB,IAArB,CAK1B,CAJA,IAAA2C,wBAAArM,iBAAA,CAA8C,SAA9C,CAAyD,IAAAsM,mBAAzD,CAIA,CAHIzM,CAGJ,CAHaJ,QAAAC,cAAA,CAAuB,MAAvB,CAGb,CAFAG,CAAAT,UAAAO,IAAA,CAAqB,IAAAL,YAAAgC,OAArB,CAEA,CADA,IAAA+K,wBAAAtM,YAAA,CAAyCF,CAAzC,CACA,CAAA,IAAAV,SAAAY,YAAA,CAA0B,IAAAsM,wBAA1B,CAXJ,CAaA,KAAAE,mBAAA,CAA0B,IAAA/B,UAAAd,KAAA,CAAoB,IAApB,CAC1B;IAAA8C,kBAAA,CAAyB,IAAA7B,SAAAjB,KAAA,CAAmB,IAAnB,CACzB,KAAA+C,iBAAA,CAAwB,IAAA5B,QAAAnB,KAAA,CAAkB,IAAlB,CACxB,KAAAgD,oBAAA,CAA2B,IAAA1B,WAAAtB,KAAA,CAAqB,IAArB,CAC3B,KAAA6B,cAAAvL,iBAAA,CAAoC,QAApC,CAA8C,IAAAuM,mBAA9C,CACA,KAAAhB,cAAAvL,iBAAA,CAAoC,OAApC,CAA6C,IAAAwM,kBAA7C,CACA,KAAAjB,cAAAvL,iBAAA,CAAoC,MAApC,CAA4C,IAAAyM,iBAA5C,CACA,KAAAtN,SAAAa,iBAAA,CAA+B,SAA/B,CAA0C,IAAA0M,oBAA1C,CACA,KAAAhC,eAAA,EACA,KAAAvL,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAiL,YAA5B,CAjCe,CADuB,CAuC9C9I,EAAAY,SAAA,CAA0B,CACtBqE,YAAakD,CADS;AAEtBxD,cAAe,kBAFO,CAGtBrC,SAAU,iBAHY,CAItBsB,OAAQ,CAAA,CAJc,CAA1B,CA8BIsH,EAAAA,CAAqBA,QAA2B,CAAC7K,CAAD,CAAU,CAC1D,IAAA3C,SAAA,CAAgB2C,CAEhB,KAAA6G,KAAA,EAH0D,CAK9DlF,OAAA,mBAAA,CAA+BkJ,CAO/BA,EAAAjH,UAAAkD,UAAA,CAAyC,CAAEiB,aAAc,IAAhB,CASzC8C,EAAAjH,UAAApG,YAAA,CAA2C,CACvCwK,MAAO,wBADgC,CAEvC1I,iBAAkB,sBAFqB,CAGvC8I,qBAAsB,qCAHiB,CAIvC7I,iBAAkB,mCAJqB,CAKvC8I,cAAe,oBALwB,CAMvC7I,OAAQ,YAN+B,CAOvC8I,WAAY,YAP2B,CAQvCC,YAAa,aAR0B,CASvCC,WAAY,YAT2B,CAiB3CqC;CAAAjH,UAAA8E,UAAA,CAAyCoC,QAAS,CAAC5D,CAAD,CAAQ,CACtD,IAAA0B,eAAA,EADsD,CAS1DiC,EAAAjH,UAAAiF,SAAA,CAAwCkC,QAAS,CAAC7D,CAAD,CAAQ,CACrD,IAAA7J,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA8K,WAA5B,CADqD,CASzDuC,EAAAjH,UAAAmF,QAAA,CAAuCiC,QAAS,CAAC9D,CAAD,CAAQ,CACpD,IAAA7J,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA8K,WAA/B,CADoD,CASxDuC,EAAAjH,UAAAsF,WAAA,CAA0C+B,QAAS,CAAC/D,CAAD,CAAQ,CACvD,IAAAkC,MAAA,EADuD,CAQ3DyB,EAAAjH,UAAAgF,eAAA,CAA8CsC,QAAS,EAAG,CACtD,IAAA5B,cAAA,EACA,KAAAC,iBAAA,EAFsD,CAS1DsB,EAAAjH,UAAAwF,MAAA,CAAqC+B,QAAS,EAAG,CAG7CxJ,MAAA+E,WAAA,CAAkB,QAAS,EAAG,CAC1B,IAAA+C,cAAAtC,KAAA,EAD0B,CAAZS,KAAA,CAEX,IAFW,CAAlB,CAEc,IAAAd,UAAAiB,aAFd,CAH6C,CAajD8C,EAAAjH,UAAA2F,iBAAA;AAAgD6B,QAAS,EAAG,CACpD,IAAA3B,cAAAE,QAAJ,CACI,IAAAtM,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAgL,WAA5B,CADJ,CAGI,IAAAnL,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAAgL,WAA/B,CAJoD,CAO5DqC,EAAAjH,UAAA,iBAAA,CAAmDiH,CAAAjH,UAAA2F,iBAMnDsB,EAAAjH,UAAA0F,cAAA,CAA6C+B,QAAS,EAAG,CACjD,IAAA5B,cAAAnC,SAAJ,CACI,IAAAjK,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA+K,YAA5B,CADJ,CAGI,IAAAlL,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA+K,YAA/B,CAJiD,CAOzDsC,EAAAjH,UAAA,cAAA,CAAgDiH,CAAAjH,UAAA0F,cAMhDuB,EAAAjH,UAAAwD,QAAA,CAAuCkE,QAAS,EAAG,CAC/C,IAAA7B,cAAAnC,SAAA;AAA8B,CAAA,CAC9B,KAAAsB,eAAA,EAF+C,CAInDiC,EAAAjH,UAAA,QAAA,CAA0CiH,CAAAjH,UAAAwD,QAM1CyD,EAAAjH,UAAA2D,OAAA,CAAsCgE,QAAS,EAAG,CAC9C,IAAA9B,cAAAnC,SAAA,CAA8B,CAAA,CAC9B,KAAAsB,eAAA,EAF8C,CAIlDiC,EAAAjH,UAAA,OAAA,CAAyCiH,CAAAjH,UAAA2D,OAMzCsD,EAAAjH,UAAAmG,MAAA,CAAqCyB,QAAS,EAAG,CAC7C,IAAA/B,cAAAE,QAAA,CAA6B,CAAA,CAC7B,KAAAf,eAAA,EAF6C,CAIjDiC,EAAAjH,UAAA,MAAA,CAAwCiH,CAAAjH,UAAAmG,MAMxCc,EAAAjH,UAAAqG,QAAA,CAAuCwB,QAAS,EAAG,CAC/C,IAAAhC,cAAAE,QAAA,CAA6B,CAAA,CAC7B,KAAAf,eAAA,EAF+C,CAInDiC,EAAAjH,UAAA,QAAA,CAA0CiH,CAAAjH,UAAAqG,QAI1CY,EAAAjH,UAAAiD,KAAA,CAAoC6E,QAAS,EAAG,CAC5C,GAAI,IAAArO,SAAJ,CAAmB,CACf,IAAAoM,cAAA,CAAqB,IAAApM,SAAAqB,cAAA,CAA4B,GAA5B;AAAkC,IAAAlB,YAAAwK,MAAlC,CACrB,IAAI,IAAA3K,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAA8B,iBAAjC,CAAJ,CAAyE,CACrE,IAAAjC,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA4K,qBAA5B,CACA,KAAAmC,wBAAA,CAA+B5M,QAAAC,cAAA,CAAuB,MAAvB,CAC/B,KAAA2M,wBAAAjN,UAAAO,IAAA,CAA2C,IAAAL,YAAA+B,iBAA3C,CACA,KAAAgL,wBAAAjN,UAAAO,IAAA,CAA2C,IAAAL,YAAA8B,iBAA3C,CACA,KAAAiL,wBAAAjN,UAAAO,IAAA,CAA2C,IAAAL,YAAA6K,cAA3C,CACA,KAAAmC,mBAAA,CAA0B,IAAAtB,WAAAtB,KAAA,CAAqB,IAArB,CAC1B;IAAA2C,wBAAArM,iBAAA,CAA8C,SAA9C,CAAyD,IAAAsM,mBAAzD,CACA,KAAIzM,EAASJ,QAAAC,cAAA,CAAuB,MAAvB,CACbG,EAAAT,UAAAO,IAAA,CAAqB,IAAAL,YAAAgC,OAArB,CACA,KAAA+K,wBAAAtM,YAAA,CAAyCF,CAAzC,CACA,KAAAV,SAAAY,YAAA,CAA0B,IAAAsM,wBAA1B,CAXqE,CAazE,IAAAE,mBAAA,CAA0B,IAAA/B,UAAAd,KAAA,CAAoB,IAApB,CAC1B,KAAA8C,kBAAA,CAAyB,IAAA7B,SAAAjB,KAAA,CAAmB,IAAnB,CACzB,KAAA+C,iBAAA,CAAwB,IAAA5B,QAAAnB,KAAA,CAAkB,IAAlB,CACxB,KAAA+D,sBAAA,CAA6B,IAAAzC,WAAAtB,KAAA,CAAqB,IAArB,CAC7B,KAAA6B,cAAAvL,iBAAA,CAAoC,QAApC;AAA8C,IAAAuM,mBAA9C,CACA,KAAAhB,cAAAvL,iBAAA,CAAoC,OAApC,CAA6C,IAAAwM,kBAA7C,CACA,KAAAjB,cAAAvL,iBAAA,CAAoC,MAApC,CAA4C,IAAAyM,iBAA5C,CACA,KAAAtN,SAAAa,iBAAA,CAA+B,SAA/B,CAA0C,IAAAyN,sBAA1C,CACA,KAAA/C,eAAA,EACA,KAAAvL,SAAAC,UAAAO,IAAA,CAA4B,aAA5B,CAxBe,CADyB,CA8BhD8B,EAAAY,SAAA,CAA0B,CACtBqE,YAAaiG,CADS,CAEtBvG,cAAe,oBAFO,CAGtBrC,SAAU,oBAHY,CAItBsB,OAAQ,CAAA,CAJc,CAA1B,CA8BA,KAAIqI,EAAeA,QAAqB,CAAC5L,CAAD,CAAU,CAC9C,IAAA3C,SAAA,CAAgB2C,CAEhB,KAAA6G,KAAA,EAH8C,CAKlDlF,OAAA,aAAA,CAAyBiK,CAOzBA,EAAAhI,UAAAkD,UAAA,CAAmC,CAE/B+E,4BAA6B,EAFE;AAI/BC,6BAA8B,EAJC,CAO/BC,cAAe,GAPgB,CAenCH,EAAAhI,UAAAoI,UAAA,CAAmC,CAC/BC,MAAO,EADwB,CAE/BC,OAAQ,EAFuB,CAG/BC,MAAO,EAHwB,CAI/BC,SAAU,EAJqB,CAK/BC,WAAY,EALmB,CAenCT,EAAAhI,UAAApG,YAAA,CAAqC,CACjC8O,UAAW,qBADsB,CAEjCC,QAAS,mBAFwB,CAGjCC,KAAM,gBAH2B,CAIjCC,sBAAuB,iCAJU,CAKjC1F,cAAe,sBALkB,CAMjCqB,qBAAsB,qCANW,CAOjC5I,OAAQ,YAPyB,CASjCiJ,YAAa,aAToB,CAUjCiE,WAAY,YAVqB,CAWjCC,aAAc,cAXmB,CAajCC,YAAa,uBAboB;AAejCC,aAAc,wBAfmB,CAgBjCC,SAAU,oBAhBuB,CAiBjCC,UAAW,qBAjBsB,CAkBjCC,UAAW,qBAlBsB,CAuBrCpB,EAAAhI,UAAAiD,KAAA,CAA8BoG,QAAS,EAAG,CACtC,GAAI,IAAA5P,SAAJ,CAAmB,CAEf,IAAI6P,EAAYvP,QAAAC,cAAA,CAAuB,KAAvB,CAChBsP,EAAA5P,UAAAO,IAAA,CAAwB,IAAAL,YAAA8O,UAAxB,CACA,KAAAjP,SAAA8P,cAAAC,aAAA,CAAyCF,CAAzC,CAAoD,IAAA7P,SAApD,CACA,KAAAA,SAAA8P,cAAAE,YAAA,CAAwC,IAAAhQ,SAAxC,CACA6P,EAAAjP,YAAA,CAAsB,IAAAZ,SAAtB,CACA,KAAAiQ,WAAA,CAAkBJ,CAElB,KAAIK,EAAU5P,QAAAC,cAAA,CAAuB,KAAvB,CACd2P,EAAAjQ,UAAAO,IAAA,CAAsB,IAAAL,YAAA+O,QAAtB,CACA,KAAAiB,SAAA;AAAgBD,CAChBL,EAAAE,aAAA,CAAuBG,CAAvB,CAAgC,IAAAlQ,SAAhC,CAIA,IAFIoQ,CAEJ,CAFc,IAAApQ,SAAAe,aAAA,CAA2B,KAA3B,CAEd,EAFmD,IAAAf,SAAAe,aAAA,CAA2B,cAA3B,CAEnD,CAEI,GADAsP,CACA,CADQ/P,QAAAgQ,eAAA,CAAwBF,CAAxB,CACR,CACI,IAAAG,YAEA,CAFmBF,CAEnB,CADAA,CAAAxP,iBAAA,CAAuB,OAAvB,CAAgC,IAAA2P,gBAAAjG,KAAA,CAA0B,IAA1B,CAAhC,CACA,CAAA8F,CAAAxP,iBAAA,CAAuB,SAAvB,CAAkC,IAAA4P,wBAAAlG,KAAA,CAAkC,IAAlC,CAAlC,CAGJmG,EAAAA,CAAQ,IAAA1Q,SAAA8E,iBAAA,CAA+B,GAA/B,CAAqC,IAAA3E,YAAAgP,KAArC,CACZ,KAAAwB,kBAAA,CAAyB,IAAAC,yBAAArG,KAAA,CAAmC,IAAnC,CACzB,KAAAsG,gBAAA,CAAuB,IAAAC,iBAAAvG,KAAA,CAA2B,IAA3B,CACvB,KAAK,IAAI9G,EAAI,CAAb,CAAgBA,CAAhB,CAAoBiN,CAAA/M,OAApB,CAAkCF,CAAA,EAAlC,CAEIiN,CAAA,CAAMjN,CAAN,CAAA5C,iBAAA,CAA0B,OAA1B;AAAmC,IAAAgQ,gBAAnC,CAIA,CAFAH,CAAA,CAAMjN,CAAN,CAAAsN,SAEA,CAFoB,IAEpB,CAAAL,CAAA,CAAMjN,CAAN,CAAA5C,iBAAA,CAA0B,SAA1B,CAAqC,IAAA8P,kBAArC,CAGJ,IAAI,IAAA3Q,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAuJ,cAAjC,CAAJ,CAEI,IADA,IAAA1J,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA4K,qBAA5B,CACK,CAAAtH,CAAA,CAAI,CAAT,CAAYA,CAAZ,CAAgBiN,CAAA/M,OAAhB,CAA8BF,CAAA,EAA9B,CAAmC,CAC/B,IAAI+D,EAAOkJ,CAAA,CAAMjN,CAAN,CAAX,CACIpD,EAAkBC,QAAAC,cAAA,CAAuB,MAAvB,CACtBF,EAAAJ,UAAAO,IAAA,CAA8B,IAAAL,YAAAiP,sBAA9B,CACA,KAAI1O,EAASJ,QAAAC,cAAA,CAAuB,MAAvB,CACbG,EAAAT,UAAAO,IAAA,CAAqB,IAAAL,YAAAgC,OAArB,CACA9B,EAAAO,YAAA,CAA4BF,CAA5B,CACA8G,EAAA5G,YAAA,CAAiBP,CAAjB,CACAmH,EAAAvH,UAAAO,IAAA,CAAmB,IAAAL,YAAAuJ,cAAnB,CAR+B,CAYnC,IAAA1J,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAoP,YAAjC,CAAJ;AACI,IAAAY,SAAAlQ,UAAAO,IAAA,CAA4B,IAAAL,YAAAoP,YAA5B,CAEA,KAAAvP,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAqP,aAAjC,CAAJ,EACI,IAAAW,SAAAlQ,UAAAO,IAAA,CAA4B,IAAAL,YAAAqP,aAA5B,CAEA,KAAAxP,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAsP,SAAjC,CAAJ,EACI,IAAAU,SAAAlQ,UAAAO,IAAA,CAA4B,IAAAL,YAAAsP,SAA5B,CAEA,KAAAzP,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAuP,UAAjC,CAAJ,EACI,IAAAS,SAAAlQ,UAAAO,IAAA,CAA4B,IAAAL,YAAAuP,UAA5B,CAEA,KAAA1P,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAwP,UAAjC,CAAJ,EACI,IAAAQ,SAAAlQ,UAAAO,IAAA,CAA4B,IAAAL,YAAAwP,UAA5B,CAEJE;CAAA5P,UAAAO,IAAA,CAAwB,IAAAL,YAAAiL,YAAxB,CAjEe,CADmB,CA4E1CmD,EAAAhI,UAAAiK,gBAAA,CAAyCQ,QAAS,CAACC,CAAD,CAAM,CACpD,GAAI,IAAAjR,SAAJ,EAAqB,IAAAuQ,YAArB,CAAuC,CACnC,IAAIW,EAAO,IAAAX,YAAAY,sBAAA,EAAX,CACIC,EAAU,IAAAb,YAAAT,cAAAqB,sBAAA,EACV,KAAAnR,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAwP,UAAjC,CAAJ,GACW,IAAA3P,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAqP,aAAjC,CAAJ,EAEH,IAAAS,WAAAoB,MAAAC,MACA,CAD8BF,CAAAE,MAC9B,CAD8CJ,CAAAI,MAC9C,CAD2D,IAC3D,CAAA,IAAArB,WAAAoB,MAAAE,IAAA,CAA4B,IAAAhB,YAAAiB,UAA5B,CAAyD,IAAAjB,YAAAkB,aAAzD,CAAyF,IAHtF,EAII,IAAAzR,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAsP,SAAjC,CAAJ;CAEH,IAAAQ,WAAAoB,MAAAK,KACA,CAD6B,IAAAnB,YAAAoB,WAC7B,CAD2D,IAC3D,CAAA,IAAA1B,WAAAoB,MAAAO,OAAA,CAA+BR,CAAAQ,OAA/B,CAAgDV,CAAAK,IAAhD,CAA2D,IAHxD,EAII,IAAAvR,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAuP,UAAjC,CAAJ,EAEH,IAAAO,WAAAoB,MAAAC,MACA,CAD8BF,CAAAE,MAC9B,CAD8CJ,CAAAI,MAC9C,CAD2D,IAC3D,CAAA,IAAArB,WAAAoB,MAAAO,OAAA,CAA+BR,CAAAQ,OAA/B,CAAgDV,CAAAK,IAAhD,CAA2D,IAHxD,GAMH,IAAAtB,WAAAoB,MAAAK,KACA,CAD6B,IAAAnB,YAAAoB,WAC7B,CAD2D,IAC3D,CAAA,IAAA1B,WAAAoB,MAAAE,IAAA,CAA4B,IAAAhB,YAAAiB,UAA5B,CAAyD,IAAAjB,YAAAkB,aAAzD,CAAyF,IAPtF,CATP,CAHmC,CAsBvC,IAAAI,OAAA,CAAYZ,CAAZ,CAvBoD,CA+BxD1C,EAAAhI,UAAAkK,wBAAA,CAAiDqB,QAAS,CAACb,CAAD,CAAM,CAC5D,GAAI,IAAAjR,SAAJ;AAAqB,IAAAiQ,WAArB,EAAwC,IAAAM,YAAxC,CAA0D,CACtD,IAAIG,EAAQ,IAAA1Q,SAAA8E,iBAAA,CAA+B,GAA/B,CAAqC,IAAA3E,YAAAgP,KAArC,CAA6D,kBAA7D,CACRuB,EAAJ,EAA4B,CAA5B,CAAaA,CAAA/M,OAAb,EAAiC,IAAAsM,WAAAhQ,UAAAC,SAAA,CAAmC,IAAAC,YAAAkP,WAAnC,CAAjC,GACQ4B,CAAAc,QAAJ,GAAoB,IAAApD,UAAAI,SAApB,EACIkC,CAAAhQ,eAAA,EACA,CAAAyP,CAAA,CAAMA,CAAA/M,OAAN,CAAqB,CAArB,CAAAqO,MAAA,EAFJ,EAGWf,CAAAc,QAHX,GAG2B,IAAApD,UAAAK,WAH3B,GAIIiC,CAAAhQ,eAAA,EACA,CAAAyP,CAAA,CAAM,CAAN,CAAAsB,MAAA,EALJ,CADJ,CAFsD,CADE,CAoBhEzD,EAAAhI,UAAAqK,yBAAA,CAAkDqB,QAAS,CAAChB,CAAD,CAAM,CAC7D,GAAI,IAAAjR,SAAJ,EAAqB,IAAAiQ,WAArB,CAAsC,CAClC,IAAIS,EAAQ,IAAA1Q,SAAA8E,iBAAA,CAA+B,GAA/B,CAAqC,IAAA3E,YAAAgP,KAArC;AAA6D,kBAA7D,CACZ,IAAIuB,CAAJ,EAA4B,CAA5B,CAAaA,CAAA/M,OAAb,EAAiC,IAAAsM,WAAAhQ,UAAAC,SAAA,CAAmC,IAAAC,YAAAkP,WAAnC,CAAjC,CAAkG,CAC9F,IAAI6C,EAAe7L,KAAAE,UAAAC,MAAAC,KAAA,CAA2BiK,CAA3B,CAAAzM,QAAA,CAA0CgN,CAAAkB,OAA1C,CACflB,EAAAc,QAAJ,GAAoB,IAAApD,UAAAI,SAApB,EACIkC,CAAAhQ,eAAA,EACA,CAAmB,CAAnB,CAAIiR,CAAJ,CACIxB,CAAA,CAAMwB,CAAN,CAAqB,CAArB,CAAAF,MAAA,EADJ,CAGItB,CAAA,CAAMA,CAAA/M,OAAN,CAAqB,CAArB,CAAAqO,MAAA,EALR,EAOWf,CAAAc,QAAJ,GAAoB,IAAApD,UAAAK,WAApB,EACHiC,CAAAhQ,eAAA,EACA,CAAIyP,CAAA/M,OAAJ,CAAmBuO,CAAnB,CAAkC,CAAlC,CACIxB,CAAA,CAAMwB,CAAN,CAAqB,CAArB,CAAAF,MAAA,EADJ,CAGItB,CAAA,CAAM,CAAN,CAAAsB,MAAA,EALD,EAOIf,CAAAc,QAAJ,GAAoB,IAAApD,UAAAG,MAApB,EAA4CmC,CAAAc,QAA5C,GAA4D,IAAApD,UAAAC,MAA5D,EACHqC,CAAAhQ,eAAA,EAOA,CALIH,CAKJ,CALQ,IAAIsR,UAAJ,CAAe,WAAf,CAKR,CAJAnB,CAAAkB,OAAA/M,cAAA,CAAyBtE,CAAzB,CAIA,CAHAA,CAGA,CAHI,IAAIsR,UAAJ,CAAe,SAAf,CAGJ;AAFAnB,CAAAkB,OAAA/M,cAAA,CAAyBtE,CAAzB,CAEA,CAAAmQ,CAAAkB,OAAAE,MAAA,EARG,EASIpB,CAAAc,QATJ,GASoB,IAAApD,UAAAE,OATpB,GAUHoC,CAAAhQ,eAAA,EACA,CAAA,IAAAqR,KAAA,EAXG,CAhBuF,CAFhE,CADuB,CAyCjE/D,EAAAhI,UAAAuK,iBAAA,CAA0CyB,QAAS,CAACtB,CAAD,CAAM,CACjDA,CAAAkB,OAAAK,aAAA,CAAwB,UAAxB,CAAJ,CACIvB,CAAAwB,gBAAA,EADJ,EAII,IAAAC,SACA,CADgB,CAAA,CAChB,CAAApO,MAAA+E,WAAA,CAAkB,QAAS,CAAC4H,CAAD,CAAM,CAC7B,IAAAqB,KAAA,EACA,KAAAI,SAAA,CAAgB,CAAA,CAFa,CAAfnI,KAAA,CAGX,IAHW,CAAlB,CAGc,IAAAd,UAAAiF,cAHd,CALJ,CADqD,CAqBzDH,EAAAhI,UAAAoM,WAAA,CAAoCC,QAAS,CAACC,CAAD,CAASC,CAAT,CAAgB,CACrD,IAAA9S,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAwP,UAAjC,CAAJ,CAEI,IAAA3P,SAAAqR,MAAA0B,KAFJ,CAE+B,EAF/B,CAGW,IAAA/S,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAqP,aAAjC,CAAJ;AAEH,IAAAxP,SAAAqR,MAAA0B,KAFG,CAEwB,SAFxB,CAEoCD,CAFpC,CAEoD,OAFpD,CAE2DA,CAF3D,CAEmE,KAFnE,CAGI,IAAA9S,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAsP,SAAjC,CAAJ,CAEH,IAAAzP,SAAAqR,MAAA0B,KAFG,CAEwB,OAFxB,CAEkCF,CAFlC,CAE2C,OAF3C,CAEqDA,CAFrD,CAE8D,OAF9D,CAGI,IAAA7S,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAuP,UAAjC,CAAJ,CAEH,IAAA1P,SAAAqR,MAAA0B,KAFG,CAEwB,OAFxB,CAEkCF,CAFlC,CAE2C,KAF3C,CAEmDC,CAFnD,CAE2D,KAF3D,CAEmED,CAFnE,CAE4E,KAF5E,CAEoFC,CAFpF,CAE4F,KAF5F,CAKH,IAAA9S,SAAAqR,MAAA0B,KALG,CAKwB,EAf0B,CAwB7DxE,EAAAhI,UAAAyM,4BAAA,CAAqDC,QAAS,CAAChC,CAAD,CAAM,CAChEA,CAAAkB,OAAAlS,UAAA2L,OAAA,CAA4B2C,CAAAhI,UAAApG,YAAAmP,aAA5B,CADgE,CAQpEf,EAAAhI,UAAA2M,yBAAA,CAAkDC,QAAS,EAAG,CAC1D,IAAAnT,SAAAa,iBAAA,CAA+B,eAA/B;AAAgD,IAAAmS,4BAAhD,CACA,KAAAhT,SAAAa,iBAAA,CAA+B,qBAA/B,CAAsD,IAAAmS,4BAAtD,CAF0D,CAS9DzE,EAAAhI,UAAAlE,KAAA,CAA8B+Q,QAAS,CAACnC,CAAD,CAAM,CACzC,GAAI,IAAAjR,SAAJ,EAAqB,IAAAiQ,WAArB,EAAwC,IAAAE,SAAxC,CAAuD,CAEnD,IAAI0C,EAAS,IAAA7S,SAAAmR,sBAAA,EAAA0B,OAAb,CACIC,EAAQ,IAAA9S,SAAAmR,sBAAA,EAAA2B,MAEZ,KAAA7C,WAAAoB,MAAAyB,MAAA,CAA8BA,CAA9B,CAAsC,IACtC,KAAA7C,WAAAoB,MAAAwB,OAAA,CAA+BA,CAA/B,CAAwC,IACxC,KAAA1C,SAAAkB,MAAAyB,MAAA,CAA4BA,CAA5B,CAAoC,IACpC,KAAA3C,SAAAkB,MAAAwB,OAAA,CAA6BA,CAA7B,CAAsC,IAKtC,KAJA,IAAIQ,EAAqB,IAAA5J,UAAA+E,4BAArB6E,CAAkE,IAAA5J,UAAAgF,6BAAtE;AAGIiC,EAAQ,IAAA1Q,SAAA8E,iBAAA,CAA+B,GAA/B,CAAqC,IAAA3E,YAAAgP,KAArC,CAHZ,CAIS1L,EAAI,CAAb,CAAgBA,CAAhB,CAAoBiN,CAAA/M,OAApB,CAAkCF,CAAA,EAAlC,CAAuC,CACnC,IAAI6P,EAAY,IAAhB,CAEIA,EADA,IAAAtT,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAsP,SAAjC,CAAJ,EAAmE,IAAAzP,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAuP,UAAjC,CAAnE,EACiBmD,CADjB,CAC0BnC,CAAA,CAAMjN,CAAN,CAAA+N,UAD1B,CAC+Cd,CAAA,CAAMjN,CAAN,CAAAgO,aAD/C,EACwEoB,CADxE,CACiFQ,CADjF,CACsG,GADtG,CAGgB3C,CAAA,CAAMjN,CAAN,CAAA+N,UAHhB,CAGqCqB,CAHrC,CAG8CQ,CAH9C,CAGmE,GAEnE3C,EAAA,CAAMjN,CAAN,CAAA4N,MAAAkC,gBAAA,CAAiCD,CAPE,CAUvC,IAAAX,WAAA,CAAgBE,CAAhB,CAAwBC,CAAxB,CAGAxO,OAAAoE,sBAAA,CAA6B,QAAS,EAAG,CACrC,IAAA1I,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAmP,aAA5B,CACA,KAAAtP,SAAAqR,MAAA0B,KAAA,CAA2B,SAA3B,CAAuCD,CAAvC,CAA+C,KAA/C,CAAuDD,CAAvD,CAAgE,OAChE,KAAA5C,WAAAhQ,UAAAO,IAAA,CAA8B,IAAAL,YAAAkP,WAA9B,CAHqC,CAAZ9E,KAAA,CAItB,IAJsB,CAA7B,CAMA;IAAA2I,yBAAA,EAEA,KAAIjQ,EAAW,QAAS,CAACnC,CAAD,CAAI,CAOpBA,CAAJ,GAAUmQ,CAAV,EAAkB,IAAAyB,SAAlB,EAAmC5R,CAAAqR,OAAAqB,WAAnC,GAA2D,IAAAxT,SAA3D,GACIM,QAAAmT,oBAAA,CAA6B,OAA7B,CAAsCxQ,CAAtC,CACA,CAAA,IAAAqP,KAAA,EAFJ,CAPwB,CAAb/H,KAAA,CAWR,IAXQ,CAYfjK,SAAAO,iBAAA,CAA0B,OAA1B,CAAmCoC,CAAnC,CA9CmD,CADd,CAkD7CsL,EAAAhI,UAAA,KAAA,CAAiCgI,CAAAhI,UAAAlE,KAMjCkM,EAAAhI,UAAA+L,KAAA,CAA8BoB,QAAS,EAAG,CACtC,GAAI,IAAA1T,SAAJ,EAAqB,IAAAiQ,WAArB,EAAwC,IAAAE,SAAxC,CAAuD,CAGnD,IAFA,IAAIO,EAAQ,IAAA1Q,SAAA8E,iBAAA,CAA+B,GAA/B,CAAqC,IAAA3E,YAAAgP,KAArC,CAAZ,CAES1L,EAAI,CAAb,CAAgBA,CAAhB,CAAoBiN,CAAA/M,OAApB,CAAkCF,CAAA,EAAlC,CACIiN,CAAA,CAAMjN,CAAN,CAAA4N,MAAAsC,eAAA,CAA8B,kBAA9B,CAGAzC,EAAAA,CAAO,IAAAlR,SAAAmR,sBAAA,EACP0B,EAAAA;AAAS3B,CAAA2B,OACTC,EAAAA,CAAQ5B,CAAA4B,MAGZ,KAAA9S,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAmP,aAA5B,CACA,KAAAqD,WAAA,CAAgBE,CAAhB,CAAwBC,CAAxB,CACA,KAAA7C,WAAAhQ,UAAA2L,OAAA,CAAiC,IAAAzL,YAAAkP,WAAjC,CAEA,KAAA6D,yBAAA,EAhBmD,CADjB,CAoB1C3E,EAAAhI,UAAA,KAAA,CAAiCgI,CAAAhI,UAAA+L,KAMjC/D,EAAAhI,UAAAsL,OAAA,CAAgC+B,QAAS,CAAC3C,CAAD,CAAM,CACvC,IAAAhB,WAAAhQ,UAAAC,SAAA,CAAmC,IAAAC,YAAAkP,WAAnC,CAAJ,CACI,IAAAiD,KAAA,EADJ,CAGI,IAAAjQ,KAAA,CAAU4O,CAAV,CAJuC,CAO/C1C,EAAAhI,UAAA,OAAA,CAAmCgI,CAAAhI,UAAAsL,OAGnCvP,EAAAY,SAAA,CAA0B,CACtBqE,YAAagH,CADS,CAEtBtH,cAAe,cAFO,CAGtBrC,SAAU,aAHY,CAItBsB,OAAQ,CAAA,CAJc,CAA1B,CA8BI2N,EAAAA,CAAmBA,QAAyB,CAAClR,CAAD,CAAU,CACtD,IAAA3C,SAAA;AAAgB2C,CAEhB,KAAA6G,KAAA,EAHsD,CAK1DlF,OAAA,iBAAA,CAA6BuP,CAO7BA,EAAAtN,UAAAkD,UAAA,CAAuC,EASvCoK,EAAAtN,UAAApG,YAAA,CAAyC,CAAE2T,oBAAqB,6BAAvB,CAOzCD,EAAAtN,UAAAwN,YAAA,CAAyCC,QAAS,CAACC,CAAD,CAAI,CAC9C,IAAAjU,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAA2T,oBAAjC,CAAJ,GAGA,IAAAI,aAAA7C,MAAAyB,MAHA,CAGgCmB,CAHhC,CAGoC,GAHpC,CADkD,CAMtDJ,EAAAtN,UAAA,YAAA,CAA4CsN,CAAAtN,UAAAwN,YAO5CF,EAAAtN,UAAA4N,UAAA,CAAuCC,QAAS,CAACH,CAAD,CAAI,CAChD,IAAAI,WAAAhD,MAAAyB,MAAA,CAA8BmB,CAA9B,CAAkC,GAClC,KAAAK,QAAAjD,MAAAyB,MAAA,CAA2B,GAA3B,CAAiCmB,CAAjC,CAAqC,GAFW,CAIpDJ,EAAAtN,UAAA,UAAA,CAA0CsN,CAAAtN,UAAA4N,UAI1CN,EAAAtN,UAAAiD,KAAA;AAAkC+K,QAAS,EAAG,CAC1C,GAAI,IAAAvU,SAAJ,CAAmB,CACf,IAAIwU,EAAKlU,QAAAC,cAAA,CAAuB,KAAvB,CACTiU,EAAA5Q,UAAA,CAAe,sBACf,KAAA5D,SAAAY,YAAA,CAA0B4T,CAA1B,CACA,KAAAN,aAAA,CAAoBM,CACpBA,EAAA,CAAKlU,QAAAC,cAAA,CAAuB,KAAvB,CACLiU,EAAA5Q,UAAA,CAAe,oBACf,KAAA5D,SAAAY,YAAA,CAA0B4T,CAA1B,CACA,KAAAH,WAAA,CAAkBG,CAClBA,EAAA,CAAKlU,QAAAC,cAAA,CAAuB,KAAvB,CACLiU,EAAA5Q,UAAA,CAAe,iBACf,KAAA5D,SAAAY,YAAA,CAA0B4T,CAA1B,CACA,KAAAF,QAAA,CAAeE,CACf,KAAAN,aAAA7C,MAAAyB,MAAA,CAAgC,IAChC,KAAAuB,WAAAhD,MAAAyB,MAAA,CAA8B,MAC9B,KAAAwB,QAAAjD,MAAAyB,MAAA,CAA2B,IAC3B,KAAA9S,SAAAC,UAAAO,IAAA,CAA4B,aAA5B,CAhBe,CADuB,CAsB9C8B;CAAAY,SAAA,CAA0B,CACtBqE,YAAasM,CADS,CAEtB5M,cAAe,kBAFO,CAGtBrC,SAAU,iBAHY,CAItBsB,OAAQ,CAAA,CAJc,CAA1B,CA8BIuO,EAAAA,CAAgBA,QAAsB,CAAC9R,CAAD,CAAU,CAChD,IAAA3C,SAAA,CAAgB2C,CAEhB,KAAA6G,KAAA,EAHgD,CAKpDlF,OAAA,cAAA,CAA0BmQ,CAO1BA,EAAAlO,UAAAkD,UAAA,CAAoC,CAAEiB,aAAc,IAAhB,CASpC+J,EAAAlO,UAAApG,YAAA,CAAsC,CAClC8K,WAAY,YADsB,CAElCC,YAAa,aAFqB,CAGlCC,WAAY,YAHsB,CAIlCC,YAAa,aAJqB,CAKlCsJ,SAAU,cALwB,CAMlCC,UAAW,mBANuB,CAOlCC,mBAAoB,yBAPc,CAQlCC,mBAAoB,yBARc,CASlCnL,cAAe,sBATmB;AAUlCqB,qBAAsB,qCAVY,CAWlC7I,iBAAkB,6BAXgB,CAYlC8I,cAAe,oBAZmB,CAalC7I,OAAQ,YAb0B,CAqBtCsS,EAAAlO,UAAA8E,UAAA,CAAoCyJ,QAAS,CAACjL,CAAD,CAAQ,CAG7CkL,CAAAA,CAASzU,QAAA0U,uBAAA,CAAgC,IAAA7U,YAAAuU,SAAhC,CACb,KAAK,IAAIjR,EAAI,CAAb,CAAgBA,CAAhB,CAAoBsR,CAAApR,OAApB,CAAmCF,CAAA,EAAnC,CACiBsR,CAAA,CAAOtR,CAAP,CAAApC,cAAA4T,CAAwB,GAAxBA,CAA8B,IAAA9U,YAAAwU,UAA9BM,CAETlU,aAAA,CAAoB,MAApB,CAAJ,GAAoC,IAAAmU,YAAAnU,aAAA,CAA8B,MAA9B,CAApC,EAC8C,WAD9C,GACQ,MAAOgU,EAAA,CAAOtR,CAAP,CAAA,cADf,EAEQsR,CAAA,CAAOtR,CAAP,CAAA,cAAA8H,eAAA,EATqC,CAoBrDkJ,EAAAlO,UAAAiF,SAAA,CAAmC2J,QAAS,CAACtL,CAAD,CAAQ,CAChD,IAAA7J,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA8K,WAA5B,CADgD,CASpDwJ;CAAAlO,UAAAmF,QAAA,CAAkC0J,QAAS,CAACvL,CAAD,CAAQ,CAC/C,IAAA7J,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA8K,WAA/B,CAD+C,CASnDwJ,EAAAlO,UAAA8O,WAAA,CAAqCC,QAAS,CAACzL,CAAD,CAAQ,CAClD,IAAAkC,MAAA,EADkD,CAQtD0I,EAAAlO,UAAAgF,eAAA,CAAyCgK,QAAS,EAAG,CACjD,IAAAtJ,cAAA,EACA,KAAAC,iBAAA,EAFiD,CASrDuI,EAAAlO,UAAAwF,MAAA,CAAgCyJ,QAAS,EAAG,CAGxClR,MAAA+E,WAAA,CAAkB,QAAS,EAAG,CAC1B,IAAA6L,YAAApL,KAAA,EAD0B,CAAZS,KAAA,CAEX,IAFW,CAAlB,CAEc,IAAAd,UAAAiB,aAFd,CAHwC,CAa5C+J,EAAAlO,UAAA0F,cAAA,CAAwCwJ,QAAS,EAAG,CAC5C,IAAAP,YAAAjL,SAAJ,CACI,IAAAjK,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA+K,YAA5B,CADJ,CAGI,IAAAlL,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA+K,YAA/B,CAJ4C,CAOpDuJ;CAAAlO,UAAA,cAAA,CAA2CkO,CAAAlO,UAAA0F,cAM3CwI,EAAAlO,UAAA2F,iBAAA,CAA2CwJ,QAAS,EAAG,CAC/C,IAAAR,YAAA5I,QAAJ,CACI,IAAAtM,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAgL,WAA5B,CADJ,CAGI,IAAAnL,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAAgL,WAA/B,CAJ+C,CAOvDsJ,EAAAlO,UAAA,iBAAA,CAA8CkO,CAAAlO,UAAA2F,iBAM9CuI,EAAAlO,UAAAwD,QAAA,CAAkC4L,QAAS,EAAG,CAC1C,IAAAT,YAAAjL,SAAA,CAA4B,CAAA,CAC5B,KAAAsB,eAAA,EAF0C,CAI9CkJ,EAAAlO,UAAA,QAAA,CAAqCkO,CAAAlO,UAAAwD,QAMrC0K,EAAAlO,UAAA2D,OAAA,CAAiC0L,QAAS,EAAG,CACzC,IAAAV,YAAAjL,SAAA,CAA4B,CAAA,CAC5B,KAAAsB,eAAA,EAFyC,CAI7CkJ,EAAAlO,UAAA,OAAA;AAAoCkO,CAAAlO,UAAA2D,OAMpCuK,EAAAlO,UAAAmG,MAAA,CAAgCmJ,QAAS,EAAG,CACxC,IAAAX,YAAA5I,QAAA,CAA2B,CAAA,CAC3B,KAAAjB,UAAA,CAAe,IAAf,CAFwC,CAI5CoJ,EAAAlO,UAAA,MAAA,CAAmCkO,CAAAlO,UAAAmG,MAMnC+H,EAAAlO,UAAAqG,QAAA,CAAkCkJ,QAAS,EAAG,CAC1C,IAAAZ,YAAA5I,QAAA,CAA2B,CAAA,CAC3B,KAAAjB,UAAA,CAAe,IAAf,CAF0C,CAI9CoJ,EAAAlO,UAAA,QAAA,CAAqCkO,CAAAlO,UAAAqG,QAIrC6H,EAAAlO,UAAAiD,KAAA,CAA+BuM,QAAS,EAAG,CACvC,GAAI,IAAA/V,SAAJ,CAAmB,CACf,IAAAkV,YAAA,CAAmB,IAAAlV,SAAAqB,cAAA,CAA4B,GAA5B,CAAkC,IAAAlB,YAAAwU,UAAlC,CACnB,KAAAqB,oBAAA,CAA2B,IAAA3K,UAAAd,KAAA,CAAoB,IAApB,CAC3B,KAAA0L,mBAAA,CAA0B,IAAA5K,UAAAd,KAAA,CAAoB,IAApB,CAC1B,KAAA2L,kBAAA;AAAyB,IAAAxK,QAAAnB,KAAA,CAAkB,IAAlB,CACzB,KAAA4L,qBAAA,CAA4B,IAAAd,WAAA9K,KAAA,CAAqB,IAArB,CAC5B,KAAI6L,EAAc9V,QAAAC,cAAA,CAAuB,MAAvB,CAClB6V,EAAAnW,UAAAO,IAAA,CAA0B,IAAAL,YAAAyU,mBAA1B,CACA,KAAIyB,EAAc/V,QAAAC,cAAA,CAAuB,MAAvB,CAClB8V,EAAApW,UAAAO,IAAA,CAA0B,IAAAL,YAAA0U,mBAA1B,CACA,KAAA7U,SAAAY,YAAA,CAA0BwV,CAA1B,CACA,KAAApW,SAAAY,YAAA,CAA0ByV,CAA1B,CAEI,KAAArW,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAuJ,cAAjC,CAAJ,GACI,IAAA1J,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA4K,qBAA5B,CASA,CARA1K,CAQA,CARkBC,QAAAC,cAAA,CAAuB,MAAvB,CAQlB,CAPAF,CAAAJ,UAAAO,IAAA,CAA8B,IAAAL,YAAA+B,iBAA9B,CAOA;AANA7B,CAAAJ,UAAAO,IAAA,CAA8B,IAAAL,YAAAuJ,cAA9B,CAMA,CALArJ,CAAAJ,UAAAO,IAAA,CAA8B,IAAAL,YAAA6K,cAA9B,CAKA,CAJA3K,CAAAQ,iBAAA,CAAiC,SAAjC,CAA4C,IAAAsV,qBAA5C,CAIA,CAHIzV,CAGJ,CAHaJ,QAAAC,cAAA,CAAuB,MAAvB,CAGb,CAFAG,CAAAT,UAAAO,IAAA,CAAqB,IAAAL,YAAAgC,OAArB,CAEA,CADA9B,CAAAO,YAAA,CAA4BF,CAA5B,CACA,CAAA,IAAAV,SAAAY,YAAA,CAA0BP,CAA1B,CAVJ,CAYA,KAAA6U,YAAArU,iBAAA,CAAkC,QAAlC,CAA4C,IAAAmV,oBAA5C,CACA,KAAAd,YAAArU,iBAAA,CAAkC,OAAlC,CAA2C,IAAAoV,mBAA3C,CACA,KAAAf,YAAArU,iBAAA,CAAkC,MAAlC,CAA0C,IAAAqV,kBAA1C,CACA,KAAAlW,SAAAa,iBAAA,CAA+B,SAA/B;AAA0C,IAAAsV,qBAA1C,CACA,KAAA5K,eAAA,EACA,KAAAvL,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAiL,YAA5B,CA9Be,CADoB,CAoC3C9I,EAAAY,SAAA,CAA0B,CACtBqE,YAAakN,CADS,CAEtBxN,cAAe,eAFO,CAGtBrC,SAAU,cAHY,CAItBsB,OAAQ,CAAA,CAJc,CAA1B,CA8BIoQ,EAAAA,CAAiBA,QAAuB,CAAC3T,CAAD,CAAU,CAClD,IAAA3C,SAAA,CAAgB2C,CAEhB,KAAA4T,MAAA,CAAajS,MAAAwE,UAAA0N,iBAEb,KAAAhN,KAAA,EALkD,CAOtDlF,OAAA,eAAA,CAA2BgS,CAO3BA,EAAA/P,UAAAkD,UAAA,CAAqC,EASrC6M,EAAA/P,UAAApG,YAAA,CAAuC,CACnCsW,aAAc,0BADqB,CAEnCC,iBAAkB,uBAFiB,CAGnCC,gBAAiB,6BAHkB,CAInCC,iBAAkB,8BAJiB;AAKnCC,iBAAkB,8BALiB,CAMnCC,gBAAiB,iBANkB,CAOnC1L,YAAa,aAPsB,CAevCkL,EAAA/P,UAAAwQ,SAAA,CAAoCC,QAAS,CAACnN,CAAD,CAAQ,CACjD,IAAAoN,mBAAA,EADiD,CASrDX,EAAA/P,UAAA8E,UAAA,CAAqC6L,QAAS,CAACrN,CAAD,CAAQ,CAClD,IAAAoN,mBAAA,EADkD,CAStDX,EAAA/P,UAAAsF,WAAA,CAAsCsL,QAAS,CAACtN,CAAD,CAAQ,CACnDA,CAAAsI,OAAArI,KAAA,EADmD,CAavDwM,EAAA/P,UAAA6Q,sBAAA,CAAiDC,QAAS,CAACxN,CAAD,CAAQ,CAG1DA,CAAAsI,OAAJ,GAAqB,IAAAnS,SAAA8P,cAArB,GAKAjG,CAAA5I,eAAA,EAOA,CANIqW,CAMJ,CANe,IAAIlF,UAAJ,CAAe,WAAf,CAA4B,CACvCD,OAAQtI,CAAAsI,OAD+B,CAEvCoF,QAAS1N,CAAA0N,QAF8B,CAGvCC,QAAS3N,CAAA2N,QAH8B,CAIvCC,QAAS,IAAAzX,SAAAmR,sBAAA,EAAAuG,EAJ8B,CAA5B,CAMf;AAAA,IAAA1X,SAAAoF,cAAA,CAA4BkS,CAA5B,CAZA,CAH8D,CAsBlEhB,EAAA/P,UAAA0Q,mBAAA,CAA8CU,QAAS,EAAG,CAEtD,IAAIC,GAAY,IAAA5X,SAAA6X,MAAZD,CAAkC,IAAA5X,SAAA8X,IAAlCF,GAAwD,IAAA5X,SAAAoJ,IAAxDwO,CAA4E,IAAA5X,SAAA8X,IAA5EF,CACa,EAAjB,GAAIA,CAAJ,CACI,IAAA5X,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA2W,gBAA5B,CADJ,CAGI,IAAA9W,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA2W,gBAA/B,CAEC,KAAAP,MAAL,GACI,IAAAwB,iBAAA1G,MAAA2G,KAGA,CAHmCJ,CAGnC,CAFA,IAAAG,iBAAA1G,MAAA4G,WAEA,CAFyCL,CAEzC,CADA,IAAAM,iBAAA7G,MAAA2G,KACA,CADmC,CACnC,CADuCJ,CACvC,CAAA,IAAAM,iBAAA7G,MAAA4G,WAAA,CAAyC,CAAzC,CAA6CL,CAJjD,CARsD,CAqB1DtB,EAAA/P,UAAAwD,QAAA,CAAmCoO,QAAS,EAAG,CAC3C,IAAAnY,SAAAiK,SAAA;AAAyB,CAAA,CADkB,CAG/CqM,EAAA/P,UAAA,QAAA,CAAsC+P,CAAA/P,UAAAwD,QAMtCuM,EAAA/P,UAAA2D,OAAA,CAAkCkO,QAAS,EAAG,CAC1C,IAAApY,SAAAiK,SAAA,CAAyB,CAAA,CADiB,CAG9CqM,EAAA/P,UAAA,OAAA,CAAqC+P,CAAA/P,UAAA2D,OAOrCoM,EAAA/P,UAAA8R,OAAA,CAAkCC,QAAS,CAACT,CAAD,CAAQ,CAC1B,WAArB,GAAI,MAAOA,EAAX,GACI,IAAA7X,SAAA6X,MADJ,CAC0BA,CAD1B,CAGA,KAAAZ,mBAAA,EAJ+C,CAMnDX,EAAA/P,UAAA,OAAA,CAAqC+P,CAAA/P,UAAA8R,OAIrC/B,EAAA/P,UAAAiD,KAAA,CAAgC+O,QAAS,EAAG,CACxC,GAAI,IAAAvY,SAAJ,CAAmB,CACf,GAAI,IAAAuW,MAAJ,CAAgB,CAIZ,IAAIiC,EAAclY,QAAAC,cAAA,CAAuB,KAAvB,CAClBiY,EAAAvY,UAAAO,IAAA,CAA0B,IAAAL,YAAAsW,aAA1B,CACA,KAAAzW,SAAA8P,cAAAC,aAAA,CAAyCyI,CAAzC,CAAsD,IAAAxY,SAAtD,CACA,KAAAA,SAAA8P,cAAAE,YAAA,CAAwC,IAAAhQ,SAAxC,CACAwY;CAAA5X,YAAA,CAAwB,IAAAZ,SAAxB,CARY,CAAhB,IASO,CAIC6P,CAAAA,CAAYvP,QAAAC,cAAA,CAAuB,KAAvB,CAChBsP,EAAA5P,UAAAO,IAAA,CAAwB,IAAAL,YAAAuW,iBAAxB,CACA,KAAA1W,SAAA8P,cAAAC,aAAA,CAAyCF,CAAzC,CAAoD,IAAA7P,SAApD,CACA,KAAAA,SAAA8P,cAAAE,YAAA,CAAwC,IAAAhQ,SAAxC,CACA6P,EAAAjP,YAAA,CAAsB,IAAAZ,SAAtB,CACA,KAAIyY,EAAiBnY,QAAAC,cAAA,CAAuB,KAAvB,CACrBkY,EAAAxY,UAAAO,IAAA,CAA6B,IAAAL,YAAAwW,gBAA7B,CACA9G,EAAAjP,YAAA,CAAsB6X,CAAtB,CACA,KAAAV,iBAAA,CAAwBzX,QAAAC,cAAA,CAAuB,KAAvB,CACxB,KAAAwX,iBAAA9X,UAAAO,IAAA,CAAoC,IAAAL,YAAAyW,iBAApC,CACA6B,EAAA7X,YAAA,CAA2B,IAAAmX,iBAA3B,CACA;IAAAG,iBAAA,CAAwB5X,QAAAC,cAAA,CAAuB,KAAvB,CACxB,KAAA2X,iBAAAjY,UAAAO,IAAA,CAAoC,IAAAL,YAAA0W,iBAApC,CACA4B,EAAA7X,YAAA,CAA2B,IAAAsX,iBAA3B,CAjBG,CAmBP,IAAAQ,kBAAA,CAAyB,IAAA3B,SAAAxM,KAAA,CAAmB,IAAnB,CACzB,KAAAoO,mBAAA,CAA0B,IAAAtN,UAAAd,KAAA,CAAoB,IAApB,CAC1B,KAAAqO,oBAAA,CAA2B,IAAA/M,WAAAtB,KAAA,CAAqB,IAArB,CAC3B,KAAAsO,+BAAA,CAAsC,IAAAzB,sBAAA7M,KAAA,CAAgC,IAAhC,CACtC,KAAAvK,SAAAa,iBAAA,CAA+B,OAA/B,CAAwC,IAAA6X,kBAAxC,CACA,KAAA1Y,SAAAa,iBAAA,CAA+B,QAA/B,CAAyC,IAAA8X,mBAAzC,CACA;IAAA3Y,SAAAa,iBAAA,CAA+B,SAA/B,CAA0C,IAAA+X,oBAA1C,CACA,KAAA5Y,SAAA8P,cAAAjP,iBAAA,CAA6C,WAA7C,CAA0D,IAAAgY,+BAA1D,CACA,KAAA5B,mBAAA,EACA,KAAAjX,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAiL,YAA5B,CAtCe,CADqB,CA4C5C9I,EAAAY,SAAA,CAA0B,CACtBqE,YAAa+O,CADS,CAEtBrP,cAAe,gBAFO,CAGtBrC,SAAU,eAHY,CAItBsB,OAAQ,CAAA,CAJc,CAA1B,CA6BI4S,EAAAA,CAAmBA,QAAyB,CAACnW,CAAD,CAAU,CACtD,IAAA3C,SAAA,CAAgB2C,CAChB,KAAAoW,aAAA,CAAoB,IAAA/Y,SAAAqB,cAAA,CAA4B,GAA5B,CAAkC,IAAA2X,YAAAC,QAAlC,CACpB,KAAAC,eAAA,CAAsB,IAAAlZ,SAAAqB,cAAA,CAA4B,GAA5B,CAAkC,IAAA2X,YAAAG,OAAlC,CACtB;GAAKJ,CAAA,IAAAA,aAAL,CACI,KAAU7T,MAAJ,CAAU,iDAAV,CAAN,CAEJ,GAAKgU,CAAA,IAAAA,eAAL,CACI,KAAUhU,MAAJ,CAAU,iDAAV,CAAN,CAEJ,IAAAkU,OAAA,CAAc,CAAA,CAGd,KAAAC,YAAA,CADA,IAAAC,SACA,CAFA,IAAAC,eAEA,CAFsBC,IAAAA,EAGtB,KAAAC,qBAAA,CAA4B,EAC5B,KAAAC,iBAAA,CAAsB,CAAA,CAAtB,CAfsD,CAiB1DpV,OAAA,iBAAA,CAA6BwU,CAO7BA,EAAAvS,UAAAkD,UAAA,CAAuC,CAEnCkQ,iBAAkB,GAFiB,CAYvCb,EAAAvS,UAAAyS,YAAA,CAAyC,CACrCY,SAAU,cAD2B,CAErCX,QAAS,oBAF4B,CAGrCE,OAAQ,sBAH6B,CAIrCU,OAAQ,sBAJ6B,CAWzCf;CAAAvS,UAAAuT,iBAAA,CAA8CC,QAAS,EAAG,CACtD,IAAA/Z,SAAA0F,aAAA,CAA2B,aAA3B,CAA0C,MAA1C,CACI,KAAA6T,eAAJ,GACI,IAAAL,eAAAc,YAEA,CAFkC,IAAAX,YAElC,CADA,IAAAH,eAAArY,iBAAA,CAAqC,OAArC,CAA8C,IAAA0Y,eAA9C,CACA,CAAA,IAAAG,iBAAA,CAAsB,CAAA,CAAtB,CAHJ,CAKA,KAAAX,aAAAiB,YAAA,CAAgC,IAAAV,SAChC,KAAAtZ,SAAAC,UAAAO,IAAA,CAA4B,IAAAwY,YAAAa,OAA5B,CACA,KAAA7Z,SAAA0F,aAAA,CAA2B,aAA3B,CAA0C,OAA1C,CACA2D,WAAA,CAAW,IAAA4Q,SAAA1P,KAAA,CAAmB,IAAnB,CAAX,CAAqC,IAAA2P,SAArC,CAVsD,CAkB1DpB,EAAAvS,UAAA4T,aAAA,CAA0CC,QAAS,CAACC,CAAD,CAAO,CACtD,GAAab,IAAAA,EAAb;AAAIa,CAAJ,CACI,KAAUnV,MAAJ,CAAU,kEAAV,CAAN,CAEJ,GAAwBsU,IAAAA,EAAxB,GAAIa,CAAA,QAAJ,CACI,KAAUnV,MAAJ,CAAU,2CAAV,CAAN,CAEJ,GAAImV,CAAA,cAAJ,EAA8B,CAAAA,CAAA,WAA9B,CACI,KAAUnV,MAAJ,CAAU,8CAAV,CAAN,CAEA,IAAAkU,OAAJ,CACI,IAAAK,qBAAAlU,KAAA,CAA+B8U,CAA/B,CADJ,EAGI,IAAAjB,OAaA,CAbc,CAAA,CAad,CAZA,IAAAE,SAYA,CAZgBe,CAAA,QAYhB,CAVI,IAAAH,SAUJ,CAXIG,CAAA,QAAJ,CACoBA,CAAA,QADpB,CAGoB,IAQpB,CANIA,CAAA,cAMJ,GALI,IAAAd,eAKJ,CAL0Bc,CAAA,cAK1B,EAHIA,CAAA,WAGJ,GAFI,IAAAhB,YAEJ,CAFuBgB,CAAA,WAEvB,EAAA,IAAAP,iBAAA,EAhBJ,CAVsD,CA6B1DhB;CAAAvS,UAAA,aAAA,CAA6CuS,CAAAvS,UAAA4T,aAO7CrB,EAAAvS,UAAA+T,YAAA,CAAyCC,QAAS,EAAG,CACV,CAAvC,CAAI,IAAAd,qBAAA9V,OAAJ,EACI,IAAAwW,aAAA,CAAkB,IAAAV,qBAAAe,MAAA,EAAlB,CAF6C,CAUrD1B,EAAAvS,UAAA0T,SAAA,CAAsCQ,QAAS,EAAG,CAC9C,IAAAza,SAAAC,UAAA2L,OAAA,CAA+B,IAAAoN,YAAAa,OAA/B,CACAxQ,WAAA,CAAW,QAAS,EAAG,CACnB,IAAArJ,SAAA0F,aAAA,CAA2B,aAA3B,CAA0C,MAA1C,CACA,KAAAqT,aAAAiB,YAAA,CAAgC,EACnB,KAAAd,eAAAnY,aAAA,CAAiC,aAAjC,CAAb,GACI,IAAA2Y,iBAAA,CAAsB,CAAA,CAAtB,CAEA,CADA,IAAAR,eAAAc,YACA,CADkC,EAClC,CAAA,IAAAd,eAAAzF,oBAAA,CAAwC,OAAxC;AAAiD,IAAA8F,eAAjD,CAHJ,CAOA,KAAAF,YAAA,CADA,IAAAC,SACA,CAFA,IAAAC,eAEA,CAFsBC,IAAAA,EAGtB,KAAAJ,OAAA,CAAc,CAAA,CACd,KAAAkB,YAAA,EAZmB,CAAZ/P,KAAA,CAaJ,IAbI,CAAX,CAac,IAAAd,UAAAkQ,iBAbd,CAF8C,CAuBlDb,EAAAvS,UAAAmT,iBAAA,CAA8CgB,QAAS,CAAC7C,CAAD,CAAQ,CACvDA,CAAJ,CACI,IAAAqB,eAAAxT,aAAA,CAAiC,aAAjC,CAAgD,MAAhD,CADJ,CAGI,IAAAwT,eAAAyB,gBAAA,CAAoC,aAApC,CAJuD,CAS/DrY,EAAAY,SAAA,CAA0B,CACtBqE,YAAauR,CADS,CAEtB7R,cAAe,kBAFO,CAGtBrC,SAAU,iBAHY,CAItBsB,OAAQ,CAAA,CAJc,CAA1B,CA8BI0U,EAAAA,CAAkBA,QAAwB,CAACjY,CAAD,CAAU,CACpD,IAAA3C,SAAA,CAAgB2C,CAEhB,KAAA6G,KAAA,EAHoD,CAKxDlF,OAAA,gBAAA,CAA4BsW,CAO5BA,EAAArU,UAAAkD,UAAA,CAAsC,CAAEoR,wBAAyB,CAA3B,CAStCD;CAAArU,UAAApG,YAAA,CAAwC,CACpC2a,kBAAmB,oBADiB,CAEpCC,2BAA4B,6BAFQ,CAGpCC,mBAAoB,qBAHgB,CAIpCC,sBAAuB,wBAJa,CAKpCC,iBAAkB,mBALkB,CAMpCC,kBAAmB,oBANiB,CAcxCP,EAAArU,UAAA6U,YAAA,CAAwCC,QAAS,CAACC,CAAD,CAAQ,CACrD,IAAIC,EAAQjb,QAAAC,cAAA,CAAuB,KAAvB,CACZgb,EAAAtb,UAAAO,IAAA,CAAoB,IAAAL,YAAA2a,kBAApB,CACAS,EAAAtb,UAAAO,IAAA,CAAoB,IAAAL,YAAA2a,kBAApB,CAAyD,GAAzD,CAA+DQ,CAA/D,CACIE,EAAAA,CAAclb,QAAAC,cAAA,CAAuB,KAAvB,CAClBib,EAAAvb,UAAAO,IAAA,CAA0B,IAAAL,YAAA4a,2BAA1B,CACAS;CAAAvb,UAAAO,IAAA,CAA0B,IAAAL,YAAA+a,iBAA1B,CACA,KAAIO,EAAWnb,QAAAC,cAAA,CAAuB,KAAvB,CACfkb,EAAAxb,UAAAO,IAAA,CAAuB,IAAAL,YAAA8a,sBAAvB,CACA,KAAIS,EAAepb,QAAAC,cAAA,CAAuB,KAAvB,CACnBmb,EAAAzb,UAAAO,IAAA,CAA2B,IAAAL,YAAA4a,2BAA3B,CACAW,EAAAzb,UAAAO,IAAA,CAA2B,IAAAL,YAAAgb,kBAA3B,CAMA,KALA,IAAIQ,EAAe,CACfH,CADe,CAEfC,CAFe,CAGfC,CAHe,CAAnB,CAKSjY,EAAI,CAAb,CAAgBA,CAAhB,CAAoBkY,CAAAhY,OAApB,CAAyCF,CAAA,EAAzC,CAA8C,CAC1C,IAAImY,EAAStb,QAAAC,cAAA,CAAuB,KAAvB,CACbqb,EAAA3b,UAAAO,IAAA,CAAqB,IAAAL,YAAA6a,mBAArB,CACAW,EAAA,CAAalY,CAAb,CAAA7C,YAAA,CAA4Bgb,CAA5B,CAH0C,CAK9CL,CAAA3a,YAAA,CAAkB4a,CAAlB,CACAD,EAAA3a,YAAA,CAAkB6a,CAAlB,CACAF,EAAA3a,YAAA,CAAkB8a,CAAlB,CACA,KAAA1b,SAAAY,YAAA,CAA0B2a,CAA1B,CAzBqD,CA2BzDX;CAAArU,UAAA,YAAA,CAA2CqU,CAAArU,UAAA6U,YAO3CR,EAAArU,UAAAsV,KAAA,CAAiCC,QAAS,EAAG,CACzC,IAAA9b,SAAAC,UAAA2L,OAAA,CAA+B,WAA/B,CADyC,CAG7CgP,EAAArU,UAAA,KAAA,CAAoCqU,CAAArU,UAAAsV,KAQpCjB,EAAArU,UAAAwV,MAAA,CAAkCC,QAAS,EAAG,CAC1C,IAAAhc,SAAAC,UAAAO,IAAA,CAA4B,WAA5B,CAD0C,CAG9Coa,EAAArU,UAAA,MAAA,CAAqCqU,CAAArU,UAAAwV,MAIrCnB,EAAArU,UAAAiD,KAAA,CAAiCyS,QAAS,EAAG,CACzC,GAAI,IAAAjc,SAAJ,CAAmB,CACf,IAAK,IAAIyD,EAAI,CAAb,CAAgBA,CAAhB,EAAqB,IAAAgG,UAAAoR,wBAArB,CAA6DpX,CAAA,EAA7D,CACI,IAAA2X,YAAA,CAAiB3X,CAAjB,CAEJ,KAAAzD,SAAAC,UAAAO,IAAA,CAA4B,aAA5B,CAJe,CADsB,CAU7C8B,EAAAY,SAAA,CAA0B,CACtBqE,YAAaqT,CADS,CAEtB3T,cAAe,iBAFO,CAGtBrC,SAAU,gBAHY;AAItBsB,OAAQ,CAAA,CAJc,CAA1B,CA8BIgW,EAAAA,CAAiBA,QAAuB,CAACvZ,CAAD,CAAU,CAClD,IAAA3C,SAAA,CAAgB2C,CAEhB,KAAA6G,KAAA,EAHkD,CAKtDlF,OAAA,eAAA,CAA2B4X,CAO3BA,EAAA3V,UAAAkD,UAAA,CAAqC,CAAEiB,aAAc,IAAhB,CASrCwR,EAAA3V,UAAApG,YAAA,CAAuC,CACnCwK,MAAO,mBAD4B,CAEnCwR,MAAO,mBAF4B,CAGnCC,MAAO,mBAH4B,CAInCvR,aAAc,0BAJqB,CAKnCnB,cAAe,sBALoB,CAMnCqB,qBAAsB,qCANa,CAOnC7I,iBAAkB,8BAPiB,CAQnC8I,cAAe,oBARoB,CASnC7I,OAAQ,YAT2B,CAUnC8I,WAAY,YAVuB,CAWnCC,YAAa,aAXsB;AAYnCC,WAAY,YAZuB,CAoBvC+Q,EAAA3V,UAAA8E,UAAA,CAAqCgR,QAAS,CAACxS,CAAD,CAAQ,CAClD,IAAA0B,eAAA,EADkD,CAStD2Q,EAAA3V,UAAAiF,SAAA,CAAoC8Q,QAAS,CAACzS,CAAD,CAAQ,CACjD,IAAA7J,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA8K,WAA5B,CADiD,CASrDiR,EAAA3V,UAAAmF,QAAA,CAAmC6Q,QAAS,CAAC1S,CAAD,CAAQ,CAChD,IAAA7J,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA8K,WAA/B,CADgD,CASpDiR,EAAA3V,UAAAsF,WAAA,CAAsC2Q,QAAS,CAAC3S,CAAD,CAAQ,CACnD,IAAAkC,MAAA,EADmD,CAQvDmQ,EAAA3V,UAAAgF,eAAA,CAA0CkR,QAAS,EAAG,CAClD,IAAAxQ,cAAA,EACA,KAAAC,iBAAA,EAFkD,CAStDgQ,EAAA3V,UAAAwF,MAAA,CAAiC2Q,QAAS,EAAG,CAGzCpY,MAAA+E,WAAA,CAAkB,QAAS,EAAG,CAC1B,IAAA+C,cAAAtC,KAAA,EAD0B,CAAZS,KAAA,CAEX,IAFW,CAAlB,CAEc,IAAAd,UAAAiB,aAFd,CAHyC,CAa7CwR;CAAA3V,UAAA0F,cAAA,CAAyC0Q,QAAS,EAAG,CAC7C,IAAAvQ,cAAAnC,SAAJ,CACI,IAAAjK,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA+K,YAA5B,CADJ,CAGI,IAAAlL,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA+K,YAA/B,CAJ6C,CAOrDgR,EAAA3V,UAAA,cAAA,CAA4C2V,CAAA3V,UAAA0F,cAM5CiQ,EAAA3V,UAAA2F,iBAAA,CAA4C0Q,QAAS,EAAG,CAChD,IAAAxQ,cAAAE,QAAJ,CACI,IAAAtM,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAgL,WAA5B,CADJ,CAGI,IAAAnL,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAAgL,WAA/B,CAJgD,CAOxD+Q,EAAA3V,UAAA,iBAAA,CAA+C2V,CAAA3V,UAAA2F,iBAM/CgQ,EAAA3V,UAAAwD,QAAA,CAAmC8S,QAAS,EAAG,CAC3C,IAAAzQ,cAAAnC,SAAA;AAA8B,CAAA,CAC9B,KAAAsB,eAAA,EAF2C,CAI/C2Q,EAAA3V,UAAA,QAAA,CAAsC2V,CAAA3V,UAAAwD,QAMtCmS,EAAA3V,UAAA2D,OAAA,CAAkC4S,QAAS,EAAG,CAC1C,IAAA1Q,cAAAnC,SAAA,CAA8B,CAAA,CAC9B,KAAAsB,eAAA,EAF0C,CAI9C2Q,EAAA3V,UAAA,OAAA,CAAqC2V,CAAA3V,UAAA2D,OAMrCgS,EAAA3V,UAAAwW,GAAA,CAA8BC,QAAS,EAAG,CACtC,IAAA5Q,cAAAE,QAAA,CAA6B,CAAA,CAC7B,KAAAf,eAAA,EAFsC,CAI1C2Q,EAAA3V,UAAA,GAAA,CAAiC2V,CAAA3V,UAAAwW,GAMjCb,EAAA3V,UAAA0W,IAAA,CAA+BC,QAAS,EAAG,CACvC,IAAA9Q,cAAAE,QAAA,CAA6B,CAAA,CAC7B,KAAAf,eAAA,EAFuC,CAI3C2Q,EAAA3V,UAAA,IAAA,CAAkC2V,CAAA3V,UAAA0W,IAIlCf,EAAA3V,UAAAiD,KAAA,CAAgC2T,QAAS,EAAG,CACxC,GAAI,IAAAnd,SAAJ,CAAmB,CACf,IAAAoM,cAAA,CAAqB,IAAApM,SAAAqB,cAAA,CAA4B,GAA5B;AAAkC,IAAAlB,YAAAwK,MAAlC,CACrB,KAAIyS,EAAQ9c,QAAAC,cAAA,CAAuB,KAAvB,CACZ6c,EAAAnd,UAAAO,IAAA,CAAoB,IAAAL,YAAAgc,MAApB,CACA,KAAIkB,EAAQ/c,QAAAC,cAAA,CAAuB,KAAvB,CACZ8c,EAAApd,UAAAO,IAAA,CAAoB,IAAAL,YAAAic,MAApB,CACA,KAAIkB,EAAchd,QAAAC,cAAA,CAAuB,MAAvB,CAClB+c,EAAArd,UAAAO,IAAA,CAA0B,IAAAL,YAAA0K,aAA1B,CACAwS,EAAAzc,YAAA,CAAkB0c,CAAlB,CACA,KAAAtd,SAAAY,YAAA,CAA0Bwc,CAA1B,CACA,KAAApd,SAAAY,YAAA,CAA0Byc,CAA1B,CACA,KAAAzE,oBAAA,CAA2B,IAAA/M,WAAAtB,KAAA,CAAqB,IAArB,CACvB,KAAAvK,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAuJ,cAAjC,CAAJ,GACI,IAAA1J,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA4K,qBAA5B,CASA;AARA,IAAAmC,wBAQA,CAR+B5M,QAAAC,cAAA,CAAuB,MAAvB,CAQ/B,CAPA,IAAA2M,wBAAAjN,UAAAO,IAAA,CAA2C,IAAAL,YAAA+B,iBAA3C,CAOA,CANA,IAAAgL,wBAAAjN,UAAAO,IAAA,CAA2C,IAAAL,YAAAuJ,cAA3C,CAMA,CALA,IAAAwD,wBAAAjN,UAAAO,IAAA,CAA2C,IAAAL,YAAA6K,cAA3C,CAKA,CAJA,IAAAkC,wBAAArM,iBAAA,CAA8C,SAA9C,CAAyD,IAAA+X,oBAAzD,CAIA,CAHIlY,CAGJ,CAHaJ,QAAAC,cAAA,CAAuB,MAAvB,CAGb,CAFAG,CAAAT,UAAAO,IAAA,CAAqB,IAAAL,YAAAgC,OAArB,CAEA,CADA,IAAA+K,wBAAAtM,YAAA,CAAyCF,CAAzC,CACA,CAAA,IAAAV,SAAAY,YAAA,CAA0B,IAAAsM,wBAA1B,CAVJ,CAYA;IAAAyL,mBAAA,CAA0B,IAAAtN,UAAAd,KAAA,CAAoB,IAApB,CAC1B,KAAAgT,kBAAA,CAAyB,IAAA/R,SAAAjB,KAAA,CAAmB,IAAnB,CACzB,KAAAiT,iBAAA,CAAwB,IAAA9R,QAAAnB,KAAA,CAAkB,IAAlB,CACxB,KAAA6B,cAAAvL,iBAAA,CAAoC,QAApC,CAA8C,IAAA8X,mBAA9C,CACA,KAAAvM,cAAAvL,iBAAA,CAAoC,OAApC,CAA6C,IAAA0c,kBAA7C,CACA,KAAAnR,cAAAvL,iBAAA,CAAoC,MAApC,CAA4C,IAAA2c,iBAA5C,CACA,KAAAxd,SAAAa,iBAAA,CAA+B,SAA/B,CAA0C,IAAA+X,oBAA1C,CACA,KAAArN,eAAA,EACA,KAAAvL,SAAAC,UAAAO,IAAA,CAA4B,aAA5B,CAhCe,CADqB,CAsC5C8B,EAAAY,SAAA,CAA0B,CACtBqE,YAAa2U,CADS;AAEtBjV,cAAe,gBAFO,CAGtBrC,SAAU,eAHY,CAItBsB,OAAQ,CAAA,CAJc,CAA1B,CA8BIuX,EAAAA,CAAeA,QAAqB,CAAC9a,CAAD,CAAU,CAE9C,IAAA3C,SAAA,CAAgB2C,CAEhB,KAAA6G,KAAA,EAJ8C,CAMlDlF,OAAA,aAAA,CAAyBmZ,CAOzBA,EAAAlX,UAAAkD,UAAA,CAAmC,EASnCgU,EAAAlX,UAAApG,YAAA,CAAqC,CACjCud,UAAW,eADsB,CAEjCC,YAAa,iBAFoB,CAGjCnc,aAAc,WAHmB,CAIjCoc,eAAgB,aAJiB,CAKjCxd,qBAAsB,sBALW,CAMjCK,qBAAsB,4BANW,CAOjCE,WAAY,YAPqB,CAQjCkd,mCAAoC,qCARH,CAerCJ,EAAAlX,UAAAuX,UAAA;AAAmCC,QAAS,EAAG,CACvC,IAAA/d,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAC,qBAAjC,CAAJ,EACI,IAAAJ,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA0d,mCAA5B,CAGJ,KAAAG,MAAA,CAAa,IAAAhe,SAAA8E,iBAAA,CAA+B,GAA/B,CAAqC,IAAA3E,YAAAud,UAArC,CACb,KAAAO,QAAA,CAAe,IAAAje,SAAA8E,iBAAA,CAA+B,GAA/B,CAAqC,IAAA3E,YAAAwd,YAArC,CAEf,KAAK,IAAIla,EAAI,CAAb,CAAgBA,CAAhB,CAAoB,IAAAua,MAAAra,OAApB,CAAuCF,CAAA,EAAvC,CACI,IAAI5D,CAAJ,CAAgB,IAAAme,MAAA,CAAWva,CAAX,CAAhB,CAA+B,IAA/B,CAEJ,KAAAzD,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAyd,eAA5B,CAX2C,CAkB/CH,EAAAlX,UAAAjF,eAAA,CAAwC4c,QAAS,EAAG,CAChD,IAAK,IAAIC,EAAI,CAAb,CAAgBA,CAAhB,CAAoB,IAAAH,MAAAra,OAApB,CAAuCwa,CAAA,EAAvC,CACI,IAAAH,MAAA,CAAWG,CAAX,CAAAle,UAAA2L,OAAA,CAA+B,IAAAzL,YAAAqB,aAA/B,CAF4C,CAUpDic;CAAAlX,UAAAhF,iBAAA,CAA0C6c,QAAS,EAAG,CAClD,IAAK,IAAIrY,EAAI,CAAb,CAAgBA,CAAhB,CAAoB,IAAAkY,QAAAta,OAApB,CAAyCoC,CAAA,EAAzC,CACI,IAAAkY,QAAA,CAAalY,CAAb,CAAA9F,UAAA2L,OAAA,CAAiC,IAAAzL,YAAAqB,aAAjC,CAF8C,CAQtDic,EAAAlX,UAAAiD,KAAA,CAA8B6U,QAAS,EAAG,CAClC,IAAAre,SAAJ,EACI,IAAA8d,UAAA,EAFkC,CAsC1Cxb,EAAAY,SAAA,CAA0B,CACtBqE,YAAakW,CADS,CAEtBxW,cAAe,cAFO,CAGtBrC,SAAU,aAHY,CAA1B,CA6BI0Z,EAAAA,CAAoBA,QAA0B,CAAC3b,CAAD,CAAU,CACxD,IAAA3C,SAAA,CAAgB2C,CAChB,KAAA4b,QAAA,CAAe,IAAA9U,UAAA+U,YAEf,KAAAhV,KAAA,EAJwD,CAM5DlF,OAAA,kBAAA,CAA8Bga,CAO9BA,EAAA/X,UAAAkD,UAAA,CAAwC,CACpC+U,YAAc,EADsB,CAEpCC,mBAAoB,SAFgB,CAYxCH,EAAA/X,UAAApG,YAAA,CAA0C,CACtCue,MAAO,sBAD+B;AAEtC/T,MAAO,sBAF+B,CAGtCgU,SAAU,UAH4B,CAItC1T,WAAY,YAJ0B,CAKtCC,YAAa,aALyB,CAMtC0T,WAAY,YAN0B,CAOtCxT,YAAa,aAPyB,CAQtCyT,gBAAiB,iBARqB,CAgB1CP,EAAA/X,UAAAuY,WAAA,CAAyCC,QAAS,CAAClV,CAAD,CAAQ,CACtD,IAAImV,EAAkBnV,CAAAsI,OAAA0F,MAAA1W,MAAA,CAAyB,IAAzB,CAAAwC,OACA,GAAtB,GAAIkG,CAAAkI,QAAJ,EACQiN,CADR,EAC2B,IAAAT,QAD3B,EAEQ1U,CAAA5I,eAAA,EAJ8C,CAc1Dqd,EAAA/X,UAAAiF,SAAA,CAAuCyT,QAAS,CAACpV,CAAD,CAAQ,CACpD,IAAA7J,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA8K,WAA5B,CADoD,CASxDqT,EAAA/X,UAAAmF,QAAA,CAAsCwT,QAAS,CAACrV,CAAD,CAAQ,CACnD,IAAA7J,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA8K,WAA/B,CADmD,CASvDqT,EAAA/X,UAAA4Y,SAAA;AAAuCC,QAAS,CAACvV,CAAD,CAAQ,CACpD,IAAA0B,eAAA,EADoD,CAQxD+S,EAAA/X,UAAAgF,eAAA,CAA6C8T,QAAS,EAAG,CACrD,IAAApT,cAAA,EACA,KAAAqT,cAAA,EACA,KAAAC,WAAA,EACA,KAAAC,WAAA,EAJqD,CAYzDlB,EAAA/X,UAAA0F,cAAA,CAA4CwT,QAAS,EAAG,CAChD,IAAAC,OAAAzV,SAAJ,CACI,IAAAjK,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA+K,YAA5B,CADJ,CAGI,IAAAlL,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA+K,YAA/B,CAJgD,CAOxDoT,EAAA/X,UAAA,cAAA,CAA+C+X,CAAA/X,UAAA0F,cAM/CqS,EAAA/X,UAAAiZ,WAAA,CAAyCG,QAAS,EAAG,CACrC,IAAA3f,SAAAqB,cAAA,CAA4B,QAA5B,CAAZ,CACI,IAAArB,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA8K,WAA5B,CADJ;AAGI,IAAAjL,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA8K,WAA/B,CAJ6C,CAOrDqT,EAAA/X,UAAA,WAAA,CAA4C+X,CAAA/X,UAAAiZ,WAM5ClB,EAAA/X,UAAA+Y,cAAA,CAA4CM,QAAS,EAAG,CAChD,IAAAF,OAAAG,SAAJ,GACQ,IAAAH,OAAAG,SAAAC,MAAJ,CACI,IAAA9f,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAAye,WAA/B,CADJ,CAGI,IAAA5e,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAye,WAA5B,CAJR,CADoD,CASxDN,EAAA/X,UAAA,cAAA,CAA+C+X,CAAA/X,UAAA+Y,cAM/ChB,EAAA/X,UAAAgZ,WAAA,CAAyCQ,QAAS,EAAG,CAC7C,IAAAL,OAAA7H,MAAJ,EAAoD,CAApD,CAAyB,IAAA6H,OAAA7H,MAAAlU,OAAzB,CACI,IAAA3D,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAwe,SAA5B,CADJ,CAGI,IAAA3e,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAAwe,SAA/B,CAJ6C,CAOrDL;CAAA/X,UAAA,WAAA,CAA4C+X,CAAA/X,UAAAgZ,WAM5CjB,EAAA/X,UAAAwD,QAAA,CAAsCiW,QAAS,EAAG,CAC9C,IAAAN,OAAAzV,SAAA,CAAuB,CAAA,CACvB,KAAAsB,eAAA,EAF8C,CAIlD+S,EAAA/X,UAAA,QAAA,CAAyC+X,CAAA/X,UAAAwD,QAMzCuU,EAAA/X,UAAA2D,OAAA,CAAqC+V,QAAS,EAAG,CAC7C,IAAAP,OAAAzV,SAAA,CAAuB,CAAA,CACvB,KAAAsB,eAAA,EAF6C,CAIjD+S,EAAA/X,UAAA,OAAA,CAAwC+X,CAAA/X,UAAA2D,OAOxCoU,EAAA/X,UAAA8R,OAAA,CAAqC6H,QAAS,CAACrI,CAAD,CAAQ,CAClD,IAAA6H,OAAA7H,MAAA,CAAoBA,CAApB,EAA6B,EAC7B,KAAAtM,eAAA,EAFkD,CAItD+S,EAAA/X,UAAA,OAAA,CAAwC+X,CAAA/X,UAAA8R,OAIxCiG,EAAA/X,UAAAiD,KAAA,CAAmC2W,QAAS,EAAG,CAC3C,GAAI,IAAAngB,SAAJ,GACI,IAAAogB,OACAV,CADc,IAAA1f,SAAAqB,cAAA,CAA4B,GAA5B,CAAkC,IAAAlB,YAAAue,MAAlC,CACdgB;AAAA,IAAAA,OAAAA,CAAc,IAAA1f,SAAAqB,cAAA,CAA4B,GAA5B,CAAkC,IAAAlB,YAAAwK,MAAlC,CAFlB,EAGqB,CACT,IAAA+U,OAAAlN,aAAA,CAAyB,IAAA/I,UAAAgV,mBAAzB,CAAJ,GACI,IAAAF,QACA,CADe8B,QAAA,CAAS,IAAAX,OAAA3e,aAAA,CAAyB,IAAA0I,UAAAgV,mBAAzB,CAAT,CAAsE,EAAtE,CACf,CAAI6B,KAAA,CAAM,IAAA/B,QAAN,CAAJ,GACI,IAAAA,QADJ,CACmB,IAAA9U,UAAA+U,YADnB,CAFJ,CAMI,KAAAkB,OAAAlN,aAAA,CAAyB,aAAzB,CAAJ,EACI,IAAAxS,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA0e,gBAA5B,CAEJ,KAAA0B,0BAAA,CAAiC,IAAAhV,eAAAhB,KAAA,CAAyB,IAAzB,CACjC,KAAAgT,kBAAA,CAAyB,IAAA/R,SAAAjB,KAAA,CAAmB,IAAnB,CACzB,KAAAiT,iBAAA;AAAwB,IAAA9R,QAAAnB,KAAA,CAAkB,IAAlB,CACxB,KAAAiW,kBAAA,CAAyB,IAAArB,SAAA5U,KAAA,CAAmB,IAAnB,CACzB,KAAAmV,OAAA7e,iBAAA,CAA6B,OAA7B,CAAsC,IAAA0f,0BAAtC,CACA,KAAAb,OAAA7e,iBAAA,CAA6B,OAA7B,CAAsC,IAAA0c,kBAAtC,CACA,KAAAmC,OAAA7e,iBAAA,CAA6B,MAA7B,CAAqC,IAAA2c,iBAArC,CACA,KAAAkC,OAAA7e,iBAAA,CAA6B,OAA7B,CAAsC,IAAA2f,kBAAtC,CACI,KAAAjC,QAAJ,GAAqB,IAAA9U,UAAA+U,YAArB,GAGI,IAAAiC,oBACA,CAD2B,IAAA3B,WAAAvU,KAAA,CAAqB,IAArB,CAC3B,CAAA,IAAAmV,OAAA7e,iBAAA,CAA6B,SAA7B,CAAwC,IAAA4f,oBAAxC,CAJJ,CAMA,KAAIC,EAAU,IAAA1gB,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAye,WAAjC,CACd;IAAArT,eAAA,EACA,KAAAvL,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAiL,YAA5B,CACIsV,EAAJ,EACI,IAAA1gB,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAye,WAA5B,CAEA,KAAAc,OAAAlN,aAAA,CAAyB,WAAzB,CAAJ,GACI,IAAAxS,SAAAgS,MAAA,EACA,CAAA,IAAAwN,WAAA,EAFJ,CA9Ba,CAJsB,CA2C/Cld,EAAAY,SAAA,CAA0B,CACtBqE,YAAa+W,CADS,CAEtBrX,cAAe,mBAFO,CAGtBrC,SAAU,kBAHY,CAItBsB,OAAQ,CAAA,CAJc,CAA1B,CA8BIya,EAAAA,CAAkBA,QAAwB,CAAChe,CAAD,CAAU,CACpD,IAAA3C,SAAA,CAAgB2C,CAEhB,KAAA6G,KAAA,EAHoD,CAKxDlF,OAAA,gBAAA,CAA4Bqc,CAO5BA,EAAApa,UAAAkD,UAAA,CAAsC,EAStCkX,EAAApa,UAAApG,YAAA,CAAwC,CACpC4B,UAAW,WADyB,CAEpC6e,OAAQ,qBAF4B,CAGpCC,KAAM,mBAH8B;AAIpCC,MAAO,oBAJ6B,CAKpCC,IAAK,kBAL+B,CAaxCJ,EAAApa,UAAAya,kBAAA,CAA8CC,QAAS,CAACpX,CAAD,CAAQ,CACvDqX,CAAAA,CAAQrX,CAAAsI,OAAAhB,sBAAA,EACZ,KAAIO,EAAOwP,CAAAxP,KAAPA,CAAoBwP,CAAApO,MAApBpB,CAAkC,CAAtC,CACIH,EAAM2P,CAAA3P,IAANA,CAAkB2P,CAAArO,OAAlBtB,CAAiC,CADrC,CAEI4P,EAAmB,IAAAnhB,SAAAohB,YAAnBD,CAA+C,CAA/CA,CAAc,EAFlB,CAGIE,EAAkB,IAAArhB,SAAAyR,aAAlB4P,CAA+C,CAA/CA,CAAa,EACb,KAAArhB,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAA0gB,KAAjC,CAAJ,EAA+D,IAAA7gB,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAA2gB,MAAjC,CAA/D,CAE0B,CAAtB,CAAIvP,CAAJ,CAAU8P,CAAV,EACI,IAAArhB,SAAAqR,MAAAE,IACA,CAD0B,GAC1B,CAAA,IAAAvR,SAAAqR,MAAAgQ,UAAA,CAAgC,GAFpC,GAII,IAAArhB,SAAAqR,MAAAE,IACA,CAD0BA,CAC1B,CADgC,IAChC,CAAA,IAAAvR,SAAAqR,MAAAgQ,UAAA,CAAgCA,CAAhC,CAA4C,IALhD,CAFJ,CAU4B,CAAxB,CAAI3P,CAAJ,CAAWyP,CAAX,EACI,IAAAnhB,SAAAqR,MAAAK,KACA;AAD2B,GAC3B,CAAA,IAAA1R,SAAAqR,MAAA8P,WAAA,CAAiC,GAFrC,GAII,IAAAnhB,SAAAqR,MAAAK,KACA,CAD2BA,CAC3B,CADkC,IAClC,CAAA,IAAA1R,SAAAqR,MAAA8P,WAAA,CAAiCA,CAAjC,CAA8C,IALlD,CAQA,KAAAnhB,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAA4gB,IAAjC,CAAJ,CACI,IAAA/gB,SAAAqR,MAAAE,IADJ,CAC8B2P,CAAA3P,IAD9B,CAC0C,IAAAvR,SAAAyR,aAD1C,CACuE,EADvE,CAC4E,IAD5E,CAEW,IAAAzR,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAA2gB,MAAjC,CAAJ,CACH,IAAA9gB,SAAAqR,MAAAK,KADG,CACwBwP,CAAAxP,KADxB,CACqCwP,CAAApO,MADrC,CACmD,EADnD,CACwD,IADxD,CAEI,IAAA9S,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAA0gB,KAAjC,CAAJ,CACH,IAAA7gB,SAAAqR,MAAAK,KADG,CACwBwP,CAAAxP,KADxB,CACqC,IAAA1R,SAAAohB,YADrC,CACiE,EADjE,CACsE,IADtE,CAGH,IAAAphB,SAAAqR,MAAAE,IAHG,CAGuB2P,CAAA3P,IAHvB,CAGmC2P,CAAArO,OAHnC,CAGkD,EAHlD;AAGuD,IAE9D,KAAA7S,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA4B,UAA5B,CAjC2D,CAwC/D4e,EAAApa,UAAA+a,aAAA,CAAyCC,QAAS,EAAG,CACjD,IAAAvhB,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA4B,UAA/B,CADiD,CAMrD4e,EAAApa,UAAAiD,KAAA,CAAiCgY,QAAS,EAAG,CACzC,GAAI,IAAAxhB,SAAJ,CAAmB,CACf,IAAIoQ,EAAU,IAAApQ,SAAAe,aAAA,CAA2B,KAA3B,CAAVqP,EAA+C,IAAApQ,SAAAe,aAAA,CAA2B,cAA3B,CAC/CqP,EAAJ,GACI,IAAAG,YADJ,CACuBjQ,QAAAgQ,eAAA,CAAwBF,CAAxB,CADvB,CAGI,KAAAG,YAAJ,GAES,IAAAA,YAAAiC,aAAA,CAA8B,UAA9B,CASL,EARI,IAAAjC,YAAA7K,aAAA,CAA8B,UAA9B,CAA0C,GAA1C,CAQJ,CANA,IAAA+b,uBAMA,CAN8B,IAAAT,kBAAAzW,KAAA,CAA4B,IAA5B,CAM9B;AALA,IAAAmX,gCAKA,CALuC,IAAAJ,aAAA/W,KAAA,CAAuB,IAAvB,CAKvC,CAJA,IAAAgG,YAAA1P,iBAAA,CAAkC,YAAlC,CAAgD,IAAA4gB,uBAAhD,CAA6E,CAAA,CAA7E,CAIA,CAHA,IAAAlR,YAAA1P,iBAAA,CAAkC,UAAlC,CAA8C,IAAA4gB,uBAA9C,CAA2E,CAAA,CAA3E,CAGA,CAFA,IAAAlR,YAAA1P,iBAAA,CAAkC,YAAlC,CAAgD,IAAA6gB,gCAAhD,CAAsF,CAAA,CAAtF,CAEA,CADApd,MAAAzD,iBAAA,CAAwB,QAAxB,CAAkC,IAAA6gB,gCAAlC,CAAwE,CAAA,CAAxE,CACA,CAAApd,MAAAzD,iBAAA,CAAwB,YAAxB,CAAsC,IAAA6gB,gCAAtC,CAXJ,CALe,CADsB,CAuB7Cpf,EAAAY,SAAA,CAA0B,CACtBqE,YAAaoZ,CADS,CAEtB1Z,cAAe,iBAFO;AAGtBrC,SAAU,aAHY,CAA1B,CA6BI+c,EAAAA,CAAiBA,QAAuB,CAAChf,CAAD,CAAU,CAClD,IAAA3C,SAAA,CAAgB2C,CAEhB,KAAA6G,KAAA,EAHkD,CAKtDlF,OAAA,eAAA,CAA2Bqd,CAO3BA,EAAApb,UAAAkD,UAAA,CAAqC,CACjCmY,UAAW,qBADsB,CAEjCC,kBAAmB,GAFc,CAGjCC,eAAgB,GAHiB,CAIjCC,UAAW,UAJsB,CAKjCC,aAAc,cALmB,CAMjCC,cAAe,eANkB,CAcrCN,EAAApb,UAAAoI,UAAA,CAAqC,CACjCC,MAAO,EAD0B,CAEjCC,OAAQ,EAFyB,CAGjCC,MAAO,EAH0B,CAWrC6S,EAAApb,UAAA2b,MAAA,CAAiC,CAC7BC,SAAU,CADmB,CAE7BC,OAAQ,CAFqB,CAG7BC,UAAW,CAHkB,CAI7BC,OAAQ,CAJqB,CAcjCX,EAAApb,UAAApG,YAAA,CAAuC,CACnC8O,UAAW,uBADwB,CAEnCsT,OAAQ,oBAF2B,CAGnCC,OAAQ,oBAH2B,CAInCC,QAAS,qBAJ0B;AAKnCC,WAAY,2BALuB,CAMnCC,KAAM,gBAN6B,CAOnC1gB,iBAAkB,sBAPiB,CAQnCC,iBAAkB,kCARiB,CASnCC,OAAQ,YAT2B,CAUnC4I,qBAAsB,qCAVa,CAWnC6X,cAAe,4BAXoB,CAYnCC,iBAAkB,+BAZiB,CAanCC,cAAe,4BAboB,CAcnCC,aAAc,0BAdqB,CAenCC,WAAY,wBAfuB,CAgBnCC,QAAS,qBAhB0B,CAiBnCC,cAAe,+BAjBoB;AAkBnCC,IAAK,iBAlB8B,CAmBnCC,eAAgB,4BAnBmB,CAoBnCC,oBAAqB,iCApBc,CAqBnCC,qBAAsB,kCArBa,CAsBnClhB,kBAAmB,+BAtBgB,CAuBnCmhB,MAAO,uBAvB4B,CAwBnCC,WAAY,YAxBuB,CAyBnCC,SAAU,UAzByB,CA0BnCC,qBAAsB,sBA1Ba,CA2BnCC,eAAgB,mBA3BmB,CA4BnCC,WAAY,YA5BuB,CA6BnCC,gBAAiB,iBA7BkB,CA8BnCC,eAAgB,YA9BmB,CA+BnC/hB,UAAW,WA/BwB,CAgCnCqJ,YAAa,aAhCsB;AAiCnCkE,aAAc,cAjCqB,CAkCnCyU,gBAAiB,+BAlCkB,CAmCnCC,gBAAiB,+BAnCkB,CA0CvCrC,EAAApb,UAAA0d,sBAAA,CAAiDC,QAAS,EAAG,CACzD,GAAI,CAAA,IAAAC,QAAAlkB,UAAAC,SAAA,CAAgC,IAAAC,YAAAmP,aAAhC,CAAJ,CAAA,CAGA,IAAI8U,EAAgB,CAAC,IAAApkB,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAA0jB,gBAAjC,CAAjBO,EAAuF,IAAApkB,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAA4iB,aAAjC,CAC7D,EAA9B,CAAI,IAAAjhB,SAAAuiB,UAAJ,EAAoC,CAAA,IAAAF,QAAAlkB,UAAAC,SAAA,CAAgC,IAAAC,YAAAyjB,WAAhC,CAApC,EACI,IAAAO,QAAAlkB,UAAAO,IAAA,CAA2B,IAAAL,YAAAwjB,eAA3B,CAEA;AADA,IAAAQ,QAAAlkB,UAAAO,IAAA,CAA2B,IAAAL,YAAAyjB,WAA3B,CACA,CAAIQ,CAAJ,EACI,IAAAD,QAAAlkB,UAAAO,IAAA,CAA2B,IAAAL,YAAAmP,aAA3B,CAJR,EAMsC,CANtC,EAMW,IAAAxN,SAAAuiB,UANX,EAM2C,IAAAF,QAAAlkB,UAAAC,SAAA,CAAgC,IAAAC,YAAAyjB,WAAhC,CAN3C,GAOI,IAAAO,QAAAlkB,UAAA2L,OAAA,CAA8B,IAAAzL,YAAAwjB,eAA9B,CAEA,CADA,IAAAQ,QAAAlkB,UAAA2L,OAAA,CAA8B,IAAAzL,YAAAyjB,WAA9B,CACA,CAAIQ,CAAJ,EACI,IAAAD,QAAAlkB,UAAAO,IAAA,CAA2B,IAAAL,YAAAmP,aAA3B,CAVR,CAJA,CADyD,CAyB7DqS,EAAApb,UAAA+d,sBAAA,CAAiDC,QAAS,CAACtT,CAAD,CAAM,CAExDA,CAAAc,QAAJ,GAAoB,IAAApD,UAAAE,OAApB,EAA6C,IAAA2V,QAAAvkB,UAAAC,SAAA,CAAgC,IAAAC,YAAA2jB,eAAhC,CAA7C;AACI,IAAAW,aAAA,EAHwD,CAWhE9C,EAAApb,UAAAme,mBAAA,CAA8CC,QAAS,EAAG,CAClD,IAAAC,sBAAAC,QAAJ,CACI,IAAA7kB,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAA0jB,gBAA5B,CADJ,EAGI,IAAA7jB,SAAAC,UAAA2L,OAAA,CAA+B,IAAAzL,YAAA0jB,gBAA/B,CAEA,CAAI,IAAAW,QAAJ,GACI,IAAAA,QAAAvkB,UAAA2L,OAAA,CAA8B,IAAAzL,YAAA2jB,eAA9B,CACA,CAAA,IAAAgB,YAAA7kB,UAAA2L,OAAA,CAAkC,IAAAzL,YAAA2jB,eAAlC,CAFJ,CALJ,CADsD,CAkB1DnC,EAAApb,UAAAwe,qBAAA,CAAgDC,QAAS,CAAC/T,CAAD,CAAM,CAC3D,GAAIA,CAAJ,EAAwB,SAAxB,GAAWA,CAAAgU,KAAX,CACI,GAAIhU,CAAAc,QAAJ,GAAoB,IAAApD,UAAAG,MAApB,EAA4CmC,CAAAc,QAA5C,GAA4D,IAAApD,UAAAC,MAA5D,CAEIqC,CAAAhQ,eAAA,EAFJ;IAKI,OAGR,KAAAwjB,aAAA,EAV2D,CAiB/D9C,EAAApb,UAAA2e,4BAAA,CAAuDC,QAAS,EAAG,CAC/D,IAAAhB,QAAAlkB,UAAA2L,OAAA,CAA8B,IAAAzL,YAAAmP,aAA9B,CAD+D,CAQnEqS,EAAApb,UAAA6e,oBAAA,CAA+CC,QAAS,EAAG,CACnD,IAAAlB,QAAAlkB,UAAAC,SAAA,CAAgC,IAAAC,YAAAyjB,WAAhC,CAAJ,GACI,IAAAO,QAAAlkB,UAAA2L,OAAA,CAA8B,IAAAzL,YAAAyjB,WAA9B,CACA,CAAA,IAAAO,QAAAlkB,UAAAO,IAAA,CAA2B,IAAAL,YAAAmP,aAA3B,CAFJ,CADuD,CAW3DqS,EAAApb,UAAAjF,eAAA,CAA0CgkB,QAAS,CAACC,CAAD,CAAS,CACxD,IAAK,IAAIpH,EAAI,CAAb,CAAgBA,CAAhB,CAAoBoH,CAAA5hB,OAApB,CAAmCwa,CAAA,EAAnC,CACIoH,CAAA,CAAOpH,CAAP,CAAAle,UAAA2L,OAAA,CAA2B,IAAAzL,YAAA4B,UAA3B,CAFoD,CAU5D4f,EAAApb,UAAAhF,iBAAA;AAA4CikB,QAAS,CAAC7jB,CAAD,CAAS,CAC1D,IAAK,IAAIoE,EAAI,CAAb,CAAgBA,CAAhB,CAAoBpE,CAAAgC,OAApB,CAAmCoC,CAAA,EAAnC,CACIpE,CAAA,CAAOoE,CAAP,CAAA9F,UAAA2L,OAAA,CAA2B,IAAAzL,YAAA4B,UAA3B,CAFsD,CAU9D4f,EAAApb,UAAAke,aAAA,CAAwCgB,QAAS,EAAG,CAChD,IAAIC,EAAe,IAAA1lB,SAAAqB,cAAA,CAA4B,GAA5B,CAAkC,IAAAlB,YAAAuiB,WAAlC,CACnB,KAAA8B,QAAAvkB,UAAA4R,OAAA,CAA8B,IAAA1R,YAAA2jB,eAA9B,CACA,KAAAgB,YAAA7kB,UAAA4R,OAAA,CAAkC,IAAA1R,YAAA2jB,eAAlC,CAEI,KAAAU,QAAAvkB,UAAAC,SAAA,CAAgC,IAAAC,YAAA2jB,eAAhC,CAAJ,EACI,IAAAU,QAAA9e,aAAA,CAA0B,aAA1B,CAAyC,OAAzC,CACA,CAAAggB,CAAAhgB,aAAA,CAA0B,eAA1B,CAA2C,MAA3C,CAFJ,GAII,IAAA8e,QAAA9e,aAAA,CAA0B,aAA1B;AAAyC,MAAzC,CACA,CAAAggB,CAAAhgB,aAAA,CAA0B,eAA1B,CAA2C,OAA3C,CALJ,CALgD,CAapDic,EAAApb,UAAA,aAAA,CAA2Cob,CAAApb,UAAAke,aAI3C9C,EAAApb,UAAAiD,KAAA,CAAgCmc,QAAS,EAAG,CACxC,GAAI,IAAA3lB,SAAJ,CAAmB,CACf,IAAI6P,EAAYvP,QAAAC,cAAA,CAAuB,KAAvB,CAChBsP,EAAA5P,UAAAO,IAAA,CAAwB,IAAAL,YAAA8O,UAAxB,CACA,KAAI2W,EAAiB,IAAA5lB,SAAAqB,cAAA,CAA4B,QAA5B,CACrB,KAAArB,SAAA8P,cAAAC,aAAA,CAAyCF,CAAzC,CAAoD,IAAA7P,SAApD,CACA,KAAAA,SAAA8P,cAAAE,YAAA,CAAwC,IAAAhQ,SAAxC,CACA6P,EAAAjP,YAAA,CAAsB,IAAAZ,SAAtB,CACI4lB,EAAJ,EACIA,CAAA5T,MAAA,EAIJ,KAFI6T,IAAAA,EAAiB,IAAA7lB,SAAA8lB,WAAjBD,CACAE,EAAcF,CAAAliB,OADdkiB,CAEKG,EAAI,CAAb,CAAgBA,CAAhB,CAAoBD,CAApB,CAAiCC,CAAA,EAAjC,CAAsC,CAClC,IAAIC,EAAQJ,CAAA,CAAeG,CAAf,CACRC,EAAAhmB,UAAJ;AAAuBgmB,CAAAhmB,UAAAC,SAAA,CAAyB,IAAAC,YAAAoiB,OAAzB,CAAvB,GACI,IAAA4B,QADJ,CACmB8B,CADnB,CAGIA,EAAAhmB,UAAJ,EAAuBgmB,CAAAhmB,UAAAC,SAAA,CAAyB,IAAAC,YAAAqiB,OAAzB,CAAvB,GACI,IAAAgC,QADJ,CACmByB,CADnB,CAGIA,EAAAhmB,UAAJ,EAAuBgmB,CAAAhmB,UAAAC,SAAA,CAAyB,IAAAC,YAAAsiB,QAAzB,CAAvB,GACI,IAAA3gB,SADJ,CACoBmkB,CADpB,CARkC,CAYtC3hB,MAAAzD,iBAAA,CAAwB,UAAxB,CAAoC,QAAS,CAACC,CAAD,CAAI,CACzCA,CAAAolB,UAAJ,GAGI,IAAAlmB,SAAAqR,MAAA8U,UACA,CADgC,QAChC,CAAAzd,qBAAA,CAAsB,QAAS,EAAG,CAC9B,IAAA1I,SAAAqR,MAAA8U,UAAA,CAAgC,EADF,CAAZ5b,KAAA,CAEf,IAFe,CAAtB,CAJJ,CAD6C,CAAbA,KAAA,CAS7B,IAT6B,CAApC,CASc,CAAA,CATd,CAUI,KAAA4Z,QAAJ,GACI,IAAAniB,QADJ,CACmB,IAAAmiB,QAAA9iB,cAAA,CAA2B,GAA3B,CAAiC,IAAAlB,YAAA8iB,QAAjC,CADnB,CAGImD;CAAAA,CAAO,IAAAlE,MAAAC,SACP,KAAAgC,QAAJ,GACQ,IAAAA,QAAAlkB,UAAAC,SAAA,CAAgC,IAAAC,YAAAyiB,cAAhC,CAAJ,CACIwD,CADJ,CACW,IAAAlE,MAAAE,OADX,CAEW,IAAA+B,QAAAlkB,UAAAC,SAAA,CAAgC,IAAAC,YAAA0iB,iBAAhC,CAAJ,EACHuD,CAEA,CAFO,IAAAlE,MAAAG,UAEP,CADA,IAAA8B,QAAAtjB,iBAAA,CAA8B,eAA9B,CAA+C,IAAAqkB,4BAAA3a,KAAA,CAAsC,IAAtC,CAA/C,CACA,CAAA,IAAA4Z,QAAAtjB,iBAAA,CAA8B,OAA9B,CAAuC,IAAAukB,oBAAA7a,KAAA,CAA8B,IAA9B,CAAvC,CAHG,EAII,IAAA4Z,QAAAlkB,UAAAC,SAAA,CAAgC,IAAAC,YAAA2iB,cAAhC,CAJJ,GAKHsD,CACA,CADO,IAAAlE,MAAAI,OACP,CAAAzS,CAAA5P,UAAAO,IAAA,CAAwB,IAAAL,YAAAujB,qBAAxB,CANG,CAQP;AAAI0C,CAAJ,GAAa,IAAAlE,MAAAC,SAAb,EACI,IAAAgC,QAAAlkB,UAAAO,IAAA,CAA2B,IAAAL,YAAAwjB,eAA3B,CACA,CAAI,IAAA3hB,QAAJ,EACI,IAAAA,QAAA/B,UAAAO,IAAA,CAA2B,IAAAL,YAAAwjB,eAA3B,CAHR,EAKWyC,CAAJ,GAAa,IAAAlE,MAAAE,OAAb,EAAkCgE,CAAlC,GAA2C,IAAAlE,MAAAI,OAA3C,EACH,IAAA6B,QAAAlkB,UAAA2L,OAAA,CAA8B,IAAAzL,YAAAwjB,eAA9B,CACA,CAAI,IAAA3hB,QAAJ,EACI,IAAAA,QAAA/B,UAAA2L,OAAA,CAA8B,IAAAzL,YAAAwjB,eAA9B,CAHD,EAKIyC,CALJ,GAKa,IAAAlE,MAAAG,UALb,GASH,IAAAvgB,SAAAjB,iBAAA,CAA+B,QAA/B,CAAyC,IAAAojB,sBAAA1Z,KAAA,CAAgC,IAAhC,CAAzC,CACA,CAAA,IAAA0Z,sBAAA,EAVG,CAhBX,CA8BI,KAAAO,QAAJ,GACQkB,CAsCJ;AAtCmB,IAAA1lB,SAAAqB,cAAA,CAA4B,GAA5B,CAAkC,IAAAlB,YAAAuiB,WAAlC,CAsCnB,CArCKgD,CAqCL,GApCIA,CAQA,CAReplB,QAAAC,cAAA,CAAuB,KAAvB,CAQf,CAPAmlB,CAAAhgB,aAAA,CAA0B,eAA1B,CAA2C,OAA3C,CAOA,CANAggB,CAAAhgB,aAAA,CAA0B,MAA1B,CAAkC,QAAlC,CAMA,CALAggB,CAAAhgB,aAAA,CAA0B,UAA1B,CAAsC,GAAtC,CAKA,CAJAggB,CAAAzlB,UAAAO,IAAA,CAA2B,IAAAL,YAAAuiB,WAA3B,CAIA,CAHI2D,CAGJ,CAHuB/lB,QAAAC,cAAA,CAAuB,GAAvB,CAGvB,CAFA8lB,CAAApmB,UAAAO,IAAA,CAA+B,IAAAL,YAAAwiB,KAA/B,CAEA,CADA0D,CAAAC,UACA,CAD6B,IAAA7c,UAAAsY,UAC7B,CAAA2D,CAAA9kB,YAAA,CAAyBylB,CAAzB,CA4BJ,EA1BI,IAAA7B,QAAAvkB,UAAAC,SAAA,CAAgC,IAAAC,YAAA4jB,gBAAhC,CAAJ,CAEI2B,CAAAzlB,UAAAO,IAAA,CAA2B,IAAAL,YAAA4jB,gBAA3B,CAFJ,CAGW,IAAAS,QAAAvkB,UAAAC,SAAA,CAAgC,IAAAC,YAAA6jB,gBAAhC,CAHX;AAKI0B,CAAAzlB,UAAAO,IAAA,CAA2B,IAAAL,YAAA6jB,gBAA3B,CAqBJ,CAnBA0B,CAAA7kB,iBAAA,CAA8B,OAA9B,CAAuC,IAAAkkB,qBAAAxa,KAAA,CAA+B,IAA/B,CAAvC,CAmBA,CAlBAmb,CAAA7kB,iBAAA,CAA8B,SAA9B,CAAyC,IAAAkkB,qBAAAxa,KAAA,CAA+B,IAA/B,CAAzC,CAkBA,CAdA,IAAAvK,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAqjB,WAA5B,CAcA,CAXI,IAAAxjB,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAA4iB,aAAjC,CAAJ,CACI,IAAAoB,QAAApU,aAAA,CAA0B2V,CAA1B,CAAwC,IAAAvB,QAAAoC,WAAxC,CADJ,CAGI,IAAAvmB,SAAA+P,aAAA,CAA2B2V,CAA3B,CAAyC,IAAA5jB,SAAzC,CAQJ,CANI0kB,CAMJ,CANiBlmB,QAAAC,cAAA,CAAuB,KAAvB,CAMjB,CALAimB,CAAAvmB,UAAAO,IAAA,CAAyB,IAAAL,YAAA6iB,WAAzB,CAKA,CAJA,IAAAhjB,SAAAY,YAAA,CAA0B4lB,CAA1B,CAIA;AAHAA,CAAA3lB,iBAAA,CAA4B,OAA5B,CAAqC,IAAAkkB,qBAAAxa,KAAA,CAA+B,IAA/B,CAArC,CAGA,CAFA,IAAAua,YAEA,CAFmB0B,CAEnB,CADA,IAAAhC,QAAA3jB,iBAAA,CAA8B,SAA9B,CAAyC,IAAAyjB,sBAAA/Z,KAAA,CAAgC,IAAhC,CAAzC,CACA,CAAA,IAAAia,QAAA9e,aAAA,CAA0B,aAA1B,CAAyC,MAAzC,CAvCJ,CA2CA,KAAAkf,sBAAA,CAA6BtgB,MAAAmiB,WAAA,CAAkB,IAAAhd,UAAAmY,UAAlB,CAC7B,KAAAgD,sBAAA8B,YAAA,CAAuC,IAAAhC,mBAAAna,KAAA,CAA6B,IAA7B,CAAvC,CACA,KAAAma,mBAAA,EAEA,IAAI,IAAAP,QAAJ,EAAoB,IAAAniB,QAApB,CAAkC,CAC9B,IAAAhC,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAsjB,SAA5B,CACIkD,EAAAA,CAAermB,QAAAC,cAAA,CAAuB,KAAvB,CACnBomB;CAAA1mB,UAAAO,IAAA,CAA2B,IAAAL,YAAA+iB,cAA3B,CACA,KAAAiB,QAAApU,aAAA,CAA0B4W,CAA1B,CAAwC,IAAA3kB,QAAxC,CACA,KAAAmiB,QAAAnU,YAAA,CAAyB,IAAAhO,QAAzB,CACA,KAAI4kB,EAAatmB,QAAAC,cAAA,CAAuB,KAAvB,CACjBqmB,EAAA3mB,UAAAO,IAAA,CAAyB,IAAAL,YAAAijB,eAAzB,CACAwD,EAAA3mB,UAAAO,IAAA,CAAyB,IAAAL,YAAAkjB,oBAAzB,CACIwD,EAAAA,CAAiBvmB,QAAAC,cAAA,CAAuB,GAAvB,CACrBsmB,EAAA5mB,UAAAO,IAAA,CAA6B,IAAAL,YAAAwiB,KAA7B,CACAkE,EAAA7M,YAAA,CAA6B,IAAAvQ,UAAAuY,aAC7B4E,EAAAhmB,YAAA,CAAuBimB,CAAvB,CACAD,EAAA/lB,iBAAA,CAA4B,OAA5B,CAAqC,QAAS,EAAG,CAC7C,IAAAmB,QAAA8kB,WAAA,EAA2B,IAAArd,UAAAoY,kBADkB,CAAZtX,KAAA,CAE9B,IAF8B,CAArC,CAGA;IAAIwc,EAAczmB,QAAAC,cAAA,CAAuB,KAAvB,CAClBwmB,EAAA9mB,UAAAO,IAAA,CAA0B,IAAAL,YAAAijB,eAA1B,CACA2D,EAAA9mB,UAAAO,IAAA,CAA0B,IAAAL,YAAAmjB,qBAA1B,CACI0D,EAAAA,CAAkB1mB,QAAAC,cAAA,CAAuB,GAAvB,CACtBymB,EAAA/mB,UAAAO,IAAA,CAA8B,IAAAL,YAAAwiB,KAA9B,CACAqE,EAAAhN,YAAA,CAA8B,IAAAvQ,UAAAwY,cAC9B8E,EAAAnmB,YAAA,CAAwBomB,CAAxB,CACAD,EAAAlmB,iBAAA,CAA6B,OAA7B,CAAsC,QAAS,EAAG,CAC9C,IAAAmB,QAAA8kB,WAAA,EAA2B,IAAArd,UAAAoY,kBADmB,CAAZtX,KAAA,CAE/B,IAF+B,CAAtC,CAGAoc,EAAA/lB,YAAA,CAAyBgmB,CAAzB,CACAD,EAAA/lB,YAAA,CAAyB,IAAAoB,QAAzB,CACA2kB,EAAA/lB,YAAA,CAAyBmmB,CAAzB,CAGA,KAAIE,EAAmB,QAAS,EAAG,CACD,CAA9B,CAAI,IAAAjlB,QAAA8kB,WAAJ,CACIF,CAAA3mB,UAAAO,IAAA,CAAyB,IAAAL,YAAA4B,UAAzB,CADJ;AAGI6kB,CAAA3mB,UAAA2L,OAAA,CAA4B,IAAAzL,YAAA4B,UAA5B,CAEA,KAAAC,QAAA8kB,WAAJ,CAA8B,IAAA9kB,QAAAklB,YAA9B,CAAyD,IAAAllB,QAAAof,YAAzD,CACI2F,CAAA9mB,UAAAO,IAAA,CAA0B,IAAAL,YAAA4B,UAA1B,CADJ,CAGIglB,CAAA9mB,UAAA2L,OAAA,CAA6B,IAAAzL,YAAA4B,UAA7B,CAT2B,CAAZwI,KAAA,CAWhB,IAXgB,CAYvB,KAAAvI,QAAAnB,iBAAA,CAA8B,QAA9B,CAAwComB,CAAxC,CACAA,EAAA,EAEIE,EAAAA,CAAsB,QAAS,EAAG,CAE9B,IAAAC,iBAAJ,EACI9d,YAAA,CAAa,IAAA8d,iBAAb,CAEJ,KAAAA,iBAAA,CAAwB/d,UAAA,CAAW,QAAS,EAAG,CAC3C4d,CAAA,EACA,KAAAG,iBAAA,CAAwB,IAFmB,CAAZ7c,KAAA,CAG5B,IAH4B,CAAX,CAGV,IAAAd,UAAAqY,eAHU,CALU,CAAZvX,KAAA,CASnB,IATmB,CAU1BjG,OAAAzD,iBAAA,CAAwB,QAAxB;AAAkCsmB,CAAlC,CACI,KAAAnlB,QAAA/B,UAAAC,SAAA,CAAgC,IAAAC,YAAA8B,iBAAhC,CAAJ,EACI,IAAAD,QAAA/B,UAAAO,IAAA,CAA2B,IAAAL,YAAA4K,qBAA3B,CAGArJ,EAAAA,CAAO,IAAAM,QAAA8C,iBAAA,CAA8B,GAA9B,CAAoC,IAAA3E,YAAAgjB,IAApC,CACPxhB,EAAAA,CAAS,IAAAG,SAAAgD,iBAAA,CAA+B,GAA/B,CAAqC,IAAA3E,YAAAojB,MAArC,CAEb,KAAS9f,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoB/B,CAAAiC,OAApB,CAAiCF,CAAA,EAAjC,CACI,IAAIhC,CAAJ,CAAsBC,CAAA,CAAK+B,CAAL,CAAtB,CAA+B/B,CAA/B,CAAqCC,CAArC,CAA6C,IAA7C,CAjE0B,CAoElC,IAAA3B,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAiL,YAA5B,CAvLe,CADqB,CAmO5C9G,OAAA,kBAAA,CAA8B7C,CAG9Ba,EAAAY,SAAA,CAA0B,CACtBqE,YAAaoa,CADS,CAEtB1a,cAAe,gBAFO,CAGtBrC,SAAU,eAHY,CAA1B,CA6BIyiB,EAAAA,CAAoBA,QAA0B,CAAC1kB,CAAD,CAAU,CACxD,IAAA3C,SAAA,CAAgB2C,CAEhB;IAAA6G,KAAA,EAHwD,CAK5DlF,OAAA,kBAAA,CAA8B+iB,CAO9BA,EAAA9gB,UAAAkD,UAAA,CAAwC,EASxC4d,EAAA9gB,UAAApG,YAAA,CAA0C,CACtCmnB,WAAY,gBAD0B,CAEtCC,WAAY,4BAF0B,CAGtCC,eAAgB,wBAHsB,CAItCC,YAAa,aAJyB,CAKtCrc,YAAa,aALyB,CAgB1Cic,EAAA9gB,UAAAmhB,WAAA,CAAyCC,QAAS,CAACC,CAAD,CAAWC,CAAX,CAAgBC,CAAhB,CAA0B,CACxE,GAAID,CAAJ,CACI,MAAO,SAAS,EAAG,CACXD,CAAAtb,QAAJ,CACIub,CAAA5nB,UAAAO,IAAA,CAAkB,IAAAL,YAAAsnB,YAAlB,CADJ,CAGII,CAAA5nB,UAAA2L,OAAA,CAAqB,IAAAzL,YAAAsnB,YAArB,CAJW,CAAZld,KAAA,CAMA,IANA,CAQX,IAAIud,CAAJ,CACI,MAAO,SAAS,EAAG,CACf,IAAIrkB,CAAJ,CACI+Q,CACJ,IAAIoT,CAAAtb,QAAJ,CACI,IAAK7I,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBqkB,CAAAnkB,OAAhB,CAAiCF,CAAA,EAAjC,CACI+Q,CAEA,CAFKsT,CAAA,CAASrkB,CAAT,CAAApC,cAAA,CAA0B,IAA1B,CAAAA,cAAA,CAA8C,eAA9C,CAEL;AADAmT,CAAA,iBAAA9H,MAAA,EACA,CAAAob,CAAA,CAASrkB,CAAT,CAAAxD,UAAAO,IAAA,CAA0B,IAAAL,YAAAsnB,YAA1B,CAJR,KAOI,KAAKhkB,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBqkB,CAAAnkB,OAAhB,CAAiCF,CAAA,EAAjC,CACI+Q,CAEA,CAFKsT,CAAA,CAASrkB,CAAT,CAAApC,cAAA,CAA0B,IAA1B,CAAAA,cAAA,CAA8C,eAA9C,CAEL,CADAmT,CAAA,iBAAA5H,QAAA,EACA,CAAAkb,CAAA,CAASrkB,CAAT,CAAAxD,UAAA2L,OAAA,CAA6B,IAAAzL,YAAAsnB,YAA7B,CAbO,CAAZld,KAAA,CAgBA,IAhBA,CAX6D,CAsC5E8c,EAAA9gB,UAAAwhB,gBAAA,CAA8CC,QAAS,CAACH,CAAD,CAAMC,CAAN,CAAgB,CACnE,IAAIG,EAAQ3nB,QAAAC,cAAA,CAAuB,OAAvB,CAOZ0nB,EAAArkB,UAAA,CANmBskB,CAGf,mDAHeA,CAIf,IAAA/nB,YAAAqnB,eAJeU,CAMDviB,KAAA,CAAkB,GAAlB,CAClB,KAAIiiB,EAAWtnB,QAAAC,cAAA,CAAuB,OAAvB,CACfqnB,EAAA3C,KAAA,CAAgB,UAChB2C,EAAA3nB,UAAAO,IAAA,CAAuB,qBAAvB,CACIqnB;CAAJ,EACID,CAAAtb,QACA,CADmBub,CAAA5nB,UAAAC,SAAA,CAAuB,IAAAC,YAAAsnB,YAAvB,CACnB,CAAAG,CAAA/mB,iBAAA,CAA0B,QAA1B,CAAoC,IAAA6mB,WAAA,CAAgBE,CAAhB,CAA0BC,CAA1B,CAApC,CAFJ,EAGWC,CAHX,EAIIF,CAAA/mB,iBAAA,CAA0B,QAA1B,CAAoC,IAAA6mB,WAAA,CAAgBE,CAAhB,CAA0B,IAA1B,CAAgCE,CAAhC,CAApC,CAEJG,EAAArnB,YAAA,CAAkBgnB,CAAlB,CACAtlB,EAAAI,eAAA,CAAgCulB,CAAhC,CAAuC,kBAAvC,CACA,OAAOA,EApB4D,CAyBvEZ,EAAA9gB,UAAAiD,KAAA,CAAmC2e,QAAS,EAAG,CAC3C,GAAI,IAAAnoB,SAAJ,CAAmB,CACf,IAAIooB,EAAc,IAAApoB,SAAAqB,cAAA,CAA4B,IAA5B,CAAlB,CACIgnB,EAAWhiB,KAAAE,UAAAC,MAAAC,KAAA,CAA2B,IAAAzG,SAAA8E,iBAAA,CAA+B,UAA/B,CAA3B,CADf,CAEIwjB,EAAWjiB,KAAAE,UAAAC,MAAAC,KAAA,CAA2B,IAAAzG,SAAA8E,iBAAA,CAA+B,UAA/B,CAA3B,CAFf,CAGIyjB,EAAOF,CAAAG,OAAA,CAAgBF,CAAhB,CACX,IAAI,IAAAtoB,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAonB,WAAjC,CAAJ,CAAmE,CAC3DkB,IAAAA;AAAKnoB,QAAAC,cAAA,CAAuB,IAAvB,CAALkoB,CACAC,EAAiB,IAAAX,gBAAA,CAAqB,IAArB,CAA2BQ,CAA3B,CACrBE,EAAA7nB,YAAA,CAAe8nB,CAAf,CACAN,EAAAtY,cAAAC,aAAA,CAAuC0Y,CAAvC,CAA2CL,CAA3C,CACA,KAAS3kB,CAAT,CAAa,CAAb,CAAgBA,CAAhB,CAAoB8kB,CAAA5kB,OAApB,CAAiCF,CAAA,EAAjC,CAEI,GADIklB,CACJ,CADgBJ,CAAA,CAAK9kB,CAAL,CAAApC,cAAA,CAAsB,IAAtB,CAChB,CAAe,CACPunB,CAAAA,CAAKtoB,QAAAC,cAAA,CAAuB,IAAvB,CACT,IAAkD,OAAlD,GAAIgoB,CAAA,CAAK9kB,CAAL,CAAA+P,WAAAqV,SAAAC,YAAA,EAAJ,CAA2D,CACvD,IAAIC,EAAc,IAAAhB,gBAAA,CAAqBQ,CAAA,CAAK9kB,CAAL,CAArB,CAClBmlB,EAAAhoB,YAAA,CAAemoB,CAAf,CAFuD,CAI3DR,CAAA,CAAK9kB,CAAL,CAAAsM,aAAA,CAAqB6Y,CAArB,CAAyBD,CAAzB,CANW,CASnB,IAAA3oB,SAAAC,UAAAO,IAAA,CAA4B,IAAAL,YAAAiL,YAA5B,CAhB+D,CALpD,CADwB,CA4B/C9I,EAAAY,SAAA,CAA0B,CACtBqE,YAAa8f,CADS,CAEtBpgB,cAAe,mBAFO,CAGtBrC,SAAU,mBAHY,CAA1B,CA6BIokB,EAAAA,CAAiBA,QAAuB,CAACrmB,CAAD,CAAU,CAClD,IAAA3C,SAAA;AAAgB2C,CAEhB,KAAA6G,KAAA,EAHkD,CAKtDlF,OAAA,eAAA,CAA2B0kB,CAO3BA,EAAAziB,UAAAkD,UAAA,CAAqC,CACjCwf,cAAe,uBADkB,CAEjCC,aAAc,KAFmB,CAGjCC,gBAAiB,KAHgB,CAIjCC,cAAe,GAJkB,CAKjCC,YAAa,EALoB,CAerCL,EAAAziB,UAAApG,YAAA,CAAuC,CACnC6K,cAAe,oBADoB,CAEnCse,4BAA6B,qCAFM,CAGnCnnB,OAAQ,YAH2B,CAInCmN,aAAc,cAJqB,CAKnCD,WAAY,YALuB,CAavC2Z,EAAAziB,UAAAgjB,aAAA,CAAwCC,QAAS,CAAC3f,CAAD,CAAQ,CACrD,GAAKiJ,CAAA,IAAAzI,eAAAgH,MAAAyB,MAAL,EAAyCD,CAAA,IAAAxI,eAAAgH,MAAAwB,OAAzC,CAA2E,CACvE,IAAI3B,EAAO,IAAAlR,SAAAmR,sBAAA,EACX;IAAAsY,YAAA,CAAmBvY,CAAA2B,OACnB,KAAA6W,WAAA,CAAkBxY,CAAA4B,MAClB,KAAA6W,YAAA,CAAoF,CAApF,CAAmBxgB,IAAAygB,KAAA,CAAU1Y,CAAA4B,MAAV,CAAuB5B,CAAA4B,MAAvB,CAAoC5B,CAAA2B,OAApC,CAAkD3B,CAAA2B,OAAlD,CAAnB,CAAwF,CACxF,KAAAxI,eAAAgH,MAAAyB,MAAA,CAAkC,IAAA6W,YAAlC,CAAqD,IACrD,KAAAtf,eAAAgH,MAAAwB,OAAA,CAAmC,IAAA8W,YAAnC,CAAsD,IANiB,CAQ3E,IAAAtf,eAAApK,UAAAO,IAAA,CAAkC,IAAAL,YAAAkP,WAAlC,CACA,IAAmB,WAAnB,GAAIxF,CAAAob,KAAJ,EAAkC,IAAA4E,mBAAlC,CACI,IAAAA,mBAAA,CAA0B,CAAA,CAD9B,KAOI,IAJmB,YAIf,GAJAhgB,CAAAob,KAIA,GAHA,IAAA4E,mBAGA,CAH0B,CAAA,CAG1B,EAAA,EAAa,CAAb,CADa,IAAAC,cAAAC,EACb,CAAJ,CAAA,CAGA,IAAAC,cAAA,CAAmB,CAAnB,CACIC,EAAAA,CAAQpgB,CAAAqgB,cAAA/Y,sBAAA,EAIZ;GAAsB,CAAtB,GAAItH,CAAA2N,QAAJ,EAA6C,CAA7C,GAA2B3N,CAAA4N,QAA3B,CACI0S,CACA,CADIhhB,IAAAihB,MAAA,CAAWH,CAAAnX,MAAX,CAAyB,CAAzB,CACJ,CAAA4E,CAAA,CAAIvO,IAAAihB,MAAA,CAAWH,CAAApX,OAAX,CAA0B,CAA1B,CAFR,KAGO,CAEH,IAAI4E,EAA4B+B,IAAAA,EAAlB,GAAA3P,CAAA4N,QAAA,CAA8B5N,CAAA4N,QAA9B,CAA8C5N,CAAAwgB,QAAA,CAAc,CAAd,CAAA5S,QAC5D0S,EAAA,CAAIhhB,IAAAihB,MAAA,EAF4B5Q,IAAAA,EAAlBhC,GAAA3N,CAAA2N,QAAAA,CAA8B3N,CAAA2N,QAA9BA,CAA8C3N,CAAAwgB,QAAA,CAAc,CAAd,CAAA7S,QAExD,EAAqByS,CAAAvY,KAArB,CACJgG,EAAA,CAAIvO,IAAAihB,MAAA,CAAW3S,CAAX,CAAqBwS,CAAA1Y,IAArB,CAJD,CAMP,IAAA+Y,YAAA,CAAiBH,CAAjB,CAAoBzS,CAApB,CACA,KAAA6S,gBAAA,CAAqB,CAAA,CAArB,CACAjmB,OAAAoE,sBAAA,CAA6B,IAAA8hB,iBAAAjgB,KAAA,CAA2B,IAA3B,CAA7B,CAnBA,CAjBiD,CA6CzDye,EAAAziB,UAAAkkB,WAAA,CAAsCC,QAAS,CAAC7gB,CAAD,CAAQ,CAE/CA,CAAJ,EAA8B,CAA9B,GAAaA,CAAA8gB,OAAb,EAIIrmB,MAAA+E,WAAA,CAAkB,QAAS,EAAG,CAC1B,IAAAgB,eAAApK,UAAA2L,OAAA,CAAqC,IAAAzL,YAAAkP,WAArC,CAD0B,CAAZ9E,KAAA,CAEX,IAFW,CAAlB;AAEc,CAFd,CAN+C,CAcvDye,EAAAziB,UAAAiD,KAAA,CAAgCohB,QAAS,EAAG,CACxC,GAAI,IAAA5qB,SAAJ,CAAmB,CACf,IAAI6qB,EAAc,IAAA7qB,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAA6K,cAAjC,CACb,KAAAhL,SAAAC,UAAAC,SAAA,CAAiC,IAAAC,YAAAmpB,4BAAjC,CAAL,GACI,IAAAjf,eAiFA,CAjFsB,IAAArK,SAAAqB,cAAA,CAA4B,GAA5B,CAAkC,IAAAlB,YAAAgC,OAAlC,CAiFtB,CA7EA,IAAA2oB,GA6EA,CA9EA,IAAAC,GA8EA,CA/EA,IAAApB,YA+EA,CAhFA,IAAAqB,YAgFA,CAhFmB,CAgFnB,CAzEA,IAAAnB,mBAyEA,CAzE0B,CAAA,CAyE1B,CAxEA,IAAAoB,iBAwEA,CAxEwB,IAAA1B,aAAAhf,KAAA,CAAuB,IAAvB,CAwExB,CAvEA,IAAAvK,SAAAa,iBAAA,CAA+B,WAA/B,CAA4C,IAAAoqB,iBAA5C,CAuEA,CAtEA,IAAAjrB,SAAAa,iBAAA,CAA+B,YAA/B;AAA6C,IAAAoqB,iBAA7C,CAsEA,CArEA,IAAAC,eAqEA,CArEsB,IAAAT,WAAAlgB,KAAA,CAAqB,IAArB,CAqEtB,CApEA,IAAAvK,SAAAa,iBAAA,CAA+B,SAA/B,CAA0C,IAAAqqB,eAA1C,CAoEA,CAnEA,IAAAlrB,SAAAa,iBAAA,CAA+B,YAA/B,CAA6C,IAAAqqB,eAA7C,CAmEA,CAlEA,IAAAlrB,SAAAa,iBAAA,CAA+B,UAA/B,CAA2C,IAAAqqB,eAA3C,CAkEA,CAjEA,IAAAlrB,SAAAa,iBAAA,CAA+B,MAA/B,CAAuC,IAAAqqB,eAAvC,CAiEA,CA5DA,IAAApB,cA4DA,CA5DqBqB,QAAS,EAAG,CAC7B,MAAO,KAAAH,YADsB,CA4DjC,CArDA,IAAAhB,cAqDA,CArDqBoB,QAAS,CAACC,CAAD,CAAK,CAC/B,IAAAL,YAAA,CAAmBK,CADY,CAqDnC,CA9CA,IAAAC,iBA8CA,CA9CwBC,QAAS,EAAG,CAChC,MAAO,KAAAlhB,eADyB,CA8CpC,CAtCA,IAAAigB,YAsCA;AAtCmBkB,QAAS,CAACC,CAAD,CAAOC,CAAP,CAAa,CACrC,IAAAX,GAAA,CAAUU,CACV,KAAAX,GAAA,CAAUY,CAF2B,CAsCzC,CA9BA,IAAAnB,gBA8BA,CA9BuBoB,QAAS,CAAC5P,CAAD,CAAQ,CACpC,GAA4B,IAA5B,GAAI,IAAA1R,eAAJ,CAAkC,CAC9B,IAAIuhB,CAAJ,CAGIC,EAAS,YAATA,CAAwB,IAAAd,GAAxBc,CAAkC,MAAlCA,CAA2C,IAAAf,GAA3Ce,CAAqD,KACrD9P,EAAJ,CACI+P,CADJ,CACY,IAAAriB,UAAAwf,cADZ,EAII6C,CAEA,CAFQ,IAAAriB,UAAA4f,YAER,CAAIwB,CAAJ,GACIgB,CADJ,CACa,YADb,CAC4B,IAAAnC,WAD5B,CAC8C,CAD9C,CACkD,MADlD,CAC2D,IAAAD,YAD3D,CAC8E,CAD9E,CACkF,KADlF,CANJ,CAUAmC,EAAA,CAAkB,wBAAlB,CAA6CC,CAA7C,CAAsDC,CACtD,KAAAzhB,eAAAgH,MAAA0a,gBAAA,CAA4CH,CAC5C,KAAAvhB,eAAAgH,MAAA2a,YAAA,CAAwCJ,CACxC,KAAAvhB,eAAAgH,MAAA4a,UAAA,CAAsCL,CAClC7P,EAAJ,CACI,IAAA1R,eAAApK,UAAA2L,OAAA,CAAqC,IAAAzL,YAAAmP,aAArC,CADJ;AAGI,IAAAjF,eAAApK,UAAAO,IAAA,CAAkC,IAAAL,YAAAmP,aAAlC,CAtB0B,CADE,CA8BxC,CAAA,IAAAkb,iBAAA,CAAwB0B,QAAS,EAAG,CACP,CAAzB,CAAI,IAAAlB,YAAA,EAAJ,CACI1mB,MAAAoE,sBAAA,CAA6B,IAAA8hB,iBAAAjgB,KAAA,CAA2B,IAA3B,CAA7B,CADJ,CAGI,IAAAggB,gBAAA,CAAqB,CAAA,CAArB,CAJ4B,CAlFxC,CAFe,CADqB,CAiG5CjoB,EAAAY,SAAA,CAA0B,CACtBqE,YAAayhB,CADS,CAEtB/hB,cAAe,gBAFO,CAGtBrC,SAAU,sBAHY,CAItBsB,OAAQ,CAAA,CAJc,CAA1B,CAr5Ha,CAAX,CAAA;", -"sources":["material.js"], -"names":["MaterialTab","tab","ctx","element_","classList","contains","CssClasses_","MDL_JS_RIPPLE_EFFECT","rippleContainer","document","createElement","add","MDL_RIPPLE_CONTAINER","ripple","MDL_RIPPLE","appendChild","addEventListener","e","getAttribute","charAt","preventDefault","href","split","panel","querySelector","resetTabState_","resetPanelState_","ACTIVE_CLASS","MaterialLayoutTab","tabs","panels","layout","selectTab","content_","IS_ACTIVE","tabBar_","JS_RIPPLE_EFFECT","RIPPLE_CONTAINER","RIPPLE","TAB_MANUAL_SWITCH","show","componentHandler","upgradeDom","optJsClass","optCssClass","upgradeElement","element","upgradeElements","elements","upgradeAllRegistered","registerUpgradedCallback","jsClass","callback","register","config","downgradeElements","nodes","findRegisteredClass_","name","optReplace","i","registeredComponents_","length","className","getUpgradedListOfElement_","dataUpgraded","isElementUpgraded_","upgradedList","indexOf","createEvent_","eventType","bubbles","cancelable","window","CustomEvent","ev","createEvent","initEvent","upgradeDomInternal","cssClass","registeredClass","querySelectorAll","n","upgradeElementInternal","Element","Error","upgradingEv","dispatchEvent","defaultPrevented","classesToUpgrade","push","forEach","component","setAttribute","join","instance","classConstructor","createdComponents_","j","m","callbacks","widget","upgradedEv","upgradeElementsInternal","Array","isArray","prototype","slice","call","HTMLElement","children","deconstructComponentInternal","componentIndex","splice","upgrades","componentPlace","classAsString","upgradeAllRegisteredInternal","registerUpgradedCallbackInternal","regClass","registerInternal","newConfig","constructor","item","hasOwnProperty","componentConfigProperty_","found","downgradeNodesInternal","downgradeNode","node","filter","NodeList","Node","documentElement","componentHandler.upgradeElement","componentHandler.register","Date","now","Date.now","getTime","vendors","requestAnimationFrame","vp","cancelAnimationFrame","test","navigator","userAgent","lastTime","window.requestAnimationFrame","nextTime","Math","max","setTimeout","clearTimeout","MaterialButton","init","Constant_","RIPPLE_EFFECT","blurHandler_","MaterialButton.prototype.blurHandler_","event","blur","disable","MaterialButton.prototype.disable","disabled","enable","MaterialButton.prototype.enable","MaterialButton.prototype.init","rippleElement_","boundRippleBlurHandler","bind","boundButtonBlurHandler","MaterialCheckbox","TINY_TIMEOUT","INPUT","BOX_OUTLINE","FOCUS_HELPER","TICK_OUTLINE","RIPPLE_IGNORE_EVENTS","RIPPLE_CENTER","IS_FOCUSED","IS_DISABLED","IS_CHECKED","IS_UPGRADED","onChange_","MaterialCheckbox.prototype.onChange_","updateClasses_","onFocus_","MaterialCheckbox.prototype.onFocus_","onBlur_","MaterialCheckbox.prototype.onBlur_","remove","onMouseUp_","MaterialCheckbox.prototype.onMouseUp_","blur_","MaterialCheckbox.prototype.updateClasses_","checkDisabled","checkToggleState","MaterialCheckbox.prototype.blur_","inputElement_","MaterialCheckbox.prototype.checkToggleState","checked","MaterialCheckbox.prototype.checkDisabled","MaterialCheckbox.prototype.disable","MaterialCheckbox.prototype.enable","check","MaterialCheckbox.prototype.check","uncheck","MaterialCheckbox.prototype.uncheck","MaterialCheckbox.prototype.init","boxOutline","tickContainer","tickOutline","rippleContainerElement_","boundRippleMouseUp","boundInputOnChange","boundInputOnFocus","boundInputOnBlur","boundElementMouseUp","MaterialIconToggle","MaterialIconToggle.prototype.onChange_","MaterialIconToggle.prototype.onFocus_","MaterialIconToggle.prototype.onBlur_","MaterialIconToggle.prototype.onMouseUp_","MaterialIconToggle.prototype.updateClasses_","MaterialIconToggle.prototype.blur_","MaterialIconToggle.prototype.checkToggleState","MaterialIconToggle.prototype.checkDisabled","MaterialIconToggle.prototype.disable","MaterialIconToggle.prototype.enable","MaterialIconToggle.prototype.check","MaterialIconToggle.prototype.uncheck","MaterialIconToggle.prototype.init","boundElementOnMouseUp","MaterialMenu","TRANSITION_DURATION_SECONDS","TRANSITION_DURATION_FRACTION","CLOSE_TIMEOUT","Keycodes_","ENTER","ESCAPE","SPACE","UP_ARROW","DOWN_ARROW","CONTAINER","OUTLINE","ITEM","ITEM_RIPPLE_CONTAINER","IS_VISIBLE","IS_ANIMATING","BOTTOM_LEFT","BOTTOM_RIGHT","TOP_LEFT","TOP_RIGHT","UNALIGNED","MaterialMenu.prototype.init","container","parentElement","insertBefore","removeChild","container_","outline","outline_","forElId","forEl","getElementById","forElement_","handleForClick_","handleForKeyboardEvent_","items","boundItemKeydown_","handleItemKeyboardEvent_","boundItemClick_","handleItemClick_","tabIndex","MaterialMenu.prototype.handleForClick_","evt","rect","getBoundingClientRect","forRect","style","right","top","offsetTop","offsetHeight","left","offsetLeft","bottom","toggle","MaterialMenu.prototype.handleForKeyboardEvent_","keyCode","focus","MaterialMenu.prototype.handleItemKeyboardEvent_","currentIndex","target","MouseEvent","click","hide","MaterialMenu.prototype.handleItemClick_","hasAttribute","stopPropagation","closing_","applyClip_","MaterialMenu.prototype.applyClip_","height","width","clip","removeAnimationEndListener_","MaterialMenu.prototype.removeAnimationEndListener_","addAnimationEndListener_","MaterialMenu.prototype.addAnimationEndListener_","MaterialMenu.prototype.show","transitionDuration","itemDelay","transitionDelay","parentNode","removeEventListener","MaterialMenu.prototype.hide","removeProperty","MaterialMenu.prototype.toggle","MaterialProgress","INDETERMINATE_CLASS","setProgress","MaterialProgress.prototype.setProgress","p","progressbar_","setBuffer","MaterialProgress.prototype.setBuffer","bufferbar_","auxbar_","MaterialProgress.prototype.init","el","MaterialRadio","JS_RADIO","RADIO_BTN","RADIO_OUTER_CIRCLE","RADIO_INNER_CIRCLE","MaterialRadio.prototype.onChange_","radios","getElementsByClassName","button","btnElement_","MaterialRadio.prototype.onFocus_","MaterialRadio.prototype.onBlur_","onMouseup_","MaterialRadio.prototype.onMouseup_","MaterialRadio.prototype.updateClasses_","MaterialRadio.prototype.blur_","MaterialRadio.prototype.checkDisabled","MaterialRadio.prototype.checkToggleState","MaterialRadio.prototype.disable","MaterialRadio.prototype.enable","MaterialRadio.prototype.check","MaterialRadio.prototype.uncheck","MaterialRadio.prototype.init","boundChangeHandler_","boundFocusHandler_","boundBlurHandler_","boundMouseUpHandler_","outerCircle","innerCircle","MaterialSlider","isIE_","msPointerEnabled","IE_CONTAINER","SLIDER_CONTAINER","BACKGROUND_FLEX","BACKGROUND_LOWER","BACKGROUND_UPPER","IS_LOWEST_VALUE","onInput_","MaterialSlider.prototype.onInput_","updateValueStyles_","MaterialSlider.prototype.onChange_","MaterialSlider.prototype.onMouseUp_","onContainerMouseDown_","MaterialSlider.prototype.onContainerMouseDown_","newEvent","buttons","clientX","clientY","y","MaterialSlider.prototype.updateValueStyles_","fraction","value","min","backgroundLower_","flex","webkitFlex","backgroundUpper_","MaterialSlider.prototype.disable","MaterialSlider.prototype.enable","change","MaterialSlider.prototype.change","MaterialSlider.prototype.init","containerIE","backgroundFlex","boundInputHandler","boundChangeHandler","boundMouseUpHandler","boundContainerMouseDownHandler","MaterialSnackbar","textElement_","cssClasses_","MESSAGE","actionElement_","ACTION","active","actionText_","message_","actionHandler_","undefined","queuedNotifications_","setActionHidden_","ANIMATION_LENGTH","SNACKBAR","ACTIVE","displaySnackbar_","MaterialSnackbar.prototype.displaySnackbar_","textContent","cleanup_","timeout_","showSnackbar","MaterialSnackbar.prototype.showSnackbar","data","checkQueue_","MaterialSnackbar.prototype.checkQueue_","shift","MaterialSnackbar.prototype.cleanup_","MaterialSnackbar.prototype.setActionHidden_","removeAttribute","MaterialSpinner","MDL_SPINNER_LAYER_COUNT","MDL_SPINNER_LAYER","MDL_SPINNER_CIRCLE_CLIPPER","MDL_SPINNER_CIRCLE","MDL_SPINNER_GAP_PATCH","MDL_SPINNER_LEFT","MDL_SPINNER_RIGHT","createLayer","MaterialSpinner.prototype.createLayer","index","layer","leftClipper","gapPatch","rightClipper","circleOwners","circle","stop","MaterialSpinner.prototype.stop","start","MaterialSpinner.prototype.start","MaterialSpinner.prototype.init","MaterialSwitch","TRACK","THUMB","MaterialSwitch.prototype.onChange_","MaterialSwitch.prototype.onFocus_","MaterialSwitch.prototype.onBlur_","MaterialSwitch.prototype.onMouseUp_","MaterialSwitch.prototype.updateClasses_","MaterialSwitch.prototype.blur_","MaterialSwitch.prototype.checkDisabled","MaterialSwitch.prototype.checkToggleState","MaterialSwitch.prototype.disable","MaterialSwitch.prototype.enable","on","MaterialSwitch.prototype.on","off","MaterialSwitch.prototype.off","MaterialSwitch.prototype.init","track","thumb","focusHelper","boundFocusHandler","boundBlurHandler","MaterialTabs","TAB_CLASS","PANEL_CLASS","UPGRADED_CLASS","MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS","initTabs_","MaterialTabs.prototype.initTabs_","tabs_","panels_","MaterialTabs.prototype.resetTabState_","k","MaterialTabs.prototype.resetPanelState_","MaterialTabs.prototype.init","MaterialTextfield","maxRows","NO_MAX_ROWS","MAX_ROWS_ATTRIBUTE","LABEL","IS_DIRTY","IS_INVALID","HAS_PLACEHOLDER","onKeyDown_","MaterialTextfield.prototype.onKeyDown_","currentRowCount","MaterialTextfield.prototype.onFocus_","MaterialTextfield.prototype.onBlur_","onReset_","MaterialTextfield.prototype.onReset_","MaterialTextfield.prototype.updateClasses_","checkValidity","checkDirty","checkFocus","MaterialTextfield.prototype.checkDisabled","input_","MaterialTextfield.prototype.checkFocus","MaterialTextfield.prototype.checkValidity","validity","valid","MaterialTextfield.prototype.checkDirty","MaterialTextfield.prototype.disable","MaterialTextfield.prototype.enable","MaterialTextfield.prototype.change","MaterialTextfield.prototype.init","label_","parseInt","isNaN","boundUpdateClassesHandler","boundResetHandler","boundKeyDownHandler","invalid","MaterialTooltip","BOTTOM","LEFT","RIGHT","TOP","handleMouseEnter_","MaterialTooltip.prototype.handleMouseEnter_","props","marginLeft","offsetWidth","marginTop","hideTooltip_","MaterialTooltip.prototype.hideTooltip_","MaterialTooltip.prototype.init","boundMouseEnterHandler","boundMouseLeaveAndScrollHandler","MaterialLayout","MAX_WIDTH","TAB_SCROLL_PIXELS","RESIZE_TIMEOUT","MENU_ICON","CHEVRON_LEFT","CHEVRON_RIGHT","Mode_","STANDARD","SEAMED","WATERFALL","SCROLL","HEADER","DRAWER","CONTENT","DRAWER_BTN","ICON","HEADER_SEAMED","HEADER_WATERFALL","HEADER_SCROLL","FIXED_HEADER","OBFUSCATOR","TAB_BAR","TAB_CONTAINER","TAB","TAB_BAR_BUTTON","TAB_BAR_LEFT_BUTTON","TAB_BAR_RIGHT_BUTTON","PANEL","HAS_DRAWER","HAS_TABS","HAS_SCROLLING_HEADER","CASTING_SHADOW","IS_COMPACT","IS_SMALL_SCREEN","IS_DRAWER_OPEN","ON_LARGE_SCREEN","ON_SMALL_SCREEN","contentScrollHandler_","MaterialLayout.prototype.contentScrollHandler_","header_","headerVisible","scrollTop","keyboardEventHandler_","MaterialLayout.prototype.keyboardEventHandler_","drawer_","toggleDrawer","screenSizeHandler_","MaterialLayout.prototype.screenSizeHandler_","screenSizeMediaQuery_","matches","obfuscator_","drawerToggleHandler_","MaterialLayout.prototype.drawerToggleHandler_","type","headerTransitionEndHandler_","MaterialLayout.prototype.headerTransitionEndHandler_","headerClickHandler_","MaterialLayout.prototype.headerClickHandler_","MaterialLayout.prototype.resetTabState_","tabBar","MaterialLayout.prototype.resetPanelState_","MaterialLayout.prototype.toggleDrawer","drawerButton","MaterialLayout.prototype.init","focusedElement","directChildren","childNodes","numChildren","c","child","persisted","overflowY","mode","drawerButtonIcon","innerHTML","firstChild","obfuscator","matchMedia","addListener","tabContainer","leftButton","leftButtonIcon","scrollLeft","rightButton","rightButtonIcon","tabUpdateHandler","scrollWidth","windowResizeHandler","resizeTimeoutId_","MaterialDataTable","DATA_TABLE","SELECTABLE","SELECT_ELEMENT","IS_SELECTED","selectRow_","MaterialDataTable.prototype.selectRow_","checkbox","row","opt_rows","createCheckbox_","MaterialDataTable.prototype.createCheckbox_","label","labelClasses","MaterialDataTable.prototype.init","firstHeader","bodyRows","footRows","rows","concat","th","headerCheckbox","firstCell","td","nodeName","toUpperCase","rowCheckbox","MaterialRipple","INITIAL_SCALE","INITIAL_SIZE","INITIAL_OPACITY","FINAL_OPACITY","FINAL_SCALE","RIPPLE_EFFECT_IGNORE_EVENTS","downHandler_","MaterialRipple.prototype.downHandler_","boundHeight","boundWidth","rippleSize_","sqrt","ignoringMouseDown_","getFrameCount","frameCount","setFrameCount","bound","currentTarget","x","round","touches","setRippleXY","setRippleStyles","animFrameHandler","upHandler_","MaterialRipple.prototype.upHandler_","detail","MaterialRipple.prototype.init","recentering","y_","x_","frameCount_","boundDownHandler","boundUpHandler","this.getFrameCount","this.setFrameCount","fC","getRippleElement","this.getRippleElement","this.setRippleXY","newX","newY","this.setRippleStyles","transformString","offset","scale","webkitTransform","msTransform","transform","this.animFrameHandler"] + "version": 3, + "file": "material.min.js", + "lineCount": 345, + "mappings": "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", + "sources": [ + "material.js" + ], + "names": [ + "MaterialTab", + "tab", + "ctx", + "element_", + "classList", + "contains", + "CssClasses_", + "MDL_JS_RIPPLE_EFFECT", + "rippleContainer", + "document", + "createElement", + "add", + "MDL_RIPPLE_CONTAINER", + "ripple", + "MDL_RIPPLE", + "appendChild", + "addEventListener", + "e", + "getAttribute", + "charAt", + "preventDefault", + "href", + "split", + "panel", + "querySelector", + "resetTabState_", + "resetPanelState_", + "ACTIVE_CLASS", + "MaterialLayoutTab", + "tabs", + "panels", + "layout", + "selectTab", + "content_", + "IS_ACTIVE", + "tabBar_", + "JS_RIPPLE_EFFECT", + "RIPPLE_CONTAINER", + "RIPPLE", + "TAB_MANUAL_SWITCH", + "show", + "componentHandler", + "upgradeDom", + "optJsClass", + "optCssClass", + "upgradeElement", + "element", + "upgradeElements", + "elements", + "upgradeAllRegistered", + "registerUpgradedCallback", + "jsClass", + "callback", + "register", + "config", + "downgradeElements", + "nodes", + "findRegisteredClass_", + "name", + "optReplace", + "i", + "registeredComponents_", + "length", + "className", + "getUpgradedListOfElement_", + "dataUpgraded", + "isElementUpgraded_", + "upgradedList", + "indexOf", + "createEvent_", + "eventType", + "bubbles", + "cancelable", + "window", + "CustomEvent", + "ev", + "createEvent", + "initEvent", + "upgradeDomInternal", + "cssClass", + "registeredClass", + "querySelectorAll", + "n", + "upgradeElementInternal", + "Element", + "Error", + "upgradingEv", + "dispatchEvent", + "defaultPrevented", + "classesToUpgrade", + "push", + "forEach", + "component", + "setAttribute", + "join", + "instance", + "classConstructor", + "createdComponents_", + "j", + "m", + "callbacks", + "widget", + "upgradedEv", + "upgradeElementsInternal", + "Array", + "isArray", + "prototype", + "slice", + "call", + "HTMLElement", + "children", + "deconstructComponentInternal", + "componentIndex", + "splice", + "upgrades", + "componentPlace", + "classAsString", + "upgradeAllRegisteredInternal", + "registerUpgradedCallbackInternal", + "regClass", + "registerInternal", + "newConfig", + "constructor", + "item", + "hasOwnProperty", + "componentConfigProperty_", + "found", + "downgradeNodesInternal", + "downgradeNode", + "node", + "filter", + "NodeList", + "Node", + "documentElement", + "componentHandler.upgradeElement", + "componentHandler.register", + "Date", + "now", + "Date.now", + "getTime", + "vendors", + "requestAnimationFrame", + "vp", + "cancelAnimationFrame", + "test", + "navigator", + "userAgent", + "lastTime", + "window.requestAnimationFrame", + "nextTime", + "Math", + "max", + "setTimeout", + "clearTimeout", + "MaterialButton", + "init", + "Constant_", + "RIPPLE_EFFECT", + "blurHandler_", + "MaterialButton.prototype.blurHandler_", + "event", + "blur", + "disable", + "MaterialButton.prototype.disable", + "disabled", + "enable", + "MaterialButton.prototype.enable", + "MaterialButton.prototype.init", + "rippleElement_", + "boundRippleBlurHandler", + "bind", + "boundButtonBlurHandler", + "MaterialCheckbox", + "TINY_TIMEOUT", + "INPUT", + "BOX_OUTLINE", + "FOCUS_HELPER", + "TICK_OUTLINE", + "RIPPLE_IGNORE_EVENTS", + "RIPPLE_CENTER", + "IS_FOCUSED", + "IS_DISABLED", + "IS_CHECKED", + "IS_UPGRADED", + "onChange_", + "MaterialCheckbox.prototype.onChange_", + "updateClasses_", + "onFocus_", + "MaterialCheckbox.prototype.onFocus_", + "onBlur_", + "MaterialCheckbox.prototype.onBlur_", + "remove", + "onMouseUp_", + "MaterialCheckbox.prototype.onMouseUp_", + "blur_", + "MaterialCheckbox.prototype.updateClasses_", + "checkDisabled", + "checkToggleState", + "MaterialCheckbox.prototype.blur_", + "inputElement_", + "MaterialCheckbox.prototype.checkToggleState", + "checked", + "MaterialCheckbox.prototype.checkDisabled", + "MaterialCheckbox.prototype.disable", + "MaterialCheckbox.prototype.enable", + "check", + "MaterialCheckbox.prototype.check", + "uncheck", + "MaterialCheckbox.prototype.uncheck", + "MaterialCheckbox.prototype.init", + "boxOutline", + "tickContainer", + "tickOutline", + "rippleContainerElement_", + "boundRippleMouseUp", + "boundInputOnChange", + "boundInputOnFocus", + "boundInputOnBlur", + "boundElementMouseUp", + "MaterialIconToggle", + "MaterialIconToggle.prototype.onChange_", + "MaterialIconToggle.prototype.onFocus_", + "MaterialIconToggle.prototype.onBlur_", + "MaterialIconToggle.prototype.onMouseUp_", + "MaterialIconToggle.prototype.updateClasses_", + "MaterialIconToggle.prototype.blur_", + "MaterialIconToggle.prototype.checkToggleState", + "MaterialIconToggle.prototype.checkDisabled", + "MaterialIconToggle.prototype.disable", + "MaterialIconToggle.prototype.enable", + "MaterialIconToggle.prototype.check", + "MaterialIconToggle.prototype.uncheck", + "MaterialIconToggle.prototype.init", + "boundElementOnMouseUp", + "MaterialMenu", + "TRANSITION_DURATION_SECONDS", + "TRANSITION_DURATION_FRACTION", + "CLOSE_TIMEOUT", + "Keycodes_", + "ENTER", + "ESCAPE", + "SPACE", + "UP_ARROW", + "DOWN_ARROW", + "CONTAINER", + "OUTLINE", + "ITEM", + "ITEM_RIPPLE_CONTAINER", + "IS_VISIBLE", + "IS_ANIMATING", + "BOTTOM_LEFT", + "BOTTOM_RIGHT", + "TOP_LEFT", + "TOP_RIGHT", + "UNALIGNED", + "MaterialMenu.prototype.init", + "container", + "parentElement", + "insertBefore", + "removeChild", + "container_", + "outline", + "outline_", + "forElId", + "forEl", + "getElementById", + "forElement_", + "handleForClick_", + "handleForKeyboardEvent_", + "items", + "boundItemKeydown_", + "handleItemKeyboardEvent_", + "boundItemClick_", + "handleItemClick_", + "tabIndex", + "MaterialMenu.prototype.handleForClick_", + "evt", + "rect", + "getBoundingClientRect", + "forRect", + "style", + "right", + "top", + "offsetTop", + "offsetHeight", + "left", + "offsetLeft", + "bottom", + "toggle", + "MaterialMenu.prototype.handleForKeyboardEvent_", + "keyCode", + "focus", + "MaterialMenu.prototype.handleItemKeyboardEvent_", + "currentIndex", + "target", + "MouseEvent", + "click", + "hide", + "MaterialMenu.prototype.handleItemClick_", + "hasAttribute", + "stopPropagation", + "closing_", + "applyClip_", + "MaterialMenu.prototype.applyClip_", + "height", + "width", + "clip", + "removeAnimationEndListener_", + "MaterialMenu.prototype.removeAnimationEndListener_", + "addAnimationEndListener_", + "MaterialMenu.prototype.addAnimationEndListener_", + "MaterialMenu.prototype.show", + "transitionDuration", + "itemDelay", + "transitionDelay", + "parentNode", + "removeEventListener", + "MaterialMenu.prototype.hide", + "removeProperty", + "MaterialMenu.prototype.toggle", + "MaterialProgress", + "INDETERMINATE_CLASS", + "setProgress", + "MaterialProgress.prototype.setProgress", + "p", + "progressbar_", + "setBuffer", + "MaterialProgress.prototype.setBuffer", + "bufferbar_", + "auxbar_", + "MaterialProgress.prototype.init", + "el", + "MaterialRadio", + "JS_RADIO", + "RADIO_BTN", + "RADIO_OUTER_CIRCLE", + "RADIO_INNER_CIRCLE", + "MaterialRadio.prototype.onChange_", + "radios", + "getElementsByClassName", + "button", + "btnElement_", + "MaterialRadio.prototype.onFocus_", + "MaterialRadio.prototype.onBlur_", + "onMouseup_", + "MaterialRadio.prototype.onMouseup_", + "MaterialRadio.prototype.updateClasses_", + "MaterialRadio.prototype.blur_", + "MaterialRadio.prototype.checkDisabled", + "MaterialRadio.prototype.checkToggleState", + "MaterialRadio.prototype.disable", + "MaterialRadio.prototype.enable", + "MaterialRadio.prototype.check", + "MaterialRadio.prototype.uncheck", + "MaterialRadio.prototype.init", + "boundChangeHandler_", + "boundFocusHandler_", + "boundBlurHandler_", + "boundMouseUpHandler_", + "outerCircle", + "innerCircle", + "MaterialSlider", + "isIE_", + "msPointerEnabled", + "IE_CONTAINER", + "SLIDER_CONTAINER", + "BACKGROUND_FLEX", + "BACKGROUND_LOWER", + "BACKGROUND_UPPER", + "IS_LOWEST_VALUE", + "onInput_", + "MaterialSlider.prototype.onInput_", + "updateValueStyles_", + "MaterialSlider.prototype.onChange_", + "MaterialSlider.prototype.onMouseUp_", + "onContainerMouseDown_", + "MaterialSlider.prototype.onContainerMouseDown_", + "newEvent", + "buttons", + "clientX", + "clientY", + "y", + "MaterialSlider.prototype.updateValueStyles_", + "fraction", + "value", + "min", + "backgroundLower_", + "flex", + "webkitFlex", + "backgroundUpper_", + "MaterialSlider.prototype.disable", + "MaterialSlider.prototype.enable", + "change", + "MaterialSlider.prototype.change", + "MaterialSlider.prototype.init", + "containerIE", + "backgroundFlex", + "boundInputHandler", + "boundChangeHandler", + "boundMouseUpHandler", + "boundContainerMouseDownHandler", + "MaterialSnackbar", + "textElement_", + "cssClasses_", + "MESSAGE", + "actionElement_", + "ACTION", + "active", + "actionText_", + "message_", + "actionHandler_", + "undefined", + "queuedNotifications_", + "setActionHidden_", + "ANIMATION_LENGTH", + "SNACKBAR", + "ACTIVE", + "displaySnackbar_", + "MaterialSnackbar.prototype.displaySnackbar_", + "textContent", + "cleanup_", + "timeout_", + "showSnackbar", + "MaterialSnackbar.prototype.showSnackbar", + "data", + "checkQueue_", + "MaterialSnackbar.prototype.checkQueue_", + "shift", + "MaterialSnackbar.prototype.cleanup_", + "MaterialSnackbar.prototype.setActionHidden_", + "removeAttribute", + "MaterialSpinner", + "MDL_SPINNER_LAYER_COUNT", + "MDL_SPINNER_LAYER", + "MDL_SPINNER_CIRCLE_CLIPPER", + "MDL_SPINNER_CIRCLE", + "MDL_SPINNER_GAP_PATCH", + "MDL_SPINNER_LEFT", + "MDL_SPINNER_RIGHT", + "createLayer", + "MaterialSpinner.prototype.createLayer", + "index", + "layer", + "leftClipper", + "gapPatch", + "rightClipper", + "circleOwners", + "circle", + "stop", + "MaterialSpinner.prototype.stop", + "start", + "MaterialSpinner.prototype.start", + "MaterialSpinner.prototype.init", + "MaterialSwitch", + "TRACK", + "THUMB", + "MaterialSwitch.prototype.onChange_", + "MaterialSwitch.prototype.onFocus_", + "MaterialSwitch.prototype.onBlur_", + "MaterialSwitch.prototype.onMouseUp_", + "MaterialSwitch.prototype.updateClasses_", + "MaterialSwitch.prototype.blur_", + "MaterialSwitch.prototype.checkDisabled", + "MaterialSwitch.prototype.checkToggleState", + "MaterialSwitch.prototype.disable", + "MaterialSwitch.prototype.enable", + "on", + "MaterialSwitch.prototype.on", + "off", + "MaterialSwitch.prototype.off", + "MaterialSwitch.prototype.init", + "track", + "thumb", + "focusHelper", + "boundFocusHandler", + "boundBlurHandler", + "MaterialTabs", + "TAB_CLASS", + "PANEL_CLASS", + "UPGRADED_CLASS", + "MDL_JS_RIPPLE_EFFECT_IGNORE_EVENTS", + "initTabs_", + "MaterialTabs.prototype.initTabs_", + "tabs_", + "panels_", + "MaterialTabs.prototype.resetTabState_", + "k", + "MaterialTabs.prototype.resetPanelState_", + "MaterialTabs.prototype.init", + "MaterialTextfield", + "maxRows", + "NO_MAX_ROWS", + "MAX_ROWS_ATTRIBUTE", + "LABEL", + "IS_DIRTY", + "IS_INVALID", + "HAS_PLACEHOLDER", + "onKeyDown_", + "MaterialTextfield.prototype.onKeyDown_", + "currentRowCount", + "MaterialTextfield.prototype.onFocus_", + "MaterialTextfield.prototype.onBlur_", + "onReset_", + "MaterialTextfield.prototype.onReset_", + "MaterialTextfield.prototype.updateClasses_", + "checkValidity", + "checkDirty", + "checkFocus", + "MaterialTextfield.prototype.checkDisabled", + "input_", + "MaterialTextfield.prototype.checkFocus", + "MaterialTextfield.prototype.checkValidity", + "validity", + "valid", + "MaterialTextfield.prototype.checkDirty", + "MaterialTextfield.prototype.disable", + "MaterialTextfield.prototype.enable", + "MaterialTextfield.prototype.change", + "MaterialTextfield.prototype.init", + "label_", + "parseInt", + "isNaN", + "boundUpdateClassesHandler", + "boundResetHandler", + "boundKeyDownHandler", + "invalid", + "MaterialTooltip", + "BOTTOM", + "LEFT", + "RIGHT", + "TOP", + "handleMouseEnter_", + "MaterialTooltip.prototype.handleMouseEnter_", + "props", + "marginLeft", + "offsetWidth", + "marginTop", + "hideTooltip_", + "MaterialTooltip.prototype.hideTooltip_", + "MaterialTooltip.prototype.init", + "boundMouseEnterHandler", + "boundMouseLeaveAndScrollHandler", + "MaterialLayout", + "MAX_WIDTH", + "TAB_SCROLL_PIXELS", + "RESIZE_TIMEOUT", + "MENU_ICON", + "CHEVRON_LEFT", + "CHEVRON_RIGHT", + "Mode_", + "STANDARD", + "SEAMED", + "WATERFALL", + "SCROLL", + "HEADER", + "DRAWER", + "CONTENT", + "DRAWER_BTN", + "ICON", + "HEADER_SEAMED", + "HEADER_WATERFALL", + "HEADER_SCROLL", + "FIXED_HEADER", + "OBFUSCATOR", + "TAB_BAR", + "TAB_CONTAINER", + "TAB", + "TAB_BAR_BUTTON", + "TAB_BAR_LEFT_BUTTON", + "TAB_BAR_RIGHT_BUTTON", + "PANEL", + "HAS_DRAWER", + "HAS_TABS", + "HAS_SCROLLING_HEADER", + "CASTING_SHADOW", + "IS_COMPACT", + "IS_SMALL_SCREEN", + "IS_DRAWER_OPEN", + "ON_LARGE_SCREEN", + "ON_SMALL_SCREEN", + "contentScrollHandler_", + "MaterialLayout.prototype.contentScrollHandler_", + "header_", + "headerVisible", + "scrollTop", + "keyboardEventHandler_", + "MaterialLayout.prototype.keyboardEventHandler_", + "drawer_", + "toggleDrawer", + "screenSizeHandler_", + "MaterialLayout.prototype.screenSizeHandler_", + "screenSizeMediaQuery_", + "matches", + "obfuscator_", + "drawerToggleHandler_", + "MaterialLayout.prototype.drawerToggleHandler_", + "type", + "headerTransitionEndHandler_", + "MaterialLayout.prototype.headerTransitionEndHandler_", + "headerClickHandler_", + "MaterialLayout.prototype.headerClickHandler_", + "MaterialLayout.prototype.resetTabState_", + "tabBar", + "MaterialLayout.prototype.resetPanelState_", + "MaterialLayout.prototype.toggleDrawer", + "drawerButton", + "MaterialLayout.prototype.init", + "focusedElement", + "directChildren", + "childNodes", + "numChildren", + "c", + "child", + "persisted", + "overflowY", + "mode", + "drawerButtonIcon", + "innerHTML", + "firstChild", + "obfuscator", + "matchMedia", + "addListener", + "tabContainer", + "leftButton", + "leftButtonIcon", + "scrollLeft", + "rightButton", + "rightButtonIcon", + "tabUpdateHandler", + "scrollWidth", + "windowResizeHandler", + "resizeTimeoutId_", + "MaterialDataTable", + "DATA_TABLE", + "SELECTABLE", + "SELECT_ELEMENT", + "IS_SELECTED", + "selectRow_", + "MaterialDataTable.prototype.selectRow_", + "checkbox", + "row", + "opt_rows", + "createCheckbox_", + "MaterialDataTable.prototype.createCheckbox_", + "label", + "labelClasses", + "MaterialDataTable.prototype.init", + "firstHeader", + "bodyRows", + "footRows", + "rows", + "concat", + "th", + "headerCheckbox", + "firstCell", + "td", + "nodeName", + "toUpperCase", + "rowCheckbox", + "MaterialRipple", + "INITIAL_SCALE", + "INITIAL_SIZE", + "INITIAL_OPACITY", + "FINAL_OPACITY", + "FINAL_SCALE", + "RIPPLE_EFFECT_IGNORE_EVENTS", + "downHandler_", + "MaterialRipple.prototype.downHandler_", + "boundHeight", + "boundWidth", + "rippleSize_", + "sqrt", + "ignoringMouseDown_", + "getFrameCount", + "frameCount", + "setFrameCount", + "bound", + "currentTarget", + "x", + "round", + "touches", + "setRippleXY", + "setRippleStyles", + "animFrameHandler", + "upHandler_", + "MaterialRipple.prototype.upHandler_", + "detail", + "MaterialRipple.prototype.init", + "recentering", + "y_", + "x_", + "frameCount_", + "boundDownHandler", + "boundUpHandler", + "this.getFrameCount", + "this.setFrameCount", + "fC", + "getRippleElement", + "this.getRippleElement", + "this.setRippleXY", + "newX", + "newY", + "this.setRippleStyles", + "transformString", + "offset", + "scale", + "webkitTransform", + "msTransform", + "transform", + "this.animFrameHandler" + ] } diff --git a/app/modules/web/themes/material-blue/js/mdl-jquery-modal-dialog.map b/app/modules/web/themes/material-blue/js/mdl-jquery-modal-dialog.map index f3f9c38d..7bfab178 100644 --- a/app/modules/web/themes/material-blue/js/mdl-jquery-modal-dialog.map +++ b/app/modules/web/themes/material-blue/js/mdl-jquery-modal-dialog.map @@ -1,8 +1,58 @@ { -"version":3, -"file":"mdl-jquery-modal-dialog.min.js", -"lineCount":7, -"mappings":"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", -"sources":[" [synthetic:base] "," [synthetic:util/findinternal] "," [synthetic:util/defineproperty] "," [synthetic:util/global] "," [synthetic:util/polyfill] "," [synthetic:es6/array/find] ","mdl-jquery-modal-dialog.js"], -"names":["mdlDialog","hideDialog","dialog","$","document","off","css","opacity","setTimeout","remove","show","showDialog","options","extend","id","title","text","neutral","negative","positive","cancelable","contentStyle","onLoaded","hideOther","appendTo","content","find","buttonBar","onClick","neuButton","click","e","preventDefault","negButton","posButton","on","which","stopPropagation","componentHandler","upgradeDom","hide"] + "version": 3, + "file": "mdl-jquery-modal-dialog.min.js", + "lineCount": 7, + "mappings": "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", + "sources": [ + " [synthetic:base] ", + " [synthetic:util/findinternal] ", + " [synthetic:util/defineproperty] ", + " [synthetic:util/global] ", + " [synthetic:util/polyfill] ", + " [synthetic:es6/array/find] ", + "mdl-jquery-modal-dialog.js" + ], + "names": [ + "mdlDialog", + "hideDialog", + "dialog", + "$", + "document", + "off", + "css", + "opacity", + "setTimeout", + "remove", + "show", + "showDialog", + "options", + "extend", + "id", + "title", + "text", + "neutral", + "negative", + "positive", + "cancelable", + "contentStyle", + "onLoaded", + "hideOther", + "appendTo", + "content", + "find", + "buttonBar", + "onClick", + "neuButton", + "click", + "e", + "preventDefault", + "negButton", + "posButton", + "on", + "which", + "stopPropagation", + "componentHandler", + "upgradeDom", + "hide" + ] } diff --git a/app/modules/web/themes/material-blue/views/account/account-editpass.inc b/app/modules/web/themes/material-blue/views/account/account-editpass.inc index 2587896d..3a4bcdec 100644 --- a/app/modules/web/themes/material-blue/views/account/account-editpass.inc +++ b/app/modules/web/themes/material-blue/views/account/account-editpass.inc @@ -1,13 +1,12 @@ diff --git a/app/modules/web/themes/material-blue/views/account/search-header.inc b/app/modules/web/themes/material-blue/views/account/search-header.inc index 8d31a0c1..5580cb8e 100644 --- a/app/modules/web/themes/material-blue/views/account/search-header.inc +++ b/app/modules/web/themes/material-blue/views/account/search-header.inc @@ -1,13 +1,12 @@
info -
-

. + * along with sysPass. If not, see . */ -define('APP_ROOT', __DIR__); -define('APP_MODULE', 'cli'); +const APP_ROOT = __DIR__; +const APP_MODULE = 'cli'; require APP_ROOT . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'Base.php'; diff --git a/index.php b/index.php index 12274c33..c0fb08fb 100644 --- a/index.php +++ b/index.php @@ -1,10 +1,10 @@ . + * along with sysPass. If not, see . */ -define('APP_ROOT', __DIR__); -define('APP_MODULE', 'web'); +const APP_ROOT = __DIR__; +const APP_MODULE = 'web'; require APP_ROOT . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'Base.php'; \ No newline at end of file diff --git a/lib/Base.php b/lib/Base.php index 34426122..1f18107b 100644 --- a/lib/Base.php +++ b/lib/Base.php @@ -29,13 +29,16 @@ use SP\Bootstrap; defined('APP_ROOT') || die(); // Core PATHS -define('DS', DIRECTORY_SEPARATOR); -define('BASE_PATH', __DIR__); -define('APP_PATH', APP_ROOT . DS . 'app'); -define('VENDOR_PATH', APP_ROOT . DS . 'vendor'); -define('SQL_PATH', APP_ROOT . DS . 'schemas'); -define('PUBLIC_PATH', APP_ROOT . DS . 'public'); -define('XML_SCHEMA', SQL_PATH . DS . 'syspass.xsd'); +const DS = DIRECTORY_SEPARATOR; +const BASE_PATH = __DIR__; +const APP_PATH = APP_ROOT . DS . 'app'; +const VENDOR_PATH = APP_ROOT . DS . 'vendor'; +const SQL_PATH = APP_ROOT . DS . 'schemas'; +const PUBLIC_PATH = APP_ROOT . DS . 'public'; +const XML_SCHEMA = SQL_PATH . DS . 'syspass.xsd'; +const RESOURCES_PATH = APP_PATH . DS . 'resources'; +const MODULES_PATH = APP_PATH . DS . 'modules'; +const LOCALES_PATH = APP_PATH . DS . 'locales'; // Start tracking the memory used $memInit = memory_get_usage(); @@ -53,9 +56,11 @@ define('DEBUG', getenv('DEBUG') || false); define('CONFIG_PATH', getenv('CONFIG_PATH') ?: APP_PATH . DS . 'config'); -define('RESOURCES_PATH', APP_PATH . DS . 'resources'); + // Setup config files +const OLD_CONFIG_FILE = CONFIG_PATH . DS . 'config.php'; + define('CONFIG_FILE', getenv('CONFIG_FILE') ?: CONFIG_PATH . DS . 'config.xml'); @@ -65,15 +70,12 @@ define('ACTIONS_FILE', define('MIMETYPES_FILE', getenv('MIMETYPES_FILE') ?: RESOURCES_PATH . DS . 'mime.xml'); -define('OLD_CONFIG_FILE', CONFIG_PATH . DS . 'config.php'); define('LOG_FILE', getenv('LOG_FILE') ?: CONFIG_PATH . DS . 'syspass.log'); -define('LOCK_FILE', CONFIG_PATH . DS . '.lock'); +const LOCK_FILE = CONFIG_PATH . DS . '.lock'; // Setup application paths -define('MODULES_PATH', APP_PATH . DS . 'modules'); -define('LOCALES_PATH', APP_PATH . DS . 'locales'); define('BACKUP_PATH', getenv('BACKUP_PATH') ?: APP_PATH . DS . 'backup'); diff --git a/lib/BaseFunctions.php b/lib/BaseFunctions.php index 84819006..e599b63b 100644 --- a/lib/BaseFunctions.php +++ b/lib/BaseFunctions.php @@ -28,11 +28,11 @@ use DI\ContainerBuilder; -define('LOG_FORMAT', "[%s] [%s] %s"); +const LOG_FORMAT = "[%s] [%s] %s"; /** * [timestamp] [type] [caller] data */ -define('LOG_FORMAT_OWN', '[%s] syspass.%s: logger {"message":"%s","caller":"%s"}' . PHP_EOL); +const LOG_FORMAT_OWN = '[%s] syspass.%s: logger {"message":"%s","caller":"%s"}' . PHP_EOL; /** * Basic logger to handle some debugging and exception messages. @@ -56,9 +56,21 @@ function logger($data, ?string $type = 'DEBUG') $caller = getLastCaller(); if (is_scalar($data)) { - $line = sprintf(LOG_FORMAT_OWN, $date, $type, $data, $caller); + $line = sprintf( + LOG_FORMAT_OWN, + $date, + $type, + $data, + $caller + ); } else { - $line = sprintf(LOG_FORMAT_OWN, $date, $type, print_r($data, true), $caller); + $line = sprintf( + LOG_FORMAT_OWN, + $date, + $type, + print_r($data, true), + $caller + ); } $useOwn = (!defined('LOG_FILE') @@ -67,9 +79,19 @@ function logger($data, ?string $type = 'DEBUG') if ($useOwn === false) { if (is_scalar($data)) { - $line = sprintf(LOG_FORMAT, $type, $data, $caller); + $line = sprintf( + LOG_FORMAT, + $type, + $data, + $caller + ); } else { - $line = sprintf(LOG_FORMAT, $type, print_r($data, true), $caller); + $line = sprintf( + LOG_FORMAT, + $type, + print_r($data, true), + $caller + ); } error_log($line); @@ -86,40 +108,39 @@ function printLastCallers() /** * Print last caller from backtrace - * - * @param int $skip - * - * @return string */ -function getLastCaller($skip = 2): string +function getLastCaller(int $skip = 2): string { $callers = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5); - if (isset($callers[$skip], $callers[$skip]['class'], $callers[$skip]['function'])) { + if (isset($callers[$skip]['class'], $callers[$skip]['function'])) { return $callers[$skip]['class'] . '::' . $callers[$skip]['function']; } return 'N/A'; } -/** - * @param Throwable $e - * - * @return string - */ function formatStackTrace(Throwable $e): string { $out = []; foreach ($e->getTrace() as $index => $trace) { if (isset($trace['file'])) { - $file = sprintf('%s(%d)', $trace['file'], $trace['line']); + $file = sprintf( + '%s(%d)', + $trace['file'], + $trace['line'] + ); } else { $file = '[internal function]'; } if (isset($trace['class'])) { - $function = sprintf('%s->%s', $trace['class'], $trace['function']); + $function = sprintf( + '%s->%s', + $trace['class'], + $trace['function'] + ); } else { $function = $trace['function']; } @@ -138,7 +159,13 @@ function formatStackTrace(Throwable $e): string } } - $out[] = sprintf('#%d %s: %s(%s)', $index, $file, $function, implode(',', $args)); + $out[] = sprintf( + '#%d %s: %s(%s)', + $index, + $file, + $function, + implode(',', $args) + ); } return implode(PHP_EOL, $out); @@ -151,29 +178,39 @@ function formatStackTrace(Throwable $e): string */ function processException(\Exception $exception) { - logger(sprintf("%s\n%s", __($exception->getMessage()), formatStackTrace($exception)), 'EXCEPTION'); + logger(sprintf( + "%s\n%s", + __($exception->getMessage()), + formatStackTrace($exception)), + 'EXCEPTION'); if (($previous = $exception->getPrevious()) !== null) { - logger(sprintf("(P) %s\n%s", __($previous->getMessage()), $previous->getTraceAsString()), 'EXCEPTION'); + logger(sprintf( + "(P) %s\n%s", + __($previous->getMessage()), + $previous->getTraceAsString()), + 'EXCEPTION'); } } -/** - * @param array $trace - * - * @return string - */ function formatTrace(array $trace): string { $btLine = []; $i = 0; foreach ($trace as $caller) { - $class = isset($caller['class']) ? $caller['class'] : ''; - $file = isset($caller['file']) ? $caller['file'] : ''; - $line = isset($caller['line']) ? $caller['line'] : 0; + $class = $caller['class'] ?? ''; + $file = $caller['file'] ?? ''; + $line = $caller['line'] ?? 0; - $btLine[] = sprintf('Caller %d: %s\%s (%s:%d)', $i, $class, $caller['function'], $file, $line); + $btLine[] = sprintf( + 'Caller %d: %s\%s (%s:%d)', + $i, + $class, + $caller['function'], + $file, + $line + ); $i++; } @@ -185,21 +222,19 @@ function formatTrace(array $trace): string * * @param string $message * @param bool $translate Si es necesario traducir - * - * @return string */ -function __(string $message, $translate = true): string +function __(string $message, bool $translate = true): string { - return $translate === true && $message !== '' && mb_strlen($message) < 4096 ? gettext($message) : $message; + return $translate === true + && $message !== '' + && mb_strlen($message) < 4096 + ? gettext($message) + : $message; } /** * Returns an untranslated string (gettext placeholder). * Dummy function to extract strings from source code - * - * @param string $message - * - * @return string */ function __u(string $message): string { @@ -208,24 +243,18 @@ function __u(string $message): string /** * Alias para obtener las locales de un dominio - * - * @param string $domain - * @param string $message - * @param bool $translate - * - * @return string */ function _t(string $domain, string $message, bool $translate = true): string { - return $translate === true && $message !== '' && mb_strlen($message) < 4096 ? dgettext($domain, $message) : $message; + return $translate === true + && $message !== '' + && mb_strlen($message) < 4096 + ? dgettext($domain, $message) + : $message; } /** * Capitalización de cadenas multi byte - * - * @param $string - * - * @return string */ function mb_ucfirst($string): string { @@ -236,27 +265,21 @@ function mb_ucfirst($string): string * Devuelve el tiempo actual en coma flotante. * Esta función se utiliza para calcular el tiempo de renderizado con coma flotante * - * @param float $from - * * @returns float con el tiempo actual - * @return float */ -function getElapsedTime($from) +function getElapsedTime(float $from): float { - if ($from === 0) { + if ($from === 0.0) { return 0; } - return microtime(true) - floatval($from); + return microtime(true) - $from; } /** * Inicializar módulo - * - * @param $module - * @param ContainerBuilder|null $builder */ -function initModule($module, ContainerBuilder $builder = null) +function initModule(string $module, ?ContainerBuilder $builder = null) { $dir = dir(MODULES_PATH); @@ -281,9 +304,6 @@ function initModule($module, ContainerBuilder $builder = null) } /** - * @param $dir - * @param $levels - * * @return bool|string */ function nDirname($dir, $levels) diff --git a/lib/Definitions.php b/lib/Definitions.php index d056a8be..81f98ed0 100644 --- a/lib/Definitions.php +++ b/lib/Definitions.php @@ -26,7 +26,7 @@ use Monolog\Logger; use PHPMailer\PHPMailer\PHPMailer; use Psr\Container\ContainerInterface; use SP\Config\Config; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Acl\Acl; use SP\Core\Acl\Actions; use SP\Core\Context\ContextInterface; @@ -53,36 +53,41 @@ use function DI\get; return [ Request::class => create(Request::class) ->constructor(\Klein\Request::createFromGlobals()), - ContextInterface::class => function (ContainerInterface $c) { - if (APP_MODULE === 'web') { - return $c->get(SessionContext::class); - } + ContextInterface::class => + static function (ContainerInterface $c) { + if (APP_MODULE === 'web') { + return $c->get(SessionContext::class); + } - return $c->get(StatelessContext::class); - }, - Config::class => function (ContainerInterface $c) { - return new Config( - new XmlHandler(new FileHandler(CONFIG_FILE)), - new FileCache(Config::CONFIG_CACHE_FILE), - $c); - }, - ConfigData::class => function (Config $config) { - return $config->getConfigData(); - }, + return $c->get(StatelessContext::class); + }, + Config::class => + static function (ContainerInterface $c) { + return new Config( + new XmlHandler(new FileHandler(CONFIG_FILE)), + new FileCache(Config::CONFIG_CACHE_FILE), + $c); + }, + ConfigDataInterface::class => + static function (Config $config) { + return $config->getConfigData(); + }, DBStorageInterface::class => create(MySQLHandler::class) ->constructor(factory([DatabaseConnectionData::class, 'getFromConfig'])), - Actions::class => function (ContainerInterface $c) { - return new Actions( - new FileCache(Actions::ACTIONS_CACHE_FILE), - new XmlHandler(new FileHandler(ACTIONS_FILE)) - ); - }, - MimeTypes::class => function () { - return new MimeTypes( - new FileCache(MimeTypes::MIME_CACHE_FILE), - new XmlHandler(new FileHandler(MIMETYPES_FILE)) - ); - }, + Actions::class => + static function (ContainerInterface $c) { + return new Actions( + new FileCache(Actions::ACTIONS_CACHE_FILE), + new XmlHandler(new FileHandler(ACTIONS_FILE)) + ); + }, + MimeTypes::class => + static function () { + return new MimeTypes( + new FileCache(MimeTypes::MIME_CACHE_FILE), + new XmlHandler(new FileHandler(MIMETYPES_FILE)) + ); + }, Acl::class => autowire(Acl::class) ->constructorParameter('action', get(Actions::class)), ThemeInterface::class => autowire(Theme::class) diff --git a/lib/SP/Adapters/AccountAdapter.php b/lib/SP/Adapters/AccountAdapter.php index 7b82a15d..08166e2d 100644 --- a/lib/SP/Adapters/AccountAdapter.php +++ b/lib/SP/Adapters/AccountAdapter.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,14 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Adapters; use League\Fractal\Resource\Collection; use SP\Core\Acl\ActionsInterface; -use SP\Core\Exceptions\SPException; use SP\DataModel\Dto\AccountDetailsResponse; use SP\Mvc\Controller\ItemTrait; use SP\Mvc\View\Components\SelectItemAdapter; @@ -46,12 +45,12 @@ final class AccountAdapter extends AdapterBase ]; /** - * @param AccountDetailsResponse $data - * - * @return Collection - * @throws SPException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + * @throws \SP\Services\ServiceException */ - public function includeCustomFields(AccountDetailsResponse $data) + public function includeCustomFields(AccountDetailsResponse $data): Collection { return $this->collection( $this->getCustomFieldsForItem(ActionsInterface::ACCOUNT, $data->getId()), @@ -59,11 +58,6 @@ final class AccountAdapter extends AdapterBase ); } - /** - * @param AccountDetailsResponse $data - * - * @return array - */ public function transform(AccountDetailsResponse $data): array { $account = $data->getAccountVData(); @@ -71,32 +65,32 @@ final class AccountAdapter extends AdapterBase return [ 'id' => (int)$account->getId(), 'name' => $account->getName(), - 'clientId' => (int)$account->getClientId(), + 'clientId' => $account->getClientId(), 'clientName' => $account->getClientName(), - 'categoryId' => (int)$account->getCategoryId(), + 'categoryId' => $account->getCategoryId(), 'categoryName' => $account->getCategoryName(), - 'userId' => (int)$account->getUserId(), + 'userId' => $account->getUserId(), 'userName' => $account->getUserName(), 'userLogin' => $account->getUserLogin(), - 'userGroupId' => (int)$account->getUserGroupId(), + 'userGroupId' => $account->getUserGroupId(), 'userGroupName' => $account->getUserGroupName(), - 'userEditId' => (int)$account->getUserEditId(), + 'userEditId' => $account->getUserEditId(), 'userEditName' => $account->getUserEditName(), 'userEditLogin' => $account->getUserEditLogin(), 'login' => $account->getLogin(), 'url' => $account->getUrl(), 'notes' => $account->getNotes(), - 'otherUserEdit' => (int)$account->getOtherUserEdit(), - 'otherUserGroupEdit' => (int)$account->getOtherUserGroupEdit(), - 'dateAdd' => (int)$account->getDateAdd(), - 'dateEdit' => (int)$account->getDateEdit(), - 'countView' => (int)$account->getCountView(), - 'countDecrypt' => (int)$account->getCountDecrypt(), - 'isPrivate' => (int)$account->getIsPrivate(), - 'isPrivateGroup' => (int)$account->getIsPrivateGroup(), - 'passDate' => (int)$account->getPassDate(), - 'passDateChange' => (int)$account->getPassDateChange(), - 'parentId' => (int)$account->getParentId(), + 'otherUserEdit' => $account->getOtherUserEdit(), + 'otherUserGroupEdit' => $account->getOtherUserGroupEdit(), + 'dateAdd' => $account->getDateAdd(), + 'dateEdit' => $account->getDateEdit(), + 'countView' => $account->getCountView(), + 'countDecrypt' => $account->getCountDecrypt(), + 'isPrivate' => $account->getIsPrivate(), + 'isPrivateGroup' => $account->getIsPrivateGroup(), + 'passDate' => $account->getPassDate(), + 'passDateChange' => $account->getPassDateChange(), + 'parentId' => $account->getParentId(), 'publicLinkHash' => $account->getPublicLinkHash(), 'tags' => SelectItemAdapter::factory($data->getTags())->getItemsFromModel(), 'users' => SelectItemAdapter::factory($data->getUsers())->getItemsFromModel(), diff --git a/lib/SP/Adapters/AdapterBase.php b/lib/SP/Adapters/AdapterBase.php index 057b8a7e..35b1a328 100644 --- a/lib/SP/Adapters/AdapterBase.php +++ b/lib/SP/Adapters/AdapterBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,14 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Adapters; use League\Fractal\TransformerAbstract; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; /** * Class AdapterBase @@ -35,17 +35,9 @@ use SP\Config\ConfigData; */ abstract class AdapterBase extends TransformerAbstract { - /** - * @var ConfigData - */ - protected $configData; + protected ConfigDataInterface $configData; - /** - * AccountAdapter constructor. - * - * @param ConfigData $configData - */ - public function __construct(ConfigData $configData) + public function __construct(ConfigDataInterface $configData) { $this->configData = $configData; } diff --git a/lib/SP/Adapters/CategoryAdapter.php b/lib/SP/Adapters/CategoryAdapter.php index a4735819..9710ade5 100644 --- a/lib/SP/Adapters/CategoryAdapter.php +++ b/lib/SP/Adapters/CategoryAdapter.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,14 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Adapters; use League\Fractal\Resource\Collection; use SP\Core\Acl\ActionsInterface; -use SP\Core\Exceptions\SPException; use SP\DataModel\CategoryData; use SP\Mvc\Controller\ItemTrait; use SP\Util\Link; @@ -45,12 +44,12 @@ final class CategoryAdapter extends AdapterBase ]; /** - * @param CategoryData $data - * - * @return Collection - * @throws SPException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + * @throws \SP\Services\ServiceException */ - public function includeCustomFields(CategoryData $data) + public function includeCustomFields(CategoryData $data): Collection { return $this->collection( $this->getCustomFieldsForItem(ActionsInterface::CATEGORY, $data->id), @@ -58,15 +57,10 @@ final class CategoryAdapter extends AdapterBase ); } - /** - * @param CategoryData $data - * - * @return array - */ public function transform(CategoryData $data): array { return [ - 'id' => (int)$data->getId(), + 'id' => $data->getId(), 'name' => $data->getName(), 'description' => $data->getDescription(), 'customFields' => null, diff --git a/lib/SP/Adapters/ClientAdapter.php b/lib/SP/Adapters/ClientAdapter.php index be67d6ab..bbe08401 100644 --- a/lib/SP/Adapters/ClientAdapter.php +++ b/lib/SP/Adapters/ClientAdapter.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,14 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Adapters; use League\Fractal\Resource\Collection; use SP\Core\Acl\ActionsInterface; -use SP\Core\Exceptions\SPException; use SP\DataModel\ClientData; use SP\Mvc\Controller\ItemTrait; use SP\Util\Link; @@ -45,12 +44,12 @@ final class ClientAdapter extends AdapterBase ]; /** - * @param ClientData $data - * - * @return Collection - * @throws SPException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + * @throws \SP\Services\ServiceException */ - public function includeCustomFields(ClientData $data) + public function includeCustomFields(ClientData $data): Collection { return $this->collection( $this->getCustomFieldsForItem(ActionsInterface::CLIENT, $data->id), @@ -58,15 +57,10 @@ final class ClientAdapter extends AdapterBase ); } - /** - * @param ClientData $data - * - * @return array - */ public function transform(ClientData $data): array { return [ - 'id' => (int)$data->getId(), + 'id' => $data->getId(), 'name' => $data->getName(), 'description' => $data->getDescription(), 'global' => $data->isGlobal, diff --git a/lib/SP/Adapters/CustomFieldAdapter.php b/lib/SP/Adapters/CustomFieldAdapter.php index c466e00c..7e5dfbc6 100644 --- a/lib/SP/Adapters/CustomFieldAdapter.php +++ b/lib/SP/Adapters/CustomFieldAdapter.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Adapters; @@ -34,11 +34,6 @@ use SP\Services\CustomField\CustomFieldItem; */ final class CustomFieldAdapter extends AdapterBase { - /** - * @param CustomFieldItem $data - * - * @return array - */ public function transform(CustomFieldItem $data): array { return [ diff --git a/lib/SP/Bootstrap.php b/lib/SP/Bootstrap.php index a9f2c693..3f6e5e4f 100644 --- a/lib/SP/Bootstrap.php +++ b/lib/SP/Bootstrap.php @@ -34,7 +34,7 @@ use PHPMailer\PHPMailer\Exception; use Psr\Container\ContainerInterface; use RuntimeException; use SP\Config\Config; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Config\ConfigUtil; use SP\Core\Exceptions\ConfigException; use SP\Core\Exceptions\InitializationException; @@ -85,29 +85,15 @@ final class Bootstrap /** * @var bool Indica si la versión de PHP es correcta */ - public static bool $checkPhpVersion; - /** - * @var ContainerInterface - */ - private static $container; - /** - * @var Klein - */ - private $router; - /** - * @var Request - */ - private $request; - /** - * @var ConfigData - */ - private $configData; + public static bool $checkPhpVersion = false; + private static ContainerInterface $container; + private Klein $router; + private Request $request; + private ConfigDataInterface $configData; /** * Bootstrap constructor. * - * @param Container $container - * * @throws \DI\DependencyException * @throws \DI\NotFoundException */ @@ -125,9 +111,6 @@ final class Bootstrap $this->initRouter(); } - /** - * Inicializar router - */ protected function initRouter(): void { $this->router->onError(function ($router, $err_msg, $type, $err) { @@ -162,9 +145,6 @@ final class Bootstrap ); } - /** - * @return \Closure - */ private function manageCorsRequest(): Closure { return function ($request, $response) { @@ -175,20 +155,20 @@ final class Bootstrap }; } - /** - * @param \Klein\Response $response - */ private function setCors(Response $response): void { - $response->header('Access-Control-Allow-Origin', $this->configData->getApplicationUrl() ?? $this->request->getHttpHost()); - $response->header('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization'); + $response->header( + 'Access-Control-Allow-Origin', + $this->configData->getApplicationUrl() + ?? $this->request->getHttpHost() + ); + $response->header( + 'Access-Control-Allow-Headers', + 'X-Requested-With, Content-Type, Accept, Origin, Authorization' + ); $response->header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); } - /** - * - * @return \Closure - */ private function manageApiRequest(): Closure { return function ($request, $response, $service) { @@ -197,16 +177,21 @@ final class Bootstrap $apiRequest = self::$container->get(ApiRequest::class); - [$controller, $action] = explode('/', $apiRequest->getMethod()); + [$controllerName, $action] = explode('/', $apiRequest->getMethod()); + + $controllerClass = self::getControllerClass($controllerName); - $controllerClass = 'SP\\Modules\\' . ucfirst(APP_MODULE) . '\\Controllers\\' . ucfirst($controller) . 'Controller'; $method = $action . 'Action'; if (!method_exists($controllerClass, $method)) { logger($controllerClass . '::' . $method); /** @var Response $response */ - $response->headers()->set('Content-type', 'application/json; charset=utf-8'); + $response->headers() + ->set( + 'Content-type', + 'application/json; charset=utf-8' + ); return $response->body( JsonRpcResponse::getResponseError( @@ -220,7 +205,7 @@ final class Bootstrap $this->initializeCommon(); self::$container->get(InitApi::class) - ->initialize($controller); + ->initialize($controllerName); logger('Routing call: ' . $controllerClass . '::' . $method); @@ -238,6 +223,15 @@ final class Bootstrap }; } + private static function getControllerClass(string $controllerName): string + { + return sprintf( + 'SP\Modules\%s\Controllers\%sController', + ucfirst(APP_MODULE), + ucfirst($controllerName) + ); + } + /** * @throws ConfigException * @throws Core\Exceptions\CheckException @@ -292,11 +286,19 @@ final class Bootstrap // Establecer las cabeceras de autentificación para apache+php-cgi // Establecer las cabeceras de autentificación para que apache+php-cgi funcione si la variable es renombrada por apache if (($server->get('HTTP_AUTHORIZATION') !== null - && preg_match('/Basic\s+(.*)$/i', $server->get('HTTP_AUTHORIZATION'), $matches)) + && preg_match( + '/Basic\s+(.*)$/i', + $server->get('HTTP_AUTHORIZATION'), + $matches)) || ($server->get('REDIRECT_HTTP_AUTHORIZATION') !== null - && preg_match('/Basic\s+(.*)$/i', $server->get('REDIRECT_HTTP_AUTHORIZATION'), $matches)) + && preg_match( + '/Basic\s+(.*)$/i', + $server->get('REDIRECT_HTTP_AUTHORIZATION'), + $matches)) ) { - [$name, $password] = explode(':', base64_decode($matches[1]), 2); + [$name, $password] = explode(':', + base64_decode($matches[1]), + 2); $server->set('PHP_AUTH_USER', strip_tags($name)); $server->set('PHP_AUTH_PW', strip_tags($password)); @@ -343,7 +345,7 @@ final class Bootstrap /** * Establecer las rutas de la aplicación. * Esta función establece las rutas del sistema de archivos y web de la aplicación. - * La variables de clase definidas son $SERVERROOT, $WEBROOT y $SUBURI + * Las variables de clase definidas son $SERVERROOT, $WEBROOT y $SUBURI */ private function initPaths(): void { @@ -401,10 +403,6 @@ final class Bootstrap } } - /** - * - * @return \Closure - */ private function manageWebRequest(): Closure { return function ($request, $response, $service) { @@ -420,8 +418,8 @@ final class Bootstrap if (!preg_match_all( '#(?P[a-zA-Z]+)(?:/(?P[a-zA-Z]+))?(?P(/[a-zA-Z\d.]+)+)?#', $route, - $matches) - ) { + $matches + )) { throw new RuntimeException(self::OOPS_MESSAGE); } @@ -437,7 +435,7 @@ final class Bootstrap '/') )); - $controllerClass = 'SP\\Modules\\' . ucfirst(APP_MODULE) . '\\Controllers\\' . ucfirst($controllerName) . 'Controller'; + $controllerClass = self::getControllerClass($controllerName); $this->initializePluginClasses(); @@ -458,7 +456,12 @@ final class Bootstrap ->initialize($controllerName); } - logger('Routing call: ' . $controllerClass . '::' . $methodName . '::' . print_r($methodParams, true)); + logger(sprintf( + 'Routing call: %s::%s::%s', + $controllerClass, + $methodName, + print_r($methodParams, true) + )); $controller = new $controllerClass(self::$container, $methodName); @@ -478,9 +481,6 @@ final class Bootstrap }; } - /** - * initializePluginClasses - */ protected function initializePluginClasses(): void { $loader = require APP_ROOT . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; @@ -490,24 +490,21 @@ final class Bootstrap } } - /** - * @return ContainerInterface - */ - public static function getContainer() + public static function getContainer(): ContainerInterface { return self::$container; } /** - * @param Container $container - * @param string $module - * * @throws InitializationException * @throws DependencyException * @throws NotFoundException * @throws Core\Context\ContextException */ - public static function run(Container $container, string $module = APP_MODULE): void + public static function run( + Container $container, + string $module = APP_MODULE + ): void { switch ($module) { case 'web': diff --git a/lib/SP/Config/Config.php b/lib/SP/Config/Config.php index ff02d557..293f53a4 100644 --- a/lib/SP/Config/Config.php +++ b/lib/SP/Config/Config.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Config; @@ -30,6 +30,7 @@ use Psr\Container\ContainerInterface; use SP\Core\AppInfoInterface; use SP\Core\Context\ContextInterface; use SP\Core\Exceptions\ConfigException; +use SP\Core\Exceptions\SPException; use SP\Services\Config\ConfigBackupService; use SP\Storage\File\FileCacheInterface; use SP\Storage\File\FileException; @@ -47,45 +48,24 @@ final class Config * Cache file name */ public const CONFIG_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'config.cache'; - /** - * @var int - */ - private static $timeUpdated; - /** - * @var ContextInterface - */ - private $context; - /** - * @var bool - */ - private $configLoaded = false; - /** - * @var ConfigData - */ - private $configData; - /** - * @var XmlFileStorageInterface - */ - private $fileStorage; - /** - * @var FileCacheInterface - */ - private $fileCache; - /** - * @var ContainerInterface - */ - private $dic; + private static int $timeUpdated; + private ContextInterface $context; + private bool $configLoaded = false; + private ?ConfigDataInterface $configData = null; + private XmlFileStorageInterface $fileStorage; + private FileCacheInterface $fileCache; + private ContainerInterface $dic; /** * Config constructor. * - * @param XmlFileStorageInterface $fileStorage - * @param FileCacheInterface $fileCache - * @param ContainerInterface $dic - * * @throws ConfigException */ - public function __construct(XmlFileStorageInterface $fileStorage, FileCacheInterface $fileCache, ContainerInterface $dic) + public function __construct( + XmlFileStorageInterface $fileStorage, + FileCacheInterface $fileCache, + ContainerInterface $dic + ) { $this->fileCache = $fileCache; $this->fileStorage = $fileStorage; @@ -98,7 +78,7 @@ final class Config /** * @throws ConfigException */ - private function initialize() + private function initialize(): void { if (!$this->configLoaded) { try { @@ -139,7 +119,7 @@ final class Config processException($e); throw new ConfigException($e->getMessage(), - ConfigException::CRITICAL, + SPException::CRITICAL, null, $e->getCode(), $e); @@ -147,9 +127,6 @@ final class Config } } - /** - * @return bool - */ private function isCacheExpired(): bool { try { @@ -162,22 +139,17 @@ final class Config /** * Cargar el archivo de configuración * - * @return ConfigData * @throws FileException */ - public function loadConfigFromFile(): ConfigData + public function loadConfigFromFile(): ConfigDataInterface { return $this->configMapper($this->fileStorage->load('config')->getItems()); } /** * Map the config array keys with ConfigData class setters - * - * @param array $items - * - * @return ConfigData */ - private function configMapper(array $items): ConfigData + private function configMapper(array $items): ConfigDataInterface { $configData = new ConfigData(); @@ -196,13 +168,12 @@ final class Config /** * Guardar la configuración * - * @param ConfigData $configData - * @param bool $backup - * - * @return Config * @throws FileException */ - public function saveConfig(ConfigData $configData, ?bool $backup = true): Config + public function saveConfig( + ConfigDataInterface $configData, + ?bool $backup = true + ): Config { if ($backup) { $this->dic->get(ConfigBackupService::class) @@ -226,9 +197,6 @@ final class Config return $this; } - /** - * @return int - */ public static function getTimeUpdated(): int { return self::$timeUpdated; @@ -236,12 +204,8 @@ final class Config /** * Commits a config data - * - * @param ConfigData $configData - * - * @return Config */ - public function updateConfig(ConfigData $configData): Config + public function updateConfig(ConfigDataInterface $configData): Config { $configData->setConfigDate(time()); $configData->setConfigSaver($this->context->getUserData()->getLogin()); @@ -256,12 +220,8 @@ final class Config /** * Cargar la configuración desde el contexto - * - * @param bool $reload - * - * @return ConfigData */ - public function loadConfig(?bool $reload = false): ConfigData + public function loadConfig(?bool $reload = false): ConfigDataInterface { try { $configData = $this->fileCache->load(); @@ -285,15 +245,16 @@ final class Config } /** - * @return ConfigData + * Returns a clone of the configuration data + * + * @return \SP\Config\ConfigDataInterface */ - public function getConfigData(): ConfigData + public function getConfigData(): ConfigDataInterface { return clone $this->configData; } /** - * @return Config * @throws FileException * @throws EnvironmentIsBrokenException */ diff --git a/lib/SP/Config/ConfigCache.php b/lib/SP/Config/ConfigCache.php deleted file mode 100644 index bbb2047d..00000000 --- a/lib/SP/Config/ConfigCache.php +++ /dev/null @@ -1,94 +0,0 @@ -. - */ - -namespace SP\Config; - -use SP\Storage\File\FileCacheInterface; -use SP\Storage\File\FileException; - -/** - * Class ConfigCache - * - * @package SP\Config - */ -final class ConfigCache -{ - /** - * Cache file name - */ - const CONFIG_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'config.cache'; - /** - * @var FileCacheInterface - */ - private $fileCache; - - - /** - * ConfigCache constructor. - * - * @param FileCacheInterface $fileCache - */ - public function __construct(FileCacheInterface $fileCache) - { - $this->fileCache = $fileCache; - } - - /** - * Saves config into the cache file - * - * @param ConfigData $configData - */ - public function saveConfigToCache(ConfigData $configData) - { - try { - $this->fileCache->save($configData); - - logger('Saved config cache'); - } catch (FileException $e) { - processException($e); - } - } - - /** - * Loads config from the cache file - * - * @return ConfigData - */ - public function loadConfigFromCache() - { - try { - $configData = $this->fileCache->load(); - - if ($configData instanceof ConfigData) { - logger('Loaded config cache'); - - return $configData; - } - } catch (FileException $e) { - processException($e); - } - - return null; - } -} \ No newline at end of file diff --git a/lib/SP/Config/ConfigData.php b/lib/SP/Config/ConfigData.php index 8fbf773c..9dd0ca78 100644 --- a/lib/SP/Config/ConfigData.php +++ b/lib/SP/Config/ConfigData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Config; @@ -29,551 +29,341 @@ use SP\Core\DataCollection; /** * Class configData - * - * @package SP\Config */ -final class ConfigData extends DataCollection implements JsonSerializable +final class ConfigData extends DataCollection + implements JsonSerializable, ConfigDataInterface { - const PUBLIC_LINK_MAX_VIEWS = 3; - const PUBLIC_LINK_MAX_TIME = 600; - const ACCOUNT_COUNT = 12; - const DB_PORT = 3306; - const FILES_ALLOWED_SIZE = 1024; - const MAIL_PORT = 587; - const SESSION_TIMEOUT = 300; - const SITE_THEME = 'material-blue'; - const SYSLOG_PORT = 514; - const ACCOUNT_EXPIRE_TIME = 10368000; + private const PUBLIC_LINK_MAX_VIEWS = 3; + private const PUBLIC_LINK_MAX_TIME = 600; + private const ACCOUNT_COUNT = 12; + private const DB_PORT = 3306; + private const FILES_ALLOWED_SIZE = 1024; + private const MAIL_PORT = 587; + private const SESSION_TIMEOUT = 300; + private const SITE_THEME = 'material-blue'; + private const SYSLOG_PORT = 514; + private const ACCOUNT_EXPIRE_TIME = 10368000; + private const PROXY_PORT = 8080; - /** - * @return array - */ public function getAttributes(): array { return $this->attributes; } - /** - * @return array - */ public function getLogEvents(): array { return $this->get('logEvents', []); } - /** - * @param array|null $logEvents - */ - public function setLogEvents(?array $logEvents) + public function setLogEvents(?array $logEvents): ConfigDataInterface { - $this->set('logEvents', $logEvents ?: []); + $this->set('logEvents', $logEvents); + + return $this; } - /** - * @return boolean - */ public function isDokuwikiEnabled(): bool { return $this->get('dokuwikiEnabled', false); } - /** - * @param bool|null $dokuwikiEnabled - * - * @return $this - */ - public function setDokuwikiEnabled(?bool $dokuwikiEnabled): ConfigData + public function setDokuwikiEnabled(?bool $dokuwikiEnabled): ConfigDataInterface { $this->set('dokuwikiEnabled', (bool)$dokuwikiEnabled); return $this; } - /** - * @return string|null - */ public function getDokuwikiUrl(): ?string { return $this->get('dokuwikiUrl'); } - /** - * @param string|null $dokuwikiUrl - * - * @return $this - */ - public function setDokuwikiUrl(?string $dokuwikiUrl): ConfigData + public function setDokuwikiUrl(?string $dokuwikiUrl): ConfigDataInterface { $this->set('dokuwikiUrl', $dokuwikiUrl); return $this; } - /** - * @return string|null - */ public function getDokuwikiUrlBase(): ?string { return $this->get('dokuwikiUrlBase'); } - /** - * @param string|null $dokuwikiUrlBase - * - * @return $this - */ - public function setDokuwikiUrlBase(?string $dokuwikiUrlBase): ConfigData + public function setDokuwikiUrlBase(?string $dokuwikiUrlBase): ConfigDataInterface { $this->set('dokuwikiUrlBase', $dokuwikiUrlBase); return $this; } - /** - * @return string|null - */ public function getDokuwikiUser(): ?string { return $this->get('dokuwikiUser'); } - /** - * @param string|null $dokuwikiUser - * - * @return $this - */ - public function setDokuwikiUser(?string $dokuwikiUser): ConfigData + public function setDokuwikiUser(?string $dokuwikiUser): ConfigDataInterface { $this->set('dokuwikiUser', $dokuwikiUser); return $this; } - /** - * @return string|null - */ public function getDokuwikiPass(): ?string { return $this->get('dokuwikiPass'); } - /** - * @param string|null $dokuwikiPass - * - * @return $this - */ - public function setDokuwikiPass(?string $dokuwikiPass): ConfigData + public function setDokuwikiPass(?string $dokuwikiPass): ConfigDataInterface { $this->set('dokuwikiPass', $dokuwikiPass); return $this; } - /** - * @return string|null - */ public function getDokuwikiNamespace(): ?string { return $this->get('dokuwikiNamespace'); } - /** - * @param string|null $dokuwikiNamespace - * - * @return $this - */ - public function setDokuwikiNamespace(?string $dokuwikiNamespace): ConfigData + public function setDokuwikiNamespace(?string $dokuwikiNamespace): ConfigDataInterface { $this->set('dokuwikiNamespace', $dokuwikiNamespace); return $this; } - /** - * @return int - */ public function getLdapDefaultGroup(): int { return (int)$this->get('ldapDefaultGroup'); } - /** - * @param int|null $ldapDefaultGroup - * - * @return $this - */ - public function setLdapDefaultGroup(?int $ldapDefaultGroup): ConfigData + public function setLdapDefaultGroup(?int $ldapDefaultGroup): ConfigDataInterface { $this->set('ldapDefaultGroup', (int)$ldapDefaultGroup); return $this; } - /** - * @return int - */ public function getLdapDefaultProfile(): int { return (int)$this->get('ldapDefaultProfile'); } - /** - * @param int|null $ldapDefaultProfile - * - * @return $this - */ - public function setLdapDefaultProfile(?int $ldapDefaultProfile): ConfigData + public function setLdapDefaultProfile(?int $ldapDefaultProfile): ConfigDataInterface { $this->set('ldapDefaultProfile', (int)$ldapDefaultProfile); return $this; } - /** - * @return boolean - */ public function isProxyEnabled(): bool { return $this->get('proxyEnabled', false); } - /** - * @param boolean|null $proxyEnabled - * - * @return $this - */ - public function setProxyEnabled(?bool $proxyEnabled): ConfigData + public function setProxyEnabled(?bool $proxyEnabled): ConfigDataInterface { $this->set('proxyEnabled', (bool)$proxyEnabled); return $this; } - /** - * @return string|null - */ public function getProxyServer(): ?string { return $this->get('proxyServer'); } - /** - * @param string|null $proxyServer - * - * @return $this - */ - public function setProxyServer(?string $proxyServer): ConfigData + public function setProxyServer(?string $proxyServer): ConfigDataInterface { $this->set('proxyServer', $proxyServer); return $this; } - /** - * @return int - */ public function getProxyPort(): int { - return $this->get('proxyPort', 8080); + return $this->get('proxyPort', self::PROXY_PORT); } - /** - * @param int|null $proxyPort - * - * @return $this - */ - public function setProxyPort(?int $proxyPort): ConfigData + public function setProxyPort(?int $proxyPort): ConfigDataInterface { $this->set('proxyPort', (int)$proxyPort); return $this; } - /** - * @return string|null - */ public function getProxyUser(): ?string { return $this->get('proxyUser'); } - /** - * @param string|null $proxyUser - * - * @return $this - */ - public function setProxyUser(?string $proxyUser): ConfigData + public function setProxyUser(?string $proxyUser): ConfigDataInterface { $this->set('proxyUser', $proxyUser); return $this; } - /** - * @return string|null - */ public function getProxyPass(): ?string { return $this->get('proxyPass'); } - /** - * @param string|null $proxyPass - * - * @return $this - */ - public function setProxyPass(?string $proxyPass): ConfigData + public function setProxyPass(?string $proxyPass): ConfigDataInterface { $this->set('proxyPass', $proxyPass); return $this; } - /** - * @return int - */ public function getPublinksMaxViews(): int { return $this->get('publinksMaxViews', self::PUBLIC_LINK_MAX_VIEWS); } - /** - * @param int|null $publinksMaxViews - * - * @return $this - */ - public function setPublinksMaxViews(?int $publinksMaxViews): ConfigData + public function setPublinksMaxViews(?int $publinksMaxViews): ConfigDataInterface { $this->set('publinksMaxViews', (int)$publinksMaxViews); return $this; } - /** - * @return int - */ public function getPublinksMaxTime(): int { return $this->get('publinksMaxTime', self::PUBLIC_LINK_MAX_TIME); } - /** - * @param int|null $publinksMaxTime - * - * @return $this - */ - public function setPublinksMaxTime(?int $publinksMaxTime): ConfigData + public function setPublinksMaxTime(?int $publinksMaxTime): ConfigDataInterface { $this->set('publinksMaxTime', (int)$publinksMaxTime); return $this; } - /** - * @return boolean - */ public function isSyslogEnabled(): bool { return $this->get('syslogEnabled', false); } - /** - * @param boolean|null $syslogEnabled - * - * @return $this - */ - public function setSyslogEnabled(?bool $syslogEnabled): ConfigData + public function setSyslogEnabled(?bool $syslogEnabled): ConfigDataInterface { $this->set('syslogEnabled', (bool)$syslogEnabled); return $this; } - /** - * @return boolean - */ public function isSyslogRemoteEnabled(): bool { return $this->get('syslogRemoteEnabled', false); } - /** - * @param boolean|null $syslogRemoteEnabled - * - * @return $this - */ - public function setSyslogRemoteEnabled(?bool $syslogRemoteEnabled): ConfigData + public function setSyslogRemoteEnabled(?bool $syslogRemoteEnabled): ConfigDataInterface { $this->set('syslogRemoteEnabled', (bool)$syslogRemoteEnabled); return $this; } - /** - * @return string|null - */ public function getSyslogServer(): ?string { return $this->get('syslogServer'); } - /** - * @param string|null $syslogServer - * - * @return $this - */ - public function setSyslogServer(?string $syslogServer): ConfigData + public function setSyslogServer(?string $syslogServer): ConfigDataInterface { $this->set('syslogServer', $syslogServer); return $this; } - /** - * @return int - */ public function getSyslogPort(): int { return $this->get('syslogPort', self::SYSLOG_PORT); } - /** - * @param int|null $syslogPort - * - * @return $this - */ - public function setSyslogPort(?int $syslogPort): ConfigData + public function setSyslogPort(?int $syslogPort): ConfigDataInterface { $this->set('syslogPort', (int)$syslogPort); return $this; } - /** - * @return string|null - */ public function getBackupHash(): ?string { return $this->get('backup_hash'); } - /** - * @param string|null $backup_hash - * - * @return $this - */ - public function setBackupHash(?string $backup_hash): ConfigData + public function setBackupHash(?string $backup_hash): ConfigDataInterface { $this->set('backup_hash', $backup_hash); return $this; } - /** - * @return string|null - */ public function getExportHash(): ?string { return $this->get('export_hash'); } - /** - * @param string|null $export_hash - * - * @return $this - */ - public function setExportHash(?string $export_hash): ConfigData + public function setExportHash(?string $export_hash): ConfigDataInterface { $this->set('export_hash', $export_hash); return $this; } - /** - * @return string|null - */ public function getLdapBindUser(): ?string { return $this->get('ldapBindUser'); } - /** - * @param string|null $ldapBindUser - * - * @return $this - */ - public function setLdapBindUser(?string $ldapBindUser): ConfigData + public function setLdapBindUser(?string $ldapBindUser): ConfigDataInterface { $this->set('ldapBindUser', $ldapBindUser); return $this; } - /** - * @return int - */ public function getAccountCount(): int { return $this->get('accountCount', self::ACCOUNT_COUNT); } - /** - * @param int|null $accountCount - * - * @return $this - */ - public function setAccountCount(?int $accountCount): ConfigData + public function setAccountCount(?int $accountCount): ConfigDataInterface { $this->set('accountCount', (int)$accountCount); return $this; } - /** - * @return boolean - */ public function isAccountLink(): bool { return $this->get('accountLink', true); } - /** - * @param bool|null $accountLink - * - * @return $this - */ - public function setAccountLink(?bool $accountLink): ConfigData + public function setAccountLink(?bool $accountLink): ConfigDataInterface { $this->set('accountLink', (bool)$accountLink); return $this; } - /** - * @return bool - */ public function isCheckUpdates(): bool { return $this->get('checkUpdates', false); } - /** - * @param bool|null $checkUpdates - * - * @return $this - */ - public function setCheckUpdates(?bool $checkUpdates): ConfigData + public function setCheckUpdates(?bool $checkUpdates): ConfigDataInterface { $this->set('checkUpdates', (bool)$checkUpdates); return $this; } - /** - * @return string - */ - public function getConfigHash() + public function getConfigHash(): ?string { return $this->get('configHash'); } @@ -581,875 +371,528 @@ final class ConfigData extends DataCollection implements JsonSerializable /** * Generates a hash from current config options */ - public function setConfigHash(): ConfigData + public function setConfigHash(): ConfigDataInterface { $this->set('configHash', sha1(serialize($this->attributes))); return $this; } - /** - * @return string|null - */ public function getDbHost(): ?string { return $this->get('dbHost'); } - /** - * @param string|null $dbHost - * - * @return $this - */ - public function setDbHost(?string $dbHost): ConfigData + public function setDbHost(?string $dbHost): ConfigDataInterface { $this->set('dbHost', $dbHost); return $this; } - /** - * @return string|null - */ public function getDbName(): ?string { return $this->get('dbName'); } - /** - * @param string|null $dbName - * - * @return $this - */ - public function setDbName(?string $dbName): ConfigData + public function setDbName(?string $dbName): ConfigDataInterface { $this->set('dbName', $dbName); return $this; } - /** - * @return string|null - */ public function getDbPass(): ?string { return $this->get('dbPass'); } - /** - * @param string|null $dbPass - * - * @return $this - */ - public function setDbPass(?string $dbPass): ConfigData + public function setDbPass(?string $dbPass): ConfigDataInterface { $this->set('dbPass', $dbPass); return $this; } - /** - * @return string|null - */ public function getDbUser(): ?string { return $this->get('dbUser'); } - /** - * @param string|null $dbUser - * - * @return $this - */ - public function setDbUser(?string $dbUser): ConfigData + public function setDbUser(?string $dbUser): ConfigDataInterface { $this->set('dbUser', $dbUser); return $this; } - /** - * @return bool - */ public function isDebug(): bool { return $this->get('debug', false); } - /** - * @param bool|null $debug - * - * @return $this - */ - public function setDebug(?bool $debug): ConfigData + public function setDebug(?bool $debug): ConfigDataInterface { $this->set('debug', (bool)$debug); return $this; } - /** - * @return bool - */ public function isDemoEnabled(): bool { return $this->get('demoEnabled', false); } - /** - * @param bool|null $demoEnabled - * - * @return $this - */ - public function setDemoEnabled(?bool $demoEnabled): ConfigData + public function setDemoEnabled(?bool $demoEnabled): ConfigDataInterface { $this->set('demoEnabled', (bool)$demoEnabled); return $this; } - /** - * @return array - */ public function getFilesAllowedExts(): array { return $this->get('filesAllowedExts', []); } - /** - * @return int - */ public function getFilesAllowedSize(): int { return $this->get('filesAllowedSize', self::FILES_ALLOWED_SIZE); } - /** - * @param int|null $filesAllowedSize - * - * @return $this - */ - public function setFilesAllowedSize(?int $filesAllowedSize): ConfigData + public function setFilesAllowedSize(?int $filesAllowedSize): ConfigDataInterface { $this->set('filesAllowedSize', (int)$filesAllowedSize); return $this; } - /** - * @return bool - */ public function isFilesEnabled(): bool { return $this->get('filesEnabled', true); } - /** - * @param bool|null $filesEnabled - * - * @return $this - */ - public function setFilesEnabled(?bool $filesEnabled): ConfigData + public function setFilesEnabled(?bool $filesEnabled): ConfigDataInterface { $this->set('filesEnabled', (bool)$filesEnabled); return $this; } - /** - * @return bool - */ public function isGlobalSearch(): bool { return $this->get('globalSearch', true); } - /** - * @param bool|null $globalSearch - * - * @return $this - */ - public function setGlobalSearch(?bool $globalSearch): ConfigData + public function setGlobalSearch(?bool $globalSearch): ConfigDataInterface { $this->set('globalSearch', (bool)$globalSearch); return $this; } - /** - * @return bool - */ public function isInstalled(): bool { return $this->get('installed', false); } - /** - * @param bool|null $installed - * - * @return $this - */ - public function setInstalled(?bool $installed): ConfigData + public function setInstalled(?bool $installed): ConfigDataInterface { $this->set('installed', (bool)$installed); return $this; } - /** - * @return string|null - */ public function getLdapBase(): ?string { return $this->get('ldapBase'); } - /** - * @param string|null $ldapBase - * - * @return $this - */ - public function setLdapBase(?string $ldapBase): ConfigData + public function setLdapBase(?string $ldapBase): ConfigDataInterface { $this->set('ldapBase', $ldapBase); return $this; } - /** - * @return bool - */ public function isLdapEnabled(): bool { return $this->get('ldapEnabled', false); } - /** - * @param bool|null $ldapEnabled - * - * @return $this - */ - public function setLdapEnabled(?bool $ldapEnabled): ConfigData + public function setLdapEnabled(?bool $ldapEnabled): ConfigDataInterface { $this->set('ldapEnabled', (bool)$ldapEnabled); return $this; } - /** - * @return string|null - */ public function getLdapGroup(): ?string { return $this->get('ldapGroup'); } - /** - * @param string|null $ldapGroup - * - * @return $this - */ - public function setLdapGroup(?string $ldapGroup): ConfigData + public function setLdapGroup(?string $ldapGroup): ConfigDataInterface { $this->set('ldapGroup', $ldapGroup); return $this; } - /** - * @return string|null - */ public function getLdapServer(): ?string { return $this->get('ldapServer'); } - /** - * @param string|null $ldapServer - * - * @return $this - */ - public function setLdapServer(?string $ldapServer): ConfigData + public function setLdapServer(?string $ldapServer): ConfigDataInterface { $this->set('ldapServer', $ldapServer); return $this; } - /** - * @return bool - */ public function isLogEnabled(): bool { return $this->get('logEnabled', true); } - /** - * @param bool|null $logEnabled - * - * @return $this - */ - public function setLogEnabled(?bool $logEnabled): ConfigData + public function setLogEnabled(?bool $logEnabled): ConfigDataInterface { $this->set('logEnabled', (bool)$logEnabled); return $this; } - /** - * @return bool - */ public function isMailAuthenabled(): bool { return $this->get('mailAuthenabled', false); } - /** - * @param bool|null $mailAuthenabled - * - * @return $this - */ - public function setMailAuthenabled(?bool $mailAuthenabled): ConfigData + public function setMailAuthenabled(?bool $mailAuthenabled): ConfigDataInterface { $this->set('mailAuthenabled', (bool)$mailAuthenabled); return $this; } - /** - * @return bool - */ public function isMailEnabled(): bool { return $this->get('mailEnabled', false); } - /** - * @param bool|null $mailEnabled - * - * @return $this - */ - public function setMailEnabled(?bool $mailEnabled): ConfigData + public function setMailEnabled(?bool $mailEnabled): ConfigDataInterface { $this->set('mailEnabled', (bool)$mailEnabled); return $this; } - /** - * @return string|null - */ public function getMailFrom(): ?string { return $this->get('mailFrom'); } - /** - * @param string|null $mailFrom - * - * @return $this - */ - public function setMailFrom(?string $mailFrom): ConfigData + public function setMailFrom(?string $mailFrom): ConfigDataInterface { $this->set('mailFrom', $mailFrom); return $this; } - /** - * @return string|null - */ public function getMailPass(): ?string { return $this->get('mailPass'); } - /** - * @param string|null $mailPass - * - * @return $this - */ - public function setMailPass(?string $mailPass): ConfigData + public function setMailPass(?string $mailPass): ConfigDataInterface { $this->set('mailPass', $mailPass); return $this; } - /** - * @return int - */ public function getMailPort(): int { return $this->get('mailPort', self::MAIL_PORT); } - /** - * @param int|null $mailPort - * - * @return $this - */ - public function setMailPort(?int $mailPort): ConfigData + public function setMailPort(?int $mailPort): ConfigDataInterface { $this->set('mailPort', (int)$mailPort); return $this; } - /** - * @return bool - */ public function isMailRequestsEnabled(): bool { return $this->get('mailRequestsEnabled', false); } - /** - * @param bool|null $mailRequestsEnabled - * - * @return $this - */ - public function setMailRequestsEnabled(?bool $mailRequestsEnabled): ConfigData + public function setMailRequestsEnabled(?bool $mailRequestsEnabled): ConfigDataInterface { $this->set('mailRequestsEnabled', (bool)$mailRequestsEnabled); return $this; } - /** - * @return string|null - */ public function getMailSecurity(): ?string { return $this->get('mailSecurity'); } - /** - * @param string|null $mailSecurity - * - * @return $this - */ - public function setMailSecurity(?string $mailSecurity): ConfigData + public function setMailSecurity(?string $mailSecurity): ConfigDataInterface { $this->set('mailSecurity', $mailSecurity); return $this; } - /** - * @return string|null - */ public function getMailServer(): ?string { return $this->get('mailServer'); } - /** - * @param string|null $mailServer - * - * @return $this - */ - public function setMailServer(?string $mailServer): ConfigData + public function setMailServer(?string $mailServer): ConfigDataInterface { $this->set('mailServer', $mailServer); return $this; } - /** - * @return string|null - */ public function getMailUser(): ?string { return $this->get('mailUser'); } - /** - * @param string|null $mailUser - * - * @return $this - */ - public function setMailUser(?string $mailUser): ConfigData + public function setMailUser(?string $mailUser): ConfigDataInterface { $this->set('mailUser', $mailUser); return $this; } - /** - * @return bool - */ public function isMaintenance(): bool { return $this->get('maintenance', false); } - /** - * @param bool|null $maintenance - * - * @return $this - */ - public function setMaintenance(?bool $maintenance): ConfigData + public function setMaintenance(?bool $maintenance): ConfigDataInterface { $this->set('maintenance', (bool)$maintenance); return $this; } - /** - * @return string|null - */ public function getPasswordSalt(): ?string { return $this->get('passwordSalt'); } - /** - * @param string|null $passwordSalt - * - * @return $this - */ - public function setPasswordSalt(?string $passwordSalt): ConfigData + public function setPasswordSalt(?string $passwordSalt): ConfigDataInterface { $this->set('passwordSalt', $passwordSalt); return $this; } - /** - * @return bool - */ public function isResultsAsCards(): bool { return $this->get('resultsAsCards', false); } - /** - * @param bool|null $resultsAsCards - * - * @return $this - */ - public function setResultsAsCards(?bool $resultsAsCards): ConfigData + public function setResultsAsCards(?bool $resultsAsCards): ConfigDataInterface { $this->set('resultsAsCards', (bool)$resultsAsCards); return $this; } - /** - * @return int - */ public function getSessionTimeout(): int { return $this->get('sessionTimeout', self::SESSION_TIMEOUT); } - /** - * @param int|null $sessionTimeout - * - * @return $this - */ - public function setSessionTimeout(?int $sessionTimeout): ConfigData + public function setSessionTimeout(?int $sessionTimeout): ConfigDataInterface { $this->set('sessionTimeout', (int)$sessionTimeout); return $this; } - /** - * @return string|null - */ public function getSiteLang(): ?string { return $this->get('siteLang'); } - /** - * @param string|null $siteLang - * - * @return $this - */ - public function setSiteLang(?string $siteLang): ConfigData + public function setSiteLang(?string $siteLang): ConfigDataInterface { $this->set('siteLang', $siteLang); return $this; } - /** - * @return string - */ public function getSiteTheme(): string { return $this->get('siteTheme', self::SITE_THEME); } - /** - * @param string|null $siteTheme - * - * @return $this - */ - public function setSiteTheme(?string $siteTheme): ConfigData + public function setSiteTheme(?string $siteTheme): ConfigDataInterface { $this->set('siteTheme', $siteTheme); return $this; } - /** - * @return string|null - */ public function getConfigVersion(): ?string { return (string)$this->get('configVersion'); } - /** - * @param string|null $configVersion - * - * @return $this - */ - public function setConfigVersion(?string $configVersion): ConfigData + public function setConfigVersion(?string $configVersion): ConfigDataInterface { $this->set('configVersion', $configVersion); return $this; } - /** - * @return bool - */ public function isWikiEnabled(): bool { return $this->get('wikiEnabled', false); } - /** - * @param bool|null $wikiEnabled - * - * @return $this - */ - public function setWikiEnabled(?bool $wikiEnabled): ConfigData + public function setWikiEnabled(?bool $wikiEnabled): ConfigDataInterface { $this->set('wikiEnabled', (bool)$wikiEnabled); return $this; } - /** - * @return array - */ public function getWikiFilter(): array { return $this->get('wikiFilter', []); } - /** - * @param array|null $wikiFilter - * - * @return $this - */ - public function setWikiFilter(?array $wikiFilter): ConfigData + public function setWikiFilter(?array $wikiFilter): ConfigDataInterface { - $this->set('wikiFilter', $wikiFilter ?: []); + $this->set('wikiFilter', $wikiFilter); return $this; } - /** - * @return string|null - */ public function getWikiPageurl(): ?string { return $this->get('wikiPageurl'); } - /** - * @param string|null $wikiPageurl - * - * @return $this - */ - public function setWikiPageurl(?string $wikiPageurl): ConfigData + public function setWikiPageurl(?string $wikiPageurl): ConfigDataInterface { $this->set('wikiPageurl', $wikiPageurl); return $this; } - /** - * @return string|null - */ public function getWikiSearchurl(): ?string { return $this->get('wikiSearchurl'); } - /** - * @param string|null $wikiSearchurl - * - * @return $this - */ - public function setWikiSearchurl(?string $wikiSearchurl): ConfigData + public function setWikiSearchurl(?string $wikiSearchurl): ConfigDataInterface { $this->set('wikiSearchurl', $wikiSearchurl); return $this; } - /** - * @return string|null - */ public function getLdapBindPass(): ?string { return $this->get('ldapBindPass'); } - /** - * @param string|null $ldapBindPass - * - * @return $this - */ - public function setLdapBindPass(?string $ldapBindPass): ConfigData + public function setLdapBindPass(?string $ldapBindPass): ConfigDataInterface { $this->set('ldapBindPass', $ldapBindPass); return $this; } - /** - * @return bool - */ public function isPublinksImageEnabled(): bool { return $this->get('publinksImageEnabled', false); } - /** - * @param bool|null $publinksImageEnabled - * - * @return $this - */ - public function setPublinksImageEnabled(?bool $publinksImageEnabled): ConfigData + public function setPublinksImageEnabled(?bool $publinksImageEnabled): ConfigDataInterface { $this->set('publinksImageEnabled', (bool)$publinksImageEnabled); return $this; } - /** - * @return bool - */ public function isHttpsEnabled(): bool { return $this->get('httpsEnabled', false); } - /** - * @param bool|null $httpsEnabled - * - * @return $this - */ - public function setHttpsEnabled(?bool $httpsEnabled): ConfigData + public function setHttpsEnabled(?bool $httpsEnabled): ConfigDataInterface { $this->set('httpsEnabled', (bool)$httpsEnabled); return $this; } - /** - * @return bool - */ public function isCheckNotices(): bool { return $this->get('checkNotices', false); } - /** - * @param bool|null $checknotices - * - * @return $this - */ - public function setCheckNotices(?bool $checknotices): ConfigData + public function setCheckNotices(?bool $checknotices): ConfigDataInterface { $this->set('checkNotices', (bool)$checknotices); return $this; } - /** - * @return bool - */ public function isAccountPassToImage(): bool { return $this->get('accountPassToImage', false); } - /** - * @param bool|null $accountPassToImage - * - * @return $this - */ - public function setAccountPassToImage(?bool $accountPassToImage): ConfigData + public function setAccountPassToImage(?bool $accountPassToImage): ConfigDataInterface { $this->set('accountPassToImage', (bool)$accountPassToImage); return $this; } - /** - * @return string|null - */ public function getUpgradeKey(): ?string { return $this->get('upgradeKey'); } - /** - * @param string|null $upgradeKey - * - * @return $this - */ - public function setUpgradeKey(?string $upgradeKey): ConfigData + public function setUpgradeKey(?string $upgradeKey): ConfigDataInterface { $this->set('upgradeKey', $upgradeKey); return $this; } - /** - * @return int - */ public function getDbPort(): int { return $this->get('dbPort', self::DB_PORT); } - /** - * @param int|null $dbPort - * - * @return $this - */ - public function setDbPort(?int $dbPort): ConfigData + public function setDbPort(?int $dbPort): ConfigDataInterface { $this->set('dbPort', (int)$dbPort); return $this; } - /** - * @return bool - */ public function isPublinksEnabled(): bool { return $this->get('publinksEnabled', false); } - /** - * @param bool|null $publinksEnabled - * - * @return $this - */ - public function setPublinksEnabled(?bool $publinksEnabled): ConfigData + public function setPublinksEnabled(?bool $publinksEnabled): ConfigDataInterface { $this->set('publinksEnabled', (bool)$publinksEnabled); @@ -1464,117 +907,81 @@ final class ConfigData extends DataCollection implements JsonSerializable * which is a value of any type other than a resource. * @since 5.4.0 */ - public function jsonSerialize() + public function jsonSerialize(): array { return $this->attributes; } - /** - * @return string - */ - public function getConfigSaver() + public function getConfigSaver(): ?string { return $this->get('configSaver'); } - /** - * @param string|null $configSaver - * - * @return $this - */ - public function setConfigSaver(?string $configSaver): ConfigData + public function setConfigSaver(?string $configSaver): ConfigDataInterface { $this->set('configSaver', $configSaver); return $this; } - /** - * @return string|null - */ public function getDbSocket(): ?string { return $this->get('dbSocket'); } - /** - * @param string|null $dbSocket - */ - public function setDbSocket(?string $dbSocket) + public function setDbSocket(?string $dbSocket): ConfigDataInterface { $this->set('dbSocket', $dbSocket); + + return $this; } - /** - * @return bool - */ public function isEncryptSession(): bool { return (bool)$this->get('encryptSession', false); } - /** - * @param bool|null $encryptSession - * - * @return $this - */ - public function setEncryptSession(?bool $encryptSession): ConfigData + public function setEncryptSession(?bool $encryptSession): ConfigDataInterface { $this->set('encryptSession', (bool)$encryptSession); return $this; } - /** - * @return bool - */ public function isAccountFullGroupAccess(): bool { return (bool)$this->get('accountFullGroupAccess', false); } - /** - * @param bool|null $accountFullGroupAccess - * - * @return $this - */ - public function setAccountFullGroupAccess(?bool $accountFullGroupAccess): ConfigData + public function setAccountFullGroupAccess(?bool $accountFullGroupAccess): ConfigDataInterface { $this->set('accountFullGroupAccess', (bool)$accountFullGroupAccess); return $this; } - /** - * @return bool - */ public function isAuthBasicEnabled(): bool { return (bool)$this->get('authBasicEnabled', true); } - /** - * @param bool|null $authBasicEnabled - */ - public function setAuthBasicEnabled(?bool $authBasicEnabled) + public function setAuthBasicEnabled(?bool $authBasicEnabled): ConfigDataInterface { $this->set('authBasicEnabled', (bool)$authBasicEnabled); + + return $this; } - /** - * @return string|null - */ public function getAuthBasicDomain(): ?string { return $this->get('authBasicDomain'); } - /** - * @param string|null $authBasicDomain - */ - public function setAuthBasicDomain(?string $authBasicDomain) + public function setAuthBasicDomain(?string $authBasicDomain): ConfigDataInterface { $this->set('authBasicDomain', $authBasicDomain); + + return $this; } /** @@ -1585,76 +992,59 @@ final class ConfigData extends DataCollection implements JsonSerializable return (bool)$this->get('authBasicAutoLoginEnabled', true); } - /** - * @param bool|null $authBasicAutoLoginEnabled - */ - public function setAuthBasicAutoLoginEnabled(?bool $authBasicAutoLoginEnabled) + public function setAuthBasicAutoLoginEnabled(?bool $authBasicAutoLoginEnabled): ConfigDataInterface { $this->set('authBasicAutoLoginEnabled', $authBasicAutoLoginEnabled); + + return $this; } - /** - * @return int|null - */ public function getSsoDefaultGroup(): ?int { return $this->get('ssoDefaultGroup'); } - /** - * @param int|null $ssoDefaultGroup - */ - public function setSsoDefaultGroup(?int $ssoDefaultGroup) + public function setSsoDefaultGroup(?int $ssoDefaultGroup): ConfigDataInterface { $this->set('ssoDefaultGroup', $ssoDefaultGroup); + + return $this; } - /** - * @return int|null - */ public function getSsoDefaultProfile(): ?int { return $this->get('ssoDefaultProfile'); } - /** - * @param int|null $ssoDefaultProfile - */ - public function setSsoDefaultProfile(?int $ssoDefaultProfile) + public function setSsoDefaultProfile(?int $ssoDefaultProfile): ConfigDataInterface { $this->set('ssoDefaultProfile', $ssoDefaultProfile); + + return $this; } - /** - * @return array - */ public function getMailRecipients(): array { return $this->get('mailRecipients', []); } - /** - * @param array|null $mailRecipients - */ - public function setMailRecipients(?array $mailRecipients) + public function setMailRecipients(?array $mailRecipients): ConfigDataInterface { - $this->set('mailRecipients', $mailRecipients ?: []); + $this->set('mailRecipients', $mailRecipients); + + return $this; } - /** - * @return array - */ public function getMailEvents(): array { return $this->get('mailEvents', []); } - /** - * @param array|null $mailEvents - */ - public function setMailEvents(?array $mailEvents) + public function setMailEvents(?array $mailEvents): ConfigDataInterface { - $this->set('mailEvents', $mailEvents ?: []); + $this->set('mailEvents', $mailEvents); + + return $this; } /** @@ -1665,236 +1055,168 @@ final class ConfigData extends DataCollection implements JsonSerializable return (string)$this->get('databaseVersion'); } - /** - * @param string|null $databaseVersion - * - * @return ConfigData - */ - public function setDatabaseVersion(?string $databaseVersion): ConfigData + public function setDatabaseVersion(?string $databaseVersion): ConfigDataInterface { $this->set('databaseVersion', $databaseVersion); return $this; } - /** - * @return int - */ public function getConfigDate(): int { return (int)$this->get('configDate'); } - /** - * @param int $configDate - * - * @return $this - */ - public function setConfigDate(int $configDate): ConfigData + public function setConfigDate(int $configDate): ConfigDataInterface { - $this->set('configDate', (int)$configDate); + $this->set('configDate', $configDate); return $this; } - /** - * @return bool - */ public function isAccountExpireEnabled(): bool { return (bool)$this->get('accountExpireEnabled', false); } - /** - * @param bool|null $accountExpireEnabled - * - * @return ConfigData - */ - public function setAccountExpireEnabled(?bool $accountExpireEnabled): ConfigData + public function setAccountExpireEnabled(?bool $accountExpireEnabled): ConfigDataInterface { $this->set('accountExpireEnabled', (bool)$accountExpireEnabled); return $this; } - /** - * @return int - */ public function getAccountExpireTime(): int { return $this->get('accountExpireTime', self::ACCOUNT_EXPIRE_TIME); } - /** - * @param int|null $accountExpireTime - * - * @return ConfigData - */ - public function setAccountExpireTime(?int $accountExpireTime): ConfigData + public function setAccountExpireTime(?int $accountExpireTime): ConfigDataInterface { $this->set('accountExpireTime', (int)$accountExpireTime); return $this; } - /** - * @return bool - */ public function isLdapTlsEnabled(): bool { return $this->get('ldapTlsEnabled', false); } - /** - * @param bool|null $ldapTlsEnabled - */ - public function setLdapTlsEnabled(?bool $ldapTlsEnabled) + public function setLdapTlsEnabled(?bool $ldapTlsEnabled): ConfigDataInterface { $this->set('ldapTlsEnabled', (int)$ldapTlsEnabled); + + return $this; } - /** - * @return array - */ public function getFilesAllowedMime(): array { return $this->get('filesAllowedMime', []); } - /** - * @param array|null $filesAllowedMime - */ - public function setFilesAllowedMime(?array $filesAllowedMime) + public function setFilesAllowedMime(?array $filesAllowedMime): ConfigDataInterface { - $this->set('filesAllowedMime', $filesAllowedMime ?: []); + $this->set('filesAllowedMime', $filesAllowedMime); + + return $this; } - /** - * @return int - */ public function getLdapType(): int { return (int)$this->get('ldapType'); } - /** - * @param int|null $ldapType - */ - public function setLdapType(?int $ldapType) + public function setLdapType(?int $ldapType): ConfigDataInterface { $this->set('ldapType', (int)$ldapType); + + return $this; } - /** - * @return string - */ public function getAppVersion(): string { return $this->get('appVersion'); } - /** - * @param string|null $appVersion - */ - public function setAppVersion(?string $appVersion) + public function setAppVersion(?string $appVersion): ConfigDataInterface { $this->set('appVersion', $appVersion); + + return $this; } - /** - * @return string|null - */ public function getApplicationUrl(): ?string { return $this->get('applicationUrl'); } - /** - * @param string|null $applicationUrl - */ - public function setApplicationUrl(?string $applicationUrl) + public function setApplicationUrl(?string $applicationUrl): ConfigDataInterface { - $this->set('applicationUrl', $applicationUrl ? rtrim($applicationUrl, '/') : null); + $this->set('applicationUrl', $applicationUrl + ? rtrim($applicationUrl, '/') + : null); + + return $this; } - /** - * @return string|null - */ public function getLdapFilterUserObject(): ?string { return $this->get('ldapFilterUserObject'); } - /** - * @param string|null $filter - */ - public function setLdapFilterUserObject(?string $filter) + public function setLdapFilterUserObject(?string $filter): ConfigDataInterface { $this->set('ldapFilterUserObject', $filter); + + return $this; } - /** - * @return string|null - */ public function getLdapFilterGroupObject(): ?string { return $this->get('ldapFilterGroupObject'); } - /** - * @param string|null $filter - */ - public function setLdapFilterGroupObject(?string $filter) + public function setLdapFilterGroupObject(?string $filter): ConfigDataInterface { $this->set('ldapFilterGroupObject', $filter); + + return $this; } - /** - * @return array|null - */ - public function getLdapFilterUserAttributes(): ?array + public function getLdapFilterUserAttributes(): array { - return $this->get('ldapFilterUserAttributes'); + return $this->get('ldapFilterUserAttributes', []); } - /** - * @param array|null $attributes - */ - public function setLdapFilterUserAttributes(?array $attributes) + public function setLdapFilterUserAttributes(?array $attributes): ConfigDataInterface { - $this->set('ldapFilterUserAttributes', $attributes ?: []); + $this->set('ldapFilterUserAttributes', $attributes); + + return $this; } - /** - * @return array|null - */ - public function getLdapFilterGroupAttributes(): ?array + public function getLdapFilterGroupAttributes(): array { - return $this->get('ldapFilterGroupAttributes'); + return $this->get('ldapFilterGroupAttributes', []); } - /** - * @param array|null $attributes - */ - public function setLdapFilterGroupAttributes(?array $attributes) + public function setLdapFilterGroupAttributes(?array $attributes): ConfigDataInterface { - $this->set('ldapFilterGroupAttributes', $attributes ?: []); + $this->set('ldapFilterGroupAttributes', $attributes); + + return $this; } - /** - * @return bool - */ public function isLdapDatabaseEnabled(): bool { return $this->get('ldapDatabaseEnabled', true); } - /** - * @param bool|null $ldapDatabaseEnabled - */ - public function setLdapDatabaseEnabled(?bool $ldapDatabaseEnabled) + public function setLdapDatabaseEnabled(?bool $ldapDatabaseEnabled): ConfigDataInterface { $this->set('ldapDatabaseEnabled', (int)$ldapDatabaseEnabled); - } + return $this; + } } diff --git a/lib/SP/Config/ConfigDataInterface.php b/lib/SP/Config/ConfigDataInterface.php new file mode 100644 index 00000000..5286d3ec --- /dev/null +++ b/lib/SP/Config/ConfigDataInterface.php @@ -0,0 +1,1190 @@ +. + */ + +namespace SP\Config; + + +/** + * Class configData + * + * @package SP\Config + */ +interface ConfigDataInterface +{ + /** + * @return array + */ + public function getAttributes(): array; + + /** + * @return array + */ + public function getLogEvents(): array; + + /** + * @param array|null $logEvents + * + * @return ConfigDataInterface + */ + public function setLogEvents(?array $logEvents): ConfigDataInterface; + + /** + * @return boolean + */ + public function isDokuwikiEnabled(): bool; + + /** + * @param bool|null $dokuwikiEnabled + * + * @return $this + */ + public function setDokuwikiEnabled(?bool $dokuwikiEnabled): ConfigDataInterface; + + /** + * @return string|null + */ + public function getDokuwikiUrl(): ?string; + + /** + * @param string|null $dokuwikiUrl + * + * @return $this + */ + public function setDokuwikiUrl(?string $dokuwikiUrl): ConfigDataInterface; + + /** + * @return string|null + */ + public function getDokuwikiUrlBase(): ?string; + + /** + * @param string|null $dokuwikiUrlBase + * + * @return $this + */ + public function setDokuwikiUrlBase(?string $dokuwikiUrlBase): ConfigDataInterface; + + /** + * @return string|null + */ + public function getDokuwikiUser(): ?string; + + /** + * @param string|null $dokuwikiUser + * + * @return $this + */ + public function setDokuwikiUser(?string $dokuwikiUser): ConfigDataInterface; + + /** + * @return string|null + */ + public function getDokuwikiPass(): ?string; + + /** + * @param string|null $dokuwikiPass + * + * @return $this + */ + public function setDokuwikiPass(?string $dokuwikiPass): ConfigDataInterface; + + /** + * @return string|null + */ + public function getDokuwikiNamespace(): ?string; + + /** + * @param string|null $dokuwikiNamespace + * + * @return $this + */ + public function setDokuwikiNamespace(?string $dokuwikiNamespace): ConfigDataInterface; + + /** + * @return int + */ + public function getLdapDefaultGroup(): int; + + /** + * @param int|null $ldapDefaultGroup + * + * @return $this + */ + public function setLdapDefaultGroup(?int $ldapDefaultGroup): ConfigDataInterface; + + /** + * @return int + */ + public function getLdapDefaultProfile(): int; + + /** + * @param int|null $ldapDefaultProfile + * + * @return $this + */ + public function setLdapDefaultProfile(?int $ldapDefaultProfile): ConfigDataInterface; + + /** + * @return boolean + */ + public function isProxyEnabled(): bool; + + /** + * @param boolean|null $proxyEnabled + * + * @return $this + */ + public function setProxyEnabled(?bool $proxyEnabled): ConfigDataInterface; + + /** + * @return string|null + */ + public function getProxyServer(): ?string; + + /** + * @param string|null $proxyServer + * + * @return $this + */ + public function setProxyServer(?string $proxyServer): ConfigDataInterface; + + /** + * @return int + */ + public function getProxyPort(): int; + + /** + * @param int|null $proxyPort + * + * @return $this + */ + public function setProxyPort(?int $proxyPort): ConfigDataInterface; + + /** + * @return string|null + */ + public function getProxyUser(): ?string; + + /** + * @param string|null $proxyUser + * + * @return $this + */ + public function setProxyUser(?string $proxyUser): ConfigDataInterface; + + /** + * @return string|null + */ + public function getProxyPass(): ?string; + + /** + * @param string|null $proxyPass + * + * @return $this + */ + public function setProxyPass(?string $proxyPass): ConfigDataInterface; + + /** + * @return int + */ + public function getPublinksMaxViews(): int; + + /** + * @param int|null $publinksMaxViews + * + * @return $this + */ + public function setPublinksMaxViews(?int $publinksMaxViews): ConfigDataInterface; + + /** + * @return int + */ + public function getPublinksMaxTime(): int; + + /** + * @param int|null $publinksMaxTime + * + * @return $this + */ + public function setPublinksMaxTime(?int $publinksMaxTime): ConfigDataInterface; + + /** + * @return boolean + */ + public function isSyslogEnabled(): bool; + + /** + * @param boolean|null $syslogEnabled + * + * @return $this + */ + public function setSyslogEnabled(?bool $syslogEnabled): ConfigDataInterface; + + /** + * @return boolean + */ + public function isSyslogRemoteEnabled(): bool; + + /** + * @param boolean|null $syslogRemoteEnabled + * + * @return $this + */ + public function setSyslogRemoteEnabled(?bool $syslogRemoteEnabled): ConfigDataInterface; + + /** + * @return string|null + */ + public function getSyslogServer(): ?string; + + /** + * @param string|null $syslogServer + * + * @return $this + */ + public function setSyslogServer(?string $syslogServer): ConfigDataInterface; + + /** + * @return int + */ + public function getSyslogPort(): int; + + /** + * @param int|null $syslogPort + * + * @return $this + */ + public function setSyslogPort(?int $syslogPort): ConfigDataInterface; + + /** + * @return string|null + */ + public function getBackupHash(): ?string; + + /** + * @param string|null $backup_hash + * + * @return $this + */ + public function setBackupHash(?string $backup_hash): ConfigDataInterface; + + /** + * @return string|null + */ + public function getExportHash(): ?string; + + /** + * @param string|null $export_hash + * + * @return $this + */ + public function setExportHash(?string $export_hash): ConfigDataInterface; + + /** + * @return string|null + */ + public function getLdapBindUser(): ?string; + + /** + * @param string|null $ldapBindUser + * + * @return $this + */ + public function setLdapBindUser(?string $ldapBindUser): ConfigDataInterface; + + /** + * @return int + */ + public function getAccountCount(): int; + + /** + * @param int|null $accountCount + * + * @return $this + */ + public function setAccountCount(?int $accountCount): ConfigDataInterface; + + /** + * @return boolean + */ + public function isAccountLink(): bool; + + /** + * @param bool|null $accountLink + * + * @return $this + */ + public function setAccountLink(?bool $accountLink): ConfigDataInterface; + + /** + * @return bool + */ + public function isCheckUpdates(): bool; + + /** + * @param bool|null $checkUpdates + * + * @return $this + */ + public function setCheckUpdates(?bool $checkUpdates): ConfigDataInterface; + + /** + * @return string + */ + public function getConfigHash(); + + /** + * Generates a hash from current config options + */ + public function setConfigHash(): ConfigDataInterface; + + /** + * @return string|null + */ + public function getDbHost(): ?string; + + /** + * @param string|null $dbHost + * + * @return $this + */ + public function setDbHost(?string $dbHost): ConfigDataInterface; + + /** + * @return string|null + */ + public function getDbName(): ?string; + + /** + * @param string|null $dbName + * + * @return $this + */ + public function setDbName(?string $dbName): ConfigDataInterface; + + /** + * @return string|null + */ + public function getDbPass(): ?string; + + /** + * @param string|null $dbPass + * + * @return $this + */ + public function setDbPass(?string $dbPass): ConfigDataInterface; + + /** + * @return string|null + */ + public function getDbUser(): ?string; + + /** + * @param string|null $dbUser + * + * @return $this + */ + public function setDbUser(?string $dbUser): ConfigDataInterface; + + /** + * @return bool + */ + public function isDebug(): bool; + + /** + * @param bool|null $debug + * + * @return $this + */ + public function setDebug(?bool $debug): ConfigDataInterface; + + /** + * @return bool + */ + public function isDemoEnabled(): bool; + + /** + * @param bool|null $demoEnabled + * + * @return $this + */ + public function setDemoEnabled(?bool $demoEnabled): ConfigDataInterface; + + /** + * @return array + */ + public function getFilesAllowedExts(): array; + + /** + * @return int + */ + public function getFilesAllowedSize(): int; + + /** + * @param int|null $filesAllowedSize + * + * @return $this + */ + public function setFilesAllowedSize(?int $filesAllowedSize): ConfigDataInterface; + + /** + * @return bool + */ + public function isFilesEnabled(): bool; + + /** + * @param bool|null $filesEnabled + * + * @return $this + */ + public function setFilesEnabled(?bool $filesEnabled): ConfigDataInterface; + + /** + * @return bool + */ + public function isGlobalSearch(): bool; + + /** + * @param bool|null $globalSearch + * + * @return $this + */ + public function setGlobalSearch(?bool $globalSearch): ConfigDataInterface; + + /** + * @return bool + */ + public function isInstalled(): bool; + + /** + * @param bool|null $installed + * + * @return $this + */ + public function setInstalled(?bool $installed): ConfigDataInterface; + + /** + * @return string|null + */ + public function getLdapBase(): ?string; + + /** + * @param string|null $ldapBase + * + * @return $this + */ + public function setLdapBase(?string $ldapBase): ConfigDataInterface; + + /** + * @return bool + */ + public function isLdapEnabled(): bool; + + /** + * @param bool|null $ldapEnabled + * + * @return $this + */ + public function setLdapEnabled(?bool $ldapEnabled): ConfigDataInterface; + + /** + * @return string|null + */ + public function getLdapGroup(): ?string; + + /** + * @param string|null $ldapGroup + * + * @return $this + */ + public function setLdapGroup(?string $ldapGroup): ConfigDataInterface; + + /** + * @return string|null + */ + public function getLdapServer(): ?string; + + /** + * @param string|null $ldapServer + * + * @return $this + */ + public function setLdapServer(?string $ldapServer): ConfigDataInterface; + + /** + * @return bool + */ + public function isLogEnabled(): bool; + + /** + * @param bool|null $logEnabled + * + * @return $this + */ + public function setLogEnabled(?bool $logEnabled): ConfigDataInterface; + + /** + * @return bool + */ + public function isMailAuthenabled(): bool; + + /** + * @param bool|null $mailAuthenabled + * + * @return $this + */ + public function setMailAuthenabled(?bool $mailAuthenabled): ConfigDataInterface; + + /** + * @return bool + */ + public function isMailEnabled(): bool; + + /** + * @param bool|null $mailEnabled + * + * @return $this + */ + public function setMailEnabled(?bool $mailEnabled): ConfigDataInterface; + + /** + * @return string|null + */ + public function getMailFrom(): ?string; + + /** + * @param string|null $mailFrom + * + * @return $this + */ + public function setMailFrom(?string $mailFrom): ConfigDataInterface; + + /** + * @return string|null + */ + public function getMailPass(): ?string; + + /** + * @param string|null $mailPass + * + * @return $this + */ + public function setMailPass(?string $mailPass): ConfigDataInterface; + + /** + * @return int + */ + public function getMailPort(): int; + + /** + * @param int|null $mailPort + * + * @return $this + */ + public function setMailPort(?int $mailPort): ConfigDataInterface; + + /** + * @return bool + */ + public function isMailRequestsEnabled(): bool; + + /** + * @param bool|null $mailRequestsEnabled + * + * @return $this + */ + public function setMailRequestsEnabled(?bool $mailRequestsEnabled): ConfigDataInterface; + + /** + * @return string|null + */ + public function getMailSecurity(): ?string; + + /** + * @param string|null $mailSecurity + * + * @return $this + */ + public function setMailSecurity(?string $mailSecurity): ConfigDataInterface; + + /** + * @return string|null + */ + public function getMailServer(): ?string; + + /** + * @param string|null $mailServer + * + * @return $this + */ + public function setMailServer(?string $mailServer): ConfigDataInterface; + + /** + * @return string|null + */ + public function getMailUser(): ?string; + + /** + * @param string|null $mailUser + * + * @return $this + */ + public function setMailUser(?string $mailUser): ConfigDataInterface; + + /** + * @return bool + */ + public function isMaintenance(): bool; + + /** + * @param bool|null $maintenance + * + * @return $this + */ + public function setMaintenance(?bool $maintenance): ConfigDataInterface; + + /** + * @return string|null + */ + public function getPasswordSalt(): ?string; + + /** + * @param string|null $passwordSalt + * + * @return $this + */ + public function setPasswordSalt(?string $passwordSalt): ConfigDataInterface; + + /** + * @return bool + */ + public function isResultsAsCards(): bool; + + /** + * @param bool|null $resultsAsCards + * + * @return $this + */ + public function setResultsAsCards(?bool $resultsAsCards): ConfigDataInterface; + + /** + * @return int + */ + public function getSessionTimeout(): int; + + /** + * @param int|null $sessionTimeout + * + * @return $this + */ + public function setSessionTimeout(?int $sessionTimeout): ConfigDataInterface; + + /** + * @return string|null + */ + public function getSiteLang(): ?string; + + /** + * @param string|null $siteLang + * + * @return $this + */ + public function setSiteLang(?string $siteLang): ConfigDataInterface; + + /** + * @return string + */ + public function getSiteTheme(): string; + + /** + * @param string|null $siteTheme + * + * @return $this + */ + public function setSiteTheme(?string $siteTheme): ConfigDataInterface; + + /** + * @return string|null + */ + public function getConfigVersion(): ?string; + + /** + * @param string|null $configVersion + * + * @return $this + */ + public function setConfigVersion(?string $configVersion): ConfigDataInterface; + + /** + * @return bool + */ + public function isWikiEnabled(): bool; + + /** + * @param bool|null $wikiEnabled + * + * @return $this + */ + public function setWikiEnabled(?bool $wikiEnabled): ConfigDataInterface; + + /** + * @return array + */ + public function getWikiFilter(): array; + + /** + * @param array|null $wikiFilter + * + * @return $this + */ + public function setWikiFilter(?array $wikiFilter): ConfigDataInterface; + + /** + * @return string|null + */ + public function getWikiPageurl(): ?string; + + /** + * @param string|null $wikiPageurl + * + * @return $this + */ + public function setWikiPageurl(?string $wikiPageurl): ConfigDataInterface; + + /** + * @return string|null + */ + public function getWikiSearchurl(): ?string; + + /** + * @param string|null $wikiSearchurl + * + * @return $this + */ + public function setWikiSearchurl(?string $wikiSearchurl): ConfigDataInterface; + + /** + * @return string|null + */ + public function getLdapBindPass(): ?string; + + /** + * @param string|null $ldapBindPass + * + * @return $this + */ + public function setLdapBindPass(?string $ldapBindPass): ConfigDataInterface; + + /** + * @return bool + */ + public function isPublinksImageEnabled(): bool; + + /** + * @param bool|null $publinksImageEnabled + * + * @return $this + */ + public function setPublinksImageEnabled(?bool $publinksImageEnabled): ConfigDataInterface; + + /** + * @return bool + */ + public function isHttpsEnabled(): bool; + + /** + * @param bool|null $httpsEnabled + * + * @return $this + */ + public function setHttpsEnabled(?bool $httpsEnabled): ConfigDataInterface; + + /** + * @return bool + */ + public function isCheckNotices(): bool; + + /** + * @param bool|null $checknotices + * + * @return $this + */ + public function setCheckNotices(?bool $checknotices): ConfigDataInterface; + + /** + * @return bool + */ + public function isAccountPassToImage(): bool; + + /** + * @param bool|null $accountPassToImage + * + * @return $this + */ + public function setAccountPassToImage(?bool $accountPassToImage): ConfigDataInterface; + + /** + * @return string|null + */ + public function getUpgradeKey(): ?string; + + /** + * @param string|null $upgradeKey + * + * @return $this + */ + public function setUpgradeKey(?string $upgradeKey): ConfigDataInterface; + + /** + * @return int + */ + public function getDbPort(): int; + + /** + * @param int|null $dbPort + * + * @return $this + */ + public function setDbPort(?int $dbPort): ConfigDataInterface; + + /** + * @return bool + */ + public function isPublinksEnabled(): bool; + + /** + * @param bool|null $publinksEnabled + * + * @return $this + */ + public function setPublinksEnabled(?bool $publinksEnabled): ConfigDataInterface; + + /** + * Specify data which should be serialized to JSON + * + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php + * @return mixed data which can be serialized by json_encode, + * which is a value of any type other than a resource. + * @since 5.4.0 + */ + public function jsonSerialize(); + + /** + * @return string + */ + public function getConfigSaver(); + + /** + * @param string|null $configSaver + * + * @return $this + */ + public function setConfigSaver(?string $configSaver): ConfigDataInterface; + + /** + * @return string|null + */ + public function getDbSocket(): ?string; + + /** + * @param string|null $dbSocket + * + * @return ConfigDataInterface + */ + public function setDbSocket(?string $dbSocket): ConfigDataInterface; + + /** + * @return bool + */ + public function isEncryptSession(): bool; + + /** + * @param bool|null $encryptSession + * + * @return $this + */ + public function setEncryptSession(?bool $encryptSession): ConfigDataInterface; + + /** + * @return bool + */ + public function isAccountFullGroupAccess(): bool; + + /** + * @param bool|null $accountFullGroupAccess + * + * @return $this + */ + public function setAccountFullGroupAccess(?bool $accountFullGroupAccess): ConfigDataInterface; + + /** + * @return bool + */ + public function isAuthBasicEnabled(): bool; + + /** + * @param bool|null $authBasicEnabled + */ + public function setAuthBasicEnabled(?bool $authBasicEnabled); + + /** + * @return string|null + */ + public function getAuthBasicDomain(): ?string; + + /** + * @param string|null $authBasicDomain + * + * @return ConfigDataInterface + */ + public function setAuthBasicDomain(?string $authBasicDomain): ConfigDataInterface; + + /** + * @return bool + */ + public function isAuthBasicAutoLoginEnabled(): bool; + + /** + * @param bool|null $authBasicAutoLoginEnabled + * + * @return ConfigDataInterface + */ + public function setAuthBasicAutoLoginEnabled(?bool $authBasicAutoLoginEnabled): ConfigDataInterface; + + /** + * @return int|null + */ + public function getSsoDefaultGroup(): ?int; + + /** + * @param int|null $ssoDefaultGroup + * + * @return ConfigDataInterface + */ + public function setSsoDefaultGroup(?int $ssoDefaultGroup): ConfigDataInterface; + + /** + * @return int|null + */ + public function getSsoDefaultProfile(): ?int; + + /** + * @param int|null $ssoDefaultProfile + * + * @return ConfigDataInterface + */ + public function setSsoDefaultProfile(?int $ssoDefaultProfile): ConfigDataInterface; + + /** + * @return array|null + */ + public function getMailRecipients(): ?array; + + /** + * @param array|null $mailRecipients + * + * @return ConfigDataInterface + */ + public function setMailRecipients(?array $mailRecipients): ConfigDataInterface; + + /** + * @return array|null + */ + public function getMailEvents(): ?array; + + /** + * @param array|null $mailEvents + * + * @return ConfigDataInterface + */ + public function setMailEvents(?array $mailEvents): ConfigDataInterface; + + /** + * @return string + */ + public function getDatabaseVersion(): string; + + /** + * @param string|null $databaseVersion + * + * @return ConfigDataInterface + */ + public function setDatabaseVersion(?string $databaseVersion): ConfigDataInterface; + + /** + * @return int + */ + public function getConfigDate(): int; + + /** + * @param int $configDate + * + * @return $this + */ + public function setConfigDate(int $configDate): ConfigDataInterface; + + /** + * @return bool + */ + public function isAccountExpireEnabled(): bool; + + /** + * @param bool|null $accountExpireEnabled + * + * @return ConfigDataInterface + */ + public function setAccountExpireEnabled(?bool $accountExpireEnabled): ConfigDataInterface; + + /** + * @return int + */ + public function getAccountExpireTime(): int; + + /** + * @param int|null $accountExpireTime + * + * @return ConfigDataInterface + */ + public function setAccountExpireTime(?int $accountExpireTime): ConfigDataInterface; + + /** + * @return bool + */ + public function isLdapTlsEnabled(): bool; + + /** + * @param bool|null $ldapTlsEnabled + * + * @return ConfigDataInterface + */ + public function setLdapTlsEnabled(?bool $ldapTlsEnabled): ConfigDataInterface; + + /** + * @return array + */ + public function getFilesAllowedMime(): array; + + /** + * @param array|null $filesAllowedMime + * + * @return ConfigDataInterface + */ + public function setFilesAllowedMime(?array $filesAllowedMime): ConfigDataInterface; + + /** + * @return int + */ + public function getLdapType(): int; + + /** + * @param int|null $ldapType + * + * @return ConfigDataInterface + */ + public function setLdapType(?int $ldapType): ConfigDataInterface; + + /** + * @return string + */ + public function getAppVersion(): string; + + /** + * @param string|null $appVersion + * + * @return ConfigDataInterface + */ + public function setAppVersion(?string $appVersion): ConfigDataInterface; + + /** + * @return string|null + */ + public function getApplicationUrl(): ?string; + + /** + * @param string|null $applicationUrl + * + * @return ConfigDataInterface + */ + public function setApplicationUrl(?string $applicationUrl): ConfigDataInterface; + + /** + * @return string|null + */ + public function getLdapFilterUserObject(): ?string; + + /** + * @param string|null $filter + * + * @return ConfigDataInterface + */ + public function setLdapFilterUserObject(?string $filter): ConfigDataInterface; + + /** + * @return string|null + */ + public function getLdapFilterGroupObject(): ?string; + + /** + * @param string|null $filter + * + * @return ConfigDataInterface + */ + public function setLdapFilterGroupObject(?string $filter): ConfigDataInterface; + + /** + * @return array + */ + public function getLdapFilterUserAttributes(): array; + + /** + * @param array|null $attributes + * + * @return ConfigDataInterface + */ + public function setLdapFilterUserAttributes(?array $attributes): ConfigDataInterface; + + /** + * @return array + */ + public function getLdapFilterGroupAttributes(): array; + + /** + * @param array|null $attributes + * + * @return ConfigDataInterface + */ + public function setLdapFilterGroupAttributes(?array $attributes): ConfigDataInterface; + + /** + * @return bool + */ + public function isLdapDatabaseEnabled(): bool; + + /** + * @param bool|null $ldapDatabaseEnabled + * + * @return ConfigDataInterface + */ + public function setLdapDatabaseEnabled(?bool $ldapDatabaseEnabled): ConfigDataInterface; +} \ No newline at end of file diff --git a/lib/SP/Config/ConfigInterface.php b/lib/SP/Config/ConfigInterface.php deleted file mode 100644 index b38e6f26..00000000 --- a/lib/SP/Config/ConfigInterface.php +++ /dev/null @@ -1,88 +0,0 @@ -. - */ - -namespace SP\Config; - -defined('APP_ROOT') || die(); - -/** - * Interface ConfigInterface para las clases que gestionan la configuración de sysPass - * - * @package SP - */ -interface ConfigInterface -{ - /** - * Obtiene un valor de configuración - * - * @param string $param El valor a obtener - * @param string $default El valor por defecto - * - * @return string el valor o $default - */ - public static function getValue($param, $default = null); - - /** - * Guardar un parámetro de configuración - * - * @param string $param El parámetro a guardar - * @param string $value El valor a guardar - * @param bool $email enviar email? - * @param bool $hideValue Ocultar el valor del registro en el log - * - * @return bool - */ - public static function setValue($param, $value, $email = true, $hideValue = false); - - /** - * Elimina un parámetro de la configuración. - * - * @param string $param clave - * - * @return bool - */ - public static function deleteParam($param); - - /** - * Actualizar el array de parámetros de configuración - * - * @param $param string El parámetro a actualizar - * @param $value mixed El valor a actualizar - */ - public static function setCacheConfigValue($param, $value); - - /** - * Obtener un parámetro del array de parámetros de configuración - * - * @param $param string El parámetro a devolver - */ - public static function getCacheConfigValue($param); - - /** - * Obtener un array con la configuración almacenada. - * - * @return bool - */ - public static function readConfig(); -} \ No newline at end of file diff --git a/lib/SP/Config/ConfigUtil.php b/lib/SP/Config/ConfigUtil.php index a06ab5f4..50c8a928 100644 --- a/lib/SP/Config/ConfigUtil.php +++ b/lib/SP/Config/ConfigUtil.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Config; use SP\Core\Exceptions\ConfigException; +use SP\Core\Exceptions\SPException; use SP\Util\Checks; /** @@ -36,18 +37,14 @@ final class ConfigUtil { /** * Adaptador para convertir una cadena de extensiones a un array - * - * @param string $filesAllowedExts - * - * @return array */ - public static function filesExtsAdapter(string $filesAllowedExts) + public static function filesExtsAdapter(string $filesAllowedExts): array { if (empty($filesAllowedExts)) { return []; } - return array_map(function ($value) { + return array_map(static function ($value) { if (preg_match('/[^a-z0-9_-]+/i', $value)) { return null; } @@ -58,10 +55,6 @@ final class ConfigUtil /** * Adaptador para convertir una cadena de direcciones de email a un array - * - * @param string $mailAddresses - * - * @return array */ public static function mailAddressesAdapter(string $mailAddresses): array { @@ -69,23 +62,21 @@ final class ConfigUtil return []; } - return array_filter(explode(',', $mailAddresses), function ($value) { - return filter_var($value, FILTER_VALIDATE_EMAIL); - }); + return array_filter( + explode(',', $mailAddresses), + static fn($value) => filter_var($value, FILTER_VALIDATE_EMAIL) + ); } /** * Adaptador para convertir una cadena de eventos a un array - * - * @param array $events - * - * @return array */ - public static function eventsAdapter(array $events) + public static function eventsAdapter(array $events): array { - return array_filter($events, function ($value) { - return preg_match('/^[a-z][a-z\.]+$/i', $value); - }); + return array_filter( + $events, + static fn($value) => preg_match('/^[a-z][a-z.]+$/i', $value) + ); } /** @@ -94,18 +85,18 @@ final class ConfigUtil * * @throws ConfigException */ - public static function checkConfigDir() + public static function checkConfigDir(): void { if (!is_dir(CONFIG_PATH)) { clearstatcache(); - throw new ConfigException(__u('\'/app/config\' directory does not exist.'), ConfigException::CRITICAL); + throw new ConfigException(__u('\'/app/config\' directory does not exist.'), SPException::CRITICAL); } if (!is_writable(CONFIG_PATH)) { clearstatcache(); - throw new ConfigException(__u('Unable to write into \'/app/config\' directory'), ConfigException::CRITICAL); + throw new ConfigException(__u('Unable to write into \'/app/config\' directory'), SPException::CRITICAL); } if (!Checks::checkIsWindows() @@ -115,7 +106,7 @@ final class ConfigUtil throw new ConfigException( __u('\'/app/config\' directory permissions are wrong'), - ConfigException::ERROR, + SPException::ERROR, sprintf(__('Current: %s - Needed: 750'), $configPerms)); } } diff --git a/lib/SP/Core/Acl/AccountPermissionException.php b/lib/SP/Core/Acl/AccountPermissionException.php index 2c4d2e86..2939e641 100644 --- a/lib/SP/Core/Acl/AccountPermissionException.php +++ b/lib/SP/Core/Acl/AccountPermissionException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Acl; @@ -36,10 +36,6 @@ final class AccountPermissionException extends SPException { /** * SPException constructor. - * - * @param string $type - * @param int $code - * @param Exception|null $previous */ public function __construct(string $type, $code = 0, Exception $previous = null) { diff --git a/lib/SP/Core/Acl/Acl.php b/lib/SP/Core/Acl/Acl.php index f94831aa..f1de53b7 100644 --- a/lib/SP/Core/Acl/Acl.php +++ b/lib/SP/Core/Acl/Acl.php @@ -5,7 +5,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -20,13 +20,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Acl; use SP\Core\Context\ContextInterface; -use SP\Core\Context\SessionContext; use SP\Core\Events\Event; use SP\Core\Events\EventDispatcher; use SP\Core\Events\EventMessage; @@ -38,18 +37,9 @@ defined('APP_ROOT') || die(); */ final class Acl implements ActionsInterface { - /** - * @var Actions - */ - protected static $action; - /** - * @var SessionContext - */ - private $context; - /** - * @var EventDispatcher - */ - private $eventDispatcher; + protected static ?Actions $action; + private ContextInterface $context; + private EventDispatcher $eventDispatcher; /** * Acl constructor. @@ -58,7 +48,11 @@ final class Acl implements ActionsInterface * @param EventDispatcher $eventDispatcher * @param Actions|null $action */ - public function __construct(ContextInterface $context, EventDispatcher $eventDispatcher, Actions $action = null) + public function __construct( + ContextInterface $context, + EventDispatcher $eventDispatcher, + Actions $action = null + ) { $this->context = $context; $this->eventDispatcher = $eventDispatcher; @@ -68,10 +62,6 @@ final class Acl implements ActionsInterface /** * Returns action route - * - * @param string $actionId - * - * @return string */ public static function getActionRoute(string $actionId): string { @@ -93,10 +83,11 @@ final class Acl implements ActionsInterface * @return string * @internal param bool $shortName Si se devuelve el nombre corto de la acción */ - public static function getActionInfo(int $actionId, $translate = true): string + public static function getActionInfo(int $actionId, bool $translate = true): string { try { $text = self::$action->getActionById($actionId)->getText(); + return $translate ? __($text) : $text; } catch (ActionNotFoundException $e) { processException($e); @@ -107,13 +98,8 @@ final class Acl implements ActionsInterface /** * Comprobar los permisos de acceso del usuario a los módulos de la aplicación. - * - * @param int $action con el Id de la acción - * @param int $userId opcional, con el Id del usuario - * - * @return bool */ - public function checkUserAccess(int $action, $userId = 0): bool + public function checkUserAccess(int $action, int $userId = 0): bool { if (!($userProfile = $this->context->getUserProfile())) { return false; @@ -279,7 +265,7 @@ final class Acl implements ActionsInterface case self::EVENTLOG_CLEAR: return $userProfile->isEvl(); case self::CUSTOMFIELD_VIEW_PASS: - return ($userData->getIsAdminApp() || $userProfile->isAccViewPass()); + return $userProfile->isAccViewPass(); case self::ACCOUNT_REQUEST: case self::NOTIFICATION: case self::NOTIFICATION_VIEW: diff --git a/lib/SP/Core/Acl/ActionNotFoundException.php b/lib/SP/Core/Acl/ActionNotFoundException.php index 72c4cdeb..e747295b 100644 --- a/lib/SP/Core/Acl/ActionNotFoundException.php +++ b/lib/SP/Core/Acl/ActionNotFoundException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Acl; diff --git a/lib/SP/Core/Acl/Actions.php b/lib/SP/Core/Acl/Actions.php index 7b276e6d..c3422283 100644 --- a/lib/SP/Core/Acl/Actions.php +++ b/lib/SP/Core/Acl/Actions.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Acl; @@ -40,27 +40,17 @@ final class Actions /** * Cache file name */ - const ACTIONS_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'actions.cache'; + public const ACTIONS_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'actions.cache'; /** * Cache expire time */ - const CACHE_EXPIRE = 86400; - /** - * @var int - */ - protected $lastLoadTime; + public const CACHE_EXPIRE = 86400; /** * @var ActionData[] */ - protected $actions; - /** - * @var XmlFileStorageInterface - */ - protected $xmlFileStorage; - /** - * @var FileCacheInterface - */ - private $fileCache; + protected ?array $actions = null; + protected XmlFileStorageInterface $xmlFileStorage; + private FileCacheInterface $fileCache; /** * Action constructor. @@ -70,7 +60,10 @@ final class Actions * * @throws FileException */ - public function __construct(FileCacheInterface $fileCache, XmlFileStorageInterface $xmlFileStorage) + public function __construct( + FileCacheInterface $fileCache, + XmlFileStorageInterface $xmlFileStorage + ) { $this->xmlFileStorage = $xmlFileStorage; $this->fileCache = $fileCache; @@ -81,10 +74,9 @@ final class Actions /** * Loads actions from cache file * - * @return void * @throws FileException */ - protected function loadCache() + protected function loadCache(): void { try { if ($this->fileCache->isExpired(self::CACHE_EXPIRE) @@ -106,7 +98,7 @@ final class Actions /** * @throws FileException */ - protected function mapAndSave() + protected function mapAndSave(): void { logger('ACTION CACHE MISS', 'INFO'); @@ -119,7 +111,7 @@ final class Actions * * @throws FileException */ - protected function map() + protected function map(): void { $this->actions = []; @@ -152,7 +144,7 @@ final class Actions /** * Saves actions into cache file */ - protected function saveCache() + protected function saveCache(): void { try { $this->fileCache->save($this->actions); @@ -166,9 +158,6 @@ final class Actions /** * Returns an action by id * - * @param int $id - * - * @return ActionData * @throws ActionNotFoundException */ public function getActionById(int $id): ActionData @@ -183,7 +172,7 @@ final class Actions /** * @throws FileException */ - public function reset() + public function reset(): void { @unlink(self::ACTIONS_CACHE_FILE); diff --git a/lib/SP/Core/Acl/ActionsInterface.php b/lib/SP/Core/Acl/ActionsInterface.php index 0951c271..1f21c557 100644 --- a/lib/SP/Core/Acl/ActionsInterface.php +++ b/lib/SP/Core/Acl/ActionsInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Acl; @@ -31,159 +31,159 @@ namespace SP\Core\Acl; */ interface ActionsInterface { - const ACCOUNT = 1; - const ACCOUNT_SEARCH = 2; - const ACCOUNT_VIEW = 3; - const ACCOUNT_CREATE = 4; - const ACCOUNT_EDIT = 5; - const ACCOUNT_DELETE = 6; - const ACCOUNT_VIEW_PASS = 7; - const ACCOUNT_EDIT_PASS = 8; - const ACCOUNT_EDIT_RESTORE = 9; - const ACCOUNT_COPY = 10; - const ACCOUNT_COPY_PASS = 11; - const ACCOUNT_REQUEST = 12; - const ACCOUNT_FILE = 20; - const ACCOUNT_FILE_VIEW = 21; - const ACCOUNT_FILE_UPLOAD = 22; - const ACCOUNT_FILE_DOWNLOAD = 23; - const ACCOUNT_FILE_DELETE = 24; - const ACCOUNT_FILE_SEARCH = 25; - const ACCOUNT_FILE_LIST = 26; - const ACCOUNT_FAVORITE = 30; - const ACCOUNT_FAVORITE_VIEW = 31; - const ACCOUNT_FAVORITE_ADD = 32; - const ACCOUNT_FAVORITE_DELETE = 33; - const ACCOUNT_HISTORY_VIEW = 40; - const ACCOUNT_HISTORY_VIEW_PASS = 41; - const ACCOUNT_HISTORY_COPY_PASS = 42; - const CATEGORY = 101; - const CATEGORY_SEARCH = 102; - const CATEGORY_VIEW = 103; - const CATEGORY_CREATE = 104; - const CATEGORY_EDIT = 105; - const CATEGORY_DELETE = 106; - const TAG = 201; - const TAG_SEARCH = 202; - const TAG_VIEW = 203; - const TAG_CREATE = 204; - const TAG_EDIT = 205; - const TAG_DELETE = 206; - const CLIENT = 301; - const CLIENT_SEARCH = 302; - const CLIENT_VIEW = 303; - const CLIENT_CREATE = 304; - const CLIENT_EDIT = 305; - const CLIENT_DELETE = 306; - const CUSTOMFIELD = 401; - const CUSTOMFIELD_SEARCH = 402; - const CUSTOMFIELD_VIEW = 403; - const CUSTOMFIELD_CREATE = 404; - const CUSTOMFIELD_EDIT = 405; - const CUSTOMFIELD_DELETE = 406; - const CUSTOMFIELD_VIEW_PASS = 407; - const PUBLICLINK = 501; - const PUBLICLINK_SEARCH = 502; - const PUBLICLINK_VIEW = 503; - const PUBLICLINK_CREATE = 504; - const PUBLICLINK_EDIT = 505; - const PUBLICLINK_DELETE = 506; - const PUBLICLINK_REFRESH = 507; - const FILE = 601; - const FILE_SEARCH = 602; - const FILE_VIEW = 603; - const FILE_UPLOAD = 604; - const FILE_DOWNLOAD = 605; - const FILE_DELETE = 606; - const USER = 701; - const USER_SEARCH = 702; - const USER_VIEW = 703; - const USER_CREATE = 704; - const USER_EDIT = 705; - const USER_DELETE = 706; - const USER_EDIT_PASS = 707; - const GROUP = 801; - const GROUP_SEARCH = 802; - const GROUP_VIEW = 803; - const GROUP_CREATE = 804; - const GROUP_EDIT = 805; - const GROUP_DELETE = 806; - const PROFILE = 901; - const PROFILE_SEARCH = 902; - const PROFILE_VIEW = 903; - const PROFILE_CREATE = 904; - const PROFILE_EDIT = 905; - const PROFILE_DELETE = 906; - const AUTHTOKEN = 1001; - const AUTHTOKEN_SEARCH = 1002; - const AUTHTOKEN_VIEW = 1003; - const AUTHTOKEN_CREATE = 1004; - const AUTHTOKEN_EDIT = 1005; - const AUTHTOKEN_DELETE = 1006; - const PLUGIN = 1101; - const PLUGIN_SEARCH = 1102; - const PLUGIN_VIEW = 1103; - const PLUGIN_CREATE = 1104; - const PLUGIN_ENABLE = 1105; - const PLUGIN_DISABLE = 1106; - const PLUGIN_RESET = 1107; - const PLUGIN_DELETE = 1108; - const WIKI = 1201; - const WIKI_SEARCH = 1202; - const WIKI_VIEW = 1203; - const WIKI_CREATE = 1204; - const WIKI_EDIT = 1205; - const WIKI_DELETE = 1206; - const ACCOUNTMGR = 1301; - const ACCOUNTMGR_SEARCH = 1302; - const ACCOUNTMGR_VIEW = 1303; - const ACCOUNTMGR_DELETE = 1304; - const ACCOUNTMGR_BULK_EDIT = 1305; - const ACCOUNTMGR_HISTORY = 1311; - const ACCOUNTMGR_HISTORY_SEARCH = 1312; - const ACCOUNTMGR_HISTORY_VIEW = 1313; - const ACCOUNTMGR_HISTORY_DELETE = 1314; - const ACCOUNTMGR_HISTORY_RESTORE = 1315; - const NOTIFICATION = 1401; - const NOTIFICATION_SEARCH = 1402; - const NOTIFICATION_VIEW = 1403; - const NOTIFICATION_CREATE = 1404; - const NOTIFICATION_EDIT = 1405; - const NOTIFICATION_DELETE = 1406; - const NOTIFICATION_CHECK = 1407; - const CONFIG = 1501; - const CONFIG_GENERAL = 1502; - const CONFIG_ACCOUNT = 1510; - const CONFIG_WIKI = 1520; - const CONFIG_CRYPT = 1530; - const CONFIG_CRYPT_REFRESH = 1531; - const CONFIG_CRYPT_TEMPPASS = 1532; - const CONFIG_BACKUP = 1540; - const CONFIG_BACKUP_RUN = 1541; - const CONFIG_IMPORT = 1550; - const CONFIG_IMPORT_CSV = 1551; - const CONFIG_IMPORT_XML = 1552; - const CONFIG_EXPORT = 1560; - const CONFIG_EXPORT_RUN = 1561; - const CONFIG_MAIL = 1570; - const CONFIG_LDAP = 1580; - const CONFIG_LDAP_SYNC = 1581; - const EVENTLOG = 1701; - const EVENTLOG_SEARCH = 1702; - const EVENTLOG_CLEAR = 1703; - const ITEMPRESET = 1801; - const ITEMPRESET_SEARCH = 1802; - const ITEMPRESET_VIEW = 1803; - const ITEMPRESET_CREATE = 1804; - const ITEMPRESET_EDIT = 1805; - const ITEMPRESET_DELETE = 1806; - const TRACK = 1901; - const TRACK_SEARCH = 1902; - const TRACK_UNLOCK = 1903; - const TRACK_CLEAR = 1904; - const ITEMS_MANAGE = 5001; - const ACCESS_MANAGE = 5002; - const SECURITY_MANAGE = 5003; - const USERSETTINGS = 5010; - const USERSETTINGS_GENERAL = 5011; + public const ACCOUNT = 1; + public const ACCOUNT_SEARCH = 2; + public const ACCOUNT_VIEW = 3; + public const ACCOUNT_CREATE = 4; + public const ACCOUNT_EDIT = 5; + public const ACCOUNT_DELETE = 6; + public const ACCOUNT_VIEW_PASS = 7; + public const ACCOUNT_EDIT_PASS = 8; + public const ACCOUNT_EDIT_RESTORE = 9; + public const ACCOUNT_COPY = 10; + public const ACCOUNT_COPY_PASS = 11; + public const ACCOUNT_REQUEST = 12; + public const ACCOUNT_FILE = 20; + public const ACCOUNT_FILE_VIEW = 21; + public const ACCOUNT_FILE_UPLOAD = 22; + public const ACCOUNT_FILE_DOWNLOAD = 23; + public const ACCOUNT_FILE_DELETE = 24; + public const ACCOUNT_FILE_SEARCH = 25; + public const ACCOUNT_FILE_LIST = 26; + public const ACCOUNT_FAVORITE = 30; + public const ACCOUNT_FAVORITE_VIEW = 31; + public const ACCOUNT_FAVORITE_ADD = 32; + public const ACCOUNT_FAVORITE_DELETE = 33; + public const ACCOUNT_HISTORY_VIEW = 40; + public const ACCOUNT_HISTORY_VIEW_PASS = 41; + public const ACCOUNT_HISTORY_COPY_PASS = 42; + public const CATEGORY = 101; + public const CATEGORY_SEARCH = 102; + public const CATEGORY_VIEW = 103; + public const CATEGORY_CREATE = 104; + public const CATEGORY_EDIT = 105; + public const CATEGORY_DELETE = 106; + public const TAG = 201; + public const TAG_SEARCH = 202; + public const TAG_VIEW = 203; + public const TAG_CREATE = 204; + public const TAG_EDIT = 205; + public const TAG_DELETE = 206; + public const CLIENT = 301; + public const CLIENT_SEARCH = 302; + public const CLIENT_VIEW = 303; + public const CLIENT_CREATE = 304; + public const CLIENT_EDIT = 305; + public const CLIENT_DELETE = 306; + public const CUSTOMFIELD = 401; + public const CUSTOMFIELD_SEARCH = 402; + public const CUSTOMFIELD_VIEW = 403; + public const CUSTOMFIELD_CREATE = 404; + public const CUSTOMFIELD_EDIT = 405; + public const CUSTOMFIELD_DELETE = 406; + public const CUSTOMFIELD_VIEW_PASS = 407; + public const PUBLICLINK = 501; + public const PUBLICLINK_SEARCH = 502; + public const PUBLICLINK_VIEW = 503; + public const PUBLICLINK_CREATE = 504; + public const PUBLICLINK_EDIT = 505; + public const PUBLICLINK_DELETE = 506; + public const PUBLICLINK_REFRESH = 507; + public const FILE = 601; + public const FILE_SEARCH = 602; + public const FILE_VIEW = 603; + public const FILE_UPLOAD = 604; + public const FILE_DOWNLOAD = 605; + public const FILE_DELETE = 606; + public const USER = 701; + public const USER_SEARCH = 702; + public const USER_VIEW = 703; + public const USER_CREATE = 704; + public const USER_EDIT = 705; + public const USER_DELETE = 706; + public const USER_EDIT_PASS = 707; + public const GROUP = 801; + public const GROUP_SEARCH = 802; + public const GROUP_VIEW = 803; + public const GROUP_CREATE = 804; + public const GROUP_EDIT = 805; + public const GROUP_DELETE = 806; + public const PROFILE = 901; + public const PROFILE_SEARCH = 902; + public const PROFILE_VIEW = 903; + public const PROFILE_CREATE = 904; + public const PROFILE_EDIT = 905; + public const PROFILE_DELETE = 906; + public const AUTHTOKEN = 1001; + public const AUTHTOKEN_SEARCH = 1002; + public const AUTHTOKEN_VIEW = 1003; + public const AUTHTOKEN_CREATE = 1004; + public const AUTHTOKEN_EDIT = 1005; + public const AUTHTOKEN_DELETE = 1006; + public const PLUGIN = 1101; + public const PLUGIN_SEARCH = 1102; + public const PLUGIN_VIEW = 1103; + public const PLUGIN_CREATE = 1104; + public const PLUGIN_ENABLE = 1105; + public const PLUGIN_DISABLE = 1106; + public const PLUGIN_RESET = 1107; + public const PLUGIN_DELETE = 1108; + public const WIKI = 1201; + public const WIKI_SEARCH = 1202; + public const WIKI_VIEW = 1203; + public const WIKI_CREATE = 1204; + public const WIKI_EDIT = 1205; + public const WIKI_DELETE = 1206; + public const ACCOUNTMGR = 1301; + public const ACCOUNTMGR_SEARCH = 1302; + public const ACCOUNTMGR_VIEW = 1303; + public const ACCOUNTMGR_DELETE = 1304; + public const ACCOUNTMGR_BULK_EDIT = 1305; + public const ACCOUNTMGR_HISTORY = 1311; + public const ACCOUNTMGR_HISTORY_SEARCH = 1312; + public const ACCOUNTMGR_HISTORY_VIEW = 1313; + public const ACCOUNTMGR_HISTORY_DELETE = 1314; + public const ACCOUNTMGR_HISTORY_RESTORE = 1315; + public const NOTIFICATION = 1401; + public const NOTIFICATION_SEARCH = 1402; + public const NOTIFICATION_VIEW = 1403; + public const NOTIFICATION_CREATE = 1404; + public const NOTIFICATION_EDIT = 1405; + public const NOTIFICATION_DELETE = 1406; + public const NOTIFICATION_CHECK = 1407; + public const CONFIG = 1501; + public const CONFIG_GENERAL = 1502; + public const CONFIG_ACCOUNT = 1510; + public const CONFIG_WIKI = 1520; + public const CONFIG_CRYPT = 1530; + public const CONFIG_CRYPT_REFRESH = 1531; + public const CONFIG_CRYPT_TEMPPASS = 1532; + public const CONFIG_BACKUP = 1540; + public const CONFIG_BACKUP_RUN = 1541; + public const CONFIG_IMPORT = 1550; + public const CONFIG_IMPORT_CSV = 1551; + public const CONFIG_IMPORT_XML = 1552; + public const CONFIG_EXPORT = 1560; + public const CONFIG_EXPORT_RUN = 1561; + public const CONFIG_MAIL = 1570; + public const CONFIG_LDAP = 1580; + public const CONFIG_LDAP_SYNC = 1581; + public const EVENTLOG = 1701; + public const EVENTLOG_SEARCH = 1702; + public const EVENTLOG_CLEAR = 1703; + public const ITEMPRESET = 1801; + public const ITEMPRESET_SEARCH = 1802; + public const ITEMPRESET_VIEW = 1803; + public const ITEMPRESET_CREATE = 1804; + public const ITEMPRESET_EDIT = 1805; + public const ITEMPRESET_DELETE = 1806; + public const TRACK = 1901; + public const TRACK_SEARCH = 1902; + public const TRACK_UNLOCK = 1903; + public const TRACK_CLEAR = 1904; + public const ITEMS_MANAGE = 5001; + public const ACCESS_MANAGE = 5002; + public const SECURITY_MANAGE = 5003; + public const USERSETTINGS = 5010; + public const USERSETTINGS_GENERAL = 5011; } \ No newline at end of file diff --git a/lib/SP/Core/Acl/UnauthorizedActionException.php b/lib/SP/Core/Acl/UnauthorizedActionException.php index 6127b3d7..0ef05f1c 100644 --- a/lib/SP/Core/Acl/UnauthorizedActionException.php +++ b/lib/SP/Core/Acl/UnauthorizedActionException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Acl; diff --git a/lib/SP/Core/Acl/UnauthorizedPageException.php b/lib/SP/Core/Acl/UnauthorizedPageException.php index dbc00879..0f5f77c6 100644 --- a/lib/SP/Core/Acl/UnauthorizedPageException.php +++ b/lib/SP/Core/Acl/UnauthorizedPageException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Acl; diff --git a/lib/SP/Core/AppInfoInterface.php b/lib/SP/Core/AppInfoInterface.php index 149ce6cb..f6d7c4cb 100644 --- a/lib/SP/Core/AppInfoInterface.php +++ b/lib/SP/Core/AppInfoInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core; @@ -32,13 +32,13 @@ namespace SP\Core; */ interface AppInfoInterface { - const APP_NAME = 'sysPass'; - const APP_DESC = 'Systems Password Manager'; - const APP_ALIAS = 'SPM'; - const APP_WEBSITE_URL = 'https://www.syspass.org'; - const APP_BLOG_URL = 'https://www.cygnux.org'; - const APP_DOC_URL = 'https://doc.syspass.org'; - const APP_UPDATES_URL = 'https://api.github.com/repos/nuxsmin/sysPass/releases/latest'; - const APP_NOTICES_URL = 'https://api.github.com/repos/nuxsmin/sysPass/issues?milestone=none&state=open&labels=Notices'; - const APP_ISSUES_URL = 'https://github.com/nuxsmin/sysPass/issues'; + public const APP_NAME = 'sysPass'; + public const APP_DESC = 'Systems Password Manager'; + public const APP_ALIAS = 'SPM'; + public const APP_WEBSITE_URL = 'https://www.syspass.org'; + public const APP_BLOG_URL = 'https://www.cygnux.org'; + public const APP_DOC_URL = 'https://doc.syspass.org'; + public const APP_UPDATES_URL = 'https://api.github.com/repos/nuxsmin/sysPass/releases/latest'; + public const APP_NOTICES_URL = 'https://api.github.com/repos/nuxsmin/sysPass/issues?milestone=none&state=open&labels=Notices'; + public const APP_ISSUES_URL = 'https://github.com/nuxsmin/sysPass/issues'; } \ No newline at end of file diff --git a/lib/SP/Core/Context/ContextBase.php b/lib/SP/Core/Context/ContextBase.php index 98c9de97..e7419cba 100644 --- a/lib/SP/Core/Context/ContextBase.php +++ b/lib/SP/Core/Context/ContextBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Context; @@ -31,19 +31,13 @@ namespace SP\Core\Context; */ abstract class ContextBase implements ContextInterface { - const APP_STATUS_UPDATED = 'updated'; - const APP_STATUS_RELOADED = 'reloaded'; - const APP_STATUS_INSTALLED = 'installed'; - const APP_STATUS_LOGGEDOUT = 'loggedout'; + public const APP_STATUS_UPDATED = 'updated'; + public const APP_STATUS_RELOADED = 'reloaded'; + public const APP_STATUS_INSTALLED = 'installed'; + public const APP_STATUS_LOGGEDOUT = 'loggedout'; - /** - * @var ContextCollection - */ - private $context; - /** - * @var ContextCollection - */ - private $trasient; + private ?ContextCollection $context = null; + private ContextCollection $trasient; /** * ContextBase constructor. @@ -57,10 +51,6 @@ abstract class ContextBase implements ContextInterface * Sets an arbitrary key in the trasient collection. * This key is not bound to any known method or type * - * @param string $key - * @param mixed $value - * - * @return mixed * @throws ContextException */ public function setTrasientKey(string $key, $value) @@ -81,23 +71,18 @@ abstract class ContextBase implements ContextInterface /** * Gets an arbitrary key from the trasient collection. * This key is not bound to any known method or type - * - * @param string $key - * @param mixed $default - * - * @return mixed */ public function getTrasientKey(string $key, $default = null) { - return is_numeric($default) ? (int)$this->trasient->get($key, $default) : $this->trasient->get($key, $default); + return is_numeric($default) ? + (int)$this->trasient->get($key, $default) + : $this->trasient->get($key, $default); } /** - * @param $context - * * @throws ContextException */ - final protected function setContextReference(&$context) + final protected function setContextReference(&$context): void { if ($this->context !== null) { throw new ContextException(__u('Context already initialized')); @@ -107,7 +92,9 @@ abstract class ContextBase implements ContextInterface && ($context['context'] instanceof ContextCollection) === false ) { throw new ContextException(__u('Invalid context')); - } elseif (!isset($context['context'])) { + } + + if (!isset($context['context'])) { $context['context'] = $this->context = new ContextCollection(); return; } @@ -116,11 +103,9 @@ abstract class ContextBase implements ContextInterface } /** - * @param ContextCollection $contextCollection - * * @throws ContextException */ - final protected function setContext(ContextCollection $contextCollection) + final protected function setContext(ContextCollection $contextCollection): void { if ($this->context !== null) { throw new ContextException(__u('Context already initialized')); @@ -132,10 +117,6 @@ abstract class ContextBase implements ContextInterface /** * Devolver una variable de contexto * - * @param string $key - * @param mixed $default - * - * @return mixed * @throws ContextException */ protected function getContextKey(string $key, $default = null) @@ -148,7 +129,7 @@ abstract class ContextBase implements ContextInterface /** * @throws ContextException */ - private function checkContext() + private function checkContext(): void { if ($this->context === null) { throw new ContextException(__u('Context not initialized')); @@ -161,7 +142,6 @@ abstract class ContextBase implements ContextInterface * @param string $key El nombre de la variable * @param mixed $value El valor de la variable * - * @return mixed * @throws ContextException */ protected function setContextKey(string $key, $value) diff --git a/lib/SP/Core/Context/ContextCollection.php b/lib/SP/Core/Context/ContextCollection.php index 615d5973..21190017 100644 --- a/lib/SP/Core/Context/ContextCollection.php +++ b/lib/SP/Core/Context/ContextCollection.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Context; diff --git a/lib/SP/Core/Context/ContextException.php b/lib/SP/Core/Context/ContextException.php index ad9c06cc..903a73ca 100644 --- a/lib/SP/Core/Context/ContextException.php +++ b/lib/SP/Core/Context/ContextException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Context; diff --git a/lib/SP/Core/Context/ContextInterface.php b/lib/SP/Core/Context/ContextInterface.php index fda059e6..b3c2c3f5 100644 --- a/lib/SP/Core/Context/ContextInterface.php +++ b/lib/SP/Core/Context/ContextInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Context; diff --git a/lib/SP/Core/Context/SessionContext.php b/lib/SP/Core/Context/SessionContext.php index 31dd4ab5..afb2b1d2 100644 --- a/lib/SP/Core/Context/SessionContext.php +++ b/lib/SP/Core/Context/SessionContext.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Context; @@ -37,10 +37,10 @@ use SP\Services\User\UserLoginResponse; */ final class SessionContext extends ContextBase { - const MAX_SID_TIME = 120; + public const MAX_SID_TIME = 120; - private static $isReset = false; - private static $isLocked = false; + private static bool $isReset = false; + private static bool $isLocked = false; /** * @return bool @@ -53,7 +53,7 @@ final class SessionContext extends ContextBase /** * Closes session */ - public static function close() + public static function close(): void { if (!self::$isLocked) { logger('Session closed'); @@ -67,7 +67,7 @@ final class SessionContext extends ContextBase /** * Destruir la sesión y reiniciar */ - public static function restart() + public static function restart(): void { self::$isReset = true; @@ -145,9 +145,9 @@ final class SessionContext extends ContextBase * * @param int $time */ - public function setConfigTime(int $time) + public function setConfigTime(int $time): void { - $this->setContextKey('configTime', (int)$time); + $this->setContextKey('configTime', $time); } /** @@ -165,7 +165,7 @@ final class SessionContext extends ContextBase * * @param UserLoginResponse|null $userLoginResponse */ - public function setUserData(UserLoginResponse $userLoginResponse = null) + public function setUserData(UserLoginResponse $userLoginResponse = null): void { $this->setContextKey('userData', $userLoginResponse); } @@ -185,7 +185,7 @@ final class SessionContext extends ContextBase * * @param ProfileData $ProfileData */ - public function setUserProfile(ProfileData $ProfileData) + public function setUserProfile(ProfileData $ProfileData): void { $this->setContextKey('userProfile', $ProfileData); } @@ -201,7 +201,7 @@ final class SessionContext extends ContextBase /** * @param AccountSearchFilter $searchFilters */ - public function setSearchFilters(AccountSearchFilter $searchFilters) + public function setSearchFilters(AccountSearchFilter $searchFilters): void { $this->setContextKey('searchFilters', $searchFilters); } @@ -237,7 +237,7 @@ final class SessionContext extends ContextBase * * @param $bool */ - public function setAuthCompleted($bool) + public function setAuthCompleted($bool): void { $this->setContextKey('authCompleted', (bool)$bool); } @@ -265,7 +265,7 @@ final class SessionContext extends ContextBase * * @param string $password */ - public function setTemporaryMasterPass(string $password) + public function setTemporaryMasterPass(string $password): void { $this->setContextKey('tempmasterpass', $password); } @@ -285,7 +285,7 @@ final class SessionContext extends ContextBase * * @param $key */ - public function setPublicKey($key) + public function setPublicKey($key): void { $this->setContextKey('pubkey', $key); } @@ -329,7 +329,7 @@ final class SessionContext extends ContextBase * * @param $time int La marca de hora */ - public function setLastActivity(int $time) + public function setLastActivity(int $time): void { $this->setContextKey('lastActivity', $time); } @@ -349,7 +349,7 @@ final class SessionContext extends ContextBase * * @param $locale */ - public function setLocale($locale) + public function setLocale($locale): void { $this->setContextKey('locale', $locale); } @@ -379,7 +379,7 @@ final class SessionContext extends ContextBase * * @param array $color */ - public function setAccountColor(array $color) + public function setAccountColor(array $color): void { $this->setContextKey('accountcolor', $color); } @@ -399,7 +399,7 @@ final class SessionContext extends ContextBase * * @param string $status */ - public function setAppStatus(string $status) + public function setAppStatus(string $status): void { $this->setContextKey('status', $status); } @@ -419,7 +419,7 @@ final class SessionContext extends ContextBase * * @param string $csrf */ - public function setCSRF(string $csrf) + public function setCSRF(string $csrf): void { $this->setContextKey('csrf', $csrf); } @@ -449,7 +449,7 @@ final class SessionContext extends ContextBase * * @param Vault $vault */ - public function setVault(Vault $vault) + public function setVault(Vault $vault): void { $this->setContextKey('vault', $vault); } @@ -459,7 +459,7 @@ final class SessionContext extends ContextBase * * @param array $accountsCache */ - public function setAccountsCache(array $accountsCache) + public function setAccountsCache(array $accountsCache): void { $this->setContextKey('accountsCache', $accountsCache); } @@ -477,7 +477,7 @@ final class SessionContext extends ContextBase /** * @throws ContextException */ - public function initialize() + public function initialize(): void { // Si la sesión no puede ser iniciada, devolver un error 500 if (session_start() === false) { diff --git a/lib/SP/Core/Context/StatelessContext.php b/lib/SP/Core/Context/StatelessContext.php index 963e7c00..42496cbc 100644 --- a/lib/SP/Core/Context/StatelessContext.php +++ b/lib/SP/Core/Context/StatelessContext.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Context; @@ -39,7 +39,7 @@ final class StatelessContext extends ContextBase * * @param UserLoginResponse|null $userLoginResponse */ - public function setUserData(UserLoginResponse $userLoginResponse = null) + public function setUserData(UserLoginResponse $userLoginResponse = null): void { $this->setContextKey('userData', $userLoginResponse); } @@ -99,7 +99,7 @@ final class StatelessContext extends ContextBase * * @param ProfileData $ProfileData */ - public function setUserProfile(ProfileData $ProfileData) + public function setUserProfile(ProfileData $ProfileData): void { $this->setContextKey('userProfile', $ProfileData); } @@ -129,7 +129,7 @@ final class StatelessContext extends ContextBase * * @param $locale */ - public function setLocale($locale) + public function setLocale($locale): void { $this->setContextKey('locale', $locale); } @@ -159,7 +159,7 @@ final class StatelessContext extends ContextBase * * @param string $status */ - public function setAppStatus(string $status) + public function setAppStatus(string $status): void { $this->setContextKey('status', $status); } @@ -178,7 +178,7 @@ final class StatelessContext extends ContextBase * @return void * @throws ContextException */ - public function initialize() + public function initialize(): void { $this->setContext(new ContextCollection()); } @@ -188,9 +188,9 @@ final class StatelessContext extends ContextBase * * @param int $time */ - public function setConfigTime(int $time) + public function setConfigTime(int $time): void { - $this->setContextKey('configTime', (int)$time); + $this->setContextKey('configTime', $time); } /** @@ -218,7 +218,7 @@ final class StatelessContext extends ContextBase * * @throws ContextException */ - public function setTemporaryMasterPass(string $password) + public function setTemporaryMasterPass(string $password): void { $this->setTrasientKey('_tempmasterpass', $password); } @@ -249,10 +249,6 @@ final class StatelessContext extends ContextBase { $ctxKey = $this->getContextKey('plugins'); - if (isset($ctxKey[$pluginName][$key])) { - return $ctxKey[$pluginName][$key]; - } - - return null; + return $ctxKey[$pluginName][$key] ?? null; } } \ No newline at end of file diff --git a/lib/SP/Core/Crypt/CSRF.php b/lib/SP/Core/Crypt/CSRF.php index 86fa4989..628d6dde 100644 --- a/lib/SP/Core/Crypt/CSRF.php +++ b/lib/SP/Core/Crypt/CSRF.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,15 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Crypt; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Context\ContextInterface; -use SP\Core\Context\SessionContext; use SP\Http\Request; /** @@ -37,27 +36,22 @@ use SP\Http\Request; */ final class CSRF { - /** - * @var SessionContext - */ - private $context; - /** - * @var Request - */ - private $request; - /** - * @var ConfigData - */ - private $configData; + private ContextInterface $context; + private Request $request; + private ConfigDataInterface $configData; /** * CSRF constructor. * - * @param ContextInterface $context - * @param Request $request - * @param ConfigData $configData + * @param ContextInterface $context + * @param Request $request + * @param ConfigDataInterface $configData */ - public function __construct(ContextInterface $context, Request $request, ConfigData $configData) + public function __construct( + ContextInterface $context, + Request $request, + ConfigDataInterface $configData + ) { $this->context = $context; $this->request = $request; @@ -95,8 +89,6 @@ final class CSRF /** * Devolver la llave de cifrado para los datos de la cookie - * - * @return string */ private function getKey(): string { @@ -105,10 +97,8 @@ final class CSRF /** * Initialize the CSRF key - * - * @return void */ - public function initialize() + public function initialize(): void { if ($this->context->isLoggedIn() && $this->context->getCSRF() === null diff --git a/lib/SP/Core/Crypt/Cookie.php b/lib/SP/Core/Crypt/Cookie.php index 93fdbb38..041e1f10 100644 --- a/lib/SP/Core/Crypt/Cookie.php +++ b/lib/SP/Core/Crypt/Cookie.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Crypt; @@ -34,14 +34,8 @@ use SP\Http\Request; */ abstract class Cookie { - /** - * @var Request - */ - protected $request; - /** - * @var string - */ - private $cookieName; + protected Request $request; + private string $cookieName; /** * Cookie constructor. @@ -57,13 +51,8 @@ abstract class Cookie /** * Firmar la cookie para autentificación - * - * @param string $data - * @param string $cypher - * - * @return string */ - public final function sign(string $data, string $cypher): string + final public function sign(string $data, string $cypher): string { $data = base64_encode($data); @@ -73,20 +62,19 @@ abstract class Cookie /** * Comprobar la firma de la cookie y devolver los datos * - * @param string $data - * @param string $cypher - * * @return bool|string */ - public final function getCookieData(string $data, string $cypher) + final public function getCookieData(string $data, string $cypher) { if (strpos($data, ';') === false) { return false; } - list($signature, $data) = explode(';', $data, 2); + [$signature, $data] = explode(';', $data, 2); - return Hash::checkMessage($data, $cypher, $signature) ? base64_decode($data) : false; + return Hash::checkMessage($data, $cypher, $signature) + ? base64_decode($data) + : false; } /** @@ -96,15 +84,14 @@ abstract class Cookie */ protected function getCookie() { - return $this->request->getRequest()->cookies()->get($this->cookieName, false); + return $this->request + ->getRequest() + ->cookies() + ->get($this->cookieName, false); } /** * Sets cookie data - * - * @param string $data - * - * @return bool */ protected function setCookie(string $data): bool { diff --git a/lib/SP/Core/Crypt/Crypt.php b/lib/SP/Core/Crypt/Crypt.php index 218fda70..d479eb10 100644 --- a/lib/SP/Core/Crypt/Crypt.php +++ b/lib/SP/Core/Crypt/Crypt.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Crypt; @@ -39,14 +39,20 @@ final class Crypt /** * Encriptar datos con una clave segura * - * @param string $data - * @param string|Key $securedKey - * @param null $password + * @param string $data + * @param string|Key $securedKey + * @param string|null $password * * @return string - * @throws CryptoException + * @throws \Defuse\Crypto\Exception\BadFormatException + * @throws \Defuse\Crypto\Exception\CryptoException + * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException */ - public static function encrypt(string $data, $securedKey, $password = null) + public static function encrypt( + string $data, + $securedKey, + ?string $password = null + ): string { try { if ($securedKey instanceof Key) { @@ -57,7 +63,7 @@ final class Crypt $key = Key::loadFromAsciiSafeString($securedKey); } - return Crypto::encrypt((string)$data, $key); + return Crypto::encrypt($data, $key); } catch (CryptoException $e) { logger($e->getMessage()); @@ -66,14 +72,14 @@ final class Crypt } /** - * @param string $key - * @param string $password - * @param bool $useAscii - * * @return string|Key * @throws CryptoException */ - public static function unlockSecuredKey(string $key, string $password, $useAscii = true) + public static function unlockSecuredKey( + string $key, + string $password, + bool $useAscii = true + ) { try { if ($useAscii) { @@ -93,22 +99,31 @@ final class Crypt * * @param string $data * @param string|Key|KeyProtectedByPassword $securedKey - * @param null $password + * @param string|null $password * * @return string - * @throws CryptoException + * @throws \Defuse\Crypto\Exception\BadFormatException + * @throws \Defuse\Crypto\Exception\CryptoException + * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException + * @throws \Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException */ - public static function decrypt(string $data, $securedKey, $password = null) + public static function decrypt( + string $data, + $securedKey, + ?string $password = null + ): string { try { if ($securedKey instanceof Key) { return Crypto::decrypt($data, $securedKey); - } elseif (null !== $password) { + } + + if (null !== $password) { if ($securedKey instanceof KeyProtectedByPassword) { return Crypto::decrypt($data, $securedKey->unlockKey($password)); - } else { - return Crypto::decrypt($data, self::unlockSecuredKey($securedKey, $password, false)); } + + return Crypto::decrypt($data, self::unlockSecuredKey($securedKey, $password, false)); } return Crypto::decrypt($data, Key::loadFromAsciiSafeString($securedKey)); @@ -123,13 +138,13 @@ final class Crypt /** * Securiza una clave de seguridad * - * @param string $password - * @param bool $useAscii - * * @return string|KeyProtectedByPassword * @throws CryptoException */ - public static function makeSecuredKey(string $password, $useAscii = true) + public static function makeSecuredKey( + string $password, + bool $useAscii = true + ) { try { if ($useAscii) { diff --git a/lib/SP/Core/Crypt/CryptPKI.php b/lib/SP/Core/Crypt/CryptPKI.php index b3d51835..12393a02 100644 --- a/lib/SP/Core/Crypt/CryptPKI.php +++ b/lib/SP/Core/Crypt/CryptPKI.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Crypt; @@ -38,26 +38,15 @@ use SP\Storage\File\FileHandler; */ final class CryptPKI { - const KEY_SIZE = 1024; - const PUBLIC_KEY_FILE = CONFIG_PATH . DIRECTORY_SEPARATOR . 'pubkey.pem'; - const PRIVATE_KEY_FILE = CONFIG_PATH . DIRECTORY_SEPARATOR . 'key.pem'; + public const KEY_SIZE = 1024; + public const PUBLIC_KEY_FILE = CONFIG_PATH . DIRECTORY_SEPARATOR . 'pubkey.pem'; + public const PRIVATE_KEY_FILE = CONFIG_PATH . DIRECTORY_SEPARATOR . 'key.pem'; + + protected RSA $rsa; + private ?FileHandler $publicKeyFile = null; + private ?FileHandler $privateKeyFile = null; /** - * @var RSA - */ - protected $rsa; - /** - * @var FileHandler - */ - private $publicKeyFile; - /** - * @var FileHandler - */ - private $privateKeyFile; - - /** - * @param RSA $rsa - * * @throws SPException */ public function __construct(RSA $rsa) @@ -70,10 +59,9 @@ final class CryptPKI /** * Check if private and public keys exist * - * @return void * @throws SPException */ - private function setUp() + private function setUp(): void { $this->publicKeyFile = new FileHandler(self::PUBLIC_KEY_FILE); $this->privateKeyFile = new FileHandler(self::PRIVATE_KEY_FILE); @@ -93,20 +81,17 @@ final class CryptPKI * * @throws FileException */ - public function createKeys() + public function createKeys(): void { $keys = $this->rsa->createKey(self::KEY_SIZE); $this->publicKeyFile->save($keys['publickey']); $this->privateKeyFile->save($keys['privatekey']); - chmod(CryptPKI::PRIVATE_KEY_FILE, 0600); + chmod(self::PRIVATE_KEY_FILE, 0600); } - /** - * @return int - */ - public static function getMaxDataSize() + public static function getMaxDataSize(): int { return (self::KEY_SIZE / 8) - 11; } @@ -114,9 +99,6 @@ final class CryptPKI /** * Encriptar datos con la clave pública * - * @param string $data los datos a encriptar - * - * @return string * @throws FileException */ public function encryptRSA(string $data): string @@ -130,7 +112,6 @@ final class CryptPKI /** * Devuelve la clave pública desde el archivo * - * @return string * @throws FileException */ public function getPublicKey(): string @@ -143,23 +124,19 @@ final class CryptPKI /** * Desencriptar datos cifrados con la clave pública * - * @param string $data los datos a desencriptar - * - * @return string|false * @throws FileException */ - public function decryptRSA(string $data) + public function decryptRSA(string $data): ?string { $this->rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1); $this->rsa->loadKey($this->getPrivateKey(), RSA::PRIVATE_FORMAT_PKCS1); - return @$this->rsa->decrypt($data); + return @$this->rsa->decrypt($data) ?: null; } /** * Devuelve la clave privada desde el archivo * - * @return string * @throws FileException */ public function getPrivateKey(): string @@ -170,10 +147,9 @@ final class CryptPKI } /** - * @return int * @throws FileException */ - public function getKeySize() + public function getKeySize(): int { $this->rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1); $this->rsa->loadKey($this->getPrivateKey(), RSA::PRIVATE_FORMAT_PKCS1); diff --git a/lib/SP/Core/Crypt/CryptSessionHandler.php b/lib/SP/Core/Crypt/CryptSessionHandler.php index 6e50429c..7b084a6b 100644 --- a/lib/SP/Core/Crypt/CryptSessionHandler.php +++ b/lib/SP/Core/Crypt/CryptSessionHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Crypt; @@ -38,17 +38,9 @@ final class CryptSessionHandler extends SessionHandler /** * @var bool Indica si la sesión está encriptada */ - public static $isSecured = false; - /** - * @var Key - */ - private $key; + public static bool $isSecured = false; + private Key $key; - /** - * Session constructor. - * - * @param Key $Key - */ public function __construct(Key $Key) { $this->key = $Key; @@ -68,25 +60,25 @@ final class CryptSessionHandler extends SessionHandler *

* @since 5.4.0 */ - public function read($id) + public function read($id): string { $data = parent::read($id); if (!$data) { return ''; - } else { - try { - self::$isSecured = true; + } - return Crypt::decrypt($data, $this->key); - } catch (CryptoException $e) { - self::$isSecured = false; + try { + self::$isSecured = true; - logger($e->getMessage()); - logger('Session data not encrypted.'); + return Crypt::decrypt($data, $this->key); + } catch (CryptoException $e) { + self::$isSecured = false; - return $data; - } + logger($e->getMessage()); + logger('Session data not encrypted.'); + + return $data; } } @@ -110,7 +102,7 @@ final class CryptSessionHandler extends SessionHandler *

* @since 5.4.0 */ - public function write($id, $data) + public function write($id, $data): bool { try { $data = Crypt::encrypt($data, $this->key); diff --git a/lib/SP/Core/Crypt/Hash.php b/lib/SP/Core/Crypt/Hash.php index 2d615715..aa9ed439 100644 --- a/lib/SP/Core/Crypt/Hash.php +++ b/lib/SP/Core/Crypt/Hash.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Crypt; @@ -34,15 +34,14 @@ final class Hash /** * Longitud máxima aceptada para hashing */ - const MAX_KEY_LENGTH = 72; + public const MAX_KEY_LENGTH = 72; + private const HASH_ALGO = 'sha256'; /** * Comprobar el hash de una clave. * * @param string $key con la clave a comprobar * @param string $hash con el hash a comprobar - * - * @return bool */ public static function checkHashKey(string $key, string $hash): bool { @@ -57,10 +56,10 @@ final class Hash * * @return string */ - private static function getKey(string &$key, $isCheck = true): string + private static function getKey(string &$key, bool $isCheck = true): string { if (mb_strlen($key) > self::MAX_KEY_LENGTH) { - $key = hash('sha256', $key); + $key = hash(self::HASH_ALGO, $key); if ($isCheck === false) { logger('[INFO] Password string shortened using SHA256 and then BCRYPT'); @@ -84,28 +83,21 @@ final class Hash /** * Checks a message with a given key against a hash - * - * @param $message - * @param $key - * @param $hash - * - * @return bool */ - public static function checkMessage($message, $key, $hash): bool + public static function checkMessage( + string $message, + string $key, + string $hash + ): bool { return hash_equals($hash, self::signMessage($message, $key)); } /** * Signs a message with a given key - * - * @param $message - * @param $key - * - * @return string */ - public static function signMessage($message, $key): string + public static function signMessage(string $message, string $key): string { - return hash_hmac('sha256', $message, $key); + return hash_hmac(self::HASH_ALGO, $message, $key); } } \ No newline at end of file diff --git a/lib/SP/Core/Crypt/OldCrypt.php b/lib/SP/Core/Crypt/OldCrypt.php index bce8d583..a6b91a0b 100644 --- a/lib/SP/Core/Crypt/OldCrypt.php +++ b/lib/SP/Core/Crypt/OldCrypt.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,13 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Crypt; use SP\Bootstrap; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Exceptions\SPException; use SP\Util\Checks; @@ -66,7 +66,7 @@ final class OldCrypt */ public static function makeHashSalt($salt = null, $random = true) { - /** @var ConfigData $ConfigData */ + /** @var ConfigDataInterface $ConfigData */ $ConfigData = Bootstrap::getContainer()['configData']; if ($random === true) { diff --git a/lib/SP/Core/Crypt/SecureKeyCookie.php b/lib/SP/Core/Crypt/SecureKeyCookie.php index 9003f4e1..8634869d 100644 --- a/lib/SP/Core/Crypt/SecureKeyCookie.php +++ b/lib/SP/Core/Crypt/SecureKeyCookie.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Crypt; @@ -39,23 +39,13 @@ final class SecureKeyCookie extends Cookie /** * Nombre de la cookie */ - const COOKIE_NAME = 'SYSPASS_SK'; + public const COOKIE_NAME = 'SYSPASS_SK'; /** * Llave usada para encriptar los datos - * - * @var Key */ - private $securedKey; - /** - * @var string - */ - private $cypher; + private ?Key $securedKey = null; + private ?string $cypher = null; - /** - * @param Request $request - * - * @return SecureKeyCookie - */ public static function factory(Request $request): SecureKeyCookie { $self = new self(self::COOKIE_NAME, $request); @@ -66,8 +56,6 @@ final class SecureKeyCookie extends Cookie /** * Devolver la llave de cifrado para los datos de la cookie - * - * @return string */ public function getCypher(): string { @@ -77,7 +65,7 @@ final class SecureKeyCookie extends Cookie /** * Obtener una llave de encriptación * - * @return Key|false|string + * @return false|Key */ public function getKey() { @@ -90,8 +78,7 @@ final class SecureKeyCookie extends Cookie /** @var Vault $vault */ $vault = unserialize($data, ['allowed_classes' => Vault::class]); - if ($vault !== false - && ($vault instanceof Vault) === true + if (($vault instanceof Vault) === true ) { try { $this->securedKey = Key::loadFromAsciiSafeString($vault->getData($this->cypher)); @@ -115,10 +102,8 @@ final class SecureKeyCookie extends Cookie /** * Guardar una llave de encriptación - * - * @return Key|false */ - public function saveKey() + public function saveKey(): bool { try { if ($this->setCookie($this->sign($this->generateSecuredData()->getSerialized(), $this->cypher)) === false) { @@ -140,7 +125,6 @@ final class SecureKeyCookie extends Cookie } /** - * @return Vault * @throws CryptoException * @throws EnvironmentIsBrokenException */ @@ -152,9 +136,6 @@ final class SecureKeyCookie extends Cookie ->saveData($this->securedKey->saveToAsciiSafeString(), $this->cypher); } - /** - * @return Key - */ public function getSecuredKey(): Key { return $this->securedKey; diff --git a/lib/SP/Core/Crypt/Session.php b/lib/SP/Core/Crypt/Session.php index eaef3734..a261e47a 100644 --- a/lib/SP/Core/Crypt/Session.php +++ b/lib/SP/Core/Crypt/Session.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Crypt; @@ -37,9 +37,6 @@ final class Session /** * Devolver la clave maestra de la sesión * - * @param SessionContext $sessionContext - * - * @return string * @throws CryptoException */ public static function getSessionKey(SessionContext $sessionContext): string @@ -47,11 +44,6 @@ final class Session return $sessionContext->getVault()->getData(self::getKey($sessionContext)); } - /** - * @param SessionContext $sessionContext - * - * @return string - */ private static function getKey(SessionContext $sessionContext): string { return session_id() . $sessionContext->getSidStartTime(); @@ -60,12 +52,9 @@ final class Session /** * Guardar la clave maestra en la sesión * - * @param $data - * @param SessionContext $sessionContext - * * @throws CryptoException */ - public static function saveSessionKey($data, SessionContext $sessionContext) + public static function saveSessionKey($data, SessionContext $sessionContext): void { $sessionContext->setVault((new Vault())->saveData($data, self::getKey($sessionContext))); } @@ -73,11 +62,9 @@ final class Session /** * Regenerar la clave de sesión * - * @param SessionContext $sessionContext - * * @throws CryptoException */ - public static function reKey(SessionContext $sessionContext) + public static function reKey(SessionContext $sessionContext): void { logger(__METHOD__); diff --git a/lib/SP/Core/Crypt/UUIDCookie.php b/lib/SP/Core/Crypt/UUIDCookie.php index d3865196..77e519cb 100644 --- a/lib/SP/Core/Crypt/UUIDCookie.php +++ b/lib/SP/Core/Crypt/UUIDCookie.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Crypt; @@ -36,13 +36,8 @@ class UUIDCookie extends Cookie /** * Nombre de la cookie */ - const COOKIE_NAME = 'SYSPASS_UUID'; + public const COOKIE_NAME = 'SYSPASS_UUID'; - /** - * @param Request $request - * - * @return UUIDCookie - */ public static function factory(Request $request): UUIDCookie { return new self(self::COOKIE_NAME, $request); @@ -51,8 +46,6 @@ class UUIDCookie extends Cookie /** * Creates a cookie and sets its data * - * @param string $signKey Signing key - * * @return string|false */ public function createCookie(string $signKey) @@ -69,14 +62,14 @@ class UUIDCookie extends Cookie /** * Loads cookie data * - * @param string $signKey Signing key - * * @return false|string */ public function loadCookie(string $signKey) { $data = $this->getCookie(); - return $data !== false ? $this->getCookieData($data, $signKey) : false; + return $data !== false + ? $this->getCookieData($data, $signKey) + : false; } } \ No newline at end of file diff --git a/lib/SP/Core/Crypt/Vault.php b/lib/SP/Core/Crypt/Vault.php index 54134a33..ad435516 100644 --- a/lib/SP/Core/Crypt/Vault.php +++ b/lib/SP/Core/Crypt/Vault.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Crypt; use Defuse\Crypto\Exception\CryptoException; +use RuntimeException; /** * Class Vault @@ -33,38 +34,19 @@ use Defuse\Crypto\Exception\CryptoException; */ final class Vault { - /** - * @var string - */ - private $data; - /** - * @var string - */ - private $key; - /** - * @var int - */ - private $timeSet = 0; - /** - * @var int - */ - private $timeUpdated = 0; + private ?string $data = null; + private ?string $key = null; + private int $timeSet = 0; + private int $timeUpdated = 0; - /** - * @return static - */ public static function getInstance(): Vault { - return new Vault(); + return new self(); } /** * Regenerar la clave de sesión * - * @param string $newSeed - * @param string $oldSeed - * - * @return Vault * @throws CryptoException */ public function reKey(string $newSeed, string $oldSeed): Vault @@ -80,23 +62,20 @@ final class Vault /** * Devolver la clave maestra de la sesión * - * @param string $key - * - * @return string * @throws CryptoException */ public function getData(string $key): string { + if ($this->data === null || $this->key === null) { + throw new RuntimeException('Either data or key must be set'); + } + return Crypt::decrypt($this->data, $this->key, $key); } /** * Guardar la clave maestra en la sesión * - * @param mixed $data - * @param string $key - * - * @return $this * @throws CryptoException */ public function saveData($data, string $key): Vault @@ -111,17 +90,11 @@ final class Vault return $this; } - /** - * @return int - */ public function getTimeSet(): int { return $this->timeSet; } - /** - * @return int - */ public function getTimeUpdated(): int { return $this->timeUpdated; diff --git a/lib/SP/Core/DataCollection.php b/lib/SP/Core/DataCollection.php index 4d21535a..de98f161 100644 --- a/lib/SP/Core/DataCollection.php +++ b/lib/SP/Core/DataCollection.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core; @@ -39,10 +39,8 @@ abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countab { /** * Collection of data attributes - * - * @type array */ - protected $attributes = []; + protected array $attributes = []; /** * Retrieve an external iterator @@ -72,7 +70,7 @@ abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countab * The return value will be casted to boolean if non-boolean was returned. * @since 5.0.0 */ - public function offsetExists($offset) + public function offsetExists($offset): bool { return $this->exists($offset); } @@ -119,11 +117,7 @@ abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countab */ public function get(string $key, $default_val = null) { - if (isset($this->attributes[$key])) { - return $this->attributes[$key]; - } - - return $default_val; + return $this->attributes[$key] ?? $default_val; } /** @@ -141,7 +135,7 @@ abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countab * @return void * @since 5.0.0 */ - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { $this->set($offset, $value); } @@ -173,7 +167,7 @@ abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countab * @return void * @since 5.0.0 */ - public function offsetUnset($offset) + public function offsetUnset($offset): void { $this->remove($offset); } @@ -185,7 +179,7 @@ abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countab * * @return void */ - public function remove(string $key) + public function remove(string $key): void { unset($this->attributes[$key]); } @@ -200,7 +194,7 @@ abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countab * The return value is cast to an integer. * @since 5.1.0 */ - public function count() + public function count(): int { return count($this->attributes); } @@ -238,7 +232,7 @@ abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countab */ public function isEmpty(): bool { - return empty($this->attributes); + return count($this->attributes) === 0; } /** @@ -252,7 +246,7 @@ abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countab * @return mixed * @see get() */ - public function __get($key) + public function __get(string $key) { return $this->get($key); } @@ -269,7 +263,7 @@ abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countab * @return void * @see set() */ - public function __set($key, $value) + public function __set(string $key, $value) { $this->set($key, $value); } @@ -285,7 +279,7 @@ abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countab * @return boolean * @see exists() */ - public function __isset($key) + public function __isset(string $key) { return $this->exists($key); } @@ -302,7 +296,7 @@ abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countab * @see remove() * */ - public function __unset($key) + public function __unset(string $key) { $this->remove($key); } diff --git a/lib/SP/Core/Events/Event.php b/lib/SP/Core/Events/Event.php index 010d8fe8..cd7d33fb 100644 --- a/lib/SP/Core/Events/Event.php +++ b/lib/SP/Core/Events/Event.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,13 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Events; -use InvalidArgumentException; use SP\Core\Exceptions\InvalidClassException; +use SP\Core\Exceptions\SPException; /** * Class Event @@ -34,14 +34,8 @@ use SP\Core\Exceptions\InvalidClassException; */ final class Event { - /** - * @var object - */ - private $source; - /** - * @var EventMessage - */ - private $eventMessage; + private object $source; + private ?EventMessage $eventMessage = null; /** * Event constructor. @@ -50,23 +44,19 @@ final class Event * @param EventMessage|null $eventMessage * */ - public function __construct(object $source, EventMessage $eventMessage = null) + public function __construct( + object $source, + EventMessage $eventMessage = null + ) { - if (!is_object($source)) { - throw new InvalidArgumentException(__u('An object is needed')); - } - $this->source = $source; $this->eventMessage = $eventMessage; } /** - * @param null $type - * - * @return mixed * @throws InvalidClassException */ - public function getSource($type = null): object + public function getSource(?string $type = null): object { if ($type !== null && ($source = get_class($this->source)) !== $type @@ -74,7 +64,7 @@ final class Event ) { throw new InvalidClassException( 'Source type mismatch', - InvalidClassException::ERROR, + SPException::ERROR, sprintf('Source: %s - Expected: %s', $source, $type) ); } @@ -82,10 +72,7 @@ final class Event return $this->source; } - /** - * @return EventMessage|null - */ - public function getEventMessage() + public function getEventMessage(): ?EventMessage { return $this->eventMessage; } diff --git a/lib/SP/Core/Events/EventDispatcher.php b/lib/SP/Core/Events/EventDispatcher.php index 89581a02..888decd9 100644 --- a/lib/SP/Core/Events/EventDispatcher.php +++ b/lib/SP/Core/Events/EventDispatcher.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Events; diff --git a/lib/SP/Core/Events/EventDispatcherBase.php b/lib/SP/Core/Events/EventDispatcherBase.php index 6f341fcc..51fdea48 100644 --- a/lib/SP/Core/Events/EventDispatcherBase.php +++ b/lib/SP/Core/Events/EventDispatcherBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Events; @@ -38,7 +38,7 @@ abstract class EventDispatcherBase implements EventDispatcherInterface /** * @var EventReceiver[] */ - protected $observers = []; + protected array $observers = []; /** * Attach an SplObserver @@ -104,18 +104,16 @@ abstract class EventDispatcherBase implements EventDispatcherInterface /** * Notificar un evento - * - * @param string $eventName - * @param Event $event */ - public function notifyEvent(string $eventName, Event $event) + public function notifyEvent(string $eventName, Event $event): void { foreach ($this->observers as $observer) { if (method_exists($observer, 'getEventsString')) { $events = $observer->getEventsString(); if (!empty($events) - && ($events === '*' || preg_match('/' . $events . '/i', $eventName)) + && ($events === '*' + || preg_match('/' . $events . '/i', $eventName)) ) { // FIXME: update receivers Event $observer->updateEvent($eventName, $event); diff --git a/lib/SP/Core/Events/EventDispatcherInterface.php b/lib/SP/Core/Events/EventDispatcherInterface.php index d84fac33..9e89c96b 100644 --- a/lib/SP/Core/Events/EventDispatcherInterface.php +++ b/lib/SP/Core/Events/EventDispatcherInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Events; @@ -36,8 +36,8 @@ interface EventDispatcherInterface extends SplSubject /** * Notificar a los observadores y establecer el estado * - * @param string $eventName Nombre del evento - * @param Event $event Objeto del evento + * @param string $eventName Nombre del evento + * @param Event $event Objeto del evento */ - public function notifyEvent(string $eventName, Event $event); + public function notifyEvent(string $eventName, Event $event): void; } \ No newline at end of file diff --git a/lib/SP/Core/Events/EventMessage.php b/lib/SP/Core/Events/EventMessage.php index cf11f116..3371906d 100644 --- a/lib/SP/Core/Events/EventMessage.php +++ b/lib/SP/Core/Events/EventMessage.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Events; @@ -39,49 +39,24 @@ final class EventMessage implements MessageInterface /** * @var array Detalles de la acción en formato "detalle : descripción" */ - protected $details = []; - /** - * @var int - */ - protected $descriptionCounter = 0; - /** - * @var int - */ - protected $detailsCounter = 0; - /** - * @var array - */ - protected $description = []; - /** - * @var array - */ - protected $extra = []; + protected array $details = []; + protected int $descriptionCounter = 0; + protected int $detailsCounter = 0; + protected array $description = []; + protected array $extra = []; - /** - * @return static - */ - public static function factory() + public static function factory(): EventMessage { - return new static(); + return new self(); } - /** - * Devuelve la descripción - * - * @return array - */ - public function getDescriptionRaw() + public function getDescriptionRaw(): array { return $this->description; } /** * Establece los detalles de la acción realizada - * - * @param $key string - * @param $value string|null - * - * @return $this */ public function addDetail(string $key, ?string $value): EventMessage { @@ -98,10 +73,6 @@ final class EventMessage implements MessageInterface /** * Formatear una cadena para guardarla en el registro - * - * @param $string string La cadena a formatear - * - * @return string */ private function formatString(string $string): string { @@ -110,12 +81,8 @@ final class EventMessage implements MessageInterface /** * Establece la descripción de la acción realizada - * - * @param string $description - * - * @return $this */ - public function addDescription($description = ''): EventMessage + public function addDescription(string $description = ''): EventMessage { $this->description[] = $this->formatString($description); @@ -126,10 +93,6 @@ final class EventMessage implements MessageInterface /** * Componer un mensaje en formato texto - * - * @param string $delimiter - * - * @return string */ public function composeText(string $delimiter = PHP_EOL): string { @@ -147,13 +110,11 @@ final class EventMessage implements MessageInterface /** * Devuelve la descripción de la acción realizada - * - * @param FormatterInterface $formatter - * @param bool $translate - * - * @return string */ - public function getDescription(FormatterInterface $formatter, $translate = false): string + public function getDescription( + FormatterInterface $formatter, + bool $translate + ): string { if ($this->descriptionCounter === 0) { return ''; @@ -164,13 +125,11 @@ final class EventMessage implements MessageInterface /** * Devuelve los detalles de la acción realizada - * - * @param FormatterInterface $formatter - * @param bool $translate - * - * @return string */ - public function getDetails(FormatterInterface $formatter, bool $translate = false): string + public function getDetails( + FormatterInterface $formatter, + bool $translate = false + ): string { if ($this->detailsCounter === 0) { return ''; @@ -181,18 +140,14 @@ final class EventMessage implements MessageInterface /** * Devuelve los detalles - * - * @return array */ - public function getDetailsRaw() + public function getDetailsRaw(): array { return $this->details; } /** * Componer un mensaje en formato HTML - * - * @return string */ public function composeHtml(): string { @@ -206,36 +161,21 @@ final class EventMessage implements MessageInterface return $message; } - /** - * @return int - */ public function getDescriptionCounter(): int { return $this->descriptionCounter; } - /** - * @return int - */ public function getDetailsCounter(): int { return $this->detailsCounter; } - /** - * @return array - */ public function getExtra(): array { return $this->extra; } - /** - * @param string $type - * @param array $data - * - * @return EventMessage - */ public function setExtra(string $type, array $data): EventMessage { if (isset($this->extra[$type])) { @@ -249,16 +189,11 @@ final class EventMessage implements MessageInterface /** * Extra data are stored as an array of values per key, thus each key is unique - * - * @param string $type - * @param mixed $data - * - * @return EventMessage */ public function addExtra(string $type, $data): EventMessage { if (isset($this->extra[$type]) - && in_array($data, $this->extra[$type]) + && in_array($data, $this->extra[$type], false) ) { return $this; } diff --git a/lib/SP/Core/Events/EventReceiver.php b/lib/SP/Core/Events/EventReceiver.php index 5f8c3c33..5f5fb4ee 100644 --- a/lib/SP/Core/Events/EventReceiver.php +++ b/lib/SP/Core/Events/EventReceiver.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Events; @@ -39,7 +39,7 @@ interface EventReceiver extends SplObserver * @param string $eventType Nombre del evento * @param Event $event Objeto del evento */ - public function updateEvent(string $eventType, Event $event); + public function updateEvent(string $eventType, Event $event): void; /** * Devuelve los eventos que implementa el observador diff --git a/lib/SP/Core/Exceptions/CheckException.php b/lib/SP/Core/Exceptions/CheckException.php index 3e4a6afb..91844c7c 100644 --- a/lib/SP/Core/Exceptions/CheckException.php +++ b/lib/SP/Core/Exceptions/CheckException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/ConfigException.php b/lib/SP/Core/Exceptions/ConfigException.php index 3f24883f..5328eee1 100644 --- a/lib/SP/Core/Exceptions/ConfigException.php +++ b/lib/SP/Core/Exceptions/ConfigException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/ConstraintException.php b/lib/SP/Core/Exceptions/ConstraintException.php index 1c6971f6..b4bf10e2 100644 --- a/lib/SP/Core/Exceptions/ConstraintException.php +++ b/lib/SP/Core/Exceptions/ConstraintException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/FileNotFoundException.php b/lib/SP/Core/Exceptions/FileNotFoundException.php index 3c120d65..cb809ced 100644 --- a/lib/SP/Core/Exceptions/FileNotFoundException.php +++ b/lib/SP/Core/Exceptions/FileNotFoundException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/InitializationException.php b/lib/SP/Core/Exceptions/InitializationException.php index 63bd9c6e..e81336e1 100644 --- a/lib/SP/Core/Exceptions/InitializationException.php +++ b/lib/SP/Core/Exceptions/InitializationException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/InstallError.php b/lib/SP/Core/Exceptions/InstallError.php index 06cbaf15..daa9009f 100644 --- a/lib/SP/Core/Exceptions/InstallError.php +++ b/lib/SP/Core/Exceptions/InstallError.php @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/InvalidArgumentException.php b/lib/SP/Core/Exceptions/InvalidArgumentException.php index 8f3f554c..95ed1e21 100644 --- a/lib/SP/Core/Exceptions/InvalidArgumentException.php +++ b/lib/SP/Core/Exceptions/InvalidArgumentException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/InvalidClassException.php b/lib/SP/Core/Exceptions/InvalidClassException.php index 93b5f912..ec941c75 100644 --- a/lib/SP/Core/Exceptions/InvalidClassException.php +++ b/lib/SP/Core/Exceptions/InvalidClassException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/InvalidImageException.php b/lib/SP/Core/Exceptions/InvalidImageException.php index a645eda1..677fde7a 100644 --- a/lib/SP/Core/Exceptions/InvalidImageException.php +++ b/lib/SP/Core/Exceptions/InvalidImageException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/ItemException.php b/lib/SP/Core/Exceptions/ItemException.php index 2755d344..74625039 100644 --- a/lib/SP/Core/Exceptions/ItemException.php +++ b/lib/SP/Core/Exceptions/ItemException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/NoSuchPropertyException.php b/lib/SP/Core/Exceptions/NoSuchPropertyException.php index 55a2dd38..50f85c0b 100644 --- a/lib/SP/Core/Exceptions/NoSuchPropertyException.php +++ b/lib/SP/Core/Exceptions/NoSuchPropertyException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/QueryException.php b/lib/SP/Core/Exceptions/QueryException.php index 9e4fb5aa..f4e73e1f 100644 --- a/lib/SP/Core/Exceptions/QueryException.php +++ b/lib/SP/Core/Exceptions/QueryException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/SPException.php b/lib/SP/Core/Exceptions/SPException.php index 806d6532..56f38af4 100644 --- a/lib/SP/Core/Exceptions/SPException.php +++ b/lib/SP/Core/Exceptions/SPException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/SessionTimeout.php b/lib/SP/Core/Exceptions/SessionTimeout.php index cf898842..4a5d2eea 100644 --- a/lib/SP/Core/Exceptions/SessionTimeout.php +++ b/lib/SP/Core/Exceptions/SessionTimeout.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/Exceptions/ValidationException.php b/lib/SP/Core/Exceptions/ValidationException.php index d97f34ba..71db80f0 100644 --- a/lib/SP/Core/Exceptions/ValidationException.php +++ b/lib/SP/Core/Exceptions/ValidationException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Exceptions; diff --git a/lib/SP/Core/ItemsTypeInterface.php b/lib/SP/Core/ItemsTypeInterface.php index e01869be..436ccb6f 100644 --- a/lib/SP/Core/ItemsTypeInterface.php +++ b/lib/SP/Core/ItemsTypeInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core; @@ -31,14 +31,14 @@ namespace SP\Core; */ interface ItemsTypeInterface { - const ITEM_CATEGORIES = 1; - const ITEM_CUSTOMERS = 2; - const ITEM_CUSTOMERS_USER = 52; - const ITEM_FILES = 3; - const ITEM_TAGS = 4; - const ITEM_USERS = 5; - const ITEM_GROUPS = 6; - const ITEM_PROFILES = 7; - const ITEM_ACCOUNTS = 8; - const ITEM_ACCOUNTS_USER = 58; + public const ITEM_CATEGORIES = 1; + public const ITEM_CUSTOMERS = 2; + public const ITEM_CUSTOMERS_USER = 52; + public const ITEM_FILES = 3; + public const ITEM_TAGS = 4; + public const ITEM_USERS = 5; + public const ITEM_GROUPS = 6; + public const ITEM_PROFILES = 7; + public const ITEM_ACCOUNTS = 8; + public const ITEM_ACCOUNTS_USER = 58; } \ No newline at end of file diff --git a/lib/SP/Core/Language.php b/lib/SP/Core/Language.php index e6edf1ed..37dae624 100644 --- a/lib/SP/Core/Language.php +++ b/lib/SP/Core/Language.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,15 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core; use SP\Config\Config; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Context\ContextInterface; -use SP\Core\Context\SessionContext; use SP\Http\Request; defined('APP_ROOT') || die(); @@ -41,16 +40,12 @@ final class Language { /** * Lenguaje del usuario - * - * @var string */ - public static $userLang = ''; + public static string $userLang = ''; /** * Lenguaje global de la Aplicación - * - * @var string */ - public static $globalLang = ''; + public static string $globalLang = ''; /** * Estado de la localización. false si no existe * @@ -59,14 +54,12 @@ final class Language public static $localeStatus; /** * Si se ha establecido a las de la App - * - * @var bool */ - protected static $appSet = false; + protected static bool $appSet = false; /** - * @var array Available languages + * Available languages */ - private static $langs = [ + private static array $langs = [ 'es_ES' => 'Español', 'ca_ES' => 'Catalá', 'en_US' => 'English', @@ -82,25 +75,12 @@ final class Language 'fo' => 'Føroyskt mál', 'ja_JP' => '日本語', ]; - /** - * @var ConfigData - */ - protected $configData; - /** - * @var SessionContext - */ - protected $context; - /** - * @var Request - */ - private $request; + protected ConfigDataInterface $configData; + protected ContextInterface $context; + private Request $request; /** * Language constructor. - * - * @param ContextInterface $session - * @param Config $config - * @param Request $request */ public function __construct(ContextInterface $session, Config $config, Request $request) { @@ -113,8 +93,6 @@ final class Language /** * Devolver los lenguajes disponibles - * - * @return array */ public static function getAvailableLanguages(): array { @@ -126,7 +104,7 @@ final class Language * * @param bool $force Forzar la detección del lenguaje para los inicios de sesión */ - public function setLanguage($force = false) + public function setLanguage(bool $force = false): void { $lang = $this->context->getLocale(); @@ -144,14 +122,14 @@ final class Language /** * Devuelve el lenguaje del usuario - * - * @return string */ private function getUserLang(): string { $userData = $this->context->getUserData(); - return ($userData->getId() > 0) ? $userData->getPreferences()->getLang() : ''; + return ($userData->getId() > 0) + ? $userData->getPreferences()->getLang() + : ''; } /** @@ -165,22 +143,20 @@ final class Language /** * Devolver el lenguaje que acepta el navegador - * - * @return string */ private function getBrowserLang(): string { $lang = $this->request->getHeader('Accept-Language'); - return $lang !== '' ? str_replace('-', '_', substr($lang, 0, 5)) : 'en_US'; + return $lang !== '' + ? str_replace('-', '_', substr($lang, 0, 5)) + : 'en_US'; } /** * Establecer las locales de gettext - * - * @param string $lang El lenguaje a utilizar */ - public static function setLocales(string $lang) + public static function setLocales(string $lang): void { $lang .= '.utf8'; @@ -206,7 +182,7 @@ final class Language /** * Establecer el lenguaje global para las traducciones */ - public function setAppLocales() + public function setAppLocales(): void { if ($this->configData->getSiteLang() !== $this->context->getLocale()) { self::setLocales($this->configData->getSiteLang()); @@ -218,7 +194,7 @@ final class Language /** * Restablecer el lenguaje global para las traducciones */ - public function unsetAppLocales() + public function unsetAppLocales(): void { if (self::$appSet === true) { self::setLocales($this->context->getLocale()); @@ -229,12 +205,8 @@ final class Language /** * Comprobar si el archivo de lenguaje existe - * - * @param string $lang El lenguaje a comprobar - * - * @return bool */ - private function checkLangFile(string $lang) + private function checkLangFile(string $lang): bool { return file_exists(LOCALES_PATH . DIRECTORY_SEPARATOR . $lang); } diff --git a/lib/SP/Core/Messages/FormatterInterface.php b/lib/SP/Core/Messages/FormatterInterface.php index b837c286..b55244cc 100644 --- a/lib/SP/Core/Messages/FormatterInterface.php +++ b/lib/SP/Core/Messages/FormatterInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Messages; @@ -31,19 +31,7 @@ namespace SP\Core\Messages; */ interface FormatterInterface { - /** - * @param array $text - * @param bool $translate - * - * @return string - */ public function formatDetail(array $text, bool $translate = false): string; - /** - * @param $text - * @param bool $translate - * - * @return string - */ public function formatDescription(array $text, bool $translate = false): string; } \ No newline at end of file diff --git a/lib/SP/Core/Messages/HtmlFormatter.php b/lib/SP/Core/Messages/HtmlFormatter.php index 77a567d7..68efafe3 100644 --- a/lib/SP/Core/Messages/HtmlFormatter.php +++ b/lib/SP/Core/Messages/HtmlFormatter.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Messages; @@ -34,59 +34,56 @@ use SP\Html\Html; final class HtmlFormatter implements FormatterInterface { - /** - * @param array $text - * @param bool $translate - * - * @return string - */ public function formatDetail(array $text, bool $translate = false): string { return implode( '', - array_map(function ($value) use ($translate) { - $right = $this->buildLink($value[1]); - $left = $translate ? __($value[0]) : $value[0]; + array_map( + function ($value) use ($translate) { + $right = $this->buildLink($value[1]); + $left = $translate ? __($value[0]) : $value[0]; - if (strpos($right, '' - . '' . $left . '' - . '' . $right . '' - . '

'; - }, $text)); + return '
' + . '' . $left . '' + . '' . $right . '' + . '
'; + }, + $text) + ); } /** * Detects a link within the string and builds an HTML link - * - * @param string $text - * - * @return string */ private function buildLink(string $text): string { if (preg_match('#^https?://.*$#', $text, $matches)) { - return sprintf('%s', $matches[0], Html::truncate($matches[0], 30)); + return sprintf( + '%s', + $matches[0], + Html::truncate($matches[0], 30) + ); } return $text; } - /** - * @param array $text - * @param bool $translate - * - * @return string - */ - public function formatDescription(array $text, bool $translate = false): string + public function formatDescription( + array $text, + bool $translate = false + ): string { return implode( '', - array_map(function ($value) use ($translate) { - return '
' . ($translate ? __($value) : $value) . '
'; - }, $text)); + array_map( + static function ($value) use ($translate) { + return '
' . ($translate ? __($value) : $value) . '
'; + }, + $text) + ); } } \ No newline at end of file diff --git a/lib/SP/Core/Messages/LogMessage.php b/lib/SP/Core/Messages/LogMessage.php index 83eebc24..e4ac7e68 100644 --- a/lib/SP/Core/Messages/LogMessage.php +++ b/lib/SP/Core/Messages/LogMessage.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Messages; @@ -34,29 +34,18 @@ final class LogMessage extends MessageBase /** * @var string Acción realizada */ - protected $action; + protected string $action; /** * @var array Detalles de la acción en formato "detalle : descripción" */ - protected $details = []; - /** - * @var int - */ - protected $descriptionCounter = 0; - /** - * @var int - */ - protected $detailsCounter = 0; + protected array $details = []; + protected int $descriptionCounter = 0; + protected int $detailsCounter = 0; /** * Establece los detalles de la acción realizada - * - * @param $key string - * @param $value string - * - * @return $this */ - public function addDetails(string $key, string $value) + public function addDetails(string $key, string $value): LogMessage { if ($value === '' || $key === '') { return $this; @@ -70,10 +59,6 @@ final class LogMessage extends MessageBase /** * Formatear una cadena para guardarla en el registro - * - * @param $string string La cadena a formatear - * - * @return string */ private function formatString(string $string): string { @@ -82,10 +67,6 @@ final class LogMessage extends MessageBase /** * Establece la descripción de la acción realizada - * - * @param string $description - * - * @return $this */ public function addDescription(string $description = ''): LogMessage { @@ -97,7 +78,7 @@ final class LogMessage extends MessageBase /** * Añadir una línea en blanco a la descripción */ - public function addDescriptionLine() + public function addDescriptionLine(): LogMessage { $this->description[] = ''; $this->descriptionCounter++; @@ -107,10 +88,6 @@ final class LogMessage extends MessageBase /** * Componer un mensaje en formato texto - * - * @param string $delimiter - * - * @return string */ public function composeText(string $delimiter = PHP_EOL): string { @@ -125,10 +102,6 @@ final class LogMessage extends MessageBase /** * Devuelve la acción realizada - * - * @param bool $translate - * - * @return string */ public function getAction(bool $translate = false): string { @@ -137,10 +110,6 @@ final class LogMessage extends MessageBase /** * Establece la acción realizada - * - * @param string $action - * - * @return $this */ public function setAction(string $action): LogMessage { @@ -151,13 +120,11 @@ final class LogMessage extends MessageBase /** * Devuelve la descripción de la acción realizada - * - * @param FormatterInterface $formatter - * @param bool $translate - * - * @return string */ - public function getDescription(FormatterInterface $formatter, $translate = false): string + public function getDescription( + FormatterInterface $formatter, + bool $translate + ): string { if (count($this->description) === 0) { return ''; @@ -168,13 +135,11 @@ final class LogMessage extends MessageBase /** * Devuelve los detalles de la acción realizada - * - * @param FormatterInterface $formatter - * @param bool $translate - * - * @return string */ - public function getDetails(FormatterInterface $formatter, $translate = false): string + public function getDetails( + FormatterInterface $formatter, + bool $translate + ): string { if (count($this->details) === 0) { return ''; @@ -185,8 +150,6 @@ final class LogMessage extends MessageBase /** * Componer un mensaje en formato HTML - * - * @return string */ public function composeHtml(): string { @@ -205,7 +168,7 @@ final class LogMessage extends MessageBase /** * Restablecer la variable de descripcion */ - public function resetDescription() + public function resetDescription(): LogMessage { $this->description = []; $this->descriptionCounter = 0; @@ -224,18 +187,12 @@ final class LogMessage extends MessageBase return $this; } - /** - * @return int - */ - public function getDescriptionCounter() + public function getDescriptionCounter(): int { return $this->descriptionCounter; } - /** - * @return int - */ - public function getDetailsCounter() + public function getDetailsCounter(): int { return $this->detailsCounter; } diff --git a/lib/SP/Core/Messages/MailMessage.php b/lib/SP/Core/Messages/MailMessage.php index 2056ed95..4f4669e9 100644 --- a/lib/SP/Core/Messages/MailMessage.php +++ b/lib/SP/Core/Messages/MailMessage.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Messages; @@ -29,20 +29,18 @@ namespace SP\Core\Messages; * * @package SP\Core\Messages */ -final class MailMessage extends MessageBase implements MessageInterface +final class MailMessage extends MessageBase { /** * Adds a blank description line */ - public function addDescriptionLine() + public function addDescriptionLine(): void { $this->description[] = ''; } /** * Componer un mensaje en formato HTML - * - * @return string */ public function composeHtml(): string { @@ -57,23 +55,16 @@ final class MailMessage extends MessageBase implements MessageInterface return $message; } - /** - * @param FormatterInterface $formatter - * @param bool $translate - * - * @return string - */ - public function getDescription(FormatterInterface $formatter, $translate = false): string + public function getDescription( + FormatterInterface $formatter, + bool $translate + ): string { return $formatter->formatDescription($this->description, $translate); } /** * Componer un mensaje en formato texto - * - * @param string $delimiter - * - * @return string */ public function composeText(string $delimiter = PHP_EOL): string { diff --git a/lib/SP/Core/Messages/MessageBase.php b/lib/SP/Core/Messages/MessageBase.php index d42f3894..ec8699fd 100644 --- a/lib/SP/Core/Messages/MessageBase.php +++ b/lib/SP/Core/Messages/MessageBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Messages; @@ -31,93 +31,52 @@ namespace SP\Core\Messages; */ abstract class MessageBase implements MessageInterface { - /** - * @var string - */ - protected $title; - /** - * @var array - */ - protected $footer = []; - /** - * @var array - */ - protected $description = []; + protected string $title = ''; + protected array $footer = []; + protected array $description = []; - /** - * @return static - */ - public static function factory() + public static function factory(): MessageBase { return new static(); } - /** - * @return string - */ - public function getTitle() + public function getTitle(): string { return $this->title; } - /** - * @param string $title - * - * @return MessageBase - */ - public function setTitle($title) + public function setTitle(string $title): MessageBase { $this->title = $title; return $this; } - /** - * @param FormatterInterface $formatter - * @param bool $translate - * - * @return string - */ - public abstract function getDescription(FormatterInterface $formatter, $translate = false): string; + abstract public function getDescription( + FormatterInterface $formatter, + bool $translate + ): string; - /** - * @param array $description - * - * @return MessageBase - */ - public function setDescription(array $description) + public function setDescription(array $description): MessageBase { $this->description = $description; return $this; } - /** - * @param string $description - * - * @return MessageBase - */ - public function addDescription(string $description) + public function addDescription(string $description): MessageBase { $this->description[] = $description; return $this; } - /** - * @return array - */ - public function getFooter() + public function getFooter(): array { return $this->footer; } - /** - * @param array $footer - * - * @return MessageBase - */ - public function setFooter(array $footer) + public function setFooter(array $footer): MessageBase { $this->footer = $footer; diff --git a/lib/SP/Core/Messages/MessageInterface.php b/lib/SP/Core/Messages/MessageInterface.php index 166fa073..d8ae4edf 100644 --- a/lib/SP/Core/Messages/MessageInterface.php +++ b/lib/SP/Core/Messages/MessageInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Messages; diff --git a/lib/SP/Core/Messages/NotificationMessage.php b/lib/SP/Core/Messages/NotificationMessage.php index 46915d25..83b7be2b 100644 --- a/lib/SP/Core/Messages/NotificationMessage.php +++ b/lib/SP/Core/Messages/NotificationMessage.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Messages; @@ -33,8 +33,6 @@ final class NotificationMessage extends MessageBase { /** * Componer un mensaje en formato HTML - * - * @return string */ public function composeHtml(): string { @@ -46,11 +44,11 @@ final class NotificationMessage extends MessageBase $message .= '

' . $this->title . '

'; } - if (!empty($this->description)) { + if (count($this->description) !== 0) { $message .= '
' . $this->getDescription($formatter) . '
'; } - if (!empty($this->footer)) { + if (count($this->footer) !== 0) { $message .= '
' . implode('
', $this->footer) . '
'; } @@ -59,23 +57,16 @@ final class NotificationMessage extends MessageBase return $message; } - /** - * @param FormatterInterface $formatter - * @param bool $translate - * - * @return string - */ - public function getDescription(FormatterInterface $formatter, $translate = false): string + public function getDescription( + FormatterInterface $formatter, + bool $translate + ): string { return $formatter->formatDescription($this->description, $translate); } /** * Componer un mensaje en formato texto - * - * @param string $delimiter - * - * @return string */ public function composeText(string $delimiter = PHP_EOL): string { @@ -85,11 +76,11 @@ final class NotificationMessage extends MessageBase $parts[] = $this->title; } - if (!empty($this->description)) { + if (count($this->description) !== 0) { $parts[] = implode($delimiter, $this->description); } - if (!empty($this->footer)) { + if (count($this->footer) !== 0) { $parts[] = implode($delimiter, $this->footer); } diff --git a/lib/SP/Core/Messages/TaskMessage.php b/lib/SP/Core/Messages/TaskMessage.php index 4964888f..009423a7 100644 --- a/lib/SP/Core/Messages/TaskMessage.php +++ b/lib/SP/Core/Messages/TaskMessage.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Messages; @@ -33,56 +33,24 @@ use JsonSerializable; */ final class TaskMessage implements MessageInterface, JsonSerializable { - /** - * @var string - */ - protected $taskId; - /** - * @var string - */ - protected $task; - /** - * @var string - */ - protected $message; - /** - * @var int - */ - protected $time = 0; - /** - * @var int - */ - protected $progress = 0; - /** - * @var int - */ - protected $end = 0; + protected string $taskId; + protected string $task; + protected ?string $message = null; + protected int $time = 0; + protected int $progress = 0; + protected int $end = 0; - /** - * TaskMessage constructor. - * - * @param string $taskId - * @param string $task - */ public function __construct(string $taskId, string $task) { $this->taskId = $taskId; $this->task = $task; } - /** - * @return string - */ - public function getTask() + public function getTask(): string { return $this->task; } - /** - * @param string $task - * - * @return TaskMessage - */ public function setTask(string $task): TaskMessage { $this->task = $task; @@ -90,39 +58,23 @@ final class TaskMessage implements MessageInterface, JsonSerializable return $this; } - /** - * @return string|null - */ public function getMessage(): ?string { return $this->message; } - /** - * @param string $message - * - * @return TaskMessage - */ - public function setMessage(string $message) + public function setMessage(string $message): TaskMessage { $this->message = $message; return $this; } - /** - * @return int - */ public function getTime(): int { return $this->time; } - /** - * @param int $time - * - * @return TaskMessage - */ public function setTime(int $time): TaskMessage { $this->time = $time; @@ -130,19 +82,11 @@ final class TaskMessage implements MessageInterface, JsonSerializable return $this; } - /** - * @return int - */ public function getProgress(): int { return $this->progress; } - /** - * @param int $progress - * - * @return TaskMessage - */ public function setProgress(int $progress): TaskMessage { $this->progress = $progress; @@ -150,19 +94,11 @@ final class TaskMessage implements MessageInterface, JsonSerializable return $this; } - /** - * @return int - */ public function getEnd(): int { return $this->end; } - /** - * @param int $end - * - * @return TaskMessage - */ public function setEnd(int $end): TaskMessage { $this->end = $end; @@ -170,12 +106,16 @@ final class TaskMessage implements MessageInterface, JsonSerializable return $this; } + /** + * Componer un mensaje en formato HTML + */ + public function composeHtml(): string + { + return $this->composeText(); + } + /** * Componer un mensaje en formato texto - * - * @param string $delimiter - * - * @return string */ public function composeText(string $delimiter = ';'): string { @@ -189,51 +129,35 @@ final class TaskMessage implements MessageInterface, JsonSerializable ]); } - /** - * Componer un mensaje en formato HTML - * - * @return string - */ - public function composeHtml(): string - { - return $this->composeText(); - } - /** * Componer un mensaje en formato JSON + * + * @throws \JsonException */ public function composeJson() { - return json_encode($this); + return json_encode($this, JSON_THROW_ON_ERROR); } /** * Specify data which should be serialized to JSON * * @link http://php.net/manual/en/jsonserializable.jsonserialize.php - * @return mixed data which can be serialized by json_encode, + * @return array data which can be serialized by json_encode, * which is a value of any type other than a resource. * @since 5.4.0 */ - public function jsonSerialize() + public function jsonSerialize(): array { return get_object_vars($this); } - /** - * @return string - */ public function getTaskId(): string { return $this->taskId; } - /** - * @param string $taskId - * - * @return TaskMessage - */ - public function setTaskId(string $taskId) + public function setTaskId(string $taskId): TaskMessage { $this->taskId = $taskId; diff --git a/lib/SP/Core/Messages/TextFormatter.php b/lib/SP/Core/Messages/TextFormatter.php index 95cdff12..410ee15c 100644 --- a/lib/SP/Core/Messages/TextFormatter.php +++ b/lib/SP/Core/Messages/TextFormatter.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\Messages; @@ -31,48 +31,34 @@ namespace SP\Core\Messages; */ final class TextFormatter implements FormatterInterface { - /** - * @var string - */ - private $delimiter; + private string $delimiter; - /** - * TextFormatter constructor. - * - * @param string $delimiter - */ - public function __construct($delimiter = PHP_EOL) + public function __construct(string $delimiter = PHP_EOL) { $this->delimiter = $delimiter; } - /** - * @param array $text - * @param bool $translate - * - * @return string - */ public function formatDetail(array $text, bool $translate = false): string { return implode( $this->delimiter, - array_map(function ($value) use ($translate) { - return sprintf( - '%s: %s', - $translate ? __($value[0]) : $value[0] - , $translate ? __($value[1]) : $value[1] - ); - }, $text)); + array_map( + static function ($value) use ($translate) { + return sprintf( + '%s: %s', + $translate ? __($value[0]) : $value[0] + , $translate ? __($value[1]) : $value[1] + ); + }, + $text) + ); } - /** - * @param array $text - * @param bool $translate - * - * @return string - */ - public function formatDescription(array $text, bool $translate = false): string + public function formatDescription( + array $text, + bool $translate = false + ): string { if ($translate === true) { return implode($this->delimiter, array_map('__', $text)); diff --git a/lib/SP/Core/MimeTypes.php b/lib/SP/Core/MimeTypes.php index 5934a8f1..72fcac7a 100644 --- a/lib/SP/Core/MimeTypes.php +++ b/lib/SP/Core/MimeTypes.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core; @@ -38,37 +38,24 @@ final class MimeTypes /** * Cache file name */ - const MIME_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'mime.cache'; + public const MIME_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'mime.cache'; /** * Cache expire time */ - const CACHE_EXPIRE = 86400; - /** - * @var int - */ - protected $lastLoadTime; - /** - * @var array - */ - protected $mimeTypes; - /** - * @var XmlFileStorageInterface - */ - protected $xmlFileStorage; - /** - * @var FileCacheInterface - */ - private $fileCache; + public const CACHE_EXPIRE = 86400; + protected ?array $mimeTypes = null; + protected XmlFileStorageInterface $xmlFileStorage; + private FileCacheInterface $fileCache; /** * Mime constructor. * - * @param FileCacheInterface $fileCache - * @param XmlFileStorageInterface $xmlFileStorage - * * @throws FileException */ - public function __construct(FileCacheInterface $fileCache, XmlFileStorageInterface $xmlFileStorage) + public function __construct( + FileCacheInterface $fileCache, + XmlFileStorageInterface $xmlFileStorage + ) { $this->xmlFileStorage = $xmlFileStorage; $this->fileCache = $fileCache; @@ -79,10 +66,9 @@ final class MimeTypes /** * Loads MIME types from cache file * - * @return void * @throws FileException */ - protected function loadCache() + protected function loadCache(): void { try { if ($this->fileCache->isExpired(self::CACHE_EXPIRE) @@ -104,7 +90,7 @@ final class MimeTypes /** * @throws FileException */ - protected function mapAndSave() + protected function mapAndSave(): void { logger('MIME TYPES CACHE MISS', 'INFO'); @@ -117,7 +103,7 @@ final class MimeTypes * * @throws FileException */ - protected function map() + protected function map(): void { $this->mimeTypes = []; @@ -129,10 +115,9 @@ final class MimeTypes /** * Loads MIME types from XML * - * @return array * @throws FileException */ - protected function load() + protected function load(): array { return $this->xmlFileStorage->load('mimetypes')->getItems(); } @@ -140,7 +125,7 @@ final class MimeTypes /** * Saves MIME types into cache file */ - protected function saveCache() + protected function saveCache(): void { try { $this->fileCache->save($this->mimeTypes); @@ -154,17 +139,14 @@ final class MimeTypes /** * @throws FileException */ - public function reset() + public function reset(): void { @unlink(self::MIME_CACHE_FILE); $this->loadCache(); } - /** - * @return array - */ - public function getMimeTypes(): array + public function getMimeTypes(): ?array { return $this->mimeTypes; } diff --git a/lib/SP/Core/ModuleBase.php b/lib/SP/Core/ModuleBase.php index 313a049d..4c83e54a 100644 --- a/lib/SP/Core/ModuleBase.php +++ b/lib/SP/Core/ModuleBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,19 +19,16 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core; -use DI\Container; -use DI\DependencyException; -use DI\NotFoundException; use Klein\Klein; use Psr\Container\ContainerInterface; use SP\Bootstrap; use SP\Config\Config; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Context\ContextInterface; use SP\Core\Events\EventDispatcher; use SP\Http\Request; @@ -51,26 +48,11 @@ use SP\Util\Util; */ abstract class ModuleBase { - /** - * @var ConfigData - */ - protected $configData; - /** - * @var Config - */ - protected $config; - /** - * @var Klein - */ - protected $router; - /** - * @var Container - */ - protected $container; - /** - * @var Request - */ - protected $request; + protected ConfigDataInterface $configData; + protected Config $config; + protected Klein $router; + protected ContainerInterface $container; + protected Request $request; /** * Module constructor. @@ -86,18 +68,13 @@ abstract class ModuleBase $this->request = $container->get(Request::class); } - /** - * @param string $controller - */ abstract public function initialize(string $controller); /** * Comprobar si el modo mantenimiento está activado * Esta función comprueba si el modo mantenimiento está activado. * - * @param ContextInterface $context - * - * @return bool + * @throws \JsonException */ public function checkMaintenanceMode(ContextInterface $context): bool { @@ -116,11 +93,8 @@ abstract class ModuleBase /** * Initializes event handlers - * - * @throws DependencyException - * @throws NotFoundException */ - protected function initEventHandlers() + protected function initEventHandlers(): void { $eventDispatcher = $this->container->get(EventDispatcher::class); diff --git a/lib/SP/Core/PhpExtensionChecker.php b/lib/SP/Core/PhpExtensionChecker.php index eb8d9edc..1b892386 100644 --- a/lib/SP/Core/PhpExtensionChecker.php +++ b/lib/SP/Core/PhpExtensionChecker.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core; @@ -39,7 +39,7 @@ final class PhpExtensionChecker * true -> required * false -> not required */ - const EXTENSIONS = [ + public const EXTENSIONS = [ 'ldap' => false, 'curl' => false, 'simplexml' => false, @@ -60,14 +60,12 @@ final class PhpExtensionChecker 'fileinfo' => true ]; - const MSG_NOT_AVAILABLE = 'Oops, it seems that some extensions are not available: \'%s\''; + public const MSG_NOT_AVAILABLE = 'Oops, it seems that some extensions are not available: \'%s\''; /** * Available extensions - * - * @var array */ - private $available; + private ?array $available = null; /** * PhpExtensionChecker constructor. @@ -80,17 +78,17 @@ final class PhpExtensionChecker /** * Check for available extensions */ - public function checkExtensions() + public function checkExtensions(): void { - $this->available = array_intersect(array_keys(self::EXTENSIONS), array_map('strtolower', get_loaded_extensions())); + $this->available = array_intersect( + array_keys(self::EXTENSIONS), + array_map('strtolower', get_loaded_extensions()) + ); } /** * Checks if the extension is installed * - * @param bool $exception - * - * @return bool * @throws CheckException */ public function checkCurlAvailable(bool $exception = false): bool @@ -105,11 +103,14 @@ final class PhpExtensionChecker * @param bool $exception Throws an exception if the extension is not available * * @return bool - * @throws CheckException + * @throws \SP\Core\Exceptions\CheckException */ - public function checkIsAvailable(string $extension, bool $exception = false): bool + public function checkIsAvailable( + string $extension, + bool $exception = false + ): bool { - $result = in_array(strtolower($extension), $this->available); + $result = in_array(strtolower($extension), $this->available, true); if (!$result && $exception) { throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, $extension)); @@ -253,9 +254,13 @@ final class PhpExtensionChecker */ public function checkMandatory() { - $missing = array_filter(self::EXTENSIONS, function ($v, $k) { - return $v === true && !in_array($k, $this->available); - }, ARRAY_FILTER_USE_BOTH); + $missing = array_filter( + self::EXTENSIONS, + function ($v, $k) { + return $v === true && !in_array($k, $this->available, true); + }, + ARRAY_FILTER_USE_BOTH + ); if (count($missing) > 0) { throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, implode(',', array_keys($missing)))); @@ -266,13 +271,15 @@ final class PhpExtensionChecker /** * Returns missing extensions - * - * @return array */ public function getMissing(): array { - return array_filter(self::EXTENSIONS, function ($k) { - return !in_array($k, $this->available); - }, ARRAY_FILTER_USE_KEY); + return array_filter( + self::EXTENSIONS, + function ($k) { + return !in_array($k, $this->available, true); + }, + ARRAY_FILTER_USE_KEY + ); } } \ No newline at end of file diff --git a/lib/SP/Core/SessionUtil.php b/lib/SP/Core/SessionUtil.php index 7f16eab5..17c9e147 100644 --- a/lib/SP/Core/SessionUtil.php +++ b/lib/SP/Core/SessionUtil.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core; @@ -36,7 +36,7 @@ final class SessionUtil /** * Limpiar la sesión del usuario */ - public static function cleanSession() + public static function cleanSession(): void { foreach ($_SESSION as $key => $value) { unset($_SESSION[$key]); diff --git a/lib/SP/Core/UI/Theme.php b/lib/SP/Core/UI/Theme.php index db62e268..bd15463a 100644 --- a/lib/SP/Core/UI/Theme.php +++ b/lib/SP/Core/UI/Theme.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,16 +19,16 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\UI; use SP\Bootstrap; use SP\Config\Config; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; +use SP\Core\Context\ContextBase; use SP\Core\Context\ContextInterface; -use SP\Core\Context\SessionContext; use SP\Core\Exceptions\InvalidClassException; use SP\Storage\File\FileCacheInterface; use SP\Storage\File\FileException; @@ -42,51 +42,21 @@ defined('APP_ROOT') || die(); */ final class Theme implements ThemeInterface { - const ICONS_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'icons.cache'; + public const ICONS_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'icons.cache'; /** * Cache expire time */ - const CACHE_EXPIRE = 86400; - /** - * @var string - */ - private $themeUri = ''; - /** - * @var string - */ - private $themePath = ''; - /** - * @var string - */ - private $themePathFull = ''; - /** - * @var string - */ - private $themeName = ''; - /** - * @var string - */ - private $viewsPath = ''; - /** - * @var ThemeIcons - */ - private $icons; - /** - * @var ConfigData - */ - private $configData; - /** - * @var SessionContext - */ - private $context; - /** - * @var string - */ - private $module; - /** - * @var FileCacheInterface - */ - private $fileCache; + public const CACHE_EXPIRE = 86400; + private string $themeUri = ''; + private string $themePath = ''; + private string $themePathFull = ''; + private string $themeName = ''; + private string $viewsPath = ''; + private ?ThemeIcons $icons = null; + private ConfigDataInterface $configData; + private ContextInterface $context; + private string $module; + private FileCacheInterface $fileCache; /** * Theme constructor. @@ -97,9 +67,9 @@ final class Theme implements ThemeInterface * @param FileCacheInterface $fileCache */ public function __construct( - string $module, - Config $config, - ContextInterface $context, + string $module, + Config $config, + ContextInterface $context, FileCacheInterface $fileCache ) { @@ -114,10 +84,9 @@ final class Theme implements ThemeInterface * * @param bool $force Forzar la detección del tema para los inicios de sesión * - * @return void * @throws InvalidClassException */ - public function initTheme($force = false) + public function initTheme(bool $force): void { if (is_dir(VIEW_PATH)) { if (empty($this->themeName) || $force === true) { @@ -135,8 +104,6 @@ final class Theme implements ThemeInterface /** * Obtener el tema visual del usuario - * - * @return string|null */ protected function getUserTheme(): ?string { @@ -154,20 +121,19 @@ final class Theme implements ThemeInterface /** * Inicializar los iconos del tema actual * - * @return ThemeIcons * @throws InvalidClassException */ - private function initIcons(): ThemeIcons + private function initIcons(): void { try { - if ($this->context->getAppStatus() !== SessionContext::APP_STATUS_RELOADED + if ($this->context->getAppStatus() !== ContextBase::APP_STATUS_RELOADED && !$this->fileCache->isExpired(self::CACHE_EXPIRE) ) { $this->icons = $this->fileCache->load(); logger('Loaded icons cache', 'INFO'); - return $this->icons; + return; } } catch (FileException $e) { processException($e); @@ -175,13 +141,12 @@ final class Theme implements ThemeInterface $this->saveIcons(); - return $this->icons; } /** * @throws InvalidClassException */ - private function saveIcons() + private function saveIcons(): void { $iconsClass = $this->themePathFull . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR . 'Icons.php'; @@ -202,8 +167,6 @@ final class Theme implements ThemeInterface /** * Obtener los temas disponibles desde el directorio de temas - * - * @return array Con la información del tema */ public function getThemesAvailable(): array { @@ -254,41 +217,26 @@ final class Theme implements ThemeInterface return []; } - /** - * @return string - */ public function getThemeUri(): string { return $this->themeUri; } - /** - * @return string - */ public function getThemePath(): string { return $this->themePath; } - /** - * @return string - */ public function getThemeName(): string { return $this->themeName; } - /** - * @return ThemeIcons - */ public function getIcons(): ThemeIcons { return clone $this->icons; } - /** - * @return string - */ public function getViewsPath(): string { return $this->viewsPath; diff --git a/lib/SP/Core/UI/ThemeIcons.php b/lib/SP/Core/UI/ThemeIcons.php index 8e1c9361..d449608b 100644 --- a/lib/SP/Core/UI/ThemeIcons.php +++ b/lib/SP/Core/UI/ThemeIcons.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\UI; @@ -39,7 +39,7 @@ final class ThemeIcons /** * @var IconInterface[] */ - private $icons = []; + private array $icons = []; /** * @return IconInterface @@ -56,11 +56,8 @@ final class ThemeIcons */ public function getIconByName(string $name) { - if (isset($this->icons[$name])) { - return $this->icons[$name]; - } - - return new FontIcon($name, 'mdl-color-text--indigo-A200'); + return $this->icons[$name] + ?? new FontIcon($name, 'mdl-color-text--indigo-A200'); } /** @@ -387,7 +384,7 @@ final class ThemeIcons * @param string $alias * @param IconInterface $icon */ - public function addIcon(string $alias, IconInterface $icon) + public function addIcon(string $alias, IconInterface $icon): void { $this->icons[$alias] = $icon; } diff --git a/lib/SP/Core/UI/ThemeIconsInterface.php b/lib/SP/Core/UI/ThemeIconsInterface.php index 9d5727c3..146c3afe 100644 --- a/lib/SP/Core/UI/ThemeIconsInterface.php +++ b/lib/SP/Core/UI/ThemeIconsInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\UI; diff --git a/lib/SP/Core/UI/ThemeInterface.php b/lib/SP/Core/UI/ThemeInterface.php index cf356365..58408d9b 100644 --- a/lib/SP/Core/UI/ThemeInterface.php +++ b/lib/SP/Core/UI/ThemeInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Core\UI; @@ -36,7 +36,7 @@ interface ThemeInterface * * @return mixed */ - public function initTheme($force = false); + public function initTheme(bool $force): void; /** * Obtener los temas disponibles desde el directorio de temas diff --git a/lib/SP/DataModel/AccountData.php b/lib/SP/DataModel/AccountData.php index 80e12ab5..e1b62890 100644 --- a/lib/SP/DataModel/AccountData.php +++ b/lib/SP/DataModel/AccountData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; @@ -221,7 +221,7 @@ class AccountData extends DataModelBase implements JsonSerializable, DataModelIn } /** - * @return int|null + * @return int */ public function getId() { diff --git a/lib/SP/DataModel/AccountExtData.php b/lib/SP/DataModel/AccountExtData.php index 86e2b02b..8c98090e 100644 --- a/lib/SP/DataModel/AccountExtData.php +++ b/lib/SP/DataModel/AccountExtData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/AccountHistoryData.php b/lib/SP/DataModel/AccountHistoryData.php index 02d04e28..c73b2704 100644 --- a/lib/SP/DataModel/AccountHistoryData.php +++ b/lib/SP/DataModel/AccountHistoryData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/AccountPassData.php b/lib/SP/DataModel/AccountPassData.php index 4a4091f1..8ea99b1d 100644 --- a/lib/SP/DataModel/AccountPassData.php +++ b/lib/SP/DataModel/AccountPassData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/AccountSearchVData.php b/lib/SP/DataModel/AccountSearchVData.php index d31fcd13..d86ce76f 100644 --- a/lib/SP/DataModel/AccountSearchVData.php +++ b/lib/SP/DataModel/AccountSearchVData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/AccountToUserGroupData.php b/lib/SP/DataModel/AccountToUserGroupData.php index 5ac750ac..2bba885d 100644 --- a/lib/SP/DataModel/AccountToUserGroupData.php +++ b/lib/SP/DataModel/AccountToUserGroupData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/AccountVData.php b/lib/SP/DataModel/AccountVData.php index 11ddc26b..3689fda4 100644 --- a/lib/SP/DataModel/AccountVData.php +++ b/lib/SP/DataModel/AccountVData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; @@ -172,7 +172,7 @@ class AccountVData extends DataModelBase */ public function getDateAdd() { - return $this->dateAdd; + return (int)$this->dateAdd; } /** @@ -188,7 +188,7 @@ class AccountVData extends DataModelBase */ public function getDateEdit() { - return $this->dateEdit; + return (int)$this->dateEdit; } /** diff --git a/lib/SP/DataModel/ActionData.php b/lib/SP/DataModel/ActionData.php index 1885b13e..6d06fe15 100644 --- a/lib/SP/DataModel/ActionData.php +++ b/lib/SP/DataModel/ActionData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/AuthTokenData.php b/lib/SP/DataModel/AuthTokenData.php index 7b67482d..68e418a9 100644 --- a/lib/SP/DataModel/AuthTokenData.php +++ b/lib/SP/DataModel/AuthTokenData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/CategoryData.php b/lib/SP/DataModel/CategoryData.php index f600578d..ce3252f7 100644 --- a/lib/SP/DataModel/CategoryData.php +++ b/lib/SP/DataModel/CategoryData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/ClientData.php b/lib/SP/DataModel/ClientData.php index f1f3d020..50941f2a 100644 --- a/lib/SP/DataModel/ClientData.php +++ b/lib/SP/DataModel/ClientData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/ConfigData.php b/lib/SP/DataModel/ConfigData.php index f15ba416..5ca165a2 100644 --- a/lib/SP/DataModel/ConfigData.php +++ b/lib/SP/DataModel/ConfigData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/CustomFieldBaseData.php b/lib/SP/DataModel/CustomFieldBaseData.php index 533b1c86..b99d2d06 100644 --- a/lib/SP/DataModel/CustomFieldBaseData.php +++ b/lib/SP/DataModel/CustomFieldBaseData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/CustomFieldData.php b/lib/SP/DataModel/CustomFieldData.php index c8882661..7d220b4c 100644 --- a/lib/SP/DataModel/CustomFieldData.php +++ b/lib/SP/DataModel/CustomFieldData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/CustomFieldDefDataOld.php b/lib/SP/DataModel/CustomFieldDefDataOld.php index 4dc243dd..532a5699 100644 --- a/lib/SP/DataModel/CustomFieldDefDataOld.php +++ b/lib/SP/DataModel/CustomFieldDefDataOld.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/CustomFieldDefinitionData.php b/lib/SP/DataModel/CustomFieldDefinitionData.php index 82781407..80a2ff34 100644 --- a/lib/SP/DataModel/CustomFieldDefinitionData.php +++ b/lib/SP/DataModel/CustomFieldDefinitionData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/CustomFieldTypeData.php b/lib/SP/DataModel/CustomFieldTypeData.php index 1295370b..954ab1e7 100644 --- a/lib/SP/DataModel/CustomFieldTypeData.php +++ b/lib/SP/DataModel/CustomFieldTypeData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/DataModelBase.php b/lib/SP/DataModel/DataModelBase.php index e8041aec..cb68758c 100644 --- a/lib/SP/DataModel/DataModelBase.php +++ b/lib/SP/DataModel/DataModelBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/DataModelInterface.php b/lib/SP/DataModel/DataModelInterface.php index 7f456f82..ec590ece 100644 --- a/lib/SP/DataModel/DataModelInterface.php +++ b/lib/SP/DataModel/DataModelInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; @@ -32,13 +32,7 @@ namespace SP\DataModel; */ interface DataModelInterface { - /** - * @return int - */ public function getId(); - /** - * @return string - */ public function getName(); } \ No newline at end of file diff --git a/lib/SP/DataModel/Dto/AccountAclDto.php b/lib/SP/DataModel/Dto/AccountAclDto.php index 31dd7501..a41ba296 100644 --- a/lib/SP/DataModel/Dto/AccountAclDto.php +++ b/lib/SP/DataModel/Dto/AccountAclDto.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel\Dto; diff --git a/lib/SP/DataModel/Dto/AccountCache.php b/lib/SP/DataModel/Dto/AccountCache.php index ddc3adb8..8f062e31 100644 --- a/lib/SP/DataModel/Dto/AccountCache.php +++ b/lib/SP/DataModel/Dto/AccountCache.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel\Dto; diff --git a/lib/SP/DataModel/Dto/AccountDetailsResponse.php b/lib/SP/DataModel/Dto/AccountDetailsResponse.php index 37d17e96..6cb97fc9 100644 --- a/lib/SP/DataModel/Dto/AccountDetailsResponse.php +++ b/lib/SP/DataModel/Dto/AccountDetailsResponse.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel\Dto; diff --git a/lib/SP/DataModel/Dto/AccountHistoryCreateDto.php b/lib/SP/DataModel/Dto/AccountHistoryCreateDto.php index ca310400..6b8536ee 100644 --- a/lib/SP/DataModel/Dto/AccountHistoryCreateDto.php +++ b/lib/SP/DataModel/Dto/AccountHistoryCreateDto.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel\Dto; diff --git a/lib/SP/DataModel/Dto/AccountSearchResponse.php b/lib/SP/DataModel/Dto/AccountSearchResponse.php index 644c5cbc..77c63d68 100644 --- a/lib/SP/DataModel/Dto/AccountSearchResponse.php +++ b/lib/SP/DataModel/Dto/AccountSearchResponse.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel\Dto; diff --git a/lib/SP/DataModel/Dto/ConfigRequest.php b/lib/SP/DataModel/Dto/ConfigRequest.php index ffe16afe..efa65205 100644 --- a/lib/SP/DataModel/Dto/ConfigRequest.php +++ b/lib/SP/DataModel/Dto/ConfigRequest.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel\Dto; diff --git a/lib/SP/DataModel/EncryptedModel.php b/lib/SP/DataModel/EncryptedModel.php index 8dd21f8c..48069a31 100644 --- a/lib/SP/DataModel/EncryptedModel.php +++ b/lib/SP/DataModel/EncryptedModel.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/EventlogData.php b/lib/SP/DataModel/EventlogData.php index 428d7e27..53e108f4 100644 --- a/lib/SP/DataModel/EventlogData.php +++ b/lib/SP/DataModel/EventlogData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/FileData.php b/lib/SP/DataModel/FileData.php index c0d06fc0..7f7c7dca 100644 --- a/lib/SP/DataModel/FileData.php +++ b/lib/SP/DataModel/FileData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/FileExtData.php b/lib/SP/DataModel/FileExtData.php index fb8f1ee4..58960297 100644 --- a/lib/SP/DataModel/FileExtData.php +++ b/lib/SP/DataModel/FileExtData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/HydratableInterface.php b/lib/SP/DataModel/HydratableInterface.php index 8ee2a1aa..02a46b75 100644 --- a/lib/SP/DataModel/HydratableInterface.php +++ b/lib/SP/DataModel/HydratableInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/ItemData.php b/lib/SP/DataModel/ItemData.php index 975cf4ca..e8cfb4f5 100644 --- a/lib/SP/DataModel/ItemData.php +++ b/lib/SP/DataModel/ItemData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/ItemPreset/AccountPermission.php b/lib/SP/DataModel/ItemPreset/AccountPermission.php index 5982f08b..d5083d84 100644 --- a/lib/SP/DataModel/ItemPreset/AccountPermission.php +++ b/lib/SP/DataModel/ItemPreset/AccountPermission.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel\ItemPreset; diff --git a/lib/SP/DataModel/ItemPreset/AccountPrivate.php b/lib/SP/DataModel/ItemPreset/AccountPrivate.php index bd22cfcf..0789a51f 100644 --- a/lib/SP/DataModel/ItemPreset/AccountPrivate.php +++ b/lib/SP/DataModel/ItemPreset/AccountPrivate.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel\ItemPreset; diff --git a/lib/SP/DataModel/ItemPreset/Password.php b/lib/SP/DataModel/ItemPreset/Password.php index e1fe1b06..a8793ce8 100644 --- a/lib/SP/DataModel/ItemPreset/Password.php +++ b/lib/SP/DataModel/ItemPreset/Password.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel\ItemPreset; diff --git a/lib/SP/DataModel/ItemPreset/SessionTimeout.php b/lib/SP/DataModel/ItemPreset/SessionTimeout.php index 38669a59..67205359 100644 --- a/lib/SP/DataModel/ItemPreset/SessionTimeout.php +++ b/lib/SP/DataModel/ItemPreset/SessionTimeout.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel\ItemPreset; diff --git a/lib/SP/DataModel/ItemPresetData.php b/lib/SP/DataModel/ItemPresetData.php index b79e94ab..444b81b4 100644 --- a/lib/SP/DataModel/ItemPresetData.php +++ b/lib/SP/DataModel/ItemPresetData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/ItemSearchData.php b/lib/SP/DataModel/ItemSearchData.php index 4c17203b..4e941ef5 100644 --- a/lib/SP/DataModel/ItemSearchData.php +++ b/lib/SP/DataModel/ItemSearchData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; @@ -34,38 +34,20 @@ use SP\Util\Filter; */ class ItemSearchData { - const ORDER_ASC = 'ASC'; - const ORDER_DESC = 'DESC'; + private const ORDER_ASC = 'ASC'; + private const ORDER_DESC = 'DESC'; - /** - * @var string - */ - public $seachString = ''; - /** - * @var int - */ - public $limitStart = 0; - /** - * @var int - */ - public $limitCount = 0; - /** - * @var string - */ - public $order = self::ORDER_ASC; + public ?string $seachString = null; + public int $limitStart = 0; + public int $limitCount = 0; + public string $order = self::ORDER_ASC; - /** - * @return string|null - */ public function getSeachString(): ?string { return $this->seachString; } - /** - * @param string|null $seachString - */ - public function setSeachString(?string $seachString) + public function setSeachString(?string $seachString): void { if ($seachString) { $this->seachString = Filter::safeSearchString($seachString); @@ -74,50 +56,32 @@ class ItemSearchData } } - /** - * @return int - */ public function getLimitStart(): int { return $this->limitStart; } - /** - * @param int|null $limitStart - */ - public function setLimitStart(?int $limitStart) + public function setLimitStart(int $limitStart): void { - $this->limitStart = (int)$limitStart; + $this->limitStart = $limitStart; } - /** - * @return int - */ public function getLimitCount(): int { return $this->limitCount; } - /** - * @param int|null $limitCount - */ - public function setLimitCount(?int $limitCount) + public function setLimitCount(int $limitCount): void { - $this->limitCount = (int)$limitCount; + $this->limitCount = $limitCount; } - /** - * @return string - */ public function getOrder(): string { return $this->order; } - /** - * @param string|null $order - */ - public function setOrder(?string $order) + public function setOrder(string $order): void { $this->order = $order; } diff --git a/lib/SP/DataModel/NotificationData.php b/lib/SP/DataModel/NotificationData.php index 99dde0ea..4be152a9 100644 --- a/lib/SP/DataModel/NotificationData.php +++ b/lib/SP/DataModel/NotificationData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/ProfileData.php b/lib/SP/DataModel/ProfileData.php index 520f64e5..be148d5f 100644 --- a/lib/SP/DataModel/ProfileData.php +++ b/lib/SP/DataModel/ProfileData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/PublicLinkData.php b/lib/SP/DataModel/PublicLinkData.php index d418ce9c..ec4aa9e3 100644 --- a/lib/SP/DataModel/PublicLinkData.php +++ b/lib/SP/DataModel/PublicLinkData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/PublicLinkListData.php b/lib/SP/DataModel/PublicLinkListData.php index 58cc6105..99c74f4d 100644 --- a/lib/SP/DataModel/PublicLinkListData.php +++ b/lib/SP/DataModel/PublicLinkListData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/PublickLinkOldData.php b/lib/SP/DataModel/PublickLinkOldData.php index b7c261fa..d6d36c93 100644 --- a/lib/SP/DataModel/PublickLinkOldData.php +++ b/lib/SP/DataModel/PublickLinkOldData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/SerializedModel.php b/lib/SP/DataModel/SerializedModel.php index 1de64748..6f7ee60e 100644 --- a/lib/SP/DataModel/SerializedModel.php +++ b/lib/SP/DataModel/SerializedModel.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/TagData.php b/lib/SP/DataModel/TagData.php index feb6f59c..ea598ed1 100644 --- a/lib/SP/DataModel/TagData.php +++ b/lib/SP/DataModel/TagData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; @@ -79,6 +79,14 @@ class TagData extends DataModelBase implements DataModelInterface $this->createTagHash(); } + /** + * Formatear el nombre de la etiqueta y devolver un hash + */ + protected function createTagHash() + { + $this->hash = sha1(strtolower(preg_replace('#[\.\s_,\-;\'":()|/"]+#', '', $this->name))); + } + /** * @return string */ @@ -94,12 +102,4 @@ class TagData extends DataModelBase implements DataModelInterface { $this->hash = $hash; } - - /** - * Formatear el nombre de la etiqueta y devolver un hash - */ - protected function createTagHash() - { - $this->hash = sha1(strtolower(preg_replace('#[\.\s_,\-;\'":()|/"]+#', '', $this->name))); - } } \ No newline at end of file diff --git a/lib/SP/DataModel/TrackData.php b/lib/SP/DataModel/TrackData.php index 34186116..33f8b90b 100644 --- a/lib/SP/DataModel/TrackData.php +++ b/lib/SP/DataModel/TrackData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/UserData.php b/lib/SP/DataModel/UserData.php index 754a51d9..838a31c2 100644 --- a/lib/SP/DataModel/UserData.php +++ b/lib/SP/DataModel/UserData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; @@ -329,7 +329,7 @@ class UserData extends UserPassData implements DataModelInterface /** * @param boolean $isLdap */ - public function setIsLdap($isLdap) + public function setIsLdap(bool $isLdap) { $this->isLdap = (int)$isLdap; } diff --git a/lib/SP/DataModel/UserGroupData.php b/lib/SP/DataModel/UserGroupData.php index 9004cfe1..f3fa54ea 100644 --- a/lib/SP/DataModel/UserGroupData.php +++ b/lib/SP/DataModel/UserGroupData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; @@ -74,6 +74,14 @@ class UserGroupData extends DataModelBase implements DataModelInterface return $this->name; } + /** + * @param string $name + */ + public function setName($name) + { + $this->name = $name; + } + /** * @return string */ @@ -82,6 +90,14 @@ class UserGroupData extends DataModelBase implements DataModelInterface return $this->description; } + /** + * @param string $description + */ + public function setDescription($description) + { + $this->description = $description; + } + /** * @return array */ @@ -97,20 +113,4 @@ class UserGroupData extends DataModelBase implements DataModelInterface { $this->users = $users; } - - /** - * @param string $name - */ - public function setName($name) - { - $this->name = $name; - } - - /** - * @param string $description - */ - public function setDescription($description) - { - $this->description = $description; - } } \ No newline at end of file diff --git a/lib/SP/DataModel/UserLoginData.php b/lib/SP/DataModel/UserLoginData.php index 348f8a94..04fb9181 100644 --- a/lib/SP/DataModel/UserLoginData.php +++ b/lib/SP/DataModel/UserLoginData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/UserPassData.php b/lib/SP/DataModel/UserPassData.php index 4e2d10f5..028d2d9e 100644 --- a/lib/SP/DataModel/UserPassData.php +++ b/lib/SP/DataModel/UserPassData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/UserPassRecoverData.php b/lib/SP/DataModel/UserPassRecoverData.php index 163649ea..52c1610f 100644 --- a/lib/SP/DataModel/UserPassRecoverData.php +++ b/lib/SP/DataModel/UserPassRecoverData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/UserPreferencesData.php b/lib/SP/DataModel/UserPreferencesData.php index 99820f49..fc5ab5ca 100644 --- a/lib/SP/DataModel/UserPreferencesData.php +++ b/lib/SP/DataModel/UserPreferencesData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; @@ -54,7 +54,7 @@ class UserPreferencesData /** * @var bool */ - public $accountLink; + public $accountLink = false; /** * @var bool */ diff --git a/lib/SP/DataModel/UserProfileData.php b/lib/SP/DataModel/UserProfileData.php index d4eca988..295954e9 100644 --- a/lib/SP/DataModel/UserProfileData.php +++ b/lib/SP/DataModel/UserProfileData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/DataModel/UserToUserGroupData.php b/lib/SP/DataModel/UserToUserGroupData.php index 6fde8673..30b67931 100644 --- a/lib/SP/DataModel/UserToUserGroupData.php +++ b/lib/SP/DataModel/UserToUserGroupData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\DataModel; diff --git a/lib/SP/Html/Assets/FontIcon.php b/lib/SP/Html/Assets/FontIcon.php index 3efa048c..4478cf5e 100644 --- a/lib/SP/Html/Assets/FontIcon.php +++ b/lib/SP/Html/Assets/FontIcon.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\Assets; @@ -33,22 +33,8 @@ defined('APP_ROOT') || die(); */ final class FontIcon extends IconBase { - /** - * @param string $icon - * @param string|null $class - * @param string|null $title - */ - public function __construct(string $icon, ?string $class = null, ?string $title = null) - { - $this->setIcon($icon); - $this->setClass($class); - $this->setTitle($title); - } - /** * Devolver la clase del icono adaptada para un botón - * - * @return string */ public function getClassButton(): string { diff --git a/lib/SP/Html/Assets/IconBase.php b/lib/SP/Html/Assets/IconBase.php index 75d95d46..7c863e1f 100644 --- a/lib/SP/Html/Assets/IconBase.php +++ b/lib/SP/Html/Assets/IconBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\Assets; @@ -35,37 +35,38 @@ abstract class IconBase implements IconInterface { /** * El nombre del icono o imagen a utilizar - * - * @var string */ - protected $icon = ''; + protected string $icon; /** * Título del icono - * - * @var string */ - protected $title = ''; + protected ?string $title = null; /** * Clases CSS del icono - * - * @var array */ - protected $class = []; + protected ?array $class = null; - /** - * @return string - */ - public function getTitle(): string + public function __construct( + string $icon, + ?string $class = null, + ?string $title = null + ) { - return __($this->title); + $this->setIcon($icon); + $this->setClass($class); + $this->setTitle($title); + } + + public function getTitle(): ?string + { + if ($this->title) { + return __($this->title); + } + + return null; } - /** - * @param string|null $title - * - * @return $this - */ public function setTitle(?string $title): IconBase { $this->title = $title; @@ -73,19 +74,15 @@ abstract class IconBase implements IconInterface return $this; } - /** - * @return string - */ - public function getClass(): string + public function getClass(): ?string { - return implode(' ', $this->class); + if ($this->class) { + return implode(' ', $this->class); + } + + return null; } - /** - * @param string|null $class - * - * @return $this - */ public function setClass(?string $class): IconBase { if ($class) { @@ -95,22 +92,15 @@ abstract class IconBase implements IconInterface return $this; } - /** - * @return string - */ public function getIcon(): string { return $this->icon; } - /** - * @param string $icon - * - * @return $this - */ public function setIcon(string $icon): IconBase { $this->icon = $icon; + return $this; } } \ No newline at end of file diff --git a/lib/SP/Html/Assets/IconInterface.php b/lib/SP/Html/Assets/IconInterface.php index a17203f9..a85543aa 100644 --- a/lib/SP/Html/Assets/IconInterface.php +++ b/lib/SP/Html/Assets/IconInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\Assets; @@ -33,33 +33,15 @@ defined('APP_ROOT') || die(); */ interface IconInterface { - /** - * @param $title - */ - public function setTitle(string $title); + public function setTitle(?string $title); - /** - * @return string - */ - public function getTitle(): string; + public function getTitle(): ?string; - /** - * @param string $class - */ - public function setClass(string $class); + public function setClass(?string $class); - /** - * @return string - */ - public function getClass(): string; + public function getClass(): ?string; - /** - * @return string - */ - public function getIcon(): string; + public function getIcon(): ?string; - /** - * @param string $icon - */ public function setIcon(string $icon); } \ No newline at end of file diff --git a/lib/SP/Html/Assets/ImageIcon.php b/lib/SP/Html/Assets/ImageIcon.php index 1cda2d2f..136973bd 100644 --- a/lib/SP/Html/Assets/ImageIcon.php +++ b/lib/SP/Html/Assets/ImageIcon.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\Assets; @@ -33,15 +33,5 @@ defined('APP_ROOT') || die(); */ final class ImageIcon extends IconBase { - /** - * @param string $icon - * @param null $class - * @param null $title - */ - public function __construct(string $icon, $class = null, $title = null) - { - $this->setIcon($icon); - $this->setClass($class); - $this->setTitle($title); - } + } \ No newline at end of file diff --git a/lib/SP/Html/DataGrid/Action/DataGridAction.php b/lib/SP/Html/DataGrid/Action/DataGridAction.php index 438826a8..549385d7 100644 --- a/lib/SP/Html/DataGrid/Action/DataGridAction.php +++ b/lib/SP/Html/DataGrid/Action/DataGridAction.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid\Action; diff --git a/lib/SP/Html/DataGrid/Action/DataGridActionBase.php b/lib/SP/Html/DataGrid/Action/DataGridActionBase.php index fc38d743..c9878c9c 100644 --- a/lib/SP/Html/DataGrid/Action/DataGridActionBase.php +++ b/lib/SP/Html/DataGrid/Action/DataGridActionBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,11 +19,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid\Action; +use Closure; use RuntimeException; use SP\Html\Assets\IconInterface; @@ -39,27 +40,27 @@ abstract class DataGridActionBase implements DataGridActionInterface /** * The runtime function that determines if the action should be displayed * - * @var callable + * @var \Closure|null */ - protected $runtimeFilter; + protected ?Closure $runtimeFilter = null; /** * The runtime function to pass in the row dato to the action * - * @var callable + * @var \Closure|null */ - protected $runtimeData; + protected ?Closure $runtimeData = null; /** * Action's name * * @var string */ - protected $name = ''; + protected string $name = ''; /** * Action's title * * @var string */ - protected $title = ''; + protected string $title = ''; /** * Action's title ID * @@ -71,74 +72,74 @@ abstract class DataGridActionBase implements DataGridActionInterface * * @var string */ - protected $onClickFunction = ''; + protected string $onClickFunction = ''; /** * The OnClick event arguments * - * @var array + * @var array|null */ - protected $onClickArgs; + protected ?array $onClickArgs = null; /** * Action's icon * - * @var IconInterface + * @var IconInterface|null */ - protected $icon; + protected ?IconInterface $icon = null; /** * Sets whether this action should be skipped from listing in rows * * @var bool */ - protected $isSkip = false; + protected bool $isSkip = false; /** * The row name which determines whether the action is displayed * - * @var array + * @var array|null */ - protected $filterRowSource; + protected ?array $filterRowSource = null; /** * Sets as a help action * * @var bool */ - protected $isHelper; + protected ?bool $isHelper = null; /** * Action's type * * @var int */ - protected $type = 0; + protected int $type = 0; /** * Data attributes (ie. data-*) * - * @var array + * @var array|null */ - protected $data; + protected ?array $data = null; /** * Additional attributes (ie. name=*) * - * @var array + * @var array|null */ - protected $attributes; + protected ?array $attributes = null; /** * CSS classes * - * @var array + * @var array|null */ - protected $classes; + protected ?array $classes = null; /** * Sets as a selection action, that is, to be displayed on a selection menu * * @var bool */ - protected $isSelection = false; + protected bool $isSelection = false; /** * DataGridActionBase constructor. * - * @param int $id EL id de la acción + * @param int|null $id EL id de la acción */ - public function __construct($id = null) + public function __construct(?int $id = null) { $this->id = $id; } @@ -165,7 +166,7 @@ abstract class DataGridActionBase implements DataGridActionInterface public function setRuntimeFilter(string $class, string $method): DataGridActionInterface { if (method_exists($class, $method)) { - $this->runtimeFilter = function ($filter) use ($method) { + $this->runtimeFilter = static function ($filter) use ($method) { // new \ReflectionMethod($class, $method); return $filter->{$method}(); }; @@ -271,11 +272,16 @@ abstract class DataGridActionBase implements DataGridActionInterface { if ($this->onClickArgs !== null) { - $args = array_map(function ($value) { - return (!is_numeric($value) && $value !== 'this') ? '\'' . $value . '\'' : $value; - }, $this->onClickArgs); + $args = array_map( + static function ($value) { + return (!is_numeric($value) && $value !== 'this') ? '\'' . $value . '\'' : $value; + }, + $this->onClickArgs + ); - return count($args) > 0 ? $this->onClickFunction . '(' . implode(',', $args) . ')' : $this->onClickFunction; + return count($args) > 0 + ? $this->onClickFunction . '(' . implode(',', $args) . ')' + : $this->onClickFunction; } return $this->onClickFunction; @@ -394,7 +400,7 @@ abstract class DataGridActionBase implements DataGridActionInterface */ public function getData(): array { - return (array)$this->data; + return $this->data; } /** @@ -490,7 +496,7 @@ abstract class DataGridActionBase implements DataGridActionInterface */ public function getClasses(): array { - return (array)$this->classes; + return $this->classes; } /** diff --git a/lib/SP/Html/DataGrid/Action/DataGridActionHelp.php b/lib/SP/Html/DataGrid/Action/DataGridActionHelp.php index 0c48b8aa..e5a4fc52 100644 --- a/lib/SP/Html/DataGrid/Action/DataGridActionHelp.php +++ b/lib/SP/Html/DataGrid/Action/DataGridActionHelp.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid\Action; @@ -36,7 +36,7 @@ final class DataGridActionHelp extends DataGridActionBase /** * @var string */ - private $template; + private string $template; /** * DataGridActionHelp constructor. diff --git a/lib/SP/Html/DataGrid/Action/DataGridActionInterface.php b/lib/SP/Html/DataGrid/Action/DataGridActionInterface.php index 4c54db8c..a4ab74b3 100644 --- a/lib/SP/Html/DataGrid/Action/DataGridActionInterface.php +++ b/lib/SP/Html/DataGrid/Action/DataGridActionInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid\Action; diff --git a/lib/SP/Html/DataGrid/Action/DataGridActionSearch.php b/lib/SP/Html/DataGrid/Action/DataGridActionSearch.php index a5b4b50e..e8bea641 100644 --- a/lib/SP/Html/DataGrid/Action/DataGridActionSearch.php +++ b/lib/SP/Html/DataGrid/Action/DataGridActionSearch.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid\Action; @@ -36,21 +36,21 @@ final class DataGridActionSearch extends DataGridActionBase /** * @var string */ - private $onSubmitFunction = ''; + private string $onSubmitFunction = ''; /** * Los argumentos de la función OnSubmit * * @var array */ - private $onSubmitArgs = []; + private array $onSubmitArgs = []; /** * DataGridActionSearch constructor. * - * @param int $id EL id de la acción + * @param int|null $id EL id de la acción */ - public function __construct($id = null) + public function __construct(?int $id = null) { parent::__construct($id); @@ -65,16 +65,20 @@ final class DataGridActionSearch extends DataGridActionBase $args = []; foreach ($this->onSubmitArgs as $arg) { - $args[] = (!is_numeric($arg) && $arg !== 'this') ? '\'' . $arg . '\'' : $arg; + $args[] = (!is_numeric($arg) && $arg !== 'this') + ? '\'' . $arg . '\'' + : $arg; } - return count($args) > 0 ? 'return ' . $this->onSubmitFunction . '(' . implode(',', $args) . ');' : $this->onSubmitFunction; + return count($args) > 0 + ? 'return ' . $this->onSubmitFunction . '(' . implode(',', $args) . ');' + : $this->onSubmitFunction; } /** * @param string $onSubmitFunction */ - public function setOnSubmitFunction(string $onSubmitFunction) + public function setOnSubmitFunction(string $onSubmitFunction): void { $this->onSubmitFunction = $onSubmitFunction; } @@ -82,7 +86,7 @@ final class DataGridActionSearch extends DataGridActionBase /** * @param array $args */ - public function setOnSubmitArgs(array $args) + public function setOnSubmitArgs(array $args): void { $this->onSubmitArgs[] = $args; } diff --git a/lib/SP/Html/DataGrid/Action/DataGridActionType.php b/lib/SP/Html/DataGrid/Action/DataGridActionType.php index a5963d2a..3a5fc40a 100644 --- a/lib/SP/Html/DataGrid/Action/DataGridActionType.php +++ b/lib/SP/Html/DataGrid/Action/DataGridActionType.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid\Action; @@ -33,11 +33,11 @@ defined('APP_ROOT') || die(); */ interface DataGridActionType { - const MENUBAR_ITEM = 1; - const VIEW_ITEM = 2; - const EDIT_ITEM = 3; - const DELETE_ITEM = 4; - const SEARCH_ITEM = 5; - const SELECT_ITEM = 6; - const HELP_ITEM = 7; + public const MENUBAR_ITEM = 1; + public const VIEW_ITEM = 2; + public const EDIT_ITEM = 3; + public const DELETE_ITEM = 4; + public const SEARCH_ITEM = 5; + public const SELECT_ITEM = 6; + public const HELP_ITEM = 7; } \ No newline at end of file diff --git a/lib/SP/Html/DataGrid/DataGrid.php b/lib/SP/Html/DataGrid/DataGrid.php index fa14cc19..199cd472 100644 --- a/lib/SP/Html/DataGrid/DataGrid.php +++ b/lib/SP/Html/DataGrid/DataGrid.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid; @@ -38,7 +38,7 @@ final class DataGrid extends DataGridBase * * @var string */ - private $title = ''; + private string $title = ''; /** * @return string diff --git a/lib/SP/Html/DataGrid/DataGridBase.php b/lib/SP/Html/DataGrid/DataGridBase.php index 1766c167..b237343f 100644 --- a/lib/SP/Html/DataGrid/DataGridBase.php +++ b/lib/SP/Html/DataGrid/DataGridBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,14 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid; defined('APP_ROOT') || die(); -use SP\Core\Acl\ActionsInterface; use SP\Core\Exceptions\FileNotFoundException; use SP\Core\UI\ThemeInterface; use SP\Html\DataGrid\Action\DataGridActionInterface; @@ -48,91 +47,88 @@ abstract class DataGridBase implements DataGridInterface * * @var int */ - protected $time = 0; + protected int $time = 0; /** * El id de la matriz * * @var string */ - protected $id = ''; + protected string $id = ''; /** * La cabecera de la matriz * - * @var DataGridHeaderInterface + * @var DataGridHeaderInterface|null */ - protected $header; + protected ?DataGridHeaderInterface $header = null; /** * Los datos de la matriz * - * @var DataGridData + * @var DataGridData|null */ - protected $data; + protected ?DataGridData $data = null; /** * El paginador * - * @var DataGridPagerBase + * @var DataGridPagerBase|null */ - protected $pager; + protected ?DataGridPagerBase $pager = null; /** * Las acciones asociadas a los elementos de la matriz * * @var DataGridActionInterface[] */ - protected $actions = []; + protected array $actions = []; /** * @var int */ - protected $actionsCount = 0; + protected int $actionsCount = 0; /** * Las acciones asociadas a los elementos de la matriz que se muestran en un menú * * @var DataGridActionInterface[] */ - protected $actionsMenu = []; + protected array $actionsMenu = []; /** * @var int */ - protected $actionsMenuCount = 0; + protected int $actionsMenuCount = 0; /** * La acción a realizar al cerrar la matriz * * @var int */ - protected $onCloseAction = 0; + protected int $onCloseAction = 0; /** * La plantilla a utilizar para presentar la cabecera * - * @var string + * @var string|null */ - protected $headerTemplate; + protected ?string $headerTemplate = null; /** * La plantilla a utilizar para presentar las acciones * - * @var string + * @var string|null */ - protected $actionsTemplate; + protected ?string $actionsTemplate = null; /** * La plantilla a utilizar para presentar el paginador * - * @var string + * @var string|null */ - protected $pagerTemplate; + protected ?string $pagerTemplate = null; /** * La plantilla a utilizar para presentar los datos * - * @var string + * @var string|null */ - protected $rowsTemplate; + protected ?string $rowsTemplate = null; /** * La plantilla a utilizar para presentar la tabla * - * @var string + * @var string|null */ - protected $tableTemplate; - /** - * @var ThemeInterface - */ - protected $theme; + protected ?string $tableTemplate = null; + protected ?ThemeInterface $theme = null; /** * DataGridBase constructor. @@ -153,11 +149,11 @@ abstract class DataGridBase implements DataGridInterface } /** - * @param ActionsInterface $action + * @param int $action * * @return $this */ - public function setOnCloseAction(ActionsInterface $action) + public function setOnCloseAction(int $action): DataGridBase { $this->onCloseAction = $action; @@ -375,9 +371,9 @@ abstract class DataGridBase implements DataGridInterface * @param string $template El nombre de la plantilla a utilizar * @param string|null $base * - * @return mixed + * @return \SP\Html\DataGrid\DataGridBase */ - public function setDataRowTemplate(string $template, ?string $base = null) + public function setDataRowTemplate(string $template, ?string $base = null): DataGridBase { try { $this->rowsTemplate = $this->checkTemplate($template, $base); @@ -516,7 +512,7 @@ abstract class DataGridBase implements DataGridInterface * * @return DataGridBase */ - public function setDataTableTemplate($template, $base = null) + public function setDataTableTemplate($template, $base = null): DataGridBase { try { $this->tableTemplate = $this->checkTemplate($template, $base); diff --git a/lib/SP/Html/DataGrid/DataGridData.php b/lib/SP/Html/DataGrid/DataGridData.php index 93025e10..459099e6 100644 --- a/lib/SP/Html/DataGrid/DataGridData.php +++ b/lib/SP/Html/DataGrid/DataGridData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid; diff --git a/lib/SP/Html/DataGrid/DataGridDataBase.php b/lib/SP/Html/DataGrid/DataGridDataBase.php index ffda1125..38a26cda 100644 --- a/lib/SP/Html/DataGrid/DataGridDataBase.php +++ b/lib/SP/Html/DataGrid/DataGridDataBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid; @@ -41,29 +41,29 @@ abstract class DataGridDataBase implements DataGridDataInterface * * @var array */ - private $data = []; + private array $data = []; /** * Las columnas a mostrar de los datos obtenidos * * @var array */ - private $sources = []; + private array $sources = []; /** * La columna que identifica cada elemento de los datos de la matriz * - * @var int + * @var string */ - private $sourceId = 0; + private string $sourceId = ''; /** * Las columnas a mostrar de los datos obtenidos que son representadas con iconos * * @var array */ - private $sourcesWithIcon = []; + private array $sourcesWithIcon = []; /** * @var int */ - private $dataCount = 0; + private int $dataCount = 0; /** * @return array @@ -80,11 +80,11 @@ abstract class DataGridDataBase implements DataGridDataInterface * @param bool $truncate */ public function addDataRowSource( - string $source, - ?bool $isMethod = false, + string $source, + ?bool $isMethod = false, ?callable $filter = null, - ?bool $truncate = true - ) + ?bool $truncate = true + ): void { $this->sources[] = [ 'name' => $source, @@ -97,7 +97,7 @@ abstract class DataGridDataBase implements DataGridDataInterface /** * @param $id string */ - public function setDataRowSourceId(string $id) + public function setDataRowSourceId(string $id): void { $this->sourceId = $id; } @@ -129,7 +129,7 @@ abstract class DataGridDataBase implements DataGridDataInterface /** * @param QueryResult $queryResult */ - public function setData(QueryResult $queryResult) + public function setData(QueryResult $queryResult): void { $this->dataCount = $queryResult->getTotalNumRows(); $this->data = $queryResult->getDataAsArray(); @@ -141,10 +141,10 @@ abstract class DataGridDataBase implements DataGridDataInterface * @param mixed $value Valor para mostrar el icono */ public function addDataRowSourceWithIcon( - string $source, + string $source, IconInterface $icon, - int $value = 1 - ) + int $value = 1 + ): void { $this->sourcesWithIcon[] = [ 'field' => $source, diff --git a/lib/SP/Html/DataGrid/DataGridDataInterface.php b/lib/SP/Html/DataGrid/DataGridDataInterface.php index d6431d52..cc88b960 100644 --- a/lib/SP/Html/DataGrid/DataGridDataInterface.php +++ b/lib/SP/Html/DataGrid/DataGridDataInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid; @@ -45,11 +45,11 @@ interface DataGridDataInterface * @param bool $truncate */ public function addDataRowSource( - string $source, - bool $isMethod = false, + string $source, + bool $isMethod = false, callable $filter = null, - bool $truncate = true - ); + bool $truncate = true + ): void; /** * Devolver los orígenes de datos de la consulta @@ -63,7 +63,7 @@ interface DataGridDataInterface * * @param $id string */ - public function setDataRowSourceId(string $id); + public function setDataRowSourceId(string $id): void; /** * Devolver el origen de datos utilizado como Id de los elementos @@ -77,7 +77,7 @@ interface DataGridDataInterface * * @param QueryResult $queryResult */ - public function setData(QueryResult $queryResult); + public function setData(QueryResult $queryResult): void; /** * Devolver los datos de la consulta @@ -94,10 +94,10 @@ interface DataGridDataInterface * @param mixed $value Valor para mostrar el icono */ public function addDataRowSourceWithIcon( - string $source, + string $source, IconInterface $icon, - int $value = 1 - ); + int $value = 1 + ): void; /** * Devolver los orígenes de datos que se muestran con iconos diff --git a/lib/SP/Html/DataGrid/DataGridInterface.php b/lib/SP/Html/DataGrid/DataGridInterface.php index 0e4faa11..22f10003 100644 --- a/lib/SP/Html/DataGrid/DataGridInterface.php +++ b/lib/SP/Html/DataGrid/DataGridInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,14 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid; defined('APP_ROOT') || die(); -use SP\Core\Acl\ActionsInterface; use SP\Html\DataGrid\Action\DataGridActionInterface; use SP\Html\DataGrid\Layout\DataGridHeaderInterface; use SP\Html\DataGrid\Layout\DataGridPagerInterface; @@ -101,9 +100,9 @@ interface DataGridInterface public function getPager(): ?DataGridPagerInterface; /** - * @param ActionsInterface $action + * @param int $action */ - public function setOnCloseAction(ActionsInterface $action); + public function setOnCloseAction(int $action); /** * Establecer la plantilla utilizada para la cabecera diff --git a/lib/SP/Html/DataGrid/DataGridSort.php b/lib/SP/Html/DataGrid/DataGridSort.php index 89265d68..907edb0b 100644 --- a/lib/SP/Html/DataGrid/DataGridSort.php +++ b/lib/SP/Html/DataGrid/DataGridSort.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid; @@ -38,27 +38,27 @@ final class DataGridSort implements DataGridSortInterface /** * @var int */ - private $sortKey = 0; + private int $sortKey = 0; /** * @var string */ - private $title = ''; + private string $title = ''; /** * @var string */ - private $name = ''; + private string $name = ''; /** * @var array */ - private $class = []; + private array $class = []; /** * @var IconInterface */ - private $iconUp; + private IconInterface $iconUp; /** * @var IconInterface */ - private $iconDown; + private IconInterface $iconDown; /** * @return int @@ -73,7 +73,7 @@ final class DataGridSort implements DataGridSortInterface * * @return $this */ - public function setSortKey(int $key) + public function setSortKey(int $key): DataGridSortInterface { $this->sortKey = $key; @@ -93,7 +93,7 @@ final class DataGridSort implements DataGridSortInterface * * @return $this */ - public function setTitle(string $title): DataGridSort + public function setTitle(string $title): DataGridSortInterface { $this->title = $title; @@ -113,7 +113,7 @@ final class DataGridSort implements DataGridSortInterface * * @return $this */ - public function setName(string $name): DataGridSort + public function setName(string $name): DataGridSortInterface { $this->name = $name; @@ -133,7 +133,7 @@ final class DataGridSort implements DataGridSortInterface * * @return $this */ - public function setClass(string $class): DataGridSort + public function setClass(string $class): DataGridSortInterface { $this->class[] = $class; @@ -153,7 +153,7 @@ final class DataGridSort implements DataGridSortInterface * * @return $this */ - public function setIconUp(IconInterface $icon): DataGridSort + public function setIconUp(IconInterface $icon): DataGridSortInterface { $this->iconUp = $icon; @@ -173,7 +173,7 @@ final class DataGridSort implements DataGridSortInterface * * @return $this */ - public function setIconDown(IconInterface $icon): DataGridSort + public function setIconDown(IconInterface $icon): DataGridSortInterface { $this->iconDown = $icon; diff --git a/lib/SP/Html/DataGrid/DataGridSortInterface.php b/lib/SP/Html/DataGrid/DataGridSortInterface.php index 7fcad9f0..7042fbc2 100644 --- a/lib/SP/Html/DataGrid/DataGridSortInterface.php +++ b/lib/SP/Html/DataGrid/DataGridSortInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid; @@ -44,7 +44,7 @@ interface DataGridSortInterface /** * @param $key int */ - public function setSortKey(int $key); + public function setSortKey(int $key): DataGridSortInterface; /** * @return string @@ -54,7 +54,7 @@ interface DataGridSortInterface /** * @param $title string */ - public function setTitle(string $title); + public function setTitle(string $title): DataGridSortInterface; /** * @return string @@ -64,7 +64,7 @@ interface DataGridSortInterface /** * @param $name string */ - public function setName(string $name); + public function setName(string $name): DataGridSortInterface; /** * @return string @@ -74,7 +74,7 @@ interface DataGridSortInterface /** * @param $class string */ - public function setClass(string $class); + public function setClass(string $class): DataGridSortInterface; /** * @return IconInterface|null @@ -84,7 +84,7 @@ interface DataGridSortInterface /** * @param IconInterface $icon */ - public function setIconUp(IconInterface $icon); + public function setIconUp(IconInterface $icon): DataGridSortInterface; /** * @return IconInterface|null @@ -94,5 +94,5 @@ interface DataGridSortInterface /** * @param IconInterface $icon */ - public function setIconDown(IconInterface $icon); + public function setIconDown(IconInterface $icon): DataGridSortInterface; } \ No newline at end of file diff --git a/lib/SP/Html/DataGrid/DataGridTab.php b/lib/SP/Html/DataGrid/DataGridTab.php index 62cedb37..6aec0fa9 100644 --- a/lib/SP/Html/DataGrid/DataGridTab.php +++ b/lib/SP/Html/DataGrid/DataGridTab.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid; @@ -38,7 +38,7 @@ final class DataGridTab extends DataGridBase * * @var string */ - private $title = ''; + private string $title = ''; /** * @return string diff --git a/lib/SP/Html/DataGrid/Layout/DataGridHeader.php b/lib/SP/Html/DataGrid/Layout/DataGridHeader.php index 2aa83baf..e69c9494 100644 --- a/lib/SP/Html/DataGrid/Layout/DataGridHeader.php +++ b/lib/SP/Html/DataGrid/Layout/DataGridHeader.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid\Layout; diff --git a/lib/SP/Html/DataGrid/Layout/DataGridHeaderBase.php b/lib/SP/Html/DataGrid/Layout/DataGridHeaderBase.php index 83f1ecdd..2c5f1fb8 100644 --- a/lib/SP/Html/DataGrid/Layout/DataGridHeaderBase.php +++ b/lib/SP/Html/DataGrid/Layout/DataGridHeaderBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid\Layout; @@ -38,18 +38,18 @@ abstract class DataGridHeaderBase implements DataGridHeaderInterface * * @var array */ - private $headers = []; + private array $headers = []; /** * El ancho de las columnas * * @var int */ - private $width = 0; + private int $width = 0; /** * @param $header string */ - public function addHeader(string $header) + public function addHeader(string $header): void { $this->headers[] = $header; @@ -60,7 +60,7 @@ abstract class DataGridHeaderBase implements DataGridHeaderInterface /** * @return int */ - public function getWidth() + public function getWidth(): int { return $this->width; } diff --git a/lib/SP/Html/DataGrid/Layout/DataGridHeaderInterface.php b/lib/SP/Html/DataGrid/Layout/DataGridHeaderInterface.php index 5e4957c1..3995cbfa 100644 --- a/lib/SP/Html/DataGrid/Layout/DataGridHeaderInterface.php +++ b/lib/SP/Html/DataGrid/Layout/DataGridHeaderInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid\Layout; @@ -36,7 +36,7 @@ interface DataGridHeaderInterface /** * @param $header string */ - public function addHeader(string $header); + public function addHeader(string $header): void; /** * @return array diff --git a/lib/SP/Html/DataGrid/Layout/DataGridHeaderSort.php b/lib/SP/Html/DataGrid/Layout/DataGridHeaderSort.php index b59e93aa..d0b1f063 100644 --- a/lib/SP/Html/DataGrid/Layout/DataGridHeaderSort.php +++ b/lib/SP/Html/DataGrid/Layout/DataGridHeaderSort.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid\Layout; @@ -38,27 +38,27 @@ use SplObjectStorage; final class DataGridHeaderSort extends DataGridHeaderBase { /** - * @var DataGridActionInterface[] + * @var SplObjectStorage|DataGridActionInterface[]|null */ - private $actions; + private ?SplObjectStorage $actions = null; /** - * @var DataGridSortInterface[] + * @var SplObjectStorage|DataGridSortInterface[]|null */ - private $sortFields; + private ?SplObjectStorage $sortFields = null; /** - * @return DataGridSortInterface[] + * @return DataGridSortInterface[]|null */ - public function getSortFields(): array + public function getSortFields(): ?array { return $this->sortFields; } /** - * @return DataGridActionInterface[] + * @return DataGridActionInterface[]|null */ - public function getActions(): array + public function getActions(): ?array { return $this->actions; } @@ -66,7 +66,7 @@ final class DataGridHeaderSort extends DataGridHeaderBase /** * @param DataGridActionInterface $action */ - public function addAction(DataGridActionInterface $action) + public function addAction(DataGridActionInterface $action): void { if (null === $this->actions) { $this->actions = new SplObjectStorage(); diff --git a/lib/SP/Html/DataGrid/Layout/DataGridPager.php b/lib/SP/Html/DataGrid/Layout/DataGridPager.php index 60a7dc99..37b3a035 100644 --- a/lib/SP/Html/DataGrid/Layout/DataGridPager.php +++ b/lib/SP/Html/DataGrid/Layout/DataGridPager.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid\Layout; diff --git a/lib/SP/Html/DataGrid/Layout/DataGridPagerBase.php b/lib/SP/Html/DataGrid/Layout/DataGridPagerBase.php index fb73ddc9..063d586e 100644 --- a/lib/SP/Html/DataGrid/Layout/DataGridPagerBase.php +++ b/lib/SP/Html/DataGrid/Layout/DataGridPagerBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid\Layout; @@ -39,64 +39,64 @@ abstract class DataGridPagerBase implements DataGridPagerInterface /** * @var int */ - protected $sortKey = 0; + protected int $sortKey = 0; /** * @var int */ - protected $sortOrder = 0; + protected int $sortOrder = 0; /** * @var int */ - protected $limitStart = 0; + protected int $limitStart = 0; /** * @var int */ - protected $limitCount = 0; + protected int $limitCount = 0; /** * @var int */ - protected $totalRows = 0; + protected int $totalRows = 0; /** * @var bool */ - protected $filterOn = false; + protected bool $filterOn = false; /** * @var string */ - protected $onClickFunction = ''; + protected string $onClickFunction = ''; /** * @var array */ - protected $onClickArgs = []; + protected array $onClickArgs = []; /** * @var IconInterface */ - protected $iconPrev; + protected IconInterface $iconPrev; /** * @var IconInterface */ - protected $iconNext; + protected IconInterface $iconNext; /** * @var IconInterface */ - protected $iconFirst; + protected IconInterface $iconFirst; /** * @var IconInterface */ - protected $iconLast; + protected IconInterface $iconLast; /** * @var DataGridActionSearch */ - protected $sourceAction; + protected DataGridActionSearch $sourceAction; /** * @var string */ - protected $sk; + protected string $sk; /** * @return int */ - public function getSortOrder() + public function getSortOrder(): int { return $this->sortOrder; } @@ -106,7 +106,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return $this */ - public function setSortOrder($sortOrder) + public function setSortOrder(int $sortOrder): DataGridPagerBase { $this->sortOrder = $sortOrder; @@ -116,7 +116,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface /** * @return IconInterface */ - public function getIconPrev() + public function getIconPrev(): IconInterface { return $this->iconPrev; } @@ -126,7 +126,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return $this */ - public function setIconPrev(IconInterface $iconPrev) + public function setIconPrev(IconInterface $iconPrev): DataGridPagerBase { $this->iconPrev = $iconPrev; @@ -136,7 +136,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface /** * @return IconInterface */ - public function getIconNext() + public function getIconNext(): IconInterface { return $this->iconNext; } @@ -146,7 +146,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return $this */ - public function setIconNext(IconInterface $iconNext) + public function setIconNext(IconInterface $iconNext): DataGridPagerBase { $this->iconNext = $iconNext; @@ -156,7 +156,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface /** * @return IconInterface */ - public function getIconFirst() + public function getIconFirst(): IconInterface { return $this->iconFirst; } @@ -166,7 +166,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return $this */ - public function setIconFirst(IconInterface $iconFirst) + public function setIconFirst(IconInterface $iconFirst): DataGridPagerBase { $this->iconFirst = $iconFirst; @@ -176,7 +176,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface /** * @return IconInterface */ - public function getIconLast() + public function getIconLast(): IconInterface { return $this->iconLast; } @@ -186,7 +186,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return $this */ - public function setIconLast(IconInterface $iconLast) + public function setIconLast(IconInterface $iconLast): DataGridPagerBase { $this->iconLast = $iconLast; @@ -198,7 +198,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return int */ - public function getSortKey() + public function getSortKey(): int { return $this->sortKey; } @@ -210,7 +210,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return $this */ - public function setSortKey($sortKey) + public function setSortKey(int $sortKey): DataGridPagerBase { $this->sortKey = $sortKey; @@ -222,7 +222,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return int */ - public function getLimitStart() + public function getLimitStart(): int { return $this->limitStart; } @@ -234,7 +234,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return $this */ - public function setLimitStart($limitStart) + public function setLimitStart(int $limitStart): DataGridPagerBase { $this->limitStart = $limitStart; @@ -244,9 +244,9 @@ abstract class DataGridPagerBase implements DataGridPagerInterface /** * Devolver el número de registros en una página * - * @return mixed + * @return int */ - public function getLimitCount() + public function getLimitCount(): int { return $this->limitCount; } @@ -258,7 +258,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return $this */ - public function setLimitCount($limitCount) + public function setLimitCount(int $limitCount): DataGridPagerBase { $this->limitCount = $limitCount; @@ -270,7 +270,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return int */ - public function getFirstPage() + public function getFirstPage(): int { return ceil(($this->limitStart + 1) / $this->limitCount); } @@ -280,7 +280,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return int */ - public function getLastPage() + public function getLastPage(): int { return ceil($this->totalRows / $this->limitCount); } @@ -290,7 +290,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return int */ - public function getTotalRows() + public function getTotalRows(): int { return $this->totalRows; } @@ -302,7 +302,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return $this */ - public function setTotalRows($totalRows) + public function setTotalRows(int $totalRows): DataGridPagerBase { $this->totalRows = $totalRows; @@ -314,7 +314,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return bool */ - public function getFilterOn() + public function getFilterOn(): bool { return $this->filterOn; } @@ -326,7 +326,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return $this */ - public function setFilterOn($filterOn) + public function setFilterOn(bool $filterOn): DataGridPagerBase { $this->filterOn = $filterOn; @@ -340,7 +340,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return $this */ - public function setOnClickFunction($function) + public function setOnClickFunction(string $function): DataGridPagerBase { $this->onClickFunction = $function; @@ -352,22 +352,26 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return string */ - public function getOnClick() + public function getOnClick(): string { $args = $this->parseArgs(); - return count($args) > 0 ? $this->onClickFunction . '(' . implode(',', $args) . ')' : $this->onClickFunction; + return count($args) > 0 + ? $this->onClickFunction . '(' . implode(',', $args) . ')' + : $this->onClickFunction; } /** * @return array */ - protected function parseArgs() + protected function parseArgs(): array { $args = array(); foreach ($this->onClickArgs as $arg) { - $args[] = (!is_numeric($arg) && $arg !== 'this') ? '\'' . $arg . '\'' : $arg; + $args[] = (!is_numeric($arg) && $arg !== 'this') + ? '\'' . $arg . '\'' + : $arg; } return $args; @@ -376,11 +380,11 @@ abstract class DataGridPagerBase implements DataGridPagerInterface /** * Establecer los argumentos de la función OnClick * - * @param mixed $args + * @param string $args * * @return $this */ - public function setOnClickArgs($args) + public function setOnClickArgs(string $args): DataGridPagerBase { $this->onClickArgs[] = $args; @@ -392,7 +396,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return string */ - public function getOnClickFirst() + public function getOnClickFirst(): string { $args = $this->parseArgs(); $args[] = $this->getFirst(); @@ -403,7 +407,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface /** * @return int */ - public function getFirst() + public function getFirst(): int { return 0; } @@ -413,7 +417,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return string */ - public function getOnClickLast() + public function getOnClickLast(): string { $args = $this->parseArgs(); $args[] = $this->getLast(); @@ -424,9 +428,11 @@ abstract class DataGridPagerBase implements DataGridPagerInterface /** * @return float|int */ - public function getLast() + public function getLast(): int { - return (($this->totalRows % $this->limitCount) == 0) ? $this->totalRows - $this->limitCount : floor($this->totalRows / $this->limitCount) * $this->limitCount; + return (($this->totalRows % $this->limitCount) === 0) + ? $this->totalRows - $this->limitCount + : floor($this->totalRows / $this->limitCount) * $this->limitCount; } /** @@ -434,7 +440,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return string */ - public function getOnClickNext() + public function getOnClickNext(): string { $args = $this->parseArgs(); $args[] = $this->getNext(); @@ -445,7 +451,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface /** * @return int */ - public function getNext() + public function getNext(): int { return ($this->limitStart + $this->limitCount); } @@ -455,7 +461,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return string */ - public function getOnClickPrev() + public function getOnClickPrev(): string { $args = $this->parseArgs(); $args[] = $this->getPrev(); @@ -466,7 +472,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface /** * @return int */ - public function getPrev() + public function getPrev(): int { return ($this->limitStart - $this->limitCount); } @@ -474,7 +480,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface /** * @return DataGridActionSearch */ - public function getSourceAction() + public function getSourceAction(): DataGridActionSearch { return $this->sourceAction; } @@ -484,7 +490,7 @@ abstract class DataGridPagerBase implements DataGridPagerInterface * * @return $this */ - public function setSourceAction($sourceAction) + public function setSourceAction(DataGridActionSearch $sourceAction): DataGridPagerBase { $this->sourceAction = $sourceAction; diff --git a/lib/SP/Html/DataGrid/Layout/DataGridPagerInterface.php b/lib/SP/Html/DataGrid/Layout/DataGridPagerInterface.php index 00198db8..3a983fa8 100644 --- a/lib/SP/Html/DataGrid/Layout/DataGridPagerInterface.php +++ b/lib/SP/Html/DataGrid/Layout/DataGridPagerInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html\DataGrid\Layout; @@ -41,14 +41,14 @@ interface DataGridPagerInterface * * @param int $sortKey */ - public function setSortKey($sortKey); + public function setSortKey(int $sortKey); /** * Devolver el campo de la búsqueda * * @return int */ - public function getSortKey(); + public function getSortKey(): int; /** * Establecer el registro de inicio de la página @@ -57,14 +57,14 @@ interface DataGridPagerInterface * * @return static */ - public function setLimitStart($limitStart); + public function setLimitStart(int $limitStart): DataGridPagerInterface; /** * Devolver el registro de inicio de la página * * @return int */ - public function getLimitStart(); + public function getLimitStart(): int; /** * Establecer el número de registros en una página @@ -73,7 +73,7 @@ interface DataGridPagerInterface * * @return static */ - public function setLimitCount($limitCount); + public function setLimitCount(int $limitCount): DataGridPagerInterface; /** * Devolver el número de registros en una página @@ -87,14 +87,14 @@ interface DataGridPagerInterface * * @param int $totalRows */ - public function setTotalRows($totalRows); + public function setTotalRows(int $totalRows); /** * Devolver el número total de registros obtenidos * * @return int */ - public function getTotalRows(); + public function getTotalRows(): int; /** * Establecer si está activado el filtro @@ -103,68 +103,68 @@ interface DataGridPagerInterface * * @return static */ - public function setFilterOn($filterOn); + public function setFilterOn(bool $filterOn): DataGridPagerInterface; /** * Devolver si está activado el filtro * * @return bool */ - public function getFilterOn(); + public function getFilterOn(): bool; /** * Establecer la función javascript para paginar * * @param string $function */ - public function setOnClickFunction($function); + public function setOnClickFunction(string $function); /** * Devolver la función javascript para paginar * * @return string */ - public function getOnClick(); + public function getOnClick(): string; /** * Establecer los argumentos de la función OnClick * * @param string $args */ - public function setOnClickArgs($args); + public function setOnClickArgs(string $args); /** * Devolver la funcion para ir a la primera página * * @return string */ - public function getOnClickFirst(); + public function getOnClickFirst(): string; /** * Devolver la funcion para ir a la última página * * @return string */ - public function getOnClickLast(); + public function getOnClickLast(): string; /** * Devolver la funcion para ir a la siguiente página * * @return string */ - public function getOnClickNext(); + public function getOnClickNext(): string; /** * Devolver la funcion para ir a la página anterior * * @return string */ - public function getOnClickPrev(); + public function getOnClickPrev(): string; /** * @return IconInterface */ - public function getIconPrev(); + public function getIconPrev(): IconInterface; /** * @param IconInterface $iconPrev @@ -174,7 +174,7 @@ interface DataGridPagerInterface /** * @return IconInterface */ - public function getIconNext(); + public function getIconNext(): IconInterface; /** * @param IconInterface $iconNext @@ -184,7 +184,7 @@ interface DataGridPagerInterface /** * @return IconInterface */ - public function getIconFirst(); + public function getIconFirst(): IconInterface; /** * @param IconInterface $iconFirst @@ -194,7 +194,7 @@ interface DataGridPagerInterface /** * @return IconInterface */ - public function getIconLast(); + public function getIconLast(): IconInterface; /** * @param IconInterface $iconLast @@ -204,40 +204,40 @@ interface DataGridPagerInterface /** * @param DataGridActionSearch $sourceAction */ - public function setSourceAction($sourceAction); + public function setSourceAction(DataGridActionSearch $sourceAction); /** * @return int */ - public function getSortOrder(); + public function getSortOrder(): int; /** * @param int $sortOrder */ - public function setSortOrder($sortOrder); + public function setSortOrder(int $sortOrder); /** * @return int */ - public function getLast(); + public function getLast(): int; /** * @return int */ - public function getNext(); + public function getNext(): int; /** * @return int */ - public function getPrev(); + public function getPrev(): int; /** * @return int */ - public function getFirst(); + public function getFirst(): int; /** * @return DataGridActionSearch */ - public function getSourceAction(); + public function getSourceAction(): DataGridActionSearch; } \ No newline at end of file diff --git a/lib/SP/Html/Html.php b/lib/SP/Html/Html.php index 6ea3ba2e..b39c7082 100644 --- a/lib/SP/Html/Html.php +++ b/lib/SP/Html/Html.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html; @@ -104,7 +104,7 @@ final class Html */ public static function truncate( string $text, - int $limit, + int $limit, string $ellipsis = '...' ): string { @@ -120,10 +120,8 @@ final class Html * From: http://bavotasan.com/2011/convert-hex-color-to-rgb-using-php/ * * @param array $rgb con color en RGB - * - * @return string */ - public static function rgb2hex(array $rgb) + public static function rgb2hex(array $rgb): string { $hex = "#"; @@ -136,10 +134,6 @@ final class Html /** * Devolver una cadena con el tag HTML strong. - * - * @param string $text con la cadena de texto - * - * @return string */ public static function strongText(string $text): string { @@ -157,24 +151,26 @@ final class Html * @return string */ public static function anchorText( - string $text, + string $text, ?string $link = null, ?string $title = null, - string $attribs = '' + string $attribs = '' ): string { - $alink = $link !== null ? $link : $text; - $atitle = $title !== null ? $title : $text; + $alink = $link ?? $text; + $atitle = $title ?? $text; - return sprintf('%s', $alink, $atitle, $attribs, $text); + return sprintf( + '%s', + $alink, + $atitle, + $attribs, + $text + ); } /** * Strips out HTML tags preserving some spaces - * - * @param $text - * - * @return string */ public static function stripTags(string $text): string { @@ -183,6 +179,10 @@ final class Html } // Replace tags, then new lines, tabs and return chars, and then 2 or more spaces - return trim(preg_replace(['/<[^>]*>/', '/[\n\t\r]+/', '/\s{2,}/'], ' ', $text)); + return trim(preg_replace( + ['/<[^>]*>/', '/[\n\t\r]+/', '/\s{2,}/'], + ' ', + $text) + ); } } diff --git a/lib/SP/Html/Minify.php b/lib/SP/Html/Minify.php index 4e0b0a44..435368d0 100644 --- a/lib/SP/Html/Minify.php +++ b/lib/SP/Html/Minify.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Html; @@ -41,52 +41,35 @@ final class Minify /** * Constantes para tipos de archivos */ - const FILETYPE_JS = 1; - const FILETYPE_CSS = 2; - const OFFSET = 3600 * 24 * 30; - /** - * @var Klein - */ - protected $router; + public const FILETYPE_JS = 1; + public const FILETYPE_CSS = 2; + public const OFFSET = 3600 * 24 * 30; + + protected Klein $router; /** * Array con los archivos a procesar - * - * @var array */ - private $files = []; + private array $files = []; /** * Tipos de archivos a procesar - * - * @var int */ - private $type = 0; + private int $type = 0; /** * Base relativa de búsqueda de los archivos - * - * @var string */ - private $base = ''; + private string $base = ''; - /** - * Minify constructor. - * - * @param Klein $router - */ public function __construct(Klein $router) { $this->router = $router; } - /** - * @param string $path - * @param bool $checkPath - * - * @return $this - */ - public function setBase(string $path, $checkPath = false): Minify + public function setBase(string $path, bool $checkPath = false): Minify { - $this->base = $checkPath === true ? Request::getSecureAppPath($path) : $path; + $this->base = $checkPath === true + ? Request::getSecureAppPath($path) : + $path; return $this; } @@ -101,7 +84,7 @@ final class Minify * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function getMinified($disableMinify = false) + public function getMinified(bool $disableMinify = false): void { if (count($this->files) === 0) { return; @@ -119,16 +102,14 @@ final class Minify logger('URL:' . $file['name']); // $data .= '/* URL: ' . $file['name'] . ' */' . PHP_EOL . Util::getDataFromUrl($file['name']); - } else { - if ($file['min'] === true && $disableMinify === false) { - $data .= '/* MINIFIED FILE: ' . $file['name'] . ' */' . PHP_EOL; + } else if ($file['min'] === true && $disableMinify === false) { + $data .= '/* MINIFIED FILE: ' . $file['name'] . ' */' . PHP_EOL; - if ($this->type === self::FILETYPE_JS) { - $data .= $this->jsCompress(file_get_contents($filePath)); - } - } else { - $data .= PHP_EOL . '/* FILE: ' . $file['name'] . ' */' . PHP_EOL . file_get_contents($filePath); + if ($this->type === self::FILETYPE_JS) { + $data .= $this->jsCompress(file_get_contents($filePath)); } + } else { + $data .= PHP_EOL . '/* FILE: ' . $file['name'] . ' */' . PHP_EOL . file_get_contents($filePath); } } @@ -138,7 +119,7 @@ final class Minify /** * Sets HTTP headers */ - protected function setHeaders() + protected function setHeaders(): void { $response = $this->router->response(); $headers = $this->router->request()->headers(); @@ -207,18 +188,15 @@ final class Minify return str_replace(["\r\n", "\r", "\n", "\t"], '', preg_replace($regexReplace, '', $buffer)); } - /** - * @param string $files - * @param bool $minify - * - * @return Minify - */ - public function addFilesFromString(string $files, bool $minify = true): Minify + public function addFilesFromString( + string $files, + bool $minify = true + ): Minify { if (strrpos($files, ',')) { - $files = explode(',', $files); + $filesList = explode(',', $files); - foreach ($files as $filename) { + foreach ($filesList as $filename) { $this->addFile($filename, $minify); } } else { @@ -235,11 +213,11 @@ final class Minify * @param bool $minify Si es necesario reducir * @param string|null $base * - * @return $this + * @return \SP\Html\Minify */ public function addFile( - string $file, - bool $minify = true, + string $file, + bool $minify = true, ?string $base = null ): Minify { @@ -267,22 +245,12 @@ final class Minify /** * Comprobar si es necesario reducir - * - * @param string $file El nombre del archivo - * - * @return bool */ private function needsMinify(string $file): bool { return !preg_match('/\.min|pack\.css|js/', $file); } - /** - * @param array $files - * @param bool $minify - * - * @return Minify - */ public function addFiles(array $files, bool $minify = true): Minify { foreach ($files as $filename) { @@ -292,11 +260,7 @@ final class Minify return $this; } - /** - * @param string $file - * @param bool $minify - */ - protected function processFile(string $file, bool $minify = true) + protected function processFile(string $file, bool $minify = true): void { $filePath = $this->base . DIRECTORY_SEPARATOR . $file; @@ -315,10 +279,6 @@ final class Minify /** * Añadir un recurso desde URL - * - * @param string $url - * - * @return $this */ public function addUrl(string $url): Minify { @@ -335,14 +295,10 @@ final class Minify /** * Establecer el tipo de recurso a procesar - * - * @param int $type - * - * @return $this */ public function setType(int $type): Minify { - $this->type = (int)$type; + $this->type = $type; return $this; } diff --git a/lib/SP/Http/Address.php b/lib/SP/Http/Address.php index 852046dd..d7ab6ad8 100644 --- a/lib/SP/Http/Address.php +++ b/lib/SP/Http/Address.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Http; use SP\Core\Exceptions\InvalidArgumentException; +use SP\Core\Exceptions\SPException; /** * Class Address @@ -33,31 +34,25 @@ use SP\Core\Exceptions\InvalidArgumentException; */ final class Address { - const PATTERN_IP_ADDRESS = '#^(?
[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3})(?:/(?:(?[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3})|(?[\d]{1,2})))?$#'; + public const PATTERN_IP_ADDRESS = '#^(?
[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3})(?:/(?:(?[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3})|(?[\d]{1,2})))?$#'; /** - * @param $address - * - * @return mixed - * @throws InvalidArgumentException + * @throws \SP\Core\Exceptions\InvalidArgumentException */ - public static function toBinary(string $address) + public static function toBinary(string $address): string { if (!filter_var($address, FILTER_VALIDATE_IP) || ($binAddress = @inet_pton($address)) === false ) { logger(sprintf('%s : %s', __('Invalid IP'), $address)); - throw new InvalidArgumentException(__u('Invalid IP'), InvalidArgumentException::ERROR, $address); + throw new InvalidArgumentException(__u('Invalid IP'), SPException::ERROR, $address); } return $binAddress; } /** - * @param string $address - * - * @return string * @throws InvalidArgumentException */ public static function fromBinary(string $address): string @@ -67,7 +62,7 @@ final class Address if ($stringAddress === false) { logger(sprintf('%s : %s', __('Invalid IP'), $address)); - throw new InvalidArgumentException(__u('Invalid IP'), InvalidArgumentException::ERROR, $address); + throw new InvalidArgumentException(__u('Invalid IP'), SPException::ERROR, $address); } return $stringAddress; @@ -76,9 +71,6 @@ final class Address /** * Parses an IPv4 address from either "192.168.0.1", "192.168.0.0/255.255.255.0" or "192.168.0.0/24" formats * - * @param string $address - * - * @return array * @throws InvalidArgumentException */ public static function parse4(string $address): array @@ -87,26 +79,25 @@ final class Address return $matches; } - throw new InvalidArgumentException(__u('Invalid IP'), InvalidArgumentException::ERROR, $address); + throw new InvalidArgumentException(__u('Invalid IP'), SPException::ERROR, $address); } /** * Checks whether an IP address is included within $inAddress and $inMask * - * @param string $address - * @param string $inAddress - * @param string $inMask - * - * @return int * @throws InvalidArgumentException */ - public static function check(string $address, string $inAddress, string $inMask) + public static function check( + string $address, + string $inAddress, + string $inMask + ): bool { if (!filter_var($address, FILTER_VALIDATE_IP) || !filter_var($inAddress, FILTER_VALIDATE_IP) || !filter_var($inMask, FILTER_VALIDATE_IP) ) { - throw new InvalidArgumentException(__u('Invalid IP'), InvalidArgumentException::ERROR, $address); + throw new InvalidArgumentException(__u('Invalid IP'), SPException::ERROR, $address); } // Obtains subnets based on mask ie.: subnet === subnet @@ -115,10 +106,6 @@ final class Address /** * Converts a CIDR mask into decimal - * - * @param int $bits - * - * @return string */ public static function cidrToDec(int $bits): string { diff --git a/lib/SP/Http/Client.php b/lib/SP/Http/Client.php index c170b5e0..effdf384 100644 --- a/lib/SP/Http/Client.php +++ b/lib/SP/Http/Client.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Http; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; /** * Class Client @@ -33,12 +33,7 @@ use SP\Config\ConfigData; */ final class Client { - /** - * @param ConfigData $configData - * - * @return array - */ - public static function getOptions(ConfigData $configData): array + public static function getOptions(ConfigDataInterface $configData): array { $options = [ 'timeout' => 10, @@ -48,7 +43,8 @@ final class Client if ($configData->isProxyEnabled()) { $options['proxy'] = sprintf('tcp://%s:%d', $configData->getProxyServer(), $configData->getProxyPort()); - if (!empty($configData->getProxyUser()) && !empty($configData->getProxyPass())) { + if (!empty($configData->getProxyUser()) + && !empty($configData->getProxyPass())) { $options['auth'] = [$configData->getProxyUser(), $configData->getProxyPass()]; } } diff --git a/lib/SP/Http/Json.php b/lib/SP/Http/Json.php index 9f3e6d9b..02dc9154 100644 --- a/lib/SP/Http/Json.php +++ b/lib/SP/Http/Json.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,13 +19,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Http; -use DI\DependencyException; -use DI\NotFoundException; +use JsonException; use Klein\Klein; use Klein\Response; use SP\Bootstrap; @@ -39,31 +38,21 @@ use SP\Core\Exceptions\SPException; */ final class Json { - const SAFE = [ + public const SAFE = [ 'from' => ['\\', '"', '\''], 'to' => ['\\', '\"', '\\\''] ]; - /** - * @var Response - */ - private $response; + private Response $response; /** * Json constructor. - * - * @param Response $response */ public function __construct(Response $response) { $this->response = $response; } - /** - * @param Response $response - * - * @return Json - */ public static function factory(Response $response): Json { return new self($response); @@ -71,26 +60,23 @@ final class Json /** * @return Json - * @throws DependencyException - * @throws NotFoundException */ public static function fromDic(): Json { - return new self(Bootstrap::getContainer()->get(Klein::class)->response()); + return new self(Bootstrap::getContainer() + ->get(Klein::class) + ->response()); } /** * Devuelve un array con las cadenas formateadas para JSON - * - * @param $data mixed - * - * @return string */ public static function safeJson(&$data): string { if (is_array($data) || is_object($data)) { - array_walk_recursive($data, - function (&$value) { + array_walk_recursive( + $data, + static function (&$value) { if (is_object($value)) { foreach ($value as $property => $v) { if (is_string($v) && $v !== '') { @@ -118,9 +104,7 @@ final class Json /** * Devuelve una cadena con los carácteres formateadas para JSON * - * @param $string - * - * @return mixed + * @return array|string|string[] */ public static function safeJsonString($string) { @@ -146,9 +130,7 @@ final class Json /** * Devuelve una respuesta en formato JSON con el estado y el mensaje. * - * @param JsonResponse $jsonResponse - * - * @return bool + * @throws \JsonException */ public function returnJson(JsonResponse $jsonResponse): bool { @@ -160,7 +142,7 @@ final class Json $jsonResponse = new JsonResponse($e->getMessage()); $jsonResponse->addMessage($e->getHint()); - $this->response->body(json_encode($jsonResponse)); + $this->response->body(json_encode($jsonResponse, JSON_THROW_ON_ERROR)); } return $this->response->send(true)->isSent(); @@ -172,14 +154,14 @@ final class Json * @param mixed $data * @param int $flags JSON_* flags * - * @return string La cadena en formato JSON * @throws SPException */ public static function getJson($data, int $flags = 0): string { - $json = json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR | $flags); - if ($json === false || json_last_error() !== JSON_ERROR_NONE) { + try { + $json = json_encode($data, JSON_THROW_ON_ERROR | $flags); + } catch (JsonException $e) { throw new SPException( __u('Encoding error'), SPException::CRITICAL, diff --git a/lib/SP/Http/JsonResponse.php b/lib/SP/Http/JsonResponse.php index d2d4eee9..56b5faeb 100644 --- a/lib/SP/Http/JsonResponse.php +++ b/lib/SP/Http/JsonResponse.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Http; @@ -34,86 +34,47 @@ use stdClass; */ final class JsonResponse implements JsonSerializable { - const JSON_SUCCESS = 0; - const JSON_SUCCESS_STICKY = 100; - const JSON_ERROR = 1; - const JSON_ERROR_STICKY = 101; - const JSON_WARNING = 2; - const JSON_WARNING_STICKY = 102; - const JSON_LOGOUT = 10; + public const JSON_SUCCESS = 0; + public const JSON_SUCCESS_STICKY = 100; + public const JSON_ERROR = 1; + public const JSON_ERROR_STICKY = 101; + public const JSON_WARNING = 2; + public const JSON_WARNING_STICKY = 102; + public const JSON_LOGOUT = 10; - /** - * @var int - */ - protected $status = 1; - /** - * @var string - */ - protected $description = ''; - /** - * @var string - */ - protected $action = ''; - /** - * @var array - */ - protected $data = []; - /** - * @var array - */ - protected $messages = []; - /** - * @var string - */ - protected $container = ''; - /** - * @var string - */ - protected $csrf = ''; + protected int $status = 1; + protected ?string $description = null; + protected string $action = ''; + protected array $data = []; + protected array $messages = []; + protected string $container = ''; + protected string $csrf = ''; /** * JsonResponse constructor. - * - * @param string|null $description */ public function __construct(?string $description = null) { $this->description = $description; } - /** - * @return int - */ public function getStatus(): int { return $this->status; } - /** - * @param int $status - * - * @return JsonResponse - */ public function setStatus(int $status): JsonResponse { - $this->status = (int)$status; + $this->status = $status; return $this; } - /** - * @return string - */ public function getDescription(): ?string { return $this->description; } - /** - * @param string $description - * - * @return JsonResponse - */ public function setDescription(string $description): JsonResponse { $this->description = __($description); @@ -121,19 +82,11 @@ final class JsonResponse implements JsonSerializable return $this; } - /** - * @return string - */ public function getAction(): string { return $this->action; } - /** - * @param string $action - * - * @return JsonResponse - */ public function setAction(string $action): JsonResponse { $this->action = $action; @@ -141,9 +94,6 @@ final class JsonResponse implements JsonSerializable return $this; } - /** - * @return array - */ public function getData(): array { return $this->data; @@ -151,8 +101,6 @@ final class JsonResponse implements JsonSerializable /** * @param array|stdClass $data - * - * @return JsonResponse */ public function setData($data): JsonResponse { @@ -161,19 +109,11 @@ final class JsonResponse implements JsonSerializable return $this; } - /** - * @return array - */ public function getMessages(): array { return $this->messages; } - /** - * @param array $messages - * - * @return JsonResponse - */ public function setMessages(array $messages): JsonResponse { $this->messages = array_map('__', $messages); @@ -181,19 +121,11 @@ final class JsonResponse implements JsonSerializable return $this; } - /** - * @return string - */ public function getContainer(): string { return $this->container; } - /** - * @param string $container - * - * @return JsonResponse - */ public function setContainer(string $container): JsonResponse { $this->container = $container; @@ -201,19 +133,11 @@ final class JsonResponse implements JsonSerializable return $this; } - /** - * @return string - */ public function getCsrf(): string { return $this->csrf; } - /** - * @param string $csrf - * - * @return JsonResponse - */ public function setCsrf(string $csrf): JsonResponse { $this->csrf = $csrf; @@ -221,11 +145,6 @@ final class JsonResponse implements JsonSerializable return $this; } - /** - * @param string $message - * - * @return JsonResponse - */ public function addMessage(string $message): JsonResponse { $this->messages[] = __($message); @@ -263,8 +182,6 @@ final class JsonResponse implements JsonSerializable /** * Devolver un array con las propiedades del objeto - * - * @return array */ public function getJsonArray(): array { @@ -279,8 +196,6 @@ final class JsonResponse implements JsonSerializable /** * Establecer los valores por defecto - * - * @return JsonResponse */ public function clear(): JsonResponse { diff --git a/lib/SP/Http/Message.php b/lib/SP/Http/Message.php index 94f40394..5f861519 100644 --- a/lib/SP/Http/Message.php +++ b/lib/SP/Http/Message.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Http; @@ -31,67 +31,40 @@ namespace SP\Http; */ final class Message { - const TYPE_OK = 0; - const TYPE_ERROR = 1; - const TYPE_WARNING = 2; + public const TYPE_OK = 0; + public const TYPE_ERROR = 1; + public const TYPE_WARNING = 2; - /** - * @var int - */ - protected $type = 0; - /** - * @var string - */ - protected $description; - /** - * @var string - */ - protected $hint; + protected int $type = 0; + protected ?string $description = null; + protected ?string $hint = null; - /** - * @return int - */ public function getType(): int { return $this->type; } - /** - * @param int $type - */ - public function setType(int $type) + public function setType(int $type): void { $this->type = $type; } - /** - * @return string|null - */ public function getDescription(): ?string { return $this->description; } - /** - * @param string $description - */ - public function setDescription(string $description) + public function setDescription(string $description): void { $this->description = $description; } - /** - * @return string|null - */ public function getHint(): ?string { return $this->hint; } - /** - * @param string $hint - */ - public function setHint(string $hint) + public function setHint(string $hint): void { $this->hint = $hint; } diff --git a/lib/SP/Http/Request.php b/lib/SP/Http/Request.php index cbf291cf..8a581e5c 100644 --- a/lib/SP/Http/Request.php +++ b/lib/SP/Http/Request.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Http; @@ -45,31 +45,15 @@ final class Request * @var array Directorios seguros para include */ public const SECURE_DIRS = ['css', 'js']; - /** - * @var HeaderDataCollection - */ + private HeaderDataCollection $headers; - /** - * @var \Klein\Request - */ private \Klein\Request $request; - /** - * @var DataCollection - */ private DataCollection $params; - /** - * @var string - */ - private string $method; - /** - * @var bool - */ - private bool $https; + private ?string $method = null; + private ?bool $https = null; /** * Request constructor. - * - * @param \Klein\Request $request */ public function __construct(\Klein\Request $request) { @@ -79,9 +63,6 @@ final class Request $this->detectHttps(); } - /** - * @return DataCollection - */ private function getParamsByMethod(): DataCollection { if ($this->request->method('GET')) { @@ -106,26 +87,22 @@ final class Request /** * Devuelve un nombre de archivo seguro - * - * @param string $file - * @param string|null $base - * - * @return string */ - public static function getSecureAppFile(string $file, ?string $base = null): string + public static function getSecureAppFile( + string $file, + ?string $base = null + ): string { return basename(self::getSecureAppPath($file, $base)); } /** * Devolver una ruta segura para - * - * @param string $path - * @param string|null $base - * - * @return string */ - public static function getSecureAppPath(string $path, ?string $base = null): string + public static function getSecureAppPath( + string $path, + ?string $base = null + ): string { if ($base === null) { $base = APP_ROOT; @@ -145,8 +122,6 @@ final class Request } /** - * @param bool $fullForwarded - * * @return array|string */ public function getClientAddress(bool $fullForwarded = false) @@ -209,21 +184,16 @@ final class Request /** * Comprobar si se realiza una recarga de la página - * - * @return bool */ public function checkReload(): bool { return $this->headers->get('Cache-Control') === 'max-age=0'; } - /** - * @param string $param - * @param string|null $default - * - * @return string|null - */ - public function analyzeEmail(string $param, ?string $default = null): ?string + public function analyzeEmail( + string $param, + ?string $default = null + ): ?string { if (!$this->params->exists($param)) { return $default; @@ -234,10 +204,6 @@ final class Request /** * Analizar un valor encriptado y devolverlo desencriptado - * - * @param string $param - * - * @return string */ public function analyzeEncrypted(string $param): string { @@ -253,7 +219,7 @@ final class Request ->decryptRSA(base64_decode($encryptedData)); // Desencriptar con la clave RSA - if ($clearData === false) { + if ($clearData === null) { logger('No RSA encrypted data from request'); return $encryptedData; @@ -267,13 +233,10 @@ final class Request } } - /** - * @param string $param - * @param string|null $default - * - * @return string|null - */ - public function analyzeString(string $param, ?string $default = null): ?string + public function analyzeString( + string $param, + ?string $default = null + ): ?string { if (!$this->params->exists($param)) { return $default; @@ -282,13 +245,10 @@ final class Request return Filter::getString($this->params->get($param)); } - /** - * @param string $param - * @param string|null $default - * - * @return string|null - */ - public function analyzeUnsafeString(string $param, ?string $default = null): ?string + public function analyzeUnsafeString( + string $param, + ?string $default = null + ): ?string { if (!$this->params->exists($param)) { return $default; @@ -300,11 +260,14 @@ final class Request /** * @param string $param * @param callable|null $mapper - * @param mixed $default + * @param null $default * * @return array|null */ - public function analyzeArray(string $param, callable $mapper = null, $default = null): ?array + public function analyzeArray( + string $param, + callable $mapper = null, + $default = null): ?array { $requestValue = $this->params->get($param); @@ -321,8 +284,6 @@ final class Request /** * Comprobar si la petición es en formato JSON - * - * @return bool */ public function isJson(): bool { @@ -331,8 +292,6 @@ final class Request /** * Comprobar si la petición es Ajax - * - * @return bool */ public function isAjax(): bool { @@ -340,12 +299,6 @@ final class Request || $this->analyzeInt('isAjax', 0) === 1; } - /** - * @param string $param - * @param int|null $default - * - * @return int - */ public function analyzeInt(string $param, ?int $default = null): ?int { if (!$this->params->exists($param)) { @@ -355,22 +308,11 @@ final class Request return Filter::getInt($this->params->get($param)); } - /** - * @param string $file - * - * @return array|null - */ public function getFile(string $file): ?array { return $this->request->files()->get($file); } - /** - * @param string $param - * @param bool $default - * - * @return bool - */ public function analyzeBool(string $param, ?bool $default = null): bool { if (!$this->params->exists($param)) { @@ -418,7 +360,6 @@ final class Request * Returns the URI used by the browser and checks for the protocol used * * @see https://tools.ietf.org/html/rfc7239#section-7.5 - * @return string */ public function getHttpHost(): string { @@ -443,7 +384,6 @@ final class Request * Devolver datos de forward RFC 7239 * * @see https://tools.ietf.org/html/rfc7239#section-7.5 - * @return array|null */ public function getForwardedData(): ?array { @@ -472,11 +412,6 @@ final class Request return null; } - /** - * @param string $header - * - * @return string - */ public function getHeader(string $header): string { return $this->headers->get($header, ''); @@ -484,8 +419,6 @@ final class Request /** * Devolver datos de x-forward - * - * @return array|null */ public function getXForwardedData(): ?array { @@ -509,43 +442,26 @@ final class Request return null; } - /** - * @return string - */ - public function getMethod(): string + public function getMethod(): ?string { return $this->method; } - /** - * @return bool - */ - public function isHttps(): bool + public function isHttps(): ?bool { return $this->https; } - /** - * @return int - */ public function getServerPort(): int { return (int)$this->request->server()->get('SERVER_PORT', 80); } - /** - * @return \Klein\Request - */ public function getRequest(): \Klein\Request { return $this->request; } - /** - * @param string $key - * - * @return string - */ public function getServer(string $key): string { return (string)$this->request->server()->get($key, ''); diff --git a/lib/SP/Http/Uri.php b/lib/SP/Http/Uri.php index 896d4680..333df89e 100644 --- a/lib/SP/Http/Uri.php +++ b/lib/SP/Http/Uri.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Http; @@ -33,14 +33,8 @@ use SP\Core\Crypt\Hash; */ final class Uri { - /** - * @var string - */ - private $base; - /** - * @var array - */ - private $params = []; + private string $base; + private array $params = []; /** * Uri constructor. @@ -52,12 +46,6 @@ final class Uri $this->base = $base; } - /** - * @param string $key - * @param string $value - * - * @return string - */ private static function mapParts(string $key, string $value): string { if (strpos($key, '_') === 0) { @@ -68,7 +56,7 @@ final class Uri } /** - * @param string $param Param's name. If an '_' is set at the beginning, it will be a protected param + * @param string $param Param's name. If an '_' is set at the beginning, it will be a protected param * @param string|int $value * * @return Uri @@ -80,22 +68,14 @@ final class Uri return $this; } - /** - * @return string - */ public function getUri(): string { - return $this->base . '?' . implode('&', array_map([Uri::class, 'mapParts'], array_keys($this->params), $this->params)); + return $this->base . '?' . implode('&', array_map([__CLASS__, 'mapParts'], array_keys($this->params), $this->params)); } - /** - * @param string $key - * - * @return string - */ public function getUriSigned(string $key): string { - $uri = implode('&', array_map([Uri::class, 'mapParts'], array_keys($this->params), $this->params)); + $uri = implode('&', array_map([__CLASS__, 'mapParts'], array_keys($this->params), $this->params)); return $this->base . '?' . $uri . '&h=' . Hash::signMessage($uri, $key); } @@ -107,9 +87,13 @@ final class Uri */ public function resetParams(): Uri { - $this->params = array_filter($this->params, function ($key) { - return strpos($key, '_') === 0; - }, ARRAY_FILTER_USE_KEY); + $this->params = array_filter( + $this->params, + static function ($key) { + return strpos($key, '_') === 0; + }, + ARRAY_FILTER_USE_KEY + ); return $this; } diff --git a/lib/SP/Http/XMLRPCResponseParse.php b/lib/SP/Http/XMLRPCResponseParse.php index eb0adeff..36fdc928 100644 --- a/lib/SP/Http/XMLRPCResponseParse.php +++ b/lib/SP/Http/XMLRPCResponseParse.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Http; @@ -41,15 +41,15 @@ abstract class XMLRPCResponseParse /** * @var DOMElement */ - private $root; + private DOMElement $root; /** * @var string */ - private $xml; + private string $xml; /** * @var array */ - private $data = []; + private array $data = []; /** * Constructor @@ -224,9 +224,9 @@ abstract class XMLRPCResponseParse if (null === $val) { return $this->parseNodes($xmlValues->childNodes); - } else { - $valuesData[] = $val; } + + $valuesData[] = $val; } } diff --git a/lib/SP/Http/Xml.php b/lib/SP/Http/Xml.php index a1ed1776..c23ffb18 100644 --- a/lib/SP/Http/Xml.php +++ b/lib/SP/Http/Xml.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Http; @@ -33,20 +33,15 @@ use Klein\Response; */ final class Xml { - const SAFE = [ + public const SAFE = [ 'from' => ['&', '<', '>', '"', "\'"], 'to' => ['&', '<', '>', '"', '''] ]; - /** - * @var Response - */ - private $response; + private Response $response; /** * Xml constructor. - * - * @param Response $response */ public function __construct(Response $response) { @@ -59,7 +54,7 @@ final class Xml * @param string $description mensaje a devolver * @param int $status devuelve el estado */ - public function printXml(string $description, int $status = 1) + public function printXml(string $description, int $status = 1): void { if (!is_string($description)) { return; @@ -78,9 +73,7 @@ final class Xml } /** - * @param string $string - * - * @return mixed + * @return array|string|string[] */ public function safeString(string $string) { diff --git a/lib/SP/Mvc/Controller/ControllerTrait.php b/lib/SP/Mvc/Controller/ControllerTrait.php index 6e80e6b6..b4987b67 100644 --- a/lib/SP/Mvc/Controller/ControllerTrait.php +++ b/lib/SP/Mvc/Controller/ControllerTrait.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,16 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\Controller; use Closure; -use DI\DependencyException; -use DI\NotFoundException; use SP\Bootstrap; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Exceptions\SPException; use SP\Http\Json; use SP\Http\JsonResponse; @@ -41,13 +39,10 @@ use SP\Util\Util; * Trait ControllerTrait * * @package SP\Mvc\Controller - * @property ConfigData $configData + * @property ConfigDataInterface $configData */ trait ControllerTrait { - /** - * @return string - */ protected function getControllerName(): string { $class = static::class; @@ -58,14 +53,13 @@ trait ControllerTrait /** * Logout from current session * - * @param Request $request - * @param ConfigData $configData - * @param Closure $onRedirect - * - * @throws DependencyException - * @throws NotFoundException + * @throws \JsonException */ - protected function sessionLogout(Request $request, ConfigData $configData, Closure $onRedirect) + protected function sessionLogout( + Request $request, + ConfigDataInterface $configData, + Closure $onRedirect + ): void { if ($request->isJson()) { $jsonResponse = new JsonResponse(__u('Session not started or timed out')); @@ -103,24 +97,23 @@ trait ControllerTrait /** * Acción no disponible + * + * @throws \JsonException */ - protected function invalidAction() + protected function invalidAction(): void { Json::fromDic()->returnJson(new JsonResponse(__u('Invalid Action'))); } /** - * @param string $previousToken - * @param Request $request - * * @throws SPException * @deprecated */ - protected function checkSecurityToken(string $previousToken, Request $request) + protected function checkSecurityToken(string $previousToken, Request $request): void { - if ($request->analyzeString('h') !== null + if (isset($this->configData) + && $request->analyzeString('h') !== null && $request->analyzeString('from') === null - && isset($this->configData) ) { $request->verifySignature($this->configData->getPasswordSalt()); } else { diff --git a/lib/SP/Mvc/Controller/CrudControllerInterface.php b/lib/SP/Mvc/Controller/CrudControllerInterface.php index 4bc8548d..1b853260 100644 --- a/lib/SP/Mvc/Controller/CrudControllerInterface.php +++ b/lib/SP/Mvc/Controller/CrudControllerInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\Controller; diff --git a/lib/SP/Mvc/Controller/ExtensibleControllerInterface.php b/lib/SP/Mvc/Controller/ExtensibleControllerInterface.php index f5235e36..1c3bbc9f 100644 --- a/lib/SP/Mvc/Controller/ExtensibleControllerInterface.php +++ b/lib/SP/Mvc/Controller/ExtensibleControllerInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\Controller; @@ -43,7 +43,7 @@ interface ExtensibleControllerInterface /** * @return void */ - public function displayView(); + public function displayView(): void; /** * @return EventDispatcherInterface diff --git a/lib/SP/Mvc/Controller/ExtensibleTabControllerInterface.php b/lib/SP/Mvc/Controller/ExtensibleTabControllerInterface.php index bbb61ee6..1bc0e711 100644 --- a/lib/SP/Mvc/Controller/ExtensibleTabControllerInterface.php +++ b/lib/SP/Mvc/Controller/ExtensibleTabControllerInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\Controller; diff --git a/lib/SP/Mvc/Controller/ItemTrait.php b/lib/SP/Mvc/Controller/ItemTrait.php index ae77b464..3d1373ab 100644 --- a/lib/SP/Mvc/Controller/ItemTrait.php +++ b/lib/SP/Mvc/Controller/ItemTrait.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,27 +19,21 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\Controller; use Defuse\Crypto\Exception\CryptoException; -use DI\DependencyException; -use DI\NotFoundException; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Bootstrap; -use SP\Core\Exceptions\ConstraintException; -use SP\Core\Exceptions\QueryException; use SP\Core\Exceptions\SPException; use SP\DataModel\CustomFieldData; use SP\DataModel\ItemSearchData; use SP\Http\Request; -use SP\Repositories\NoSuchItemException; use SP\Services\CustomField\CustomFieldItem; use SP\Services\CustomField\CustomFieldService; -use SP\Services\ServiceException; use SP\Util\Filter; /** @@ -52,18 +46,12 @@ trait ItemTrait /** * Obtener la lista de campos personalizados y sus valores * - * @param int $moduleId - * @param int $itemId - * - * @return array - * @throws ConstraintException - * @throws QueryException - * @throws SPException - * @throws ServiceException - * @throws DependencyException - * @throws NotFoundException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + * @throws \SP\Services\ServiceException */ - protected function getCustomFieldsForItem(int $moduleId, $itemId): array + protected function getCustomFieldsForItem(int $moduleId, ?int $itemId): array { $customFieldService = Bootstrap::getContainer()->get(CustomFieldService::class); $customFields = []; @@ -109,21 +97,28 @@ trait ItemTrait * @param int|int[] $itemId * @param Request $request * - * @throws ConstraintException - * @throws DependencyException - * @throws NoSuchItemException - * @throws NotFoundException - * @throws QueryException - * @throws SPException - * @throws ServiceException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + * @throws \SP\Repositories\NoSuchItemException + * @throws \SP\Services\ServiceException */ - protected function addCustomFieldsForItem(int $moduleId, $itemId, Request $request) + protected function addCustomFieldsForItem( + int $moduleId, + $itemId, + Request $request): void { - $customFields = $request->analyzeArray('customfield', function ($values) { - return array_map(function ($value) { - return Filter::getString($value); - }, $values); - }); + $customFields = $request->analyzeArray( + 'customfield', + function ($values) { + return array_map( + static function ($value) { + return Filter::getString($value); + }, + $values + ); + } + ); if (!empty($customFields)) { $customFieldService = Bootstrap::getContainer()->get(CustomFieldService::class); @@ -154,7 +149,7 @@ trait ItemTrait * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function deleteCustomFieldsForItem(int $moduleId, $itemId) + protected function deleteCustomFieldsForItem(int $moduleId, $itemId): void { $customFieldService = Bootstrap::getContainer()->get(CustomFieldService::class); @@ -172,22 +167,31 @@ trait ItemTrait * @param int|int[] $itemId * @param Request $request * - * @throws ConstraintException - * @throws DependencyException - * @throws NotFoundException - * @throws QueryException - * @throws SPException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException */ - protected function updateCustomFieldsForItem(int $moduleId, $itemId, Request $request) + protected function updateCustomFieldsForItem( + int $moduleId, + $itemId, + Request $request + ): void { - $customFields = $request->analyzeArray('customfield', function ($values) { - return array_map(function ($value) { - return Filter::getString($value); - }, $values); - }); + $customFields = $request->analyzeArray( + 'customfield', + function ($values) { + return array_map( + static function ($value) { + return Filter::getString($value); + }, + $values + ); + } + ); if (!empty($customFields)) { - $customFieldService = Bootstrap::getContainer()->get(CustomFieldService::class); + $customFieldService = Bootstrap::getContainer() + ->get(CustomFieldService::class); try { foreach ($customFields as $id => $value) { @@ -209,13 +213,11 @@ trait ItemTrait /** * Returns search data object for the current request - * - * @param int $limitCount - * @param Request $request - * - * @return ItemSearchData */ - protected function getSearchData($limitCount, Request $request): ItemSearchData + protected function getSearchData( + int $limitCount, + Request $request + ): ItemSearchData { $itemSearchData = new ItemSearchData(); $itemSearchData->setSeachString($request->analyzeString('search')); @@ -225,12 +227,7 @@ trait ItemTrait return $itemSearchData; } - /** - * @param Request $request - * - * @return mixed - */ - protected function getItemsIdFromRequest(Request $request) + protected function getItemsIdFromRequest(Request $request): ?array { return $request->analyzeArray('items'); } diff --git a/lib/SP/Mvc/Controller/Validators/PasswordValidator.php b/lib/SP/Mvc/Controller/Validators/PasswordValidator.php index 2a40b63d..7e35da66 100644 --- a/lib/SP/Mvc/Controller/Validators/PasswordValidator.php +++ b/lib/SP/Mvc/Controller/Validators/PasswordValidator.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,11 +19,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\Controller\Validators; +use SP\Core\Exceptions\SPException; use SP\Core\Exceptions\ValidationException; use SP\DataModel\ItemPreset\Password; @@ -34,47 +35,43 @@ use SP\DataModel\ItemPreset\Password; */ final class PasswordValidator implements ValidatorInterface { - /** - * @var Password - */ - private $password; + private Password $password; /** * PasswordValidator constructor. - * - * @param Password $password */ public function __construct(Password $password) { $this->password = $password; } - /** - * @param Password $password - * - * @return PasswordValidator - */ public static function factory(Password $password): PasswordValidator { return new self($password); } /** - * @param string $string - * - * @return bool * @throws ValidationException */ public function validate(string $string): bool { if (mb_strlen($string) < $this->password->getLength()) { - throw new ValidationException(sprintf(__('Password needs to be %d characters long'), $this->password->getLength())); + throw new ValidationException( + sprintf( + __('Password needs to be %d characters long'), + $this->password->getLength() + ) + ); } $regex = $this->password->getRegex(); if (!empty($this->password->getRegex()) && !Validator::matchRegex($string, $regex)) { - throw new ValidationException(__u('Password does not contain the required characters'), ValidationException::ERROR, $regex); + throw new ValidationException( + __u('Password does not contain the required characters'), + SPException::ERROR, + $regex + ); } if ($this->password->isUseLetters()) { diff --git a/lib/SP/Mvc/Controller/Validators/Validator.php b/lib/SP/Mvc/Controller/Validators/Validator.php index 6162ee0e..6f6fba05 100644 --- a/lib/SP/Mvc/Controller/Validators/Validator.php +++ b/lib/SP/Mvc/Controller/Validators/Validator.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\Controller\Validators; @@ -31,72 +31,36 @@ namespace SP\Mvc\Controller\Validators; */ final class Validator { - /** - * @param string $string - * - * @return bool - */ public static function hasLetters(string $string): bool { return preg_match('#[a-z]+#i', $string) === 1; } - /** - * @param string $string - * - * @return bool - */ public static function hasNumbers(string $string): bool { return preg_match('#[\d]+#', $string) === 1; } - /** - * @param string $string - * - * @return bool - */ public static function hasUpper(string $string): bool { return preg_match('#[A-Z]+#', $string) === 1; } - /** - * @param string $string - * - * @return bool - */ public static function hasLower(string $string): bool { return preg_match('#[a-z]+#', $string) === 1; } - /** - * @param string $string - * - * @return bool - */ public static function hasSymbols(string $string): bool { return preg_match('#[$-/:-?{-~!"^_`\[\]]+#', $string) === 1; } - /** - * @param string $string - * @param string $regex - * - * @return bool - */ public static function matchRegex(string $string, string $regex): bool { return preg_match('#' . str_replace('#', '\#', $regex) . '#', $string) === 1; } - /** - * @param string $regex - * - * @return bool - */ public static function isRegex(string $regex): bool { return @preg_match('#' . str_replace('#', '\#', $regex) . '#', null) !== false; diff --git a/lib/SP/Mvc/Controller/Validators/ValidatorInterface.php b/lib/SP/Mvc/Controller/Validators/ValidatorInterface.php index 536eb7d1..066eb6f1 100644 --- a/lib/SP/Mvc/Controller/Validators/ValidatorInterface.php +++ b/lib/SP/Mvc/Controller/Validators/ValidatorInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\Controller\Validators; diff --git a/lib/SP/Mvc/Model/QueryAssignment.php b/lib/SP/Mvc/Model/QueryAssignment.php index bc0a70f4..4ab04599 100644 --- a/lib/SP/Mvc/Model/QueryAssignment.php +++ b/lib/SP/Mvc/Model/QueryAssignment.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\Model; @@ -31,22 +31,16 @@ namespace SP\Mvc\Model; */ final class QueryAssignment { - /** - * @var array - */ - protected $fields = []; - /** - * @var array - */ - protected $values = []; + protected array $fields = []; + protected array $values = []; /** - * @param $field - * @param $value + * @param string $field + * @param $value * - * @return QueryAssignment + * @return $this */ - public function addField($field, $value) + public function addField(string $field, $value): QueryAssignment { if (strpos($field, '=') === false) { $this->fields[] = $field . ' = ?'; @@ -56,43 +50,35 @@ final class QueryAssignment return $this; } - /** - * @param array $fields - * @param array $values - * - * @return QueryAssignment - */ - public function setFields(array $fields, array $values) + public function setFields(array $fields, array $values): QueryAssignment { - $this->fields = array_map(function ($value) { - return strpos($value, '=') === false ? "$value = ?" : $value; - }, $fields); + $this->fields = array_map( + static function ($value) { + return strpos($value, '=') === false + ? "$value = ?" + : $value; + }, + $fields + ); $this->values = array_merge($this->values, $values); return $this; } - /** - * @return string|null - */ - public function getAssignments() + public function getAssignments(): ?string { - return $this->hasFields() ? implode(',', $this->fields) : null; + return $this->hasFields() + ? implode(',', $this->fields) + : null; } - /** - * @return bool - */ - public function hasFields() + public function hasFields(): bool { return count($this->fields) > 0; } - /** - * @return array - */ - public function getValues() + public function getValues(): array { return $this->values; } diff --git a/lib/SP/Mvc/Model/QueryCondition.php b/lib/SP/Mvc/Model/QueryCondition.php index a2cfee6b..d7fdec48 100644 --- a/lib/SP/Mvc/Model/QueryCondition.php +++ b/lib/SP/Mvc/Model/QueryCondition.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\Model; @@ -33,25 +33,16 @@ use RuntimeException; */ final class QueryCondition { - const CONDITION_AND = ' AND '; - const CONDITION_OR = ' OR '; + public const CONDITION_AND = ' AND '; + public const CONDITION_OR = ' OR '; - /** - * @var array - */ - protected $query = []; - /** - * @var array - */ - protected $param = []; + protected array $query = []; + protected array $param = []; - /** - * @param string $query - * @param array|null $params - * - * @return QueryCondition - */ - public function addFilter(string $query, ?array $params = null): QueryCondition + public function addFilter( + string $query, + ?array $params = null + ): QueryCondition { $this->query[] = "($query)"; @@ -62,39 +53,27 @@ final class QueryCondition return $this; } - /** - * @param string $type - * - * @return string|null - */ public function getFilters(string $type = self::CONDITION_AND): ?string { if ($type !== self::CONDITION_AND && $type !== self::CONDITION_OR) { throw new RuntimeException(__u('Invalid filter type')); } - return $this->hasFilters() ? '(' . implode($type, $this->query) . ')' : null; + return $this->hasFilters() + ? '(' . implode($type, $this->query) . ')' + : null; } - /** - * @return bool - */ public function hasFilters(): bool { - return !empty($this->query); + return count($this->query) !== 0; } - /** - * @return array - */ public function getParams(): array { return $this->param; } - /** - * @return int - */ public function getFiltersCount(): int { return count($this->query); diff --git a/lib/SP/Mvc/Model/QueryJoin.php b/lib/SP/Mvc/Model/QueryJoin.php index fce2e96c..e2bdf3f0 100644 --- a/lib/SP/Mvc/Model/QueryJoin.php +++ b/lib/SP/Mvc/Model/QueryJoin.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\Model; @@ -31,22 +31,10 @@ namespace SP\Mvc\Model; */ final class QueryJoin { - /** - * @var array - */ - protected $join = []; - /** - * @var array - */ - protected $param = []; + protected array $join = []; + protected array $param = []; - /** - * @param string $join - * @param array $params - * - * @return QueryJoin - */ - public function addJoin($join, array $params = null) + public function addJoin(string $join, ?array $params = null): QueryJoin { $this->join[] = $join; @@ -57,34 +45,24 @@ final class QueryJoin return $this; } - /** - * @return string|null - */ - public function getJoins() + public function getJoins(): ?string { - return $this->hasJoins() ? implode(PHP_EOL, $this->join) : null; + return $this->hasJoins() + ? implode(PHP_EOL, $this->join) + : null; } - /** - * @return bool - */ - public function hasJoins() + public function hasJoins(): bool { - return !empty($this->join); + return count($this->join) !== 0; } - /** - * @return array - */ - public function getParams() + public function getParams(): array { return $this->param; } - /** - * @return int - */ - public function getJoinsCount() + public function getJoinsCount(): int { return count($this->join); } diff --git a/lib/SP/Mvc/View/Components/DataTab.php b/lib/SP/Mvc/View/Components/DataTab.php index d4569273..839c19d3 100644 --- a/lib/SP/Mvc/View/Components/DataTab.php +++ b/lib/SP/Mvc/View/Components/DataTab.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\View\Components; @@ -34,51 +34,28 @@ use SP\Mvc\View\Template; */ final class DataTab { - /** - * @var string - */ - protected $title; - /** - * @var Template - */ - protected $template; + protected string $title; + protected Template $template; - /** - * DataTab constructor. - * - * @param string $title - * @param Template $template - */ - public function __construct($title, Template $template) + public function __construct(string $title, Template $template) { $this->title = $title; $this->template = $template; } - /** - * @return string - */ - public function getTitle() + public function getTitle(): string { return $this->title; } - /** - * @param string $title - * - * @return DataTab - */ - public function setTitle($title) + public function setTitle(string $title): DataTab { $this->title = $title; return $this; } - /** - * @return string - */ - public function render() + public function render(): string { try { return $this->template->render(); diff --git a/lib/SP/Mvc/View/Components/ItemAdapterInterface.php b/lib/SP/Mvc/View/Components/ItemAdapterInterface.php index 51f3842c..2ccf7fe5 100644 --- a/lib/SP/Mvc/View/Components/ItemAdapterInterface.php +++ b/lib/SP/Mvc/View/Components/ItemAdapterInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\View\Components; diff --git a/lib/SP/Mvc/View/Components/SelectItem.php b/lib/SP/Mvc/View/Components/SelectItem.php index c0c93ace..207fe495 100644 --- a/lib/SP/Mvc/View/Components/SelectItem.php +++ b/lib/SP/Mvc/View/Components/SelectItem.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\View\Components; @@ -33,97 +33,67 @@ use JsonSerializable; */ final class SelectItem implements JsonSerializable { - /** - * @var int - */ protected $id; - /** - * @var string - */ - protected $name; - /** - * @var mixed - */ + protected string $name; protected $item; - /** - * @var bool - */ - protected $selected = false; - /** - * @var bool - */ - protected $skip = false; + protected bool $selected = false; + protected bool $skip = false; /** * SelectItem constructor. * - * @param int $id - * @param string $name - * @param null $item + * @param int|string $id + * @param string $name + * @param mixed $item */ - public function __construct($id, $name, $item = null) + public function __construct($id, string $name, $item = null) { - $this->id = is_numeric($id) ? (int)$id : $id; - $this->name = (string)$name; + $this->id = $id; + $this->name = $name; $this->item = $item; } /** - * @return int + * @return int|string */ public function getId() { return $this->id; } - /** - * @return string - */ - public function getName() + public function getName(): string { return $this->name; } - /** - * @return bool - */ - public function isSelected() + public function isSelected(): bool { return $this->selected; } - /** - * @param bool $selected - */ - public function setSelected($selected) + public function setSelected(bool $selected): void { - $this->selected = (bool)$selected; + $this->selected = $selected; } /** - * @param $property - * * @return mixed */ - public function getItemProperty($property) + public function getItemProperty(string $property) { - return null !== $this->item && isset($this->item->{$property}) ? $this->item->{$property} : null; + return null !== $this->item && isset($this->item->{$property}) + ? $this->item->{$property} + : null; } - /** - * @return bool - */ - public function isSkip() + public function isSkip(): bool { return $this->skip; } - /** - * @param bool $skip - */ - public function setSkip($skip) + public function setSkip(bool $skip): void { - $this->skip = (bool)$skip; + $this->skip = $skip; } /** @@ -131,6 +101,6 @@ final class SelectItem implements JsonSerializable */ public function jsonSerialize() { - return ['id' => (int)$this->id, 'name' => $this->name]; + return ['id' => $this->id, 'name' => $this->name]; } } \ No newline at end of file diff --git a/lib/SP/Mvc/View/Components/SelectItemAdapter.php b/lib/SP/Mvc/View/Components/SelectItemAdapter.php index 027c43ff..dec59e6f 100644 --- a/lib/SP/Mvc/View/Components/SelectItemAdapter.php +++ b/lib/SP/Mvc/View/Components/SelectItemAdapter.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\View\Components; @@ -36,39 +36,22 @@ use SP\Http\Json; */ final class SelectItemAdapter implements ItemAdapterInterface { - /** - * @var array - */ - protected $items; + protected array $items; - /** - * SelectItemAdapter constructor. - * - * @param array $items - */ public function __construct(array $items) { $this->items = $items; } - /** - * @param array $items - * - * @return static - */ - public static function factory(array $items) + public static function factory(array $items): SelectItemAdapter { - return new static($items); + return new SelectItemAdapter($items); } /** * Returns an array of ids from the given array of objects - * - * @param array $items - * - * @return array */ - public static function getIdFromArrayOfObjects(array $items) + public static function getIdFromArrayOfObjects(array $items): array { $ids = []; @@ -84,10 +67,9 @@ final class SelectItemAdapter implements ItemAdapterInterface /** * Returns a JSON like collection of items for a select component * - * @return string * @throws SPException */ - public function getJsonItemsFromModel() + public function getJsonItemsFromModel(): string { $out = []; @@ -105,10 +87,9 @@ final class SelectItemAdapter implements ItemAdapterInterface /** * Returns a collection of items for a select component * - * @return string * @throws SPException */ - public function getJsonItemsFromArray() + public function getJsonItemsFromArray(): string { $out = []; @@ -122,12 +103,15 @@ final class SelectItemAdapter implements ItemAdapterInterface /** * Returns a collection of items for a select component and set selected ones from an array * - * @param array $selected - * @param null $skip + * @param array $selected + * @param string|int|null $skip * * @return SelectItem[] */ - public function getItemsFromModelSelected(array $selected, $skip = null) + public function getItemsFromModelSelected( + array $selected, + $skip = null + ): array { $items = $this->getItemsFromModel(); @@ -149,7 +133,7 @@ final class SelectItemAdapter implements ItemAdapterInterface * * @return SelectItem[] */ - public function getItemsFromModel() + public function getItemsFromModel(): array { $out = []; @@ -158,7 +142,11 @@ final class SelectItemAdapter implements ItemAdapterInterface throw new RuntimeException(__u('Wrong object type')); } - $out[] = new SelectItem($item->getId(), $item->getName(), $item); + $out[] = new SelectItem( + $item->getId(), + $item->getName(), + $item + ); } return $out; @@ -167,12 +155,12 @@ final class SelectItemAdapter implements ItemAdapterInterface /** * Returns a collection of items for a select component and set selected ones from an array * - * @param array $selected - * @param bool $useValueAsKey - * * @return SelectItem[] */ - public function getItemsFromArraySelected(array $selected, $useValueAsKey = false) + public function getItemsFromArraySelected( + array $selected, + bool $useValueAsKey = false + ): array { $items = $this->getItemsFromArray(); @@ -192,7 +180,7 @@ final class SelectItemAdapter implements ItemAdapterInterface * * @return SelectItem[] */ - public function getItemsFromArray() + public function getItemsFromArray(): array { $out = []; diff --git a/lib/SP/Mvc/View/Template.php b/lib/SP/Mvc/View/Template.php index ff45d4be..4c69ca9f 100644 --- a/lib/SP/Mvc/View/Template.php +++ b/lib/SP/Mvc/View/Template.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\View; @@ -42,34 +42,22 @@ use SP\Http\Uri; */ final class Template { - const TEMPLATE_EXTENSION = '.inc'; - const PARTIALS_DIR = '_partials'; - const LAYOUTS_DIR = '_layouts'; + public const TEMPLATE_EXTENSION = '.inc'; + public const PARTIALS_DIR = '_partials'; + public const LAYOUTS_DIR = '_layouts'; - /** - * @var ThemeInterface - */ - protected $theme; + protected ThemeInterface $theme; /** * @var array List of templates to load into the view */ - private $templates = []; - /** - * @var TemplateVarCollection Template's variables collection - */ - private $vars; + private array $templates = []; + private TemplateVarCollection $vars; /** * @var string Base path for imcluding templates */ - private $base; - /** - * @var array - */ - private $contentTemplates = []; - /** - * @var bool - */ - private $upgraded = false; + private string $base; + private array $contentTemplates = []; + private bool $upgraded = false; /** * @param ThemeInterface $theme @@ -85,10 +73,11 @@ final class Template * * @param string $name Con el nombre del archivo de plantilla * @param string|null $base Directorio base para la plantilla - * - * @return bool */ - public function addContentTemplate(string $name, ?string $base = null) + public function addContentTemplate( + string $name, + ?string $base = null + ): string { try { $template = $this->checkTemplate($name, $base); @@ -110,9 +99,12 @@ final class Template * * @throws FileNotFoundException */ - private function checkTemplate(string $template, ?string $base = null): string + private function checkTemplate( + string $template, + ?string $base = null + ): string { - $base = null !== $base ? $base : (null !== $this->base ? $this->base : null); + $base = $base ?? $this->base; if ($base === null) { $templateFile = $this->theme->getViewsPath() . DIRECTORY_SEPARATOR . $template . self::TEMPLATE_EXTENSION; @@ -141,17 +133,13 @@ final class Template * @param string $file Con el nombre del archivo * @param string $name Nombre de la plantilla */ - private function setContentTemplate(string $file, string $name) + private function setContentTemplate(string $file, string $name): void { $this->contentTemplates[$name] = $file; } /** * Removes a template from the stack - * - * @param string $name - * - * @return Template */ public function removeTemplate(string $name): Template { @@ -162,10 +150,6 @@ final class Template /** * Removes a template from the stack - * - * @param string $name - * - * @return Template */ public function removeContentTemplate(string $name): Template { @@ -198,10 +182,8 @@ final class Template /** * Add partial template - * - * @param string $partial */ - public function addPartial(string $partial) + public function addPartial(string $partial): void { $this->addTemplate($partial, self::PARTIALS_DIR); } @@ -212,9 +194,9 @@ final class Template * @param string $name Con el nombre del archivo de plantilla * @param string|null $base Directorio base para la plantilla * - * @return bool + * @return string */ - public function addTemplate(string $name, ?string $base = null) + public function addTemplate(string $name, ?string $base = null): string { try { $template = $this->checkTemplate($name, $base); @@ -232,7 +214,7 @@ final class Template * @param string $file Con el nombre del archivo * @param string $name Nombre de la plantilla */ - private function setTemplate(string $file, string $name) + private function setTemplate(string $file, string $name): void { $this->templates[$name] = $file; } @@ -268,10 +250,6 @@ final class Template /** * Overloading para controlar la devolución de atributos dinámicos. - * - * @param string $name Nombre del atributo - * - * @return null */ public function __get(string $name) { @@ -292,10 +270,6 @@ final class Template /** * Returns a variable value - * - * @param string $name - * - * @return mixed */ public function get(string $name) { @@ -325,10 +299,6 @@ final class Template /** * Overloading para eliminar una variable del array de variables de la plantilla pasado como * atributo dinámico de la clase - * - * @param string $name Nombre del atributo - * - * @return $this */ public function __unset(string $name): Template { @@ -353,7 +323,7 @@ final class Template */ public function render(): string { - if (empty($this->templates)) { + if (count($this->templates) === 0) { throw new FileNotFoundException(__('Template does not contain files')); } @@ -371,7 +341,7 @@ final class Template return $this->vars->get($key, $default); }; - $_getRoute = function ($path) use ($configData) { + $_getRoute = static function ($path) use ($configData) { $baseUrl = ($configData->getApplicationUrl() ?: Bootstrap::$WEBURI) . Bootstrap::$SUBURI; $uri = new Uri($baseUrl); @@ -398,7 +368,12 @@ final class Template * @param string|null $scope string ámbito de la variable * @param int|null $index string índice del array */ - public function append(string $name, $value, ?string $scope = null, int $index = null) + public function append( + string $name, + $value, + ?string $scope = null, + int $index = null + ): void { if (null !== $scope) { $name = $scope . '_' . $name; @@ -435,33 +410,16 @@ final class Template return $this; } - /** - * Reset de las plantillas añadidas - */ - public function resetVariables() - { - $this->vars = []; - } - - /** - * @return string - */ public function getBase(): string { return $this->base; } - /** - * @param string $base - */ - public function setBase(string $base) + public function setBase(string $base): void { $this->base = $base; } - /** - * @return ThemeInterface - */ public function getTheme(): ThemeInterface { return $this->theme; @@ -475,25 +433,16 @@ final class Template logger($this->vars); } - /** - * @return array - */ public function getContentTemplates(): array { return $this->contentTemplates; } - /** - * @return bool - */ public function hasContentTemplates(): bool { return count($this->contentTemplates) > 0; } - /** - * @return array - */ public function getTemplates(): array { return $this->templates; @@ -501,8 +450,6 @@ final class Template /** * Assigns the current templates to contentTemplates - * - * @return $this */ public function upgrade(): Template { @@ -524,7 +471,11 @@ final class Template * @param mixed $value valor de la variable * @param string|null $scope string ámbito de la variable */ - public function assign(string $name, $value = '', ?string $scope = null) + public function assign( + string $name, + $value = '', + ?string $scope = null + ): void { if (null !== $scope) { $name = $scope . '_' . $name; @@ -533,9 +484,6 @@ final class Template $this->vars->set($name, $value); } - /** - * @return bool - */ public function isUpgraded(): bool { return $this->upgraded; @@ -555,5 +503,4 @@ final class Template // Clone TemplateVarCollection to avoid unwanted object references $this->vars = clone $this->vars; } - } diff --git a/lib/SP/Mvc/View/TemplateVarCollection.php b/lib/SP/Mvc/View/TemplateVarCollection.php index f8e1720b..e71cccfb 100644 --- a/lib/SP/Mvc/View/TemplateVarCollection.php +++ b/lib/SP/Mvc/View/TemplateVarCollection.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Mvc\View; diff --git a/lib/SP/Plugin/PluginBase.php b/lib/SP/Plugin/PluginBase.php index 3f6d278e..7b99c891 100644 --- a/lib/SP/Plugin/PluginBase.php +++ b/lib/SP/Plugin/PluginBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Plugin; @@ -40,33 +40,21 @@ use SP\Services\ServiceException; abstract class PluginBase implements PluginInterface { /** - * @var string Directorio base + * @var string|null Directorio base */ - protected $base; + protected ?string $base = null; /** - * @var string Tipo de plugin + * @var string|null Tipo de plugin */ - protected $type; - /** - * @var string - */ - protected $themeDir; + protected ?string $type = null; + protected ?string $themeDir = null; /** * @var mixed */ protected $data; - /** - * @var int - */ - protected $enabled; - /** - * @var PluginOperation - */ - protected $pluginOperation; - /** - * @var PluginService - */ - private $pluginService; + protected ?int $enabled; + protected PluginOperation $pluginOperation; + private PluginService $pluginService; /** * PluginBase constructor. @@ -74,8 +62,12 @@ abstract class PluginBase implements PluginInterface * @param ContainerInterface $dic * @param PluginOperation $pluginOperation */ - public final function __construct(ContainerInterface $dic, PluginOperation $pluginOperation) + final public function __construct( + ContainerInterface $dic, + PluginOperation $pluginOperation + ) { + /** @noinspection UnusedConstructorDependenciesInspection */ $this->pluginService = $dic->get(PluginService::class); $this->pluginOperation = $pluginOperation; $this->init($dic); @@ -92,7 +84,7 @@ abstract class PluginBase implements PluginInterface /** * @param string $type */ - public function setType(string $type) + public function setType(string $type): void { $this->type = $type; } @@ -116,17 +108,17 @@ abstract class PluginBase implements PluginInterface /** * @return int */ - public function getEnabled(): int + public function getEnabled(): ?int { - return (int)$this->enabled; + return $this->enabled; } /** * @param int $enabled */ - public function setEnabled(int $enabled) + public function setEnabled(int $enabled): void { - $this->enabled = (int)$enabled; + $this->enabled = $enabled; } /** @@ -139,7 +131,7 @@ abstract class PluginBase implements PluginInterface * @throws QueryException * @throws ServiceException */ - final public function saveData(int $id, $data) + final public function saveData(int $id, $data): void { if ($this->data === null) { $this->pluginOperation->create($id, $data); @@ -153,7 +145,7 @@ abstract class PluginBase implements PluginInterface /** * Establecer las locales del plugin */ - protected function setLocales() + protected function setLocales(): void { $locales = $this->getBase() . DIRECTORY_SEPARATOR . 'locales'; $name = strtolower($this->getName()); diff --git a/lib/SP/Plugin/PluginEventReceiver.php b/lib/SP/Plugin/PluginEventReceiver.php index 71154081..b6993ad7 100644 --- a/lib/SP/Plugin/PluginEventReceiver.php +++ b/lib/SP/Plugin/PluginEventReceiver.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Plugin; diff --git a/lib/SP/Plugin/PluginInterface.php b/lib/SP/Plugin/PluginInterface.php index 097bfc0f..04cfe0f1 100644 --- a/lib/SP/Plugin/PluginInterface.php +++ b/lib/SP/Plugin/PluginInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Plugin; diff --git a/lib/SP/Plugin/PluginManager.php b/lib/SP/Plugin/PluginManager.php index 50953ed3..15f1d882 100644 --- a/lib/SP/Plugin/PluginManager.php +++ b/lib/SP/Plugin/PluginManager.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Plugin; @@ -27,7 +27,6 @@ namespace SP\Plugin; use Exception; use ReflectionClass; use SP\Bootstrap; -use SP\Core\Context\ContextInterface; use SP\Core\Events\Event; use SP\Core\Events\EventDispatcher; use SP\Core\Events\EventMessage; @@ -48,55 +47,31 @@ use SP\Util\VersionUtil; */ final class PluginManager { - /** - * @var array - */ - private static $pluginsAvailable; - /** - * @var array Plugins habilitados - */ - private $enabledPlugins; + private static ?array $pluginsAvailable; + private ?array $enabledPlugins = null; /** * @var PluginInterface[] Plugins ya cargados */ - private $loadedPlugins = []; - /** - * @var array Plugins deshabilitados - */ - private $disabledPlugins = []; - /** - * @var PluginService - */ - private $pluginService; - /** - * @var ContextInterface - */ - private $context; - /** - * @var EventDispatcher - */ - private $eventDispatcher; - /** - * @var PluginDataService - */ - private $pluginDataService; + private array $loadedPlugins = []; + private array $disabledPlugins = []; + private PluginService $pluginService; + private EventDispatcher $eventDispatcher; + private PluginDataService $pluginDataService; /** * PluginManager constructor. * * @param PluginService $pluginService * @param PluginDataService $pluginDataService - * @param ContextInterface $context * @param EventDispatcher $eventDispatcher */ - public function __construct(PluginService $pluginService, + public function __construct(PluginService $pluginService, PluginDataService $pluginDataService, - ContextInterface $context, - EventDispatcher $eventDispatcher) + EventDispatcher $eventDispatcher + ) { $this->pluginService = $pluginService; $this->pluginDataService = $pluginDataService; - $this->context = $context; $this->eventDispatcher = $eventDispatcher; self::$pluginsAvailable = self::getPlugins(); @@ -153,7 +128,7 @@ final class PluginManager self::$pluginsAvailable[$name]['namespace'] ); - if ($initialize) { + if (null !== $plugin && $initialize) { $this->initPlugin($plugin); $plugin->onLoad(); } @@ -192,7 +167,7 @@ final class PluginManager // Do not load plugin's data if not compatible. // Just return the plugin instance before disabling it - if (self::checkCompatibility($plugin) === false) { + if ($this->checkCompatibility($plugin) === false) { $this->eventDispatcher->notifyEvent('plugin.load.error', new Event($this, EventMessage::factory() ->addDescription(sprintf(__('Plugin version not compatible (%s)'), implode('.', $plugin->getVersion())))) @@ -230,11 +205,18 @@ final class PluginManager $appVersion = implode('.', array_slice(Installer::VERSION, 0, 2)); if (version_compare($pluginVersion, $appVersion) === -1) { - $this->pluginService->toggleEnabledByName($plugin->getName(), false); + $this->pluginService->toggleEnabledByName( + $plugin->getName(), + false + ); - $this->eventDispatcher->notifyEvent('edit.plugin.disable', - new Event($this, EventMessage::factory() - ->addDetail(__u('Plugin disabled'), $plugin->getName())) + $this->eventDispatcher->notifyEvent( + 'edit.plugin.disable', + new Event( + $this, + EventMessage::factory() + ->addDetail(__u('Plugin disabled'), $plugin->getName()) + ) ); return false; @@ -279,7 +261,7 @@ final class PluginManager * @throws QueryException * @throws SPException */ - public function loadPlugins() + public function loadPlugins(): void { $available = array_keys(self::$pluginsAvailable); $processed = []; @@ -303,15 +285,13 @@ final class PluginManager $this->load($plugin->getName()); } - } else { - if ($plugin->getAvailable() === 1) { - $this->pluginService->toggleAvailable($plugin->getId(), false); + } else if ($plugin->getAvailable() === 1) { + $this->pluginService->toggleAvailable($plugin->getId(), false); - $this->eventDispatcher->notifyEvent('edit.plugin.unavailable', - new Event($this, EventMessage::factory() - ->addDetail(__u('Plugin unavailable'), $plugin->getName())) - ); - } + $this->eventDispatcher->notifyEvent('edit.plugin.unavailable', + new Event($this, EventMessage::factory() + ->addDetail(__u('Plugin unavailable'), $plugin->getName())) + ); } $processed[] = $plugin->getName(); @@ -328,7 +308,7 @@ final class PluginManager /** * @param string $pluginName */ - private function load(string $pluginName) + private function load(string $pluginName): void { $plugin = $this->loadPluginClass( $pluginName, @@ -357,7 +337,7 @@ final class PluginManager * @throws ConstraintException * @throws QueryException */ - private function registerPlugin(string $name) + private function registerPlugin(string $name): void { $pluginData = new PluginModel(); $pluginData->setName($name); @@ -377,7 +357,7 @@ final class PluginManager /** * @param string $version */ - public function upgradePlugins(string $version) + public function upgradePlugins(string $version): void { $available = array_keys(self::$pluginsAvailable); @@ -387,6 +367,16 @@ final class PluginManager self::$pluginsAvailable[$pluginName]['namespace'] ); + if (null === $plugin) { + $this->eventDispatcher->notifyEvent('upgrade.plugin.process', + new Event($this, EventMessage::factory() + ->addDescription(sprintf(__('Unable to upgrade the "%s" plugin'), $pluginName)) + ->addDetail(__u('Plugin'), $pluginName)) + ); + + continue; + } + try { $pluginModel = $this->pluginService->getByName($pluginName); @@ -434,10 +424,10 @@ final class PluginManager * * @throws SPException */ - public function checkEnabledPlugins() + public function checkEnabledPlugins(): void { foreach ($this->getEnabledPlugins() as $plugin) { - if (!in_array($plugin, $this->loadedPlugins)) { + if (!in_array($plugin, $this->loadedPlugins, true)) { $this->pluginService->toggleAvailableByName($plugin, false); $this->eventDispatcher->notifyEvent('edit.plugin.unavailable', diff --git a/lib/SP/Plugin/PluginOperation.php b/lib/SP/Plugin/PluginOperation.php index b70220b2..209286e9 100644 --- a/lib/SP/Plugin/PluginOperation.php +++ b/lib/SP/Plugin/PluginOperation.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Plugin; @@ -40,14 +40,8 @@ use SP\Services\ServiceException; */ final class PluginOperation { - /** - * @var PluginDataService - */ - private $pluginDataService; - /** - * @var string - */ - private $pluginName; + private PluginDataService $pluginDataService; + private string $pluginName; /** * PluginOperation constructor. @@ -55,7 +49,10 @@ final class PluginOperation * @param PluginDataService $pluginDataService * @param string $pluginName */ - public function __construct(PluginDataService $pluginDataService, string $pluginName) + public function __construct( + PluginDataService $pluginDataService, + string $pluginName + ) { $this->pluginDataService = $pluginDataService; $this->pluginName = $pluginName; @@ -104,32 +101,28 @@ final class PluginOperation } /** - * @param int $itemId - * * @throws ConstraintException * @throws QueryException * @throws NoSuchItemException */ - public function delete(int $itemId) + public function delete(int $itemId): void { $this->pluginDataService->deleteByItemId($this->pluginName, $itemId); } /** - * @param int $itemId - * @param string|null $class - * - * @return mixed|null * @throws ConstraintException * @throws CryptoException * @throws NoSuchPropertyException * @throws QueryException * @throws ServiceException */ - public function get(int $itemId, string $class = null) + public function get(int $itemId, ?string $class = null) { try { - return $this->pluginDataService->getByItemId($this->pluginName, $itemId)->hydrate($class); + return $this->pluginDataService + ->getByItemId($this->pluginName, $itemId) + ->hydrate($class); } catch (NoSuchItemException $e) { return null; } diff --git a/lib/SP/Providers/Acl/AclHandler.php b/lib/SP/Providers/Acl/AclHandler.php index d7cb9c4a..f7971ed0 100644 --- a/lib/SP/Providers/Acl/AclHandler.php +++ b/lib/SP/Providers/Acl/AclHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,16 +19,16 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Acl; -use DI\Container; use Exception; use Psr\Container\ContainerInterface; use SP\Core\Events\Event; use SP\Core\Events\EventReceiver; +use SP\Core\Exceptions\SPException; use SP\Providers\EventsTrait; use SP\Providers\Provider; use SP\Services\Account\AccountAclService; @@ -45,7 +45,7 @@ final class AclHandler extends Provider implements EventReceiver { use EventsTrait; - const EVENTS = [ + public const EVENTS = [ 'edit.userProfile', 'edit.user', 'edit.userGroup', @@ -56,11 +56,11 @@ final class AclHandler extends Provider implements EventReceiver /** * @var string */ - private $events; + private string $events; /** * @var ContainerInterface */ - private $dic; + private ContainerInterface $dic; /** * Devuelve los eventos que implementa el observador @@ -93,8 +93,9 @@ final class AclHandler extends Provider implements EventReceiver * * @return void * @since 5.1.0 + * @throws \SP\Core\Exceptions\SPException */ - public function update(SplSubject $subject) + public function update(SplSubject $subject): void { $this->updateEvent('update', new Event($subject)); } @@ -104,8 +105,10 @@ final class AclHandler extends Provider implements EventReceiver * * @param string $eventType Nombre del evento * @param Event $event Objeto del evento + * + * @throws \SP\Core\Exceptions\SPException */ - public function updateEvent(string $eventType, Event $event) + public function updateEvent(string $eventType, Event $event): void { switch ($eventType) { case 'edit.userProfile': @@ -125,10 +128,15 @@ final class AclHandler extends Provider implements EventReceiver /** * @param Event $event */ - private function processUserProfile(Event $event) + private function processUserProfile(Event $event): void { try { $eventMessage = $event->getEventMessage(); + + if (null === $eventMessage) { + throw new SPException(__u('Unable to process event for user profile')); + } + $extra = $eventMessage->getExtra(); if (isset($extra['userProfileId'])) { @@ -145,10 +153,17 @@ final class AclHandler extends Provider implements EventReceiver /** * @param Event $event + * + * @throws \SP\Core\Exceptions\SPException */ - private function processUser(Event $event) + private function processUser(Event $event): void { $eventMessage = $event->getEventMessage(); + + if (null === $eventMessage) { + throw new SPException(__u('Unable to process event for user')); + } + $extra = $eventMessage->getExtra(); if (isset($extra['userId'])) { @@ -161,10 +176,15 @@ final class AclHandler extends Provider implements EventReceiver /** * @param Event $event */ - private function processUserGroup(Event $event) + private function processUserGroup(Event $event): void { try { $eventMessage = $event->getEventMessage(); + + if (null === $eventMessage) { + throw new SPException(__u('Unable to process event for user group')); + } + $extra = $eventMessage->getExtra(); if (isset($extra['userGroupId'])) { @@ -180,9 +200,9 @@ final class AclHandler extends Provider implements EventReceiver } /** - * @param Container $dic + * @param ContainerInterface $dic */ - protected function initialize(Container $dic) + protected function initialize(ContainerInterface $dic): void { $this->dic = $dic; $this->events = $this->parseEventsToRegex(self::EVENTS); diff --git a/lib/SP/Providers/Auth/AuthDataBase.php b/lib/SP/Providers/Auth/AuthDataBase.php index fe24c17a..d08edd39 100644 --- a/lib/SP/Providers/Auth/AuthDataBase.php +++ b/lib/SP/Providers/Auth/AuthDataBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth; @@ -34,31 +34,31 @@ abstract class AuthDataBase /** * @var string */ - protected $name; + protected string $name; /** * @var string */ - protected $email; + protected string $email; /** * @var bool */ - protected $authenticated; + protected bool $authenticated; /** * @var int */ - protected $statusCode = 0; + protected int $statusCode = 0; /** * @var string */ - protected $server; + protected string $server; /** * @var bool */ - protected $authoritative = false; + protected bool $authoritative = false; /** * @var bool */ - protected $failed = false; + protected bool $failed = false; /** * @return string|null @@ -87,7 +87,7 @@ abstract class AuthDataBase /** * @param string $email */ - public function setEmail(string $email) + public function setEmail(string $email): void { $this->email = $email; } @@ -139,9 +139,9 @@ abstract class AuthDataBase /** * @param int $statusCode */ - public function setStatusCode(int $statusCode) + public function setStatusCode(int $statusCode): void { - $this->statusCode = (int)$statusCode; + $this->statusCode = $statusCode; } /** @@ -151,7 +151,7 @@ abstract class AuthDataBase */ public function isAuthoritative(): bool { - return (bool)$this->authoritative; + return $this->authoritative; } /** @@ -159,9 +159,9 @@ abstract class AuthDataBase * * @param bool $authoritative */ - public function setAuthoritative(bool $authoritative) + public function setAuthoritative(bool $authoritative): void { - $this->authoritative = (bool)$authoritative; + $this->authoritative = $authoritative; } /** diff --git a/lib/SP/Providers/Auth/AuthInterface.php b/lib/SP/Providers/Auth/AuthInterface.php index 598b9a55..347feb38 100644 --- a/lib/SP/Providers/Auth/AuthInterface.php +++ b/lib/SP/Providers/Auth/AuthInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth; @@ -36,11 +36,11 @@ interface AuthInterface /** * Autentificar al usuario * - * @param UserLoginData $UserData Datos del usuario + * @param \SP\DataModel\UserLoginData $userLoginData * * @return mixed|AuthDataBase */ - public function authenticate(UserLoginData $UserData); + public function authenticate(UserLoginData $userLoginData); /** * Indica si es requerida para acceder a la aplicación diff --git a/lib/SP/Providers/Auth/AuthProvider.php b/lib/SP/Providers/Auth/AuthProvider.php index 161f1f95..c4041fbd 100644 --- a/lib/SP/Providers/Auth/AuthProvider.php +++ b/lib/SP/Providers/Auth/AuthProvider.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth; -use DI\Container; +use Psr\Container\ContainerInterface; +use SP\Core\Exceptions\SPException; +use SP\Core\Exceptions\ValidationException; use SP\DataModel\UserLoginData; use SP\Providers\Auth\Browser\Browser; use SP\Providers\Auth\Database\Database; @@ -48,7 +50,7 @@ final class AuthProvider extends Provider /** * @var callable[] */ - protected $auths = []; + protected array $auths = []; /** * Probar los métodos de autentificación @@ -62,10 +64,9 @@ final class AuthProvider extends Provider $authsResult = []; foreach ($this->auths as $authName => $auth) { - /** @var AuthDataBase $data */ $data = $auth($userLoginData); - if ($data !== false) { + if ($data instanceof AuthDataBase) { $authsResult[] = new AuthResult($authName, $data); } } @@ -76,11 +77,11 @@ final class AuthProvider extends Provider /** * Auth constructor. * - * @param Container $dic + * @param ContainerInterface $dic * * @throws AuthException */ - protected function initialize(Container $dic) + protected function initialize(ContainerInterface $dic): void { $configData = $this->config->getConfigData(); @@ -98,9 +99,13 @@ final class AuthProvider extends Provider function (UserLoginData $userLoginData) use ($configData) { $data = LdapParams::getServerAndPort($configData->getLdapServer()); + if (count($data) === 0) { + throw new ValidationException(__u('Wrong LDAP parameters')); + } + $ldapParams = new LdapParams(); $ldapParams->setServer($data['server']); - $ldapParams->setPort(isset($data['port']) ? $data['port'] : 389); + $ldapParams->setPort($data['port'] ?? 389); $ldapParams->setSearchBase($configData->getLdapBase()); $ldapParams->setGroup($configData->getLdapGroup()); $ldapParams->setBindDn($configData->getLdapBindUser()); @@ -155,11 +160,11 @@ final class AuthProvider extends Provider * * @throws AuthException */ - private function registerAuth(callable $auth, string $name) + private function registerAuth(callable $auth, string $name): void { if (array_key_exists($name, $this->auths)) { throw new AuthException(__u('Authentication already initialized'), - AuthException::ERROR, + SPException::ERROR, __FUNCTION__); } diff --git a/lib/SP/Providers/Auth/AuthResult.php b/lib/SP/Providers/Auth/AuthResult.php index 9032a1a2..695aa018 100644 --- a/lib/SP/Providers/Auth/AuthResult.php +++ b/lib/SP/Providers/Auth/AuthResult.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth; @@ -34,11 +34,11 @@ final class AuthResult /** * @var string */ - public $authName; + public string $authName; /** * @var AuthDataBase */ - public $data; + public AuthDataBase $data; /** * AuthResult constructor. @@ -53,17 +53,17 @@ final class AuthResult } /** - * @return string|null + * @return string */ - public function getAuthName(): ?string + public function getAuthName(): string { return $this->authName; } /** - * @return AuthDataBase|null + * @return AuthDataBase */ - public function getData(): ?AuthDataBase + public function getData(): AuthDataBase { return $this->data; } diff --git a/lib/SP/Providers/Auth/Browser/Browser.php b/lib/SP/Providers/Auth/Browser/Browser.php index 15952633..89f7e69a 100644 --- a/lib/SP/Providers/Auth/Browser/Browser.php +++ b/lib/SP/Providers/Auth/Browser/Browser.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Browser; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\DataModel\UserLoginData; use SP\Http\Request; use SP\Providers\Auth\AuthInterface; @@ -39,21 +39,21 @@ use SP\Providers\Auth\AuthInterface; final class Browser implements AuthInterface { /** - * @var ConfigData + * @var ConfigDataInterface */ - private $configData; + private ConfigDataInterface $configData; /** * @var Request */ - private $request; + private Request $request; /** * Browser constructor. * - * @param ConfigData $configData - * @param Request $request + * @param ConfigDataInterface $configData + * @param Request $request */ - public function __construct(ConfigData $configData, Request $request) + public function __construct(ConfigDataInterface $configData, Request $request) { $this->configData = $configData; $this->request = $request; @@ -66,12 +66,13 @@ final class Browser implements AuthInterface * * @return BrowserAuthData */ - public function authenticate(UserLoginData $userLoginData) + public function authenticate(UserLoginData $userLoginData): BrowserAuthData { $browserAuthData = new BrowserAuthData(); $browserAuthData->setAuthoritative($this->isAuthGranted()); - if (!empty($userLoginData->getLoginUser()) && !empty($userLoginData->getLoginPass())) { + if (!empty($userLoginData->getLoginUser()) + && !empty($userLoginData->getLoginPass())) { return $browserAuthData->setAuthenticated($this->checkServerAuthUser($userLoginData->getLoginUser())); } @@ -119,7 +120,7 @@ final class Browser implements AuthInterface $login = $authUser . '@' . $domain; } - return $authUser !== null && $authUser === $login ?: null; + return $authUser === $login ?: null; } /** diff --git a/lib/SP/Providers/Auth/Browser/BrowserAuthData.php b/lib/SP/Providers/Auth/Browser/BrowserAuthData.php index c62b82ce..571cc755 100644 --- a/lib/SP/Providers/Auth/Browser/BrowserAuthData.php +++ b/lib/SP/Providers/Auth/Browser/BrowserAuthData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Browser; diff --git a/lib/SP/Providers/Auth/Database/Database.php b/lib/SP/Providers/Auth/Database/Database.php index 83cd1174..d878c3ae 100644 --- a/lib/SP/Providers/Auth/Database/Database.php +++ b/lib/SP/Providers/Auth/Database/Database.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Database; @@ -44,15 +44,15 @@ final class Database implements AuthInterface /** * @var UserLoginData $userLoginData */ - protected $userLoginData; + protected UserLoginData $userLoginData; /** * @var UserService */ - private $userService; + private UserService $userService; /** * @var UserPassService */ - private $userPassService; + private UserPassService $userPassService; /** * Database constructor. @@ -74,7 +74,7 @@ final class Database implements AuthInterface * * @return DatabaseAuthData */ - public function authenticate(UserLoginData $userLoginData) + public function authenticate(UserLoginData $userLoginData): DatabaseAuthData { $this->userLoginData = $userLoginData; diff --git a/lib/SP/Providers/Auth/Database/DatabaseAuthData.php b/lib/SP/Providers/Auth/Database/DatabaseAuthData.php index 2ca851e2..d88c22e8 100644 --- a/lib/SP/Providers/Auth/Database/DatabaseAuthData.php +++ b/lib/SP/Providers/Auth/Database/DatabaseAuthData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Database; diff --git a/lib/SP/Providers/Auth/Ldap/AttributeCollection.php b/lib/SP/Providers/Auth/Ldap/AttributeCollection.php index 58d46354..cbf55d0d 100644 --- a/lib/SP/Providers/Auth/Ldap/AttributeCollection.php +++ b/lib/SP/Providers/Auth/Ldap/AttributeCollection.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Ldap; diff --git a/lib/SP/Providers/Auth/Ldap/Ldap.php b/lib/SP/Providers/Auth/Ldap/Ldap.php index 0177fddc..c0ea992a 100644 --- a/lib/SP/Providers/Auth/Ldap/Ldap.php +++ b/lib/SP/Providers/Auth/Ldap/Ldap.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Ldap; @@ -36,23 +36,23 @@ abstract class Ldap implements LdapInterface /** * @var LdapParams */ - protected $ldapParams; + protected LdapParams $ldapParams; /** * @var EventDispatcher */ - protected $eventDispatcher; + protected EventDispatcher $eventDispatcher; /** * @var LdapActions */ - protected $ldapActions; + protected LdapActions $ldapActions; /** * @var LdapConnectionInterface */ - protected $ldapConnection; + protected LdapConnectionInterface $ldapConnection; /** * @var string */ - private $server; + protected string $server; /** * LdapBase constructor. @@ -80,7 +80,7 @@ abstract class Ldap implements LdapInterface * * @return mixed */ - protected abstract function pickServer(); + abstract protected function pickServer(): string; /** * @param LdapParams $ldapParams @@ -90,7 +90,11 @@ abstract class Ldap implements LdapInterface * @return LdapInterface * @throws LdapException */ - public static function factory(LdapParams $ldapParams, EventDispatcher $eventDispatcher, bool $debug) + public static function factory( + LdapParams $ldapParams, + EventDispatcher $eventDispatcher, + bool $debug + ): LdapInterface { $ldapConnection = new LdapConnection($ldapParams, $eventDispatcher, $debug); $ldapConnection->checkConnection(); @@ -98,10 +102,8 @@ abstract class Ldap implements LdapInterface switch ($ldapParams->getType()) { case LdapTypeInterface::LDAP_STD: return new LdapStd($ldapConnection, $eventDispatcher); - break; case LdapTypeInterface::LDAP_ADS: return new LdapMsAds($ldapConnection, $eventDispatcher); - break; } throw new LdapException(__u('LDAP type not set')); @@ -151,7 +153,7 @@ abstract class Ldap implements LdapInterface protected function getGroupFromParams(): string { if (stripos($this->ldapParams->getGroup(), 'cn') === 0) { - return LdapUtil::getGroupName($this->ldapParams->getGroup()); + return LdapUtil::getGroupName($this->ldapParams->getGroup()) ?: ''; } return $this->ldapParams->getGroup(); diff --git a/lib/SP/Providers/Auth/Ldap/LdapActions.php b/lib/SP/Providers/Auth/Ldap/LdapActions.php index c7436f66..45927ec3 100644 --- a/lib/SP/Providers/Auth/Ldap/LdapActions.php +++ b/lib/SP/Providers/Auth/Ldap/LdapActions.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ /** @noinspection PhpComposerExtensionStubsInspection */ @@ -29,6 +29,7 @@ namespace SP\Providers\Auth\Ldap; use SP\Core\Events\Event; use SP\Core\Events\EventDispatcher; use SP\Core\Events\EventMessage; +use SP\Core\Exceptions\SPException; /** @@ -41,7 +42,7 @@ final class LdapActions /** * Atributos de búsqueda */ - const USER_ATTRIBUTES = [ + public const USER_ATTRIBUTES = [ 'dn', 'displayname', 'samaccountname', @@ -57,7 +58,7 @@ final class LdapActions 'cn' ]; - const ATTRIBUTES_MAPPING = [ + public const ATTRIBUTES_MAPPING = [ 'dn' => 'dn', 'groupmembership' => 'group', 'memberof' => 'group', @@ -72,7 +73,7 @@ final class LdapActions /** * @var LdapParams */ - private $ldapParams; + private LdapParams $ldapParams; /** * @var resource */ @@ -80,7 +81,7 @@ final class LdapActions /** * @var EventDispatcher */ - private $eventDispatcher; + private EventDispatcher $eventDispatcher; /** * LdapActions constructor. @@ -90,7 +91,10 @@ final class LdapActions * * @throws LdapException */ - public function __construct(LdapConnectionInterface $ldapConnection, EventDispatcher $eventDispatcher) + public function __construct( + LdapConnectionInterface $ldapConnection, + EventDispatcher $eventDispatcher + ) { $this->ldapHandler = $ldapConnection->connectAndBind(); $this->ldapParams = $ldapConnection->getLdapParams(); @@ -126,19 +130,22 @@ final class LdapActions throw new LdapException( __u('Error while searching the group RDN'), - LdapException::ERROR, + SPException::ERROR, null, LdapCode::NO_SUCH_OBJECT ); } - return array_filter(array_map(function ($value) { - if (is_array($value)) { - return $value['dn']; - } + return array_filter(array_map( + static function ($value) { + if (is_array($value)) { + return $value['dn']; + } - return null; - }, $searchResults)); + return null; + }, + $searchResults) + ); } /** @@ -147,7 +154,7 @@ final class LdapActions protected function getGroupFromParams(): string { if (stripos($this->ldapParams->getGroup(), 'cn') === 0) { - return LdapUtil::getGroupName($this->ldapParams->getGroup()); + return LdapUtil::getGroupName($this->ldapParams->getGroup()) ?: ''; } return $this->ldapParams->getGroup(); @@ -163,8 +170,8 @@ final class LdapActions * @return bool|array */ protected function getResults( - string $filter, - ?array $attributes = null, + string $filter, + ?array $attributes = null, ?string $searchBase = null ) { @@ -207,7 +214,7 @@ final class LdapActions $searchRes, $cookie ); - } while ($cookie !== null && $cookie != ''); + } while (!empty($cookie)); return $results; } @@ -233,7 +240,7 @@ final class LdapActions throw new LdapException( __u('Error while searching the user on LDAP'), - LdapException::ERROR, + SPException::ERROR, null, LdapCode::NO_SUCH_OBJECT ); @@ -276,10 +283,10 @@ final class LdapActions * @throws LdapException */ public function getObjects( - string $filter, - array $attributes = self::USER_ATTRIBUTES, + string $filter, + array $attributes = self::USER_ATTRIBUTES, ?string $searchBase = null - ) + ): array { $searchResults = $this->getResults($filter, $attributes, $searchBase); @@ -293,7 +300,7 @@ final class LdapActions throw new LdapException( __u('Error while searching objects in base DN'), - LdapException::ERROR, + SPException::ERROR, null, LdapCode::OPERATIONS_ERROR ); diff --git a/lib/SP/Providers/Auth/Ldap/LdapAuth.php b/lib/SP/Providers/Auth/Ldap/LdapAuth.php index af4191cb..95f45b71 100644 --- a/lib/SP/Providers/Auth/Ldap/LdapAuth.php +++ b/lib/SP/Providers/Auth/Ldap/LdapAuth.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Ldap; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Events\EventDispatcher; use SP\DataModel\UserLoginData; use SP\Providers\Auth\AuthInterface; @@ -36,44 +36,44 @@ use SP\Providers\Auth\AuthInterface; */ final class LdapAuth implements AuthInterface { - const ACCOUNT_EXPIRED = 701; - const ACCOUNT_NO_GROUPS = 702; + public const ACCOUNT_EXPIRED = 701; + public const ACCOUNT_NO_GROUPS = 702; /** * @var string */ - protected $userLogin; + protected string $userLogin; /** * @var LdapAuthData */ - protected $ldapAuthData; + protected LdapAuthData $ldapAuthData; /** * @var EventDispatcher */ - protected $eventDispatcher; + protected EventDispatcher $eventDispatcher; /** * @var string */ - protected $server; + protected string $server; /** * @var LdapInterface */ - private $ldap; + private LdapInterface $ldap; /** - * @var ConfigData + * @var ConfigDataInterface */ - private $configData; + private ConfigDataInterface $configData; /** * LdapBase constructor. * - * @param LdapInterface $ldap - * @param EventDispatcher $eventDispatcher - * @param ConfigData $configData + * @param LdapInterface $ldap + * @param EventDispatcher $eventDispatcher + * @param ConfigDataInterface $configData */ - public function __construct(LdapInterface $ldap, - EventDispatcher $eventDispatcher, - ConfigData $configData) + public function __construct(LdapInterface $ldap, + EventDispatcher $eventDispatcher, + ConfigDataInterface $configData) { $this->ldap = $ldap; $this->eventDispatcher = $eventDispatcher; @@ -85,7 +85,7 @@ final class LdapAuth implements AuthInterface /** * @return LdapAuthData */ - public function getLdapAuthData(): ?LdapAuthData + public function getLdapAuthData(): LdapAuthData { return $this->ldapAuthData; } @@ -101,7 +101,7 @@ final class LdapAuth implements AuthInterface /** * @param string $userLogin */ - public function setUserLogin(string $userLogin) + public function setUserLogin(string $userLogin): void { $this->userLogin = strtolower($userLogin); } @@ -113,7 +113,7 @@ final class LdapAuth implements AuthInterface * * @return bool */ - public function authenticate(UserLoginData $userLoginData) + public function authenticate(UserLoginData $userLoginData): bool { try { $this->ldapAuthData->setAuthoritative($this->isAuthGranted()); diff --git a/lib/SP/Providers/Auth/Ldap/LdapAuthData.php b/lib/SP/Providers/Auth/Ldap/LdapAuthData.php index c7fb2850..0802d746 100644 --- a/lib/SP/Providers/Auth/Ldap/LdapAuthData.php +++ b/lib/SP/Providers/Auth/Ldap/LdapAuthData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Ldap; @@ -36,19 +36,19 @@ final class LdapAuthData extends AuthDataBase /** * @var string */ - protected $dn; + protected string $dn; /** * @var string */ - protected $groupDn; + protected string $groupDn; /** * @var int */ - protected $expire = 0; + protected int $expire = 0; /** * @var bool */ - protected $inGroup = false; + protected bool $inGroup = false; /** * @return string @@ -61,7 +61,7 @@ final class LdapAuthData extends AuthDataBase /** * @param string $dn */ - public function setDn(string $dn) + public function setDn(string $dn): void { $this->dn = $dn; } @@ -71,15 +71,15 @@ final class LdapAuthData extends AuthDataBase */ public function getExpire(): int { - return (int)$this->expire; + return $this->expire; } /** * @param int $expire */ - public function setExpire($expire) + public function setExpire(int $expire): void { - $this->expire = (int)$expire; + $this->expire = $expire; } /** @@ -93,7 +93,7 @@ final class LdapAuthData extends AuthDataBase /** * @param boolean $inGroup */ - public function setInGroup(bool $inGroup) + public function setInGroup(bool $inGroup): void { $this->inGroup = $inGroup; } @@ -109,7 +109,7 @@ final class LdapAuthData extends AuthDataBase /** * @param string $groupDn */ - public function setGroupDn(string $groupDn) + public function setGroupDn(string $groupDn): void { $this->groupDn = $groupDn; } diff --git a/lib/SP/Providers/Auth/Ldap/LdapCode.php b/lib/SP/Providers/Auth/Ldap/LdapCode.php index 6cf7992a..61de34ce 100644 --- a/lib/SP/Providers/Auth/Ldap/LdapCode.php +++ b/lib/SP/Providers/Auth/Ldap/LdapCode.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Ldap; @@ -32,12 +32,12 @@ namespace SP\Providers\Auth\Ldap; */ interface LdapCode { - const SUCCESS = 0; - const OPERATIONS_ERROR = 1; - const AUTH_METHOD_NOT_SUPPORTED = 7; - const STRONGER_AUTH_REQUIRED = 8; - const CONFIDENTIALITY_REQUIRED = 13; - const NO_SUCH_OBJECT = 32; - const INVALID_CREDENTIALS = 49; - const FILTER_ERROR = 87; + public const SUCCESS = 0; + public const OPERATIONS_ERROR = 1; + public const AUTH_METHOD_NOT_SUPPORTED = 7; + public const STRONGER_AUTH_REQUIRED = 8; + public const CONFIDENTIALITY_REQUIRED = 13; + public const NO_SUCH_OBJECT = 32; + public const INVALID_CREDENTIALS = 49; + public const FILTER_ERROR = 87; } \ No newline at end of file diff --git a/lib/SP/Providers/Auth/Ldap/LdapConnection.php b/lib/SP/Providers/Auth/Ldap/LdapConnection.php index aed48f7a..6b0f8731 100644 --- a/lib/SP/Providers/Auth/Ldap/LdapConnection.php +++ b/lib/SP/Providers/Auth/Ldap/LdapConnection.php @@ -1,10 +1,9 @@ -. + * along with sysPass. If not, see . */ +/** @noinspection PhpComposerExtensionStubsInspection */ + namespace SP\Providers\Auth\Ldap; use SP\Core\Events\Event; use SP\Core\Events\EventDispatcher; use SP\Core\Events\EventMessage; +use SP\Core\Exceptions\SPException; /** @@ -36,39 +38,18 @@ use SP\Core\Events\EventMessage; */ final class LdapConnection implements LdapConnectionInterface { - const TIMEOUT = 10; + public const TIMEOUT = 10; /** * @var resource */ private $ldapHandler; - /** - * @var LdapParams - */ - private $ldapParams; - /** - * @var EventDispatcher - */ - private $eventDispatcher; - /** - * @var bool - */ - private $isConnected = false; - /** - * @var bool - */ - private $isBound = false; - /** - * @var bool - */ - private $isTls; - /** - * @var bool - */ - private $debug; - /** - * @var string - */ - private $server; + private LdapParams $ldapParams; + private EventDispatcher $eventDispatcher; + private bool $isConnected = false; + private bool $isBound = false; + private ?bool $isTls = null; + private bool $debug; + private ?string $server = null; /** * LdapBase constructor. @@ -78,14 +59,14 @@ final class LdapConnection implements LdapConnectionInterface * @param bool $debug */ public function __construct( - LdapParams $ldapParams, + LdapParams $ldapParams, EventDispatcher $eventDispatcher, - bool $debug = false + bool $debug = false ) { $this->ldapParams = $ldapParams; $this->eventDispatcher = $eventDispatcher; - $this->debug = (bool)$debug; + $this->debug = $debug; } /** @@ -93,18 +74,15 @@ final class LdapConnection implements LdapConnectionInterface * * @throws LdapException */ - public function checkConnection() + public function checkConnection(): void { - try { - $this->connectAndBind(); - $this->eventDispatcher->notifyEvent('ldap.check.connection', - new Event($this, EventMessage::factory() - ->addDescription(__u('LDAP connection OK'))) - ); - } catch (LdapException $e) { - throw $e; - } + $this->connectAndBind(); + + $this->eventDispatcher->notifyEvent('ldap.check.connection', + new Event($this, EventMessage::factory() + ->addDescription(__u('LDAP connection OK'))) + ); } /** @@ -203,9 +181,6 @@ final class LdapConnection implements LdapConnectionInterface return $this; } - /** - * @inheritDoc - */ public function getServerUri(): string { $server = $this->getServer(); @@ -289,7 +264,7 @@ final class LdapConnection implements LdapConnectionInterface throw new LdapException( __u('Connection error (BIND)'), - LdapException::ERROR, + SPException::ERROR, self::getLdapErrorMessage($this->ldapHandler), $this->getErrorCode() ); diff --git a/lib/SP/Providers/Auth/Ldap/LdapConnectionInterface.php b/lib/SP/Providers/Auth/Ldap/LdapConnectionInterface.php index a2406c69..c8d698e8 100644 --- a/lib/SP/Providers/Auth/Ldap/LdapConnectionInterface.php +++ b/lib/SP/Providers/Auth/Ldap/LdapConnectionInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Ldap; @@ -34,7 +34,7 @@ interface LdapConnectionInterface /** * Comprobar la conexión al servidor de LDAP. */ - public function checkConnection(); + public function checkConnection(): void; /** * Comprobar si los parámetros necesarios de LDAP están establecidos. diff --git a/lib/SP/Providers/Auth/Ldap/LdapException.php b/lib/SP/Providers/Auth/Ldap/LdapException.php index 50249ed1..aa04e1c7 100644 --- a/lib/SP/Providers/Auth/Ldap/LdapException.php +++ b/lib/SP/Providers/Auth/Ldap/LdapException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Ldap; diff --git a/lib/SP/Providers/Auth/Ldap/LdapInterface.php b/lib/SP/Providers/Auth/Ldap/LdapInterface.php index 1093f50f..5259cb6e 100644 --- a/lib/SP/Providers/Auth/Ldap/LdapInterface.php +++ b/lib/SP/Providers/Auth/Ldap/LdapInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Ldap; @@ -32,7 +32,7 @@ namespace SP\Providers\Auth\Ldap; */ interface LdapInterface { - const PAGE_SIZE = 500; + public const PAGE_SIZE = 500; /** * Obtener el filtro para buscar el usuario diff --git a/lib/SP/Providers/Auth/Ldap/LdapMsAds.php b/lib/SP/Providers/Auth/Ldap/LdapMsAds.php index c65e4fdf..a87d250a 100644 --- a/lib/SP/Providers/Auth/Ldap/LdapMsAds.php +++ b/lib/SP/Providers/Auth/Ldap/LdapMsAds.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Ldap; @@ -38,10 +38,10 @@ use SP\Http\Address; */ final class LdapMsAds extends Ldap { - const DEFAULT_FILTER_USER_OBJECT = '(&(!(UserAccountControl:1.2.840.113556.1.4.804:=32))(|(objectCategory=person)(objectClass=user)))'; - const DEFAULT_FILTER_GROUP_OBJECT = '(objectCategory=group)'; - const DEFAULT_FILTER_USER_ATTRIBUTES = ['samaccountname', 'cn', 'uid', 'userPrincipalName']; - const DEFAULT_FILTER_GROUP_ATTRIBUTES = ['memberOf', 'groupMembership', 'memberof:1.2.840.113556.1.4.1941:']; + public const DEFAULT_FILTER_USER_OBJECT = '(&(!(UserAccountControl:1.2.840.113556.1.4.804:=32))(|(objectCategory=person)(objectClass=user)))'; + public const DEFAULT_FILTER_GROUP_OBJECT = '(objectCategory=group)'; + public const DEFAULT_FILTER_USER_ATTRIBUTES = ['samaccountname', 'cn', 'uid', 'userPrincipalName']; + public const DEFAULT_FILTER_GROUP_ATTRIBUTES = ['memberOf', 'groupMembership', 'memberof:1.2.840.113556.1.4.1941:']; /** * @inheritDoc @@ -122,7 +122,7 @@ final class LdapMsAds extends Ldap // los grupos del usuario if (empty($this->ldapParams->getGroup()) || $this->ldapParams->getGroup() === '*' - || in_array($this->getGroupDn(), $groupsDn) + || in_array($this->getGroupDn(), $groupsDn, true) ) { $this->eventDispatcher->notifyEvent('ldap.check.group', new Event($this, EventMessage::factory() @@ -192,7 +192,7 @@ final class LdapMsAds extends Ldap /** * @inheritDoc */ - protected function pickServer() + protected function pickServer(): string { $server = $this->ldapParams->getServer(); @@ -214,7 +214,7 @@ final class LdapMsAds extends Ldap foreach ($records as $record) { $adServers[] = $record['target']; - }; + } return count($adServers) > 0 ? array_rand($adServers) : $server; } diff --git a/lib/SP/Providers/Auth/Ldap/LdapParams.php b/lib/SP/Providers/Auth/Ldap/LdapParams.php index 7a0b15d5..43efc5e1 100644 --- a/lib/SP/Providers/Auth/Ldap/LdapParams.php +++ b/lib/SP/Providers/Auth/Ldap/LdapParams.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Ldap; @@ -31,67 +31,70 @@ namespace SP\Providers\Auth\Ldap; */ final class LdapParams { - const REGEX_SERVER = '(?(?:(?ldap|ldaps):\/\/)?[\w\.\-]+)(?::(?\d+))?'; + private const REGEX_SERVER = '(?(?:(?ldap|ldaps):\/\/)?[\w\.\-]+)(?::(?\d+))?'; /** * @var string */ - protected $server; + protected string $server; /** * @var int */ - protected $port = 389; + protected int $port = 389; /** * @var string */ - protected $searchBase; + protected string $searchBase; /** * @var string */ - protected $bindDn; + protected string $bindDn; /** * @var string */ - protected $bindPass; + protected string $bindPass; /** * @var string */ - protected $group; + protected string $group; /** * @var int */ - protected $type; + protected int $type; /** * @var bool */ - protected $tlsEnabled = false; + protected bool $tlsEnabled = false; /** * @var string */ - protected $filterUserObject; + protected string $filterUserObject; /** * @var string */ - protected $filterGroupObject; + protected string $filterGroupObject; /** * @var array */ - protected $filterUserAttributes; + protected array $filterUserAttributes; /** * @var array */ - protected $filterGroupAttributes; + protected array $filterGroupAttributes; /** * Devolver el puerto del servidor si está establecido * * @param $server * - * @return array|false + * @return array */ - public static function getServerAndPort($server) + public static function getServerAndPort($server): array { - return preg_match('#' . self::REGEX_SERVER . '#i', $server, $matches) ? $matches : false; + return preg_match( + '#' . self::REGEX_SERVER . '#i', $server, + $matches + ) ? $matches : []; } /** @@ -105,7 +108,7 @@ final class LdapParams /** * @param string|null $filterUserObject */ - public function setFilterUserObject(?string $filterUserObject = null) + public function setFilterUserObject(?string $filterUserObject = null): void { if (!empty($filterUserObject)) { $this->filterUserObject = $filterUserObject; @@ -123,7 +126,7 @@ final class LdapParams /** * @param string|null $filterGroupObject */ - public function setFilterGroupObject(?string $filterGroupObject = null) + public function setFilterGroupObject(?string $filterGroupObject = null): void { if (!empty($filterGroupObject)) { $this->filterGroupObject = $filterGroupObject; @@ -141,7 +144,7 @@ final class LdapParams /** * @param array|null $filterUserAttributes */ - public function setFilterUserAttributes(?array $filterUserAttributes = null) + public function setFilterUserAttributes(?array $filterUserAttributes = null): void { $this->filterUserAttributes = $filterUserAttributes; } @@ -157,7 +160,7 @@ final class LdapParams /** * @param array|null $filterGroupAttributes */ - public function setFilterGroupAttributes(?array $filterGroupAttributes = null) + public function setFilterGroupAttributes(?array $filterGroupAttributes = null): void { $this->filterGroupAttributes = $filterGroupAttributes; } @@ -255,6 +258,7 @@ final class LdapParams public function setGroup(string $group): LdapParams { $this->group = $group; + return $this; } @@ -291,9 +295,9 @@ final class LdapParams * * @return LdapParams */ - public function setType($type): LdapParams + public function setType(int $type): LdapParams { - $this->type = (int)$type; + $this->type = $type; return $this; } diff --git a/lib/SP/Providers/Auth/Ldap/LdapStd.php b/lib/SP/Providers/Auth/Ldap/LdapStd.php index dffe268d..cf14806c 100644 --- a/lib/SP/Providers/Auth/Ldap/LdapStd.php +++ b/lib/SP/Providers/Auth/Ldap/LdapStd.php @@ -1,10 +1,9 @@ -. + * along with sysPass. If not, see . */ +/** @noinspection PhpComposerExtensionStubsInspection */ + namespace SP\Providers\Auth\Ldap; use SP\Core\Events\Event; @@ -36,10 +37,10 @@ use SP\Core\Events\EventMessage; */ final class LdapStd extends Ldap { - const DEFAULT_FILTER_USER_OBJECT = '(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject))'; - const DEFAULT_FILTER_GROUP_OBJECT = '(|(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=group))'; - const DEFAULT_FILTER_USER_ATTRIBUTES = ['samaccountname', 'cn', 'uid', 'userPrincipalName']; - const DEFAULT_FILTER_GROUP_ATTRIBUTES = ['memberOf', 'groupMembership']; + public const DEFAULT_FILTER_USER_OBJECT = '(|(objectClass=inetOrgPerson)(objectClass=person)(objectClass=simpleSecurityObject))'; + public const DEFAULT_FILTER_GROUP_OBJECT = '(|(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=group))'; + public const DEFAULT_FILTER_USER_ATTRIBUTES = ['samaccountname', 'cn', 'uid', 'userPrincipalName']; + public const DEFAULT_FILTER_GROUP_ATTRIBUTES = ['memberOf', 'groupMembership']; /** * @inheritDoc @@ -109,7 +110,7 @@ final class LdapStd extends Ldap // los grupos del usuario if (empty($this->ldapParams->getGroup()) || $this->ldapParams->getGroup() === '*' - || in_array($this->getGroupDn(), $groupsDn) + || in_array($this->getGroupDn(), $groupsDn, true) ) { $this->eventDispatcher->notifyEvent('ldap.check.group', new Event($this, EventMessage::factory() @@ -184,9 +185,9 @@ final class LdapStd extends Ldap /** * Obtener el servidor de LDAP a utilizar * - * @return mixed + * @return string */ - protected function pickServer() + protected function pickServer(): string { return $this->ldapParams->getServer(); } diff --git a/lib/SP/Providers/Auth/Ldap/LdapTypeInterface.php b/lib/SP/Providers/Auth/Ldap/LdapTypeInterface.php index 387004dc..1f4566f6 100644 --- a/lib/SP/Providers/Auth/Ldap/LdapTypeInterface.php +++ b/lib/SP/Providers/Auth/Ldap/LdapTypeInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Auth\Ldap; @@ -32,7 +32,7 @@ namespace SP\Providers\Auth\Ldap; */ interface LdapTypeInterface { - const LDAP_STD = 1; - const LDAP_ADS = 2; - const LDAP_AZURE = 3; + public const LDAP_STD = 1; + public const LDAP_ADS = 2; + public const LDAP_AZURE = 3; } \ No newline at end of file diff --git a/lib/SP/Providers/Auth/Ldap/LdapUtil.php b/lib/SP/Providers/Auth/Ldap/LdapUtil.php index 7274d37c..fa5a4bb8 100644 --- a/lib/SP/Providers/Auth/Ldap/LdapUtil.php +++ b/lib/SP/Providers/Auth/Ldap/LdapUtil.php @@ -1,10 +1,9 @@ -. + * along with sysPass. If not, see . */ +/** @noinspection PhpComposerExtensionStubsInspection */ + namespace SP\Providers\Auth\Ldap; /** @@ -60,7 +61,11 @@ final class LdapUtil */ public static function getGroupName(string $group) { - if (preg_match('/^cn=(?[^,]+),.*/i', $group, $matches)) { + if (preg_match( + '/^cn=(?[^,]+),.*/i', + $group, + $matches) + ) { return $matches['groupname']; } @@ -75,13 +80,16 @@ final class LdapUtil */ public static function getAttributesForFilter(array $attributes, string $value): string { - $value = ldap_escape((string)$value, null, LDAP_ESCAPE_FILTER); + $value = ldap_escape($value, null, LDAP_ESCAPE_FILTER); return implode( '', - array_map(function ($attribute) use ($value) { - return sprintf('(%s=%s)', $attribute, $value); - }, $attributes) + array_map( + static function ($attribute) use ($value) { + return sprintf('(%s=%s)', $attribute, $value); + }, + $attributes + ) ); } } \ No newline at end of file diff --git a/lib/SP/Providers/EventsTrait.php b/lib/SP/Providers/EventsTrait.php index 20a26d04..f41cbc01 100644 --- a/lib/SP/Providers/EventsTrait.php +++ b/lib/SP/Providers/EventsTrait.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers; @@ -34,9 +34,9 @@ trait EventsTrait /** * @param array $events * - * @return mixed + * @return string */ - protected function parseEventsToRegex(array $events) + protected function parseEventsToRegex(array $events): string { return implode('|', array_map('preg_quote', $events)); } diff --git a/lib/SP/Providers/Log/DatabaseLogHandler.php b/lib/SP/Providers/Log/DatabaseLogHandler.php index 95c74a2d..b4951163 100644 --- a/lib/SP/Providers/Log/DatabaseLogHandler.php +++ b/lib/SP/Providers/Log/DatabaseLogHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,15 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Log; -use DI\Container; -use DI\DependencyException; -use DI\NotFoundException; use Exception; +use Psr\Container\ContainerInterface; use SP\Core\Events\Event; use SP\Core\Events\EventReceiver; use SP\Core\Exceptions\InvalidClassException; @@ -51,15 +49,15 @@ final class DatabaseLogHandler extends Provider implements EventReceiver /** * @var EventlogService */ - private $eventlogService; + private EventlogService $eventlogService; /** * @var string */ - private $events; + private string $events; /** * @var Language */ - private $language; + private Language $language; /** * Receive update from subject @@ -74,7 +72,7 @@ final class DatabaseLogHandler extends Provider implements EventReceiver * @throws InvalidClassException * @since 5.1.0 */ - public function update(SplSubject $subject) + public function update(SplSubject $subject): void { $this->updateEvent('update', new Event($subject)); } @@ -87,7 +85,7 @@ final class DatabaseLogHandler extends Provider implements EventReceiver * * @throws InvalidClassException */ - public function updateEvent(string $eventType, Event $event) + public function updateEvent(string $eventType, Event $event): void { if (strpos($eventType, 'database.') !== false) { return; @@ -148,19 +146,16 @@ final class DatabaseLogHandler extends Provider implements EventReceiver } /** - * @param Container $dic - * - * @throws DependencyException - * @throws NotFoundException + * @param ContainerInterface $dic */ - protected function initialize(Container $dic) + protected function initialize(ContainerInterface $dic): void { $this->language = $dic->get(Language::class); $this->eventlogService = $dic->get(EventlogService::class); $configEvents = $this->config->getConfigData()->getLogEvents(); - if (empty($configEvents)) { + if (count($configEvents) === 0) { $this->events = $this->parseEventsToRegex(LogInterface::EVENTS_FIXED); } else { $this->events = $this->parseEventsToRegex(array_merge($configEvents, LogInterface::EVENTS_FIXED)); diff --git a/lib/SP/Providers/Log/FileLogHandler.php b/lib/SP/Providers/Log/FileLogHandler.php index 5c20e6b0..da47cfd7 100644 --- a/lib/SP/Providers/Log/FileLogHandler.php +++ b/lib/SP/Providers/Log/FileLogHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,16 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Log; -use DI\Container; -use DI\DependencyException; -use DI\NotFoundException; use Monolog\Handler\StreamHandler; +use Psr\Container\ContainerInterface; use SP\Core\Events\Event; use SP\Core\Exceptions\InvalidClassException; use SP\Providers\EventsTrait; @@ -82,12 +80,9 @@ final class FileLogHandler extends LoggerBase } /** - * @param Container $dic - * - * @throws DependencyException - * @throws NotFoundException + * @param ContainerInterface $dic */ - protected function initialize(Container $dic) + protected function initialize(ContainerInterface $dic): void { parent::initialize($dic); diff --git a/lib/SP/Providers/Log/LogInterface.php b/lib/SP/Providers/Log/LogInterface.php index 0dfb5c09..d3e5471c 100644 --- a/lib/SP/Providers/Log/LogInterface.php +++ b/lib/SP/Providers/Log/LogInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Log; @@ -31,7 +31,7 @@ namespace SP\Providers\Log; */ interface LogInterface { - const EVENTS = [ + public const EVENTS = [ 'show.', 'create.', 'delete.', @@ -53,7 +53,7 @@ interface LogInterface 'unlock.track', ]; - const EVENTS_FIXED = [ + public const EVENTS_FIXED = [ 'upgrade.', 'acl.deny', 'plugin.load.error', diff --git a/lib/SP/Providers/Log/LoggerBase.php b/lib/SP/Providers/Log/LoggerBase.php index 2db04bb5..d4fd5dc2 100644 --- a/lib/SP/Providers/Log/LoggerBase.php +++ b/lib/SP/Providers/Log/LoggerBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,16 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Log; -use DI\Container; -use DI\DependencyException; -use DI\NotFoundException; use Exception; use Monolog\Logger; +use Psr\Container\ContainerInterface; use SP\Core\Events\Event; use SP\Core\Events\EventReceiver; use SP\Core\Exceptions\InvalidClassException; @@ -46,23 +44,23 @@ abstract class LoggerBase extends Provider implements EventReceiver { use EventsTrait; - const MESSAGE_FORMAT = 'event="%s";address="%s";user="%s";message="%s"'; + public const MESSAGE_FORMAT = 'event="%s";address="%s";user="%s";message="%s"'; /** * @var Logger */ - protected $logger; + protected Logger $logger; /** * @var Request */ - protected $request; + protected Request $request; /** * @var string */ - protected $events; + protected string $events; /** * @var Language */ - protected $language; + protected Language $language; /** * Evento de actualización @@ -72,7 +70,7 @@ abstract class LoggerBase extends Provider implements EventReceiver * * @throws InvalidClassException */ - public function updateEvent(string $eventType, Event $event) + public function updateEvent(string $eventType, Event $event): void { $this->language->setAppLocales(); @@ -103,16 +101,17 @@ abstract class LoggerBase extends Provider implements EventReceiver } /** - * @param $message - * @param $address - * @param $user + * @param string $message + * @param string $address + * @param string $user * * @return array */ final protected function formatContext( string $message, string $address, - string $user): array + string $user + ): array { return [ 'message' => trim($message), @@ -123,19 +122,16 @@ abstract class LoggerBase extends Provider implements EventReceiver } /** - * @param Container $dic - * - * @throws DependencyException - * @throws NotFoundException + * @param ContainerInterface $dic */ - protected function initialize(Container $dic) + protected function initialize(ContainerInterface $dic): void { $this->language = $dic->get(Language::class); $this->request = $dic->get(Request::class); $configEvents = $this->config->getConfigData()->getLogEvents(); - if (empty($configEvents)) { + if (count($configEvents) === 0) { $this->events = $this->parseEventsToRegex(LogInterface::EVENTS_FIXED); } else { $this->events = $this->parseEventsToRegex(array_merge($configEvents, LogInterface::EVENTS_FIXED)); diff --git a/lib/SP/Providers/Log/RemoteSyslogHandler.php b/lib/SP/Providers/Log/RemoteSyslogHandler.php index 9ec1950d..51f8959a 100644 --- a/lib/SP/Providers/Log/RemoteSyslogHandler.php +++ b/lib/SP/Providers/Log/RemoteSyslogHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,16 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Log; -use DI\Container; -use DI\DependencyException; -use DI\NotFoundException; use Monolog\Handler\SyslogUdpHandler; use Monolog\Logger; +use Psr\Container\ContainerInterface; use SP\Core\Events\Event; use SP\Core\Exceptions\InvalidClassException; use SplSubject; @@ -73,18 +71,15 @@ final class RemoteSyslogHandler extends LoggerBase * @throws InvalidClassException * @since 5.1.0 */ - public function update(SplSubject $subject) + public function update(SplSubject $subject): void { $this->updateEvent('update', new Event($subject)); } /** - * @param Container $dic - * - * @throws DependencyException - * @throws NotFoundException + * @param ContainerInterface $dic */ - protected function initialize(Container $dic) + protected function initialize(ContainerInterface $dic): void { parent::initialize($dic); @@ -101,6 +96,4 @@ final class RemoteSyslogHandler extends LoggerBase ) ); } - - } \ No newline at end of file diff --git a/lib/SP/Providers/Log/SyslogHandler.php b/lib/SP/Providers/Log/SyslogHandler.php index 971cd677..b655a393 100644 --- a/lib/SP/Providers/Log/SyslogHandler.php +++ b/lib/SP/Providers/Log/SyslogHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,15 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Log; -use DI\Container; -use DI\DependencyException; -use DI\NotFoundException; use Monolog\Handler\SyslogHandler as MSyslogHandler; +use Psr\Container\ContainerInterface; use SP\Core\Events\Event; use SP\Core\Exceptions\InvalidClassException; use SplSubject; @@ -72,18 +70,15 @@ final class SyslogHandler extends LoggerBase * @throws InvalidClassException * @since 5.1.0 */ - public function update(SplSubject $subject) + public function update(SplSubject $subject): void { $this->updateEvent('update', new Event($subject)); } /** - * @param Container $dic - * - * @throws DependencyException - * @throws NotFoundException + * @param ContainerInterface $dic */ - protected function initialize(Container $dic) + protected function initialize(ContainerInterface $dic): void { parent::initialize($dic); diff --git a/lib/SP/Providers/Mail/MailHandler.php b/lib/SP/Providers/Mail/MailHandler.php index 0649a4ca..e75e9226 100644 --- a/lib/SP/Providers/Mail/MailHandler.php +++ b/lib/SP/Providers/Mail/MailHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,15 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Mail; -use DI\Container; -use DI\DependencyException; -use DI\NotFoundException; use Exception; +use Psr\Container\ContainerInterface; use SP\Core\Events\Event; use SP\Core\Events\EventReceiver; use SP\Core\Messages\MailMessage; @@ -47,7 +45,7 @@ final class MailHandler extends Provider implements EventReceiver { use EventsTrait; - const EVENTS = [ + public const EVENTS = [ 'create.', 'delete.', 'edit.', @@ -57,7 +55,7 @@ final class MailHandler extends Provider implements EventReceiver 'run.import.end' ]; - const EVENTS_FIXED = [ + public const EVENTS_FIXED = [ 'clear.eventlog', 'refresh.masterPassword', 'update.masterPassword.start', @@ -71,15 +69,15 @@ final class MailHandler extends Provider implements EventReceiver /** * @var MailService */ - private $mailService; + private MailService $mailService; /** * @var string */ - private $events; + private string $events; /** * @var Request */ - private $request; + private Request $request; /** * Devuelve los eventos que implementa el observador @@ -113,7 +111,7 @@ final class MailHandler extends Provider implements EventReceiver * @return void * @since 5.1.0 */ - public function update(SplSubject $subject) + public function update(SplSubject $subject): void { $this->updateEvent('update', new Event($subject)); } @@ -124,7 +122,7 @@ final class MailHandler extends Provider implements EventReceiver * @param string $eventType Nombre del evento * @param Event $event Objeto del evento */ - public function updateEvent(string $eventType, Event $event) + public function updateEvent(string $eventType, Event $event): void { if (($eventMessage = $event->getEventMessage()) !== null) { try { @@ -158,12 +156,29 @@ final class MailHandler extends Provider implements EventReceiver $mailMessage->addDescriptionLine(); if ($userData->getId() !== null) { - $mailMessage->addDescription(sprintf(__('Performed by: %s (%s)'), $userData->getName(), $userData->getLogin())); + $mailMessage->addDescription( + sprintf( + __('Performed by: %s (%s)'), + $userData->getName(), + $userData->getLogin() + ) + ); } else { - $mailMessage->addDescription(sprintf(__('Performed by: %s (%s)'), 'sysPass', 'APP')); + $mailMessage->addDescription( + sprintf( + __('Performed by: %s (%s)'), + 'sysPass', + 'APP' + ) + ); } - $mailMessage->addDescription(sprintf(__('IP Address: %s'), $this->request->getClientAddress(true))); + $mailMessage->addDescription( + sprintf( + __('IP Address: %s'), + $this->request->getClientAddress(true) + ) + ); $subject = $eventMessage->getDescription(new TextFormatter(), true) ?: $eventType; @@ -179,19 +194,16 @@ final class MailHandler extends Provider implements EventReceiver } /** - * @param Container $dic - * - * @throws DependencyException - * @throws NotFoundException + * @param ContainerInterface $dic */ - protected function initialize(Container $dic) + protected function initialize(ContainerInterface $dic): void { $this->mailService = $dic->get(MailService::class); $this->request = $dic->get(Request::class); $configEvents = $this->config->getConfigData()->getMailEvents(); - if (empty($configEvents)) { + if (count($configEvents) === 0) { $this->events = $this->parseEventsToRegex(self::EVENTS_FIXED); } else { $this->events = $this->parseEventsToRegex(array_merge($configEvents, self::EVENTS_FIXED)); diff --git a/lib/SP/Providers/Mail/MailParams.php b/lib/SP/Providers/Mail/MailParams.php index cbac441a..d51fc7fe 100644 --- a/lib/SP/Providers/Mail/MailParams.php +++ b/lib/SP/Providers/Mail/MailParams.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Mail; @@ -34,29 +34,29 @@ final class MailParams /** * @var string */ - public $server; + public string $server; /** * @var int */ - public $port; + public int $port; /** * @var string */ - public $user; + public string $user; /** * @var string */ - public $pass; + public string $pass; /** * @var string */ - public $security; + public string $security; /** * @var string */ - public $from; + public string $from; /** * @var bool */ - public $mailAuthenabled; + public bool $mailAuthenabled; } \ No newline at end of file diff --git a/lib/SP/Providers/Mail/MailProvider.php b/lib/SP/Providers/Mail/MailProvider.php index 076c7ab7..7059cf48 100644 --- a/lib/SP/Providers/Mail/MailProvider.php +++ b/lib/SP/Providers/Mail/MailProvider.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,17 +19,16 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Mail; -use DI\Container; -use DI\DependencyException; -use DI\NotFoundException; use Exception; use PHPMailer\PHPMailer\PHPMailer; +use Psr\Container\ContainerInterface; use SP\Core\AppInfoInterface; +use SP\Core\Exceptions\SPException; use SP\Providers\Provider; /** @@ -42,11 +41,11 @@ final class MailProvider extends Provider /** * @var PHPMailer */ - private $mailer; + private PHPMailer $mailer; /** * @var bool */ - private $debug = false; + private bool $debug = false; /** * Inicializar la clase PHPMailer. @@ -56,7 +55,7 @@ final class MailProvider extends Provider * @return PHPMailer * @throws MailProviderException */ - public function getMailer(MailParams $mailParams) + public function getMailer(MailParams $mailParams): PHPMailer { $appName = AppInfoInterface::APP_NAME; @@ -92,7 +91,7 @@ final class MailProvider extends Provider throw new MailProviderException( __u('Unable to initialize'), - MailProviderException::ERROR, + SPException::ERROR, $e->getMessage(), $e->getCode(), $e @@ -113,16 +112,13 @@ final class MailProvider extends Provider */ public function setDebug(bool $debug) { - $this->debug = (bool)$debug; + $this->debug = $debug; } /** - * @param Container $dic - * - * @throws DependencyException - * @throws NotFoundException + * @param ContainerInterface $dic */ - protected function initialize(Container $dic) + protected function initialize(ContainerInterface $dic): void { $this->mailer = $dic->get(PHPMailer::class); } diff --git a/lib/SP/Providers/Mail/MailProviderException.php b/lib/SP/Providers/Mail/MailProviderException.php index b9fe2b16..be553415 100644 --- a/lib/SP/Providers/Mail/MailProviderException.php +++ b/lib/SP/Providers/Mail/MailProviderException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Mail; diff --git a/lib/SP/Providers/Notification/NotificationHandler.php b/lib/SP/Providers/Notification/NotificationHandler.php index 06ff408e..b4bb19d9 100644 --- a/lib/SP/Providers/Notification/NotificationHandler.php +++ b/lib/SP/Providers/Notification/NotificationHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,15 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers\Notification; -use DI\Container; -use DI\DependencyException; -use DI\NotFoundException; use Exception; +use Psr\Container\ContainerInterface; use SP\Core\Events\Event; use SP\Core\Events\EventReceiver; use SP\DataModel\NotificationData; @@ -45,7 +43,7 @@ final class NotificationHandler extends Provider implements EventReceiver { use EventsTrait; - const EVENTS = [ + public const EVENTS = [ 'request.account', 'show.account.link' ]; @@ -53,11 +51,11 @@ final class NotificationHandler extends Provider implements EventReceiver /** * @var NotificationService */ - private $notificationService; + private NotificationService $notificationService; /** * @var string */ - private $events; + private string $events; /** * Devuelve los eventos que implementa el observador @@ -91,7 +89,7 @@ final class NotificationHandler extends Provider implements EventReceiver * @return void * @since 5.1.0 */ - public function update(SplSubject $subject) + public function update(SplSubject $subject): void { $this->updateEvent('update', new Event($subject)); } @@ -102,7 +100,7 @@ final class NotificationHandler extends Provider implements EventReceiver * @param string $eventType Nombre del evento * @param Event $event Objeto del evento */ - public function updateEvent(string $eventType, Event $event) + public function updateEvent(string $eventType, Event $event): void { switch ($eventType) { case 'request.account': @@ -117,10 +115,10 @@ final class NotificationHandler extends Provider implements EventReceiver /** * @param Event $event */ - private function requestAccountNotification(Event $event) + private function requestAccountNotification(Event $event): void { $eventMessage = $event->getEventMessage(); - $data = $eventMessage->getExtra(); + $data = $eventMessage !== null ? $eventMessage->getExtra() : []; foreach ($data['userId'] as $userId) { $notificationData = new NotificationData(); @@ -136,7 +134,7 @@ final class NotificationHandler extends Provider implements EventReceiver /** * @param NotificationData $notificationData */ - private function notify(NotificationData $notificationData) + private function notify(NotificationData $notificationData): void { try { $this->notificationService->create($notificationData); @@ -148,10 +146,10 @@ final class NotificationHandler extends Provider implements EventReceiver /** * @param Event $event */ - private function showAccountLinkNotification(Event $event) + private function showAccountLinkNotification(Event $event): void { $eventMessage = $event->getEventMessage(); - $data = $eventMessage->getExtra(); + $data = $eventMessage !== null ? $eventMessage->getExtra() : []; if ($data['notify'][0] === true) { $notificationData = new NotificationData(); @@ -165,12 +163,9 @@ final class NotificationHandler extends Provider implements EventReceiver } /** - * @param Container $dic - * - * @throws DependencyException - * @throws NotFoundException + * @param ContainerInterface $dic */ - protected function initialize(Container $dic) + protected function initialize(ContainerInterface $dic): void { $this->notificationService = $dic->get(NotificationService::class); diff --git a/lib/SP/Providers/Provider.php b/lib/SP/Providers/Provider.php index 22e76dbc..eb0e5b9b 100644 --- a/lib/SP/Providers/Provider.php +++ b/lib/SP/Providers/Provider.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Providers; @@ -36,7 +36,7 @@ use SP\Core\Events\EventDispatcher; */ abstract class Provider { - const STATUS_INTERNAL_ERROR = 1000; + public const STATUS_INTERNAL_ERROR = 1000; /** * @var Config diff --git a/lib/SP/Repositories/Account/AccountFileRepository.php b/lib/SP/Repositories/Account/AccountFileRepository.php index bf3ce7c1..e7f22e42 100644 --- a/lib/SP/Repositories/Account/AccountFileRepository.php +++ b/lib/SP/Repositories/Account/AccountFileRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Account; @@ -31,7 +31,7 @@ use SP\DataModel\FileData; use SP\DataModel\FileExtData; use SP\DataModel\ItemSearchData; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -41,7 +41,7 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\Account */ -final class AccountFileRepository extends Repository implements RepositoryItemInterface +final class AccountFileRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; @@ -50,11 +50,11 @@ final class AccountFileRepository extends Repository implements RepositoryItemIn * * @param FileData $itemData * - * @return mixed + * @return int * @throws ConstraintException * @throws QueryException */ - public function create($itemData) + public function create($itemData): int { $query = /** @lang SQL */ 'INSERT INTO AccountFile @@ -87,21 +87,21 @@ final class AccountFileRepository extends Repository implements RepositoryItemIn * * @param mixed $itemData * - * @return mixed + * @return void */ - public function update($itemData) + public function update($itemData): void { throw new RuntimeException('Not implemented'); } /** - * @param $id + * @param int $id * * @return QueryResult - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getInfoById($id) + public function getInfoById(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT AF.name, @@ -133,7 +133,7 @@ final class AccountFileRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT AF.id, @@ -168,7 +168,7 @@ final class AccountFileRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function getByAccountId($id) + public function getByAccountId(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT id, @@ -198,7 +198,7 @@ final class AccountFileRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $query = /** @lang SQL */ 'SELECT AF.id, @@ -232,9 +232,9 @@ final class AccountFileRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { - if (empty($ids)) { + if (count($ids) === 0) { return new QueryResult(); } @@ -265,13 +265,13 @@ final class AccountFileRepository extends Repository implements RepositoryItemIn /** * Deletes an item * - * @param $id + * @param int $id * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function delete($id) + public function delete(int $id): int { $query = /** @lang SQL */ 'DELETE FROM AccountFile WHERE id = ? LIMIT 1'; @@ -293,9 +293,9 @@ final class AccountFileRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -312,7 +312,7 @@ final class AccountFileRepository extends Repository implements RepositoryItemIn * * @param $id int */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -322,7 +322,7 @@ final class AccountFileRepository extends Repository implements RepositoryItemIn * * @param mixed $itemData */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -332,7 +332,7 @@ final class AccountFileRepository extends Repository implements RepositoryItemIn * * @param mixed $itemData */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -342,11 +342,11 @@ final class AccountFileRepository extends Repository implements RepositoryItemIn * * @param ItemSearchData $itemSearchData * - * @return mixed + * @return \SP\Storage\Database\QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(FileExtData::class); @@ -366,7 +366,7 @@ final class AccountFileRepository extends Repository implements RepositoryItemIn INNER JOIN Client ON Account.clientId = Client.id'); $queryData->setOrder('Account.name'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere( 'AccountFile.name LIKE ? OR AccountFile.type LIKE ? diff --git a/lib/SP/Repositories/Account/AccountHistoryRepository.php b/lib/SP/Repositories/Account/AccountHistoryRepository.php index 729ce952..74a4405d 100644 --- a/lib/SP/Repositories/Account/AccountHistoryRepository.php +++ b/lib/SP/Repositories/Account/AccountHistoryRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Account; @@ -32,7 +32,7 @@ use SP\DataModel\AccountHistoryData; use SP\DataModel\Dto\AccountHistoryCreateDto; use SP\DataModel\ItemSearchData; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Services\Account\AccountPasswordRequest; use SP\Storage\Database\QueryData; @@ -43,7 +43,7 @@ use SP\Storage\Database\QueryResult; * * @package Services */ -final class AccountHistoryRepository extends Repository implements RepositoryItemInterface +final class AccountHistoryRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; @@ -155,7 +155,7 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte * @throws ConstraintException * @throws QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM AccountHistory WHERE id = ? LIMIT 1'); @@ -170,9 +170,9 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte * * @param mixed $itemData * - * @return mixed + * @return void */ - public function update($itemData) + public function update($itemData): void { throw new RuntimeException('Not implemented'); } @@ -185,7 +185,7 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte * @return QueryResult * @throws SPException */ - public function getById($id) + public function getById(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT AH.id, @@ -241,7 +241,7 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte * @throws QueryException * @throws ConstraintException */ - public function getAll() + public function getAll(): QueryResult { $query = /** @lang SQL */ 'SELECT AH.id, @@ -265,9 +265,9 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte * * @param array $ids * - * @return void + * @return QueryResult */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { throw new RuntimeException('Not implemented'); } @@ -281,9 +281,9 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -304,9 +304,9 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte * @throws ConstraintException * @throws QueryException */ - public function deleteByAccountIdBatch(array $ids) + public function deleteByAccountIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -325,7 +325,7 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte * * @return void */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -337,7 +337,7 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte * * @return void */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -349,7 +349,7 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte * * @return void */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -363,7 +363,7 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setSelect('AH.id, AH.name, C.name as clientName, C2.name as categoryName, IFNULL(AH.dateEdit,AH.dateAdd) as date, AH.isModify, AH.isDeleted'); @@ -373,7 +373,7 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte '); $queryData->setOrder('date DESC, AH.name, C.name, AH.id DESC'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere('AH.name LIKE ? OR C.name LIKE ?'); $search = '%' . $itemSearchData->getSeachString() . '%'; @@ -395,7 +395,7 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte * @throws ConstraintException * @throws QueryException */ - public function getAccountsPassData() + public function getAccountsPassData(): QueryResult { $query = /** @lang SQL */ 'SELECT id, `name`, pass, `key`, mPassHash @@ -413,11 +413,11 @@ final class AccountHistoryRepository extends Repository implements RepositoryIte * * @param AccountPasswordRequest $request * - * @return bool + * @return int * @throws ConstraintException * @throws QueryException */ - public function updatePassword(AccountPasswordRequest $request) + public function updatePassword(AccountPasswordRequest $request): int { $query = /** @lang SQL */ 'UPDATE AccountHistory SET diff --git a/lib/SP/Repositories/Account/AccountRepository.php b/lib/SP/Repositories/Account/AccountRepository.php index 8a359463..87d2aebf 100644 --- a/lib/SP/Repositories/Account/AccountRepository.php +++ b/lib/SP/Repositories/Account/AccountRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Account; @@ -39,7 +39,7 @@ use SP\Mvc\Model\QueryAssignment; use SP\Mvc\Model\QueryCondition; use SP\Mvc\Model\QueryJoin; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Services\Account\AccountPasswordRequest; use SP\Services\Account\AccountRequest; @@ -53,7 +53,7 @@ use stdClass; * * @package Services */ -final class AccountRepository extends Repository implements RepositoryItemInterface +final class AccountRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; @@ -64,7 +64,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws QueryException * @throws ConstraintException */ - public function getTotalNumAccounts() + public function getTotalNumAccounts(): stdClass { $query = /** @lang SQL */ 'SELECT SUM(n) AS num FROM @@ -77,14 +77,14 @@ final class AccountRepository extends Repository implements RepositoryItemInterf } /** - * @param $id + * @param int $id * @param QueryCondition $queryCondition * * @return QueryResult - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getPasswordForId($id, QueryCondition $queryCondition) + public function getPasswordForId(int $id, QueryCondition $queryCondition): QueryResult { $queryCondition->addFilter('Account.id = ?', [$id]); @@ -106,7 +106,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws ConstraintException * @throws QueryException */ - public function getPasswordHistoryForId(QueryCondition $queryCondition) + public function getPasswordHistoryForId(QueryCondition $queryCondition): QueryResult { $query = /** @lang SQL */ 'SELECT @@ -137,7 +137,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws ConstraintException * @throws QueryException */ - public function incrementDecryptCounter($id) + public function incrementDecryptCounter(int $id): bool { $query = /** @lang SQL */ 'UPDATE Account SET countDecrypt = (countDecrypt + 1) WHERE id = ? LIMIT 1'; @@ -158,7 +158,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws ConstraintException * @throws QueryException */ - public function create($itemData) + public function create($itemData): int { $query = /** @lang SQL */ 'INSERT INTO Account SET @@ -213,7 +213,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws ConstraintException * @throws QueryException */ - public function editPassword(AccountRequest $accountRequest) + public function editPassword(AccountRequest $accountRequest): int { $query = /** @lang SQL */ 'UPDATE Account SET @@ -248,7 +248,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws ConstraintException * @throws QueryException */ - public function updatePassword(AccountPasswordRequest $request) + public function updatePassword(AccountPasswordRequest $request): bool { $query = /** @lang SQL */ 'UPDATE Account SET @@ -274,7 +274,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws ConstraintException * @throws QueryException */ - public function editRestore($historyId, $userId) + public function editRestore(int $historyId, int $userId): bool { $query = /** @lang SQL */ 'UPDATE Account dst, @@ -314,7 +314,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws ConstraintException * @throws QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); @@ -330,10 +330,10 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * * @param AccountRequest $itemData * - * @return mixed + * @return int * @throws SPException */ - public function update($itemData) + public function update($itemData): int { $queryAssignment = new QueryAssignment(); @@ -391,10 +391,10 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * * @param AccountRequest $itemData * - * @return mixed + * @return int * @throws SPException */ - public function updateBulk($itemData) + public function updateBulk(AccountRequest $itemData): int { $queryAssignment = new QueryAssignment(); @@ -444,7 +444,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws QueryException * @throws ConstraintException */ - public function getById($id) + public function getById(int $id): QueryResult { $queryData = new QueryData(); $queryData->setQuery('SELECT * FROM account_data_v WHERE id = ? LIMIT 1'); @@ -462,7 +462,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(AccountData::class); @@ -476,7 +476,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * * @param array $ids */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { throw new RuntimeException('Not implemented'); } @@ -490,9 +490,9 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -510,7 +510,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * * @param $id int */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -520,7 +520,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * * @param mixed $itemData */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -530,7 +530,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * * @param mixed $itemData */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -544,14 +544,14 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setSelect('id, name, clientName, categoryName, userName, userGroupName'); $queryData->setFrom('account_search_v'); $queryData->setOrder('name, clientName'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere('name LIKE ? OR clientName LIKE ? OR categoryName LIKE ? @@ -583,7 +583,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws ConstraintException * @throws QueryException */ - public function incrementViewCounter($id) + public function incrementViewCounter(int $id): bool { $queryData = new QueryData(); $queryData->setQuery('UPDATE Account SET countView = (countView + 1) WHERE id = ? LIMIT 1'); @@ -595,13 +595,13 @@ final class AccountRepository extends Repository implements RepositoryItemInterf /** * Obtener los datos de una cuenta. * - * @param $id + * @param int $id * * @return QueryResult - * @throws QueryException - * @throws ConstraintException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getDataForLink($id) + public function getDataForLink(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT Account.id, @@ -638,7 +638,10 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws QueryException * @throws SPException */ - public function getByFilter(AccountSearchFilter $accountSearchFilter, QueryCondition $queryFilterUser) + public function getByFilter( + AccountSearchFilter $accountSearchFilter, + QueryCondition $queryFilterUser + ): QueryResult { $queryFilters = new QueryCondition(); @@ -656,15 +659,24 @@ final class AccountRepository extends Repository implements RepositoryItemInterf $stringFilters = $accountSearchFilter->getStringFilters(); if ($stringFilters->hasFilters()) { - $queryFilters->addFilter($stringFilters->getFilters($accountSearchFilter->getFilterOperator()), $stringFilters->getParams()); + $queryFilters->addFilter( + $stringFilters->getFilters($accountSearchFilter->getFilterOperator()), + $stringFilters->getParams() + ); } - if (!empty($accountSearchFilter->getCategoryId())) { - $queryFilters->addFilter('Account.categoryId = ?', [$accountSearchFilter->getCategoryId()]); + if ($accountSearchFilter->getCategoryId() !== null) { + $queryFilters->addFilter( + 'Account.categoryId = ?', + [$accountSearchFilter->getCategoryId()] + ); } - if (!empty($accountSearchFilter->getClientId())) { - $queryFilters->addFilter('Account.clientId = ?', [$accountSearchFilter->getClientId()]); + if ($accountSearchFilter->getClientId() !== null) { + $queryFilters->addFilter( + 'Account.clientId = ?', + [$accountSearchFilter->getClientId()] + ); } $where = []; @@ -700,7 +712,11 @@ final class AccountRepository extends Repository implements RepositoryItemInterf } $queryData->setWhere($where); - $queryData->setParams(array_merge($queryJoins->getParams(), $queryFilterUser->getParams(), $queryFilters->getParams())); + $queryData->setParams(array_merge( + $queryJoins->getParams(), + $queryFilterUser->getParams(), + $queryFilters->getParams() + )); $queryData->setSelect('DISTINCT Account.*'); $queryData->setFrom('account_search_v Account ' . $queryJoins->getJoins()); $queryData->setOrder($accountSearchFilter->getOrderString()); @@ -725,7 +741,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws ConstraintException * @throws QueryException */ - public function getForUser(QueryCondition $queryFilter) + public function getForUser(QueryCondition $queryFilter): QueryResult { $query = /** @lang SQL */ 'SELECT Account.id, Account.name, C.name AS clientName @@ -748,7 +764,7 @@ final class AccountRepository extends Repository implements RepositoryItemInterf * @throws ConstraintException * @throws QueryException */ - public function getLinked(QueryCondition $queryFilter) + public function getLinked(QueryCondition $queryFilter): QueryResult { $query = /** @lang SQL */ 'SELECT Account.id, Account.name, Client.name AS clientName @@ -766,15 +782,15 @@ final class AccountRepository extends Repository implements RepositoryItemInterf /** * Obtener los datos relativos a la clave de todas las cuentas. * - * @return array Con los datos de la clave + * @return \SP\Storage\Database\QueryResult * @throws ConstraintException * @throws QueryException */ - public function getAccountsPassData() + public function getAccountsPassData(): QueryResult { $queryData = new QueryData(); $queryData->setQuery('SELECT id, `name`, pass, `key` FROM Account WHERE BIT_LENGTH(pass) > 0'); - return $this->db->doSelect($queryData)->getDataAsArray(); + return $this->db->doSelect($queryData); } } \ No newline at end of file diff --git a/lib/SP/Repositories/Account/AccountToFavoriteRepository.php b/lib/SP/Repositories/Account/AccountToFavoriteRepository.php index 58fdf333..a21ce8d8 100644 --- a/lib/SP/Repositories/Account/AccountToFavoriteRepository.php +++ b/lib/SP/Repositories/Account/AccountToFavoriteRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Account; @@ -46,7 +46,7 @@ final class AccountToFavoriteRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function getForUserId($id) + public function getForUserId(int $id): QueryResult { $queryData = new QueryData(); $queryData->setQuery('SELECT accountId, userId FROM AccountToFavorite WHERE userId = ?'); @@ -66,7 +66,7 @@ final class AccountToFavoriteRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function add($accountId, $userId) + public function add(int $accountId, int $userId): int { $queryData = new QueryData(); $queryData->setQuery('INSERT INTO AccountToFavorite SET accountId = ?, userId = ?'); @@ -86,7 +86,7 @@ final class AccountToFavoriteRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function delete($accountId, $userId) + public function delete(int $accountId, int $userId): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM AccountToFavorite WHERE accountId = ? AND userId = ?'); diff --git a/lib/SP/Repositories/Account/AccountToTagRepository.php b/lib/SP/Repositories/Account/AccountToTagRepository.php index 814015d1..61a8fb41 100644 --- a/lib/SP/Repositories/Account/AccountToTagRepository.php +++ b/lib/SP/Repositories/Account/AccountToTagRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Account; @@ -51,7 +51,7 @@ final class AccountToTagRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function getTagsByAccountId($id) + public function getTagsByAccountId(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT T.id, T.name @@ -74,7 +74,7 @@ final class AccountToTagRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function update(AccountRequest $accountRequest) + public function update(AccountRequest $accountRequest): void { $this->deleteByAccountId($accountRequest->id); $this->add($accountRequest); @@ -89,7 +89,7 @@ final class AccountToTagRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function deleteByAccountId($id) + public function deleteByAccountId(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM AccountToTag WHERE accountId = ?'); @@ -108,7 +108,7 @@ final class AccountToTagRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function add(AccountRequest $accountRequest) + public function add(AccountRequest $accountRequest): int { $query = /** @lang SQL */ 'INSERT INTO AccountToTag (accountId, tagId) VALUES ' . $this->getParamsFromArray($accountRequest->tags, '(?,?)'); diff --git a/lib/SP/Repositories/Account/AccountToUserGroupRepository.php b/lib/SP/Repositories/Account/AccountToUserGroupRepository.php index e0b2de98..c4ab8988 100644 --- a/lib/SP/Repositories/Account/AccountToUserGroupRepository.php +++ b/lib/SP/Repositories/Account/AccountToUserGroupRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Account; @@ -51,7 +51,7 @@ final class AccountToUserGroupRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function getUserGroupsByAccountId($id) + public function getUserGroupsByAccountId(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT UserGroup.id, UserGroup.name, AccountToUserGroup.isEdit @@ -71,13 +71,13 @@ final class AccountToUserGroupRepository extends Repository /** * Obtiene el listado con el nombre de los grupos de una cuenta. * - * @param $id + * @param int $id * * @return QueryResult - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getUserGroupsByUserGroupId($id) + public function getUserGroupsByUserGroupId(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT UserGroup.id, UserGroup.name, AccountToUserGroup.isEdit @@ -101,7 +101,7 @@ final class AccountToUserGroupRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function deleteByUserGroupId($id) + public function deleteByUserGroupId(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM AccountToUserGroup WHERE userGroupId = ?'); @@ -115,11 +115,11 @@ final class AccountToUserGroupRepository extends Repository * @param AccountRequest $accountRequest * @param bool $isEdit * - * @return bool + * @return int * @throws ConstraintException * @throws QueryException */ - public function updateByType(AccountRequest $accountRequest, bool $isEdit) + public function updateByType(AccountRequest $accountRequest, bool $isEdit): int { $this->deleteTypeByAccountId($accountRequest->id, $isEdit); @@ -134,7 +134,7 @@ final class AccountToUserGroupRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function deleteTypeByAccountId($id, bool $isEdit) + public function deleteTypeByAccountId(int $id, bool $isEdit): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM AccountToUserGroup WHERE accountId = ? AND isEdit = ?'); @@ -152,7 +152,7 @@ final class AccountToUserGroupRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function addByType(AccountRequest $accountRequest, bool $isEdit) + public function addByType(AccountRequest $accountRequest, bool $isEdit): int { $items = $isEdit ? $accountRequest->userGroupsEdit : $accountRequest->userGroupsView; $values = $this->getParamsFromArray($items, '(?,?,?)'); @@ -186,7 +186,7 @@ final class AccountToUserGroupRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function deleteByAccountId($id) + public function deleteByAccountId(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM AccountToUserGroup WHERE accountId = ?'); diff --git a/lib/SP/Repositories/Account/AccountToUserRepository.php b/lib/SP/Repositories/Account/AccountToUserRepository.php index 61dac414..01464f96 100644 --- a/lib/SP/Repositories/Account/AccountToUserRepository.php +++ b/lib/SP/Repositories/Account/AccountToUserRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Account; @@ -49,16 +49,14 @@ final class AccountToUserRepository extends Repository * * @param bool $isEdit * - * @return bool - * @throws ConstraintException - * @throws QueryException + * @return void + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function updateByType(AccountRequest $accountRequest, bool $isEdit) + public function updateByType(AccountRequest $accountRequest, bool $isEdit): void { $this->deleteTypeByAccountId($accountRequest->id, $isEdit); $this->addByType($accountRequest, $isEdit); - - return false; } /** @@ -71,7 +69,7 @@ final class AccountToUserRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function deleteTypeByAccountId($id, bool $isEdit) + public function deleteTypeByAccountId(int $id, bool $isEdit): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM AccountToUser WHERE accountId = ? AND isEdit = ?'); @@ -87,11 +85,11 @@ final class AccountToUserRepository extends Repository * @param AccountRequest $accountRequest * @param bool $isEdit * - * @return bool - * @throws ConstraintException - * @throws QueryException + * @return int + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function addByType(AccountRequest $accountRequest, bool $isEdit) + public function addByType(AccountRequest $accountRequest, bool $isEdit): int { $items = $isEdit ? $accountRequest->usersEdit : $accountRequest->usersView; $values = $this->getParamsFromArray($items, '(?,?,?)'); @@ -127,7 +125,7 @@ final class AccountToUserRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function deleteByAccountId($id) + public function deleteByAccountId(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM AccountToUser WHERE accountId = ?'); @@ -146,7 +144,7 @@ final class AccountToUserRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function getUsersByAccountId($id) + public function getUsersByAccountId(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT `User`.id, `User`.name, `User`.login, AccountToUser.isEdit diff --git a/lib/SP/Repositories/AuthToken/AuthTokenRepository.php b/lib/SP/Repositories/AuthToken/AuthTokenRepository.php index a7e06ea2..c33f25e0 100644 --- a/lib/SP/Repositories/AuthToken/AuthTokenRepository.php +++ b/lib/SP/Repositories/AuthToken/AuthTokenRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\AuthToken; @@ -31,7 +31,7 @@ use SP\DataModel\AuthTokenData; use SP\DataModel\ItemSearchData; use SP\Repositories\DuplicatedItemException; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -41,20 +41,20 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\ApiToken */ -final class AuthTokenRepository extends Repository implements RepositoryItemInterface +final class AuthTokenRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; /** * Deletes an item * - * @param $id + * @param int $id * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM AuthToken WHERE id = ? LIMIT 1'); @@ -73,7 +73,7 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT id, @@ -103,7 +103,7 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $query = /** @lang SQL */ 'SELECT id, @@ -131,7 +131,7 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte * * @return void */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { throw new RuntimeException('Not implemented'); } @@ -145,9 +145,9 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -166,7 +166,7 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte * * @return void */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -180,7 +180,7 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setSelect('AuthToken.id, @@ -191,7 +191,7 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte $queryData->setFrom('AuthToken INNER JOIN User ON AuthToken.userid = User.id'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere('User.login LIKE ? OR User.name LIKE ?'); $search = '%' . $itemSearchData->getSeachString() . '%'; @@ -218,7 +218,7 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function create($itemData) + public function create($itemData): int { if ($this->checkDuplicatedOnAdd($itemData)) { throw new DuplicatedItemException(__u('The authorization already exist')); @@ -258,7 +258,7 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { $query = /** @lang SQL */ 'SELECT id FROM AuthToken @@ -279,13 +279,13 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte /** * Obtener el token de la API de un usuario * - * @param $id + * @param int $id * * @return string - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getTokenByUserId($id) + public function getTokenByUserId(int $id): ?string { $queryData = new QueryData(); $queryData->setQuery('SELECT token FROM AuthToken WHERE userId = ? AND token <> \'\' LIMIT 1'); @@ -306,7 +306,7 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function update($itemData) + public function update($itemData): int { if ($this->checkDuplicatedOnUpdate($itemData)) { throw new DuplicatedItemException(__u('The authorization already exist')); @@ -348,7 +348,7 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { $query = /** @lang SQL */ 'SELECT id FROM AuthToken @@ -374,11 +374,11 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte * @param int $id * @param string $token * - * @return bool - * @throws ConstraintException - * @throws QueryException + * @return int + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function refreshTokenByUserId($id, $token) + public function refreshTokenByUserId(int $id, string $token): int { $query = /** @lang SQL */ 'UPDATE AuthToken @@ -397,15 +397,15 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte /** * Regenerar el hash de los tokens de un usuario * - * @param int $id - * @param $vault - * @param $hash + * @param int $id + * @param string $vault + * @param string $hash * - * @return bool - * @throws ConstraintException - * @throws QueryException + * @return int + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function refreshVaultByUserId($id, $vault, $hash) + public function refreshVaultByUserId(int $id, string $vault, string $hash): int { $query = /** @lang SQL */ 'UPDATE AuthToken @@ -431,7 +431,7 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function getUserIdForToken($token) + public function getUserIdForToken(string $token) { $queryData = new QueryData(); $queryData->setQuery('SELECT userId FROM AuthToken WHERE token = ? LIMIT 1'); @@ -452,7 +452,7 @@ final class AuthTokenRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function getTokenByToken($actionId, $token) + public function getTokenByToken(int $actionId, string $token): QueryResult { $query = /** @lang SQL */ 'SELECT id, actionId, userId, vault, `hash`, token diff --git a/lib/SP/Repositories/Category/CategoryRepository.php b/lib/SP/Repositories/Category/CategoryRepository.php index 4727dcbe..7db4b50d 100644 --- a/lib/SP/Repositories/Category/CategoryRepository.php +++ b/lib/SP/Repositories/Category/CategoryRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Category; @@ -32,7 +32,7 @@ use SP\DataModel\CategoryData; use SP\DataModel\ItemSearchData; use SP\Repositories\DuplicatedItemException; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -42,7 +42,7 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\Category */ -final class CategoryRepository extends Repository implements RepositoryItemInterface +final class CategoryRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; @@ -55,10 +55,10 @@ final class CategoryRepository extends Repository implements RepositoryItemInter * @throws SPException * @throws DuplicatedItemException */ - public function create($itemData) + public function create($itemData): int { if ($this->checkDuplicatedOnAdd($itemData)) { - throw new DuplicatedItemException(__u('Duplicated category'), DuplicatedItemException::WARNING); + throw new DuplicatedItemException(__u('Duplicated category'), SPException::WARNING); } $queryData = new QueryData(); @@ -82,7 +82,7 @@ final class CategoryRepository extends Repository implements RepositoryItemInter * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT id FROM Category WHERE `hash` = ? OR `name` = ?'); @@ -104,10 +104,10 @@ final class CategoryRepository extends Repository implements RepositoryItemInter * @throws ConstraintException * @throws QueryException */ - public function update($itemData) + public function update($itemData): int { if ($this->checkDuplicatedOnUpdate($itemData)) { - throw new DuplicatedItemException(__u('Duplicated category name'), DuplicatedItemException::WARNING); + throw new DuplicatedItemException(__u('Duplicated category name'), SPException::WARNING); } $query = /** @lang SQL */ @@ -139,7 +139,7 @@ final class CategoryRepository extends Repository implements RepositoryItemInter * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT id FROM Category WHERE (`hash` = ? OR `name` = ?) AND id <> ?'); @@ -161,7 +161,7 @@ final class CategoryRepository extends Repository implements RepositoryItemInter * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(CategoryData::class); @@ -180,7 +180,7 @@ final class CategoryRepository extends Repository implements RepositoryItemInter * @throws ConstraintException * @throws QueryException */ - public function getByName($name) + public function getByName(string $name): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(CategoryData::class); @@ -200,7 +200,7 @@ final class CategoryRepository extends Repository implements RepositoryItemInter * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(CategoryData::class); @@ -218,9 +218,9 @@ final class CategoryRepository extends Repository implements RepositoryItemInter * @throws ConstraintException * @throws QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { - if (empty($ids)) { + if (count($ids) === 0) { return new QueryResult(); } @@ -244,9 +244,9 @@ final class CategoryRepository extends Repository implements RepositoryItemInter * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -261,13 +261,13 @@ final class CategoryRepository extends Repository implements RepositoryItemInter /** * Deletes an item * - * @param $id + * @param int $id * * @return int * @throws ConstraintException * @throws QueryException */ - public function delete($id) + public function delete(int $id): int { $query = /** @lang SQL */ 'DELETE FROM Category WHERE id = ? LIMIT 1'; @@ -287,7 +287,7 @@ final class CategoryRepository extends Repository implements RepositoryItemInter * * @return void */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -301,14 +301,14 @@ final class CategoryRepository extends Repository implements RepositoryItemInter * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setSelect('id, name, description'); $queryData->setFrom('Category'); $queryData->setOrder('name'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere('name LIKE ? OR description LIKE ?'); $search = '%' . $itemSearchData->getSeachString() . '%'; diff --git a/lib/SP/Repositories/Client/ClientRepository.php b/lib/SP/Repositories/Client/ClientRepository.php index c8b950f3..b47506fb 100644 --- a/lib/SP/Repositories/Client/ClientRepository.php +++ b/lib/SP/Repositories/Client/ClientRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Client; @@ -34,7 +34,7 @@ use SP\DataModel\ItemSearchData; use SP\Mvc\Model\QueryCondition; use SP\Repositories\DuplicatedItemException; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -44,7 +44,7 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\Client */ -final class ClientRepository extends Repository implements RepositoryItemInterface +final class ClientRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; @@ -57,10 +57,10 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa * @throws DuplicatedItemException * @throws SPException */ - public function create($itemData) + public function create($itemData): int { if ($this->checkDuplicatedOnAdd($itemData)) { - throw new DuplicatedItemException(__u('Duplicated client'), DuplicatedItemException::WARNING); + throw new DuplicatedItemException(__u('Duplicated client'), SPException::WARNING); } $query = /** @lang SQL */ @@ -92,7 +92,7 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT id FROM Client WHERE `hash` = ? LIMIT 1'); @@ -111,10 +111,10 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa * @throws QueryException * @throws DuplicatedItemException */ - public function update($itemData) + public function update($itemData): int { if ($this->checkDuplicatedOnUpdate($itemData)) { - throw new DuplicatedItemException(__u('Duplicated client'), DuplicatedItemException::WARNING); + throw new DuplicatedItemException(__u('Duplicated client'), SPException::WARNING); } $query = /** @lang SQL */ @@ -148,7 +148,7 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT id FROM Client WHERE (`hash` = ? OR `name` = ?) AND id <> ?'); @@ -170,7 +170,7 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa * @throws QueryException * @throws ConstraintException */ - public function getById($id) + public function getById(int $id): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(ClientData::class); @@ -189,7 +189,7 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa * @throws QueryException * @throws ConstraintException */ - public function getByName($name) + public function getByName(string $name): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(ClientData::class); @@ -209,7 +209,7 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa * @throws QueryException * @throws ConstraintException */ - public function getAll() + public function getAll(): QueryResult { $queryData = new QueryData(); $queryData->setQuery('SELECT id, `name`, description, isGlobal FROM Client ORDER BY `name`'); @@ -223,14 +223,14 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa * * @param array $ids * - * @return array + * @return QueryResult * @throws QueryException * @throws ConstraintException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { - if (empty($ids)) { - return []; + if (count($ids) === 0) { + return new QueryResult(); } $query = /** @lang SQL */ @@ -241,7 +241,7 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa $queryData->setQuery($query); $queryData->setParams($ids); - return $this->db->doSelect($queryData)->getDataAsArray(); + return $this->db->doSelect($queryData); } /** @@ -253,9 +253,9 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -270,13 +270,13 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa /** * Deletes an item * - * @param $id + * @param int $id * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM Client WHERE id = ? LIMIT 1'); @@ -293,7 +293,7 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa * * @return void */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -307,7 +307,7 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa * @throws QueryException * @throws ConstraintException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(ClientData::class); @@ -315,7 +315,7 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa $queryData->setFrom('Client'); $queryData->setOrder('name'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere('name LIKE ? OR description LIKE ?'); $search = '%' . $itemSearchData->getSeachString() . '%'; @@ -340,7 +340,7 @@ final class ClientRepository extends Repository implements RepositoryItemInterfa * @throws QueryException * @throws ConstraintException */ - public function getAllForFilter(QueryCondition $queryFilter) + public function getAllForFilter(QueryCondition $queryFilter): QueryResult { if (!$queryFilter->hasFilters()) { throw new QueryException(__u('Wrong filter')); diff --git a/lib/SP/Repositories/Config/ConfigRepository.php b/lib/SP/Repositories/Config/ConfigRepository.php index 6878309f..9d109167 100644 --- a/lib/SP/Repositories/Config/ConfigRepository.php +++ b/lib/SP/Repositories/Config/ConfigRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Config; @@ -45,7 +45,7 @@ final class ConfigRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function update(ConfigData $configData) + public function update(ConfigData $configData): bool { $queryData = new QueryData(); $queryData->setQuery('UPDATE Config SET `value` = ? WHERE parameter = ?'); @@ -61,7 +61,7 @@ final class ConfigRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function create(ConfigData $configData) + public function create(ConfigData $configData): int { $queryData = new QueryData(); $queryData->setQuery('INSERT INTO Config SET parameter = ?, `value` = ?'); @@ -77,7 +77,7 @@ final class ConfigRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $queryData = new QueryData(); $queryData->setQuery('SELECT parameter, `value` FROM Config ORDER BY parameter'); @@ -92,7 +92,7 @@ final class ConfigRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function getByParam($param) + public function getByParam(string $param): QueryResult { $queryData = new QueryData(); $queryData->setQuery('SELECT parameter, `value` FROM Config WHERE parameter = ? LIMIT 1'); @@ -108,7 +108,7 @@ final class ConfigRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function has($param) + public function has(string $param): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT parameter FROM Config WHERE parameter = ? LIMIT 1'); @@ -118,13 +118,13 @@ final class ConfigRepository extends Repository } /** - * @param $param + * @param string $param * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function deleteByParam($param) + public function deleteByParam(string $param): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM Config WHERE parameter = ? LIMIT 1'); diff --git a/lib/SP/Repositories/CustomField/CustomFieldDefCollection.php b/lib/SP/Repositories/CustomField/CustomFieldDefCollection.php index f908830d..d65b8849 100644 --- a/lib/SP/Repositories/CustomField/CustomFieldDefCollection.php +++ b/lib/SP/Repositories/CustomField/CustomFieldDefCollection.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\CustomField; diff --git a/lib/SP/Repositories/CustomField/CustomFieldDefRepository.php b/lib/SP/Repositories/CustomField/CustomFieldDefRepository.php index f7b354de..2507397a 100644 --- a/lib/SP/Repositories/CustomField/CustomFieldDefRepository.php +++ b/lib/SP/Repositories/CustomField/CustomFieldDefRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\CustomField; @@ -32,7 +32,7 @@ use SP\DataModel\CustomFieldDefinitionData; use SP\DataModel\ItemSearchData; use SP\Repositories\NoSuchItemException; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -42,24 +42,25 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\CustomField */ -final class CustomFieldDefRepository extends Repository implements RepositoryItemInterface +final class CustomFieldDefRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; + /** * @var CustomFieldDefCollection */ - private $customFieldDefCollection; + private CustomFieldDefCollection $customFieldDefCollection; /** * Creates an item * * @param CustomFieldDefinitionData $itemData * - * @return mixed + * @return int * @throws ConstraintException * @throws QueryException */ - public function create($itemData) + public function create($itemData): int { $query = /** @lang SQL */ 'INSERT INTO CustomFieldDefinition SET `name` = ?, moduleId = ?, required = ?, `help` = ?, showInList = ?, typeId = ?, isEncrypted = ?'; @@ -89,7 +90,7 @@ final class CustomFieldDefRepository extends Repository implements RepositoryIte * @throws ConstraintException * @throws QueryException */ - public function update($itemData) + public function update($itemData): int { if ($this->customFieldDefCollection->exists($itemData->getId())) { $this->customFieldDefCollection->remove($itemData->getId()); @@ -133,7 +134,7 @@ final class CustomFieldDefRepository extends Repository implements RepositoryIte * @throws QueryException * @throws NoSuchItemException */ - public function getById($id) + public function getById(int $id): CustomFieldDefinitionData { if ($this->customFieldDefCollection->exists($id)) { return $this->customFieldDefCollection->get($id); @@ -174,7 +175,7 @@ final class CustomFieldDefRepository extends Repository implements RepositoryIte * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $query = /** @lang SQL */ 'SELECT id, `name`, moduleId, required, `help`, showInList, isEncrypted, typeId @@ -197,9 +198,9 @@ final class CustomFieldDefRepository extends Repository implements RepositoryIte * @throws ConstraintException * @throws QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { - if (empty($ids)) { + if (count($ids) === 0) { return new QueryResult(); } @@ -227,9 +228,9 @@ final class CustomFieldDefRepository extends Repository implements RepositoryIte * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -247,14 +248,13 @@ final class CustomFieldDefRepository extends Repository implements RepositoryIte /** * Deletes an item * - * @param $id + * @param int $id * * @return int - * @throws ConstraintException - * @throws QueryException - * @throws SPException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM CustomFieldDefinition WHERE id = ? LIMIT 1'); @@ -269,7 +269,7 @@ final class CustomFieldDefRepository extends Repository implements RepositoryIte * * @param $id int */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -279,7 +279,7 @@ final class CustomFieldDefRepository extends Repository implements RepositoryIte * * @param mixed $itemData */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -289,7 +289,7 @@ final class CustomFieldDefRepository extends Repository implements RepositoryIte * * @param mixed $itemData */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -303,7 +303,7 @@ final class CustomFieldDefRepository extends Repository implements RepositoryIte * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(CustomFieldDefinitionData::class); @@ -311,7 +311,7 @@ final class CustomFieldDefRepository extends Repository implements RepositoryIte $queryData->setFrom('CustomFieldDefinition CFD INNER JOIN CustomFieldType CFT ON CFD.typeId = CFT.id'); $queryData->setOrder('CFD.moduleId'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere('CFD.name LIKE ? OR CFT.name LIKE ?'); $search = '%' . $itemSearchData->getSeachString() . '%'; @@ -329,12 +329,12 @@ final class CustomFieldDefRepository extends Repository implements RepositoryIte /** * Resets the custom fields collection cache */ - public function resetCollection() + public function resetCollection(): void { $this->customFieldDefCollection->clear(); } - protected function initialize() + protected function initialize(): void { $this->customFieldDefCollection = new CustomFieldDefCollection(); } diff --git a/lib/SP/Repositories/CustomField/CustomFieldRepository.php b/lib/SP/Repositories/CustomField/CustomFieldRepository.php index ead2cc25..a43f3e75 100644 --- a/lib/SP/Repositories/CustomField/CustomFieldRepository.php +++ b/lib/SP/Repositories/CustomField/CustomFieldRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\CustomField; @@ -30,7 +30,7 @@ use SP\Core\Exceptions\QueryException; use SP\DataModel\CustomFieldData; use SP\DataModel\ItemSearchData; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -40,7 +40,7 @@ use SP\Storage\Database\QueryResult; * * @package SP\Services */ -final class CustomFieldRepository extends Repository implements RepositoryItemInterface +final class CustomFieldRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; @@ -49,11 +49,11 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * * @param CustomFieldData $itemData * - * @return bool + * @return int * @throws QueryException * @throws ConstraintException */ - public function update($itemData) + public function update($itemData): int { $query = /** @lang SQL */ 'UPDATE CustomFieldData SET @@ -85,7 +85,7 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * @throws QueryException * @throws ConstraintException */ - public function checkExists($itemData) + public function checkExists(CustomFieldData $itemData): bool { $query = /** @lang SQL */ 'SELECT id @@ -110,9 +110,9 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * * @param $id * - * @return mixed + * @return void */ - public function delete($id) + public function delete($id): void { throw new RuntimeException('Not implemented'); } @@ -126,7 +126,7 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * @throws QueryException * @throws ConstraintException */ - public function create($itemData) + public function create($itemData): int { $query = /** @lang SQL */ 'INSERT INTO CustomFieldData SET itemId = ?, moduleId = ?, definitionId = ?, `data` = ?, `key` = ?'; @@ -154,7 +154,7 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * @throws QueryException * @throws ConstraintException */ - public function deleteCustomFieldData($itemId, $moduleId) + public function deleteCustomFieldData(int $itemId, int $moduleId): int { $query = /** @lang SQL */ 'DELETE FROM CustomFieldData @@ -171,15 +171,19 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn /** * Eliminar los datos de los campos personalizados del módulo * - * @param int $id - * @param int $moduleId - * @param int $definitionId + * @param int $id + * @param int $moduleId + * @param int|null $definitionId * * @return int - * @throws QueryException - * @throws ConstraintException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function deleteCustomFieldDataForDefinition($id, $moduleId, $definitionId) + public function deleteCustomFieldDataForDefinition( + int $id, + int $moduleId, + ?int $definitionId + ): int { $query = /** @lang SQL */ 'DELETE FROM CustomFieldData @@ -203,7 +207,7 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * @throws QueryException * @throws ConstraintException */ - public function deleteCustomFieldDefinitionData($definitionId) + public function deleteCustomFieldDefinitionData(int $definitionId): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM CustomFieldData WHERE definitionId = ?'); @@ -221,9 +225,9 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function deleteCustomFieldDefinitionDataBatch(array $definitionIds) + public function deleteCustomFieldDefinitionDataBatch(array $definitionIds): int { - if (empty($definitionIds)) { + if (count($definitionIds) === 0) { return 0; } @@ -244,9 +248,9 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * @throws QueryException * @throws ConstraintException */ - public function deleteCustomFieldDataBatch(array $ids, $moduleId) + public function deleteCustomFieldDataBatch(array $ids, int $moduleId): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -270,7 +274,7 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * * @return void */ - public function getById($id) + public function getById(int $id): void { throw new RuntimeException('Not implemented'); } @@ -282,7 +286,7 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(CustomFieldData::class); @@ -298,7 +302,7 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * @throws QueryException * @throws ConstraintException */ - public function getAllEncrypted() + public function getAllEncrypted(): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(CustomFieldData::class); @@ -314,7 +318,7 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * * @return void */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { throw new RuntimeException('Not implemented'); } @@ -326,7 +330,7 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * * @return void */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { throw new RuntimeException('Not implemented'); } @@ -338,7 +342,7 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * * @return void */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -346,11 +350,11 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn /** * Searches for items by a given filter * - * @param ItemSearchData $SearchData + * @param ItemSearchData $itemSearchData * - * @return mixed + * @return void */ - public function search(ItemSearchData $SearchData) + public function search(ItemSearchData $itemSearchData): void { throw new RuntimeException('Not implemented'); } @@ -358,14 +362,14 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn /** * Returns the module's item for given id * - * @param $moduleId - * @param $itemId + * @param int $moduleId + * @param int|null $itemId * * @return QueryResult - * @throws QueryException - * @throws ConstraintException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getForModuleAndItemId($moduleId, $itemId) + public function getForModuleAndItemId(int $moduleId, ?int $itemId): QueryResult { $query = /** @lang SQL */ 'SELECT CFD.name AS definitionName, @@ -400,7 +404,7 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * * @return void */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -412,7 +416,7 @@ final class CustomFieldRepository extends Repository implements RepositoryItemIn * * @return void */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { throw new RuntimeException('Not implemented'); } diff --git a/lib/SP/Repositories/CustomField/CustomFieldTypeRepository.php b/lib/SP/Repositories/CustomField/CustomFieldTypeRepository.php index 2af8c653..cb33006b 100644 --- a/lib/SP/Repositories/CustomField/CustomFieldTypeRepository.php +++ b/lib/SP/Repositories/CustomField/CustomFieldTypeRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\CustomField; @@ -31,7 +31,7 @@ use SP\Core\Exceptions\SPException; use SP\DataModel\CustomFieldTypeData; use SP\DataModel\ItemSearchData; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -41,7 +41,7 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\CustomField */ -final class CustomFieldTypeRepository extends Repository implements RepositoryItemInterface +final class CustomFieldTypeRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; @@ -50,12 +50,12 @@ final class CustomFieldTypeRepository extends Repository implements RepositoryIt * * @param CustomFieldTypeData $itemData * - * @return mixed + * @return int * @throws SPException * @throws ConstraintException * @throws QueryException */ - public function create($itemData) + public function create($itemData): int { $queryData = new QueryData(); $queryData->setQuery('INSERT INTO CustomFieldType SET `name` = ?, `text` = ?'); @@ -72,7 +72,7 @@ final class CustomFieldTypeRepository extends Repository implements RepositoryIt * * @return void */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -82,12 +82,12 @@ final class CustomFieldTypeRepository extends Repository implements RepositoryIt * * @param CustomFieldTypeData $itemData * - * @return mixed + * @return int * @throws SPException * @throws ConstraintException * @throws QueryException */ - public function update($itemData) + public function update($itemData): int { $queryData = new QueryData(); $queryData->setQuery('UPDATE CustomFieldType SET `name` = ?, `text` = ? WHERE id = ? LIMIT 1'); @@ -108,7 +108,7 @@ final class CustomFieldTypeRepository extends Repository implements RepositoryIt * * @return void */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -122,7 +122,7 @@ final class CustomFieldTypeRepository extends Repository implements RepositoryIt * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(CustomFieldTypeData::class); @@ -139,7 +139,7 @@ final class CustomFieldTypeRepository extends Repository implements RepositoryIt * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(CustomFieldTypeData::class); @@ -155,7 +155,7 @@ final class CustomFieldTypeRepository extends Repository implements RepositoryIt * * @return void */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { throw new RuntimeException('Not implemented'); } @@ -169,9 +169,9 @@ final class CustomFieldTypeRepository extends Repository implements RepositoryIt * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -188,11 +188,11 @@ final class CustomFieldTypeRepository extends Repository implements RepositoryIt * * @param $id * - * @return bool + * @return int * @throws ConstraintException * @throws QueryException */ - public function delete($id) + public function delete($id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM CustomFieldType WHERE id = ? LIMIT 1'); @@ -209,7 +209,7 @@ final class CustomFieldTypeRepository extends Repository implements RepositoryIt * * @return void */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -217,11 +217,11 @@ final class CustomFieldTypeRepository extends Repository implements RepositoryIt /** * Searches for items by a given filter * - * @param ItemSearchData $SearchData + * @param ItemSearchData $itemSearchData * - * @return mixed + * @return void */ - public function search(ItemSearchData $SearchData) + public function search(ItemSearchData $itemSearchData): void { throw new RuntimeException('Not implemented'); } diff --git a/lib/SP/Repositories/DuplicatedItemException.php b/lib/SP/Repositories/DuplicatedItemException.php index 8bde4a66..94e195d5 100644 --- a/lib/SP/Repositories/DuplicatedItemException.php +++ b/lib/SP/Repositories/DuplicatedItemException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories; diff --git a/lib/SP/Repositories/EventLog/EventlogRepository.php b/lib/SP/Repositories/EventLog/EventlogRepository.php index e55f0797..ec661ec3 100644 --- a/lib/SP/Repositories/EventLog/EventlogRepository.php +++ b/lib/SP/Repositories/EventLog/EventlogRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\EventLog; @@ -46,7 +46,7 @@ final class EventlogRepository extends Repository * @throws QueryException * @throws ConstraintException */ - public function clear() + public function clear(): bool { $queryData = new QueryData(); $queryData->setQuery('TRUNCATE TABLE EventLog'); @@ -64,14 +64,14 @@ final class EventlogRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setSelect('id, FROM_UNIXTIME(date) AS date, action, level, login, ipAddress, description'); $queryData->setFrom('EventLog'); $queryData->setOrder('id DESC'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere('action LIKE ? OR login LIKE ? OR ipAddress LIKE ? OR description LIKE ?'); $search = '%' . $itemSearchData->getSeachString() . '%'; @@ -94,7 +94,7 @@ final class EventlogRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function create(EventlogData $eventlogData) + public function create(EventlogData $eventlogData): int { $sql = 'INSERT INTO EventLog SET `date` = UNIX_TIMESTAMP(), diff --git a/lib/SP/Repositories/ItemPreset/ItemPresetRepository.php b/lib/SP/Repositories/ItemPreset/ItemPresetRepository.php index 4ad3e337..1d8e9de6 100644 --- a/lib/SP/Repositories/ItemPreset/ItemPresetRepository.php +++ b/lib/SP/Repositories/ItemPreset/ItemPresetRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\ItemPreset; @@ -30,7 +30,7 @@ use SP\Core\Exceptions\QueryException; use SP\DataModel\ItemPresetData; use SP\DataModel\ItemSearchData; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -40,7 +40,7 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\Account */ -class ItemPresetRepository extends Repository implements RepositoryItemInterface +class ItemPresetRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; @@ -53,7 +53,7 @@ class ItemPresetRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function create($itemData) + public function create($itemData): int { $queryData = new QueryData(); $queryData->setQuery( @@ -90,7 +90,7 @@ class ItemPresetRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function update($itemData) + public function update($itemData): int { $queryData = new QueryData(); $queryData->setQuery( @@ -123,13 +123,13 @@ class ItemPresetRepository extends Repository implements RepositoryItemInterface /** * Deletes an item * - * @param $id + * @param int $id * * @return int * @throws ConstraintException * @throws QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM ItemPreset WHERE id = ? LIMIT 1'); @@ -148,7 +148,7 @@ class ItemPresetRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(ItemPresetData::class); @@ -172,7 +172,12 @@ class ItemPresetRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function getByFilter(string $type, int $userId, int $userGroupId, int $userProfileId) + public function getByFilter( + string $type, + int $userId, + int $userGroupId, + int $userProfileId + ): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(ItemPresetData::class); @@ -205,7 +210,7 @@ class ItemPresetRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(ItemPresetData::class); @@ -225,9 +230,9 @@ class ItemPresetRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { - if (empty($ids)) { + if (count($ids) === 0) { return new QueryResult(); } @@ -244,15 +249,15 @@ class ItemPresetRepository extends Repository implements RepositoryItemInterface /** * Deletes all the items for given ids * - * @param array $ids + * @param int[] $ids * * @return int * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -269,7 +274,7 @@ class ItemPresetRepository extends Repository implements RepositoryItemInterface * * @param $id int */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -279,7 +284,7 @@ class ItemPresetRepository extends Repository implements RepositoryItemInterface * * @param mixed $itemData */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -289,7 +294,7 @@ class ItemPresetRepository extends Repository implements RepositoryItemInterface * * @param mixed $itemData */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -303,7 +308,7 @@ class ItemPresetRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setSelect( @@ -329,7 +334,7 @@ class ItemPresetRepository extends Repository implements RepositoryItemInterface $queryData->setOrder( 'ItemPreset.type, score DESC'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere( 'ItemPreset.type LIKE ? OR User.name LIKE ? diff --git a/lib/SP/Repositories/NoSuchItemException.php b/lib/SP/Repositories/NoSuchItemException.php index 1b018ec4..b35993e9 100644 --- a/lib/SP/Repositories/NoSuchItemException.php +++ b/lib/SP/Repositories/NoSuchItemException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories; diff --git a/lib/SP/Repositories/Notification/NotificationRepository.php b/lib/SP/Repositories/Notification/NotificationRepository.php index 79fec041..fffe2946 100644 --- a/lib/SP/Repositories/Notification/NotificationRepository.php +++ b/lib/SP/Repositories/Notification/NotificationRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Notification; @@ -31,7 +31,7 @@ use SP\DataModel\ItemSearchData; use SP\DataModel\NotificationData; use SP\Mvc\Model\QueryCondition; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -41,7 +41,7 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\Notification */ -final class NotificationRepository extends Repository implements RepositoryItemInterface +final class NotificationRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; @@ -54,7 +54,7 @@ final class NotificationRepository extends Repository implements RepositoryItemI * @throws ConstraintException * @throws QueryException */ - public function create($itemData) + public function create($itemData): QueryResult { $query = /** @lang SQL */ 'INSERT INTO Notification @@ -91,7 +91,7 @@ final class NotificationRepository extends Repository implements RepositoryItemI * @throws ConstraintException * @throws QueryException */ - public function update($itemData) + public function update($itemData): int { $query = /** @lang SQL */ 'UPDATE Notification @@ -125,13 +125,13 @@ final class NotificationRepository extends Repository implements RepositoryItemI /** * Deletes an item * - * @param $id + * @param int $id * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM Notification WHERE id = ? AND sticky = 0 LIMIT 1'); @@ -144,13 +144,13 @@ final class NotificationRepository extends Repository implements RepositoryItemI /** * Deletes an item * - * @param $id + * @param int $id * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function deleteAdmin($id) + public function deleteAdmin(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM Notification WHERE id = ? LIMIT 1'); @@ -169,9 +169,9 @@ final class NotificationRepository extends Repository implements RepositoryItemI * @throws ConstraintException * @throws QueryException */ - public function deleteAdminBatch(array $ids) + public function deleteAdminBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -192,7 +192,7 @@ final class NotificationRepository extends Repository implements RepositoryItemI * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT id, @@ -223,7 +223,7 @@ final class NotificationRepository extends Repository implements RepositoryItemI * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $query = /** @lang SQL */ 'SELECT id, @@ -255,9 +255,9 @@ final class NotificationRepository extends Repository implements RepositoryItemI * @throws ConstraintException * @throws QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { - if (empty($ids)) { + if (count($ids) === 0) { return new QueryResult(); } @@ -292,9 +292,9 @@ final class NotificationRepository extends Repository implements RepositoryItemI * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -311,7 +311,7 @@ final class NotificationRepository extends Repository implements RepositoryItemI * * @param $id int */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -321,7 +321,7 @@ final class NotificationRepository extends Repository implements RepositoryItemI * * @param mixed $itemData */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -331,7 +331,7 @@ final class NotificationRepository extends Repository implements RepositoryItemI * * @param mixed $itemData */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -345,7 +345,7 @@ final class NotificationRepository extends Repository implements RepositoryItemI * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(NotificationData::class); @@ -380,7 +380,10 @@ final class NotificationRepository extends Repository implements RepositoryItemI * @throws ConstraintException * @throws QueryException */ - public function searchForUserId(ItemSearchData $itemSearchData, int $userId): QueryResult + public function searchForUserId( + ItemSearchData $itemSearchData, + int $userId + ): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(NotificationData::class); @@ -394,7 +397,7 @@ final class NotificationRepository extends Repository implements RepositoryItemI ->addFilter('(userId IS NULL AND onlyAdmin = 0)') ->addFilter('sticky = 1'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere( '(type LIKE ? OR component LIKE ? OR description LIKE ?) AND ' . $queryCondition->getFilters(QueryCondition::CONDITION_OR) @@ -425,7 +428,10 @@ final class NotificationRepository extends Repository implements RepositoryItemI * @throws ConstraintException * @throws QueryException */ - public function searchForAdmin(ItemSearchData $itemSearchData, int $userId) + public function searchForAdmin( + ItemSearchData $itemSearchData, + int $userId + ): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(NotificationData::class); @@ -439,7 +445,7 @@ final class NotificationRepository extends Repository implements RepositoryItemI ->addFilter('onlyAdmin = 1') ->addFilter('sticky = 1'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere( '(type LIKE ? OR component LIKE ? OR description LIKE ?) AND ' . $queryCondition->getFilters(QueryCondition::CONDITION_OR) @@ -464,13 +470,13 @@ final class NotificationRepository extends Repository implements RepositoryItemI /** * Marcar una notificación como leída * - * @param $id + * @param int $id * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function setCheckedById($id) + public function setCheckedById(int $id): int { $query = /** @lang SQL */ 'UPDATE Notification SET checked = 1 WHERE id = ? LIMIT 1'; @@ -486,14 +492,14 @@ final class NotificationRepository extends Repository implements RepositoryItemI /** * Devolver las notificaciones de un usuario para una fecha y componente determinados * - * @param $component - * @param $userId + * @param string $component + * @param int $userId * * @return QueryResult - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getForUserIdByDate($component, $userId) + public function getForUserIdByDate(string $component, int $userId): QueryResult { $query = /** @lang SQL */ 'SELECT id, @@ -521,13 +527,13 @@ final class NotificationRepository extends Repository implements RepositoryItemI } /** - * @param $id + * @param int $id * * @return QueryResult - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getAllForUserId($id) + public function getAllForUserId(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT id, @@ -554,13 +560,13 @@ final class NotificationRepository extends Repository implements RepositoryItemI } /** - * @param $id + * @param int $id * * @return QueryResult - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getAllActiveForUserId($id) + public function getAllActiveForUserId(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT id, @@ -588,13 +594,13 @@ final class NotificationRepository extends Repository implements RepositoryItemI } /** - * @param $id + * @param int $id * * @return QueryResult - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getAllActiveForAdmin($id) + public function getAllActiveForAdmin(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT id, diff --git a/lib/SP/Repositories/Plugin/PluginDataModel.php b/lib/SP/Repositories/Plugin/PluginDataModel.php index 44a2d12f..47be6077 100644 --- a/lib/SP/Repositories/Plugin/PluginDataModel.php +++ b/lib/SP/Repositories/Plugin/PluginDataModel.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Plugin; diff --git a/lib/SP/Repositories/Plugin/PluginDataRepository.php b/lib/SP/Repositories/Plugin/PluginDataRepository.php index c65eb17a..dcd364ad 100644 --- a/lib/SP/Repositories/Plugin/PluginDataRepository.php +++ b/lib/SP/Repositories/Plugin/PluginDataRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,17 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Plugin; -use RuntimeException; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; -use SP\DataModel\ItemSearchData; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -39,7 +36,7 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\Plugin */ -final class PluginDataRepository extends Repository implements RepositoryItemInterface +final class PluginDataRepository extends Repository { use RepositoryItemTrait; @@ -52,7 +49,7 @@ final class PluginDataRepository extends Repository implements RepositoryItemInt * @throws ConstraintException * @throws QueryException */ - public function create($itemData) + public function create(PluginDataModel $itemData): QueryResult { $query = /** @lang SQL */ 'INSERT INTO PluginData SET `name` = ?, itemId = ?, `data` = ?, `key` = ?'; @@ -79,7 +76,7 @@ final class PluginDataRepository extends Repository implements RepositoryItemInt * @throws ConstraintException * @throws QueryException */ - public function update($itemData) + public function update(PluginDataModel $itemData): int { $query = /** @lang SQL */ 'UPDATE PluginData @@ -102,13 +99,13 @@ final class PluginDataRepository extends Repository implements RepositoryItemInt /** * Deletes an item * - * @param $id + * @param string $id * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function delete($id) + public function delete(string $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM PluginData WHERE `name` = ?'); @@ -128,7 +125,7 @@ final class PluginDataRepository extends Repository implements RepositoryItemInt * @throws ConstraintException * @throws QueryException */ - public function deleteByItemId($name, $itemId) + public function deleteByItemId(string $name, int $itemId): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM PluginData WHERE `name` = ? AND itemId = ? LIMIT 1'); @@ -141,13 +138,13 @@ final class PluginDataRepository extends Repository implements RepositoryItemInt /** * Returns the item for given id * - * @param int $id + * @param string $id * * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(string $id): QueryResult { $query = /** @lang SQL */ 'SELECT itemId, @@ -172,7 +169,7 @@ final class PluginDataRepository extends Repository implements RepositoryItemInt * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $query = /** @lang SQL */ 'SELECT itemId, @@ -192,15 +189,15 @@ final class PluginDataRepository extends Repository implements RepositoryItemInt /** * Returns all the items for given ids * - * @param array $ids + * @param string[] $ids * * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { - if (empty($ids)) { + if (count($ids) === 0) { return new QueryResult(); } @@ -224,15 +221,15 @@ final class PluginDataRepository extends Repository implements RepositoryItemInt /** * Deletes all the items for given ids * - * @param array $ids + * @param string[] $ids * * @return int * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -244,54 +241,6 @@ final class PluginDataRepository extends Repository implements RepositoryItemInt return $this->db->doQuery($queryData)->getAffectedNumRows(); } - /** - * Checks whether the item is in use or not - * - * @param $id int - * - * @return void - */ - public function checkInUse($id) - { - throw new RuntimeException('Not implemented'); - } - - /** - * Checks whether the item is duplicated on updating - * - * @param mixed $itemData - * - * @return void - */ - public function checkDuplicatedOnUpdate($itemData) - { - throw new RuntimeException('Not implemented'); - } - - /** - * Checks whether the item is duplicated on adding - * - * @param mixed $itemData - * - * @return void - */ - public function checkDuplicatedOnAdd($itemData) - { - throw new RuntimeException('Not implemented'); - } - - /** - * Searches for items by a given filter - * - * @param ItemSearchData $SearchData - * - * @return mixed - */ - public function search(ItemSearchData $SearchData) - { - throw new RuntimeException('Not implemented'); - } - /** * Devuelve los datos de un plugin por su nombre * @@ -302,7 +251,7 @@ final class PluginDataRepository extends Repository implements RepositoryItemInt * @throws ConstraintException * @throws QueryException */ - public function getByItemId($name, $itemId) + public function getByItemId(string $name, int $itemId): QueryResult { $query = /** @lang SQL */ 'SELECT itemId, diff --git a/lib/SP/Repositories/Plugin/PluginModel.php b/lib/SP/Repositories/Plugin/PluginModel.php index 6873b84a..ce28cfd0 100644 --- a/lib/SP/Repositories/Plugin/PluginModel.php +++ b/lib/SP/Repositories/Plugin/PluginModel.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Plugin; diff --git a/lib/SP/Repositories/Plugin/PluginRepository.php b/lib/SP/Repositories/Plugin/PluginRepository.php index d8534e3d..b2d654f8 100644 --- a/lib/SP/Repositories/Plugin/PluginRepository.php +++ b/lib/SP/Repositories/Plugin/PluginRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Plugin; @@ -31,7 +31,7 @@ use SP\Core\Exceptions\SPException; use SP\DataModel\ItemData; use SP\DataModel\ItemSearchData; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -41,7 +41,7 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\Plugin */ -final class PluginRepository extends Repository implements RepositoryItemInterface +final class PluginRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; @@ -54,7 +54,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa * @throws ConstraintException * @throws QueryException */ - public function create($itemData) + public function create($itemData): QueryResult { $query = /** @lang SQL */ 'INSERT INTO Plugin SET `name` = ?, `data` = ?, enabled = ?, available = ?'; @@ -81,7 +81,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa * @throws ConstraintException * @throws QueryException */ - public function update($itemData) + public function update($itemData): int { $query = /** @lang SQL */ 'UPDATE Plugin @@ -117,7 +117,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT id, @@ -144,7 +144,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $query = /** @lang SQL */ 'SELECT id, @@ -171,9 +171,9 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa * @throws ConstraintException * @throws QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { - if (empty($ids)) { + if (count($ids) === 0) { return new QueryResult(); } @@ -205,9 +205,9 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -222,14 +222,13 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa /** * Deletes an item * - * @param $id + * @param int $id * * @return int - * @throws SPException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM Plugin WHERE id = ? LIMIT 1'); @@ -246,7 +245,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa * * @return void */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -258,7 +257,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa * * @return void */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -270,7 +269,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa * * @return void */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -284,7 +283,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(PluginModel::class); @@ -292,7 +291,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa $queryData->setFrom('Plugin'); $queryData->setOrder('name'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere('name LIKE ?'); $search = '%' . $itemSearchData->getSeachString() . '%'; @@ -316,7 +315,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa * @throws ConstraintException * @throws QueryException */ - public function getByName($name) + public function getByName(string $name): QueryResult { $query = /** @lang SQL */ 'SELECT id, @@ -339,14 +338,14 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa /** * Cambiar el estado del plugin * - * @param $id - * @param $enabled + * @param int $id + * @param bool $enabled * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function toggleEnabled($id, $enabled) + public function toggleEnabled(int $id, bool $enabled): int { $queryData = new QueryData(); $queryData->setQuery('UPDATE Plugin SET enabled = ? WHERE id = ? LIMIT 1'); @@ -359,14 +358,14 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa /** * Cambiar el estado del plugin * - * @param $name - * @param $enabled + * @param string $name + * @param bool $enabled * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function toggleEnabledByName($name, $enabled) + public function toggleEnabledByName(string $name, bool $enabled): int { $queryData = new QueryData(); $queryData->setQuery('UPDATE Plugin SET enabled = ? WHERE name = ? LIMIT 1'); @@ -379,14 +378,14 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa /** * Cambiar el estado del plugin * - * @param $id - * @param $available + * @param int $id + * @param bool $available * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function toggleAvailable($id, $available) + public function toggleAvailable(int $id, bool $available): int { $queryData = new QueryData(); $queryData->setQuery('UPDATE Plugin SET available = ?, enabled = 0 WHERE id = ? LIMIT 1'); @@ -399,14 +398,14 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa /** * Cambiar el estado del plugin * - * @param $name - * @param $available + * @param string $name + * @param bool $available * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function toggleAvailableByName($name, $available) + public function toggleAvailableByName(string $name, bool $available): int { $queryData = new QueryData(); $queryData->setQuery('UPDATE Plugin SET available = ?, enabled = 0 WHERE `name` = ? LIMIT 1'); @@ -425,7 +424,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa * @throws ConstraintException * @throws QueryException */ - public function resetById($id) + public function resetById(int $id): int { $queryData = new QueryData(); $queryData->setQuery('UPDATE Plugin SET `data` = NULL WHERE id = ? LIMIT 1'); @@ -442,7 +441,7 @@ final class PluginRepository extends Repository implements RepositoryItemInterfa * @throws ConstraintException * @throws QueryException */ - public function getEnabled() + public function getEnabled(): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(ItemData::class); diff --git a/lib/SP/Repositories/PublicLink/PublicLinkRepository.php b/lib/SP/Repositories/PublicLink/PublicLinkRepository.php index 00499c5a..95e5bb35 100644 --- a/lib/SP/Repositories/PublicLink/PublicLinkRepository.php +++ b/lib/SP/Repositories/PublicLink/PublicLinkRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\PublicLink; @@ -33,7 +33,7 @@ use SP\DataModel\PublicLinkData; use SP\DataModel\PublicLinkListData; use SP\Repositories\DuplicatedItemException; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -43,20 +43,20 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\PublicLink */ -final class PublicLinkRepository extends Repository implements RepositoryItemInterface +final class PublicLinkRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; /** * Deletes an item * - * @param $id + * @param int $id * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM PublicLink WHERE id = ? LIMIT 1'); @@ -73,7 +73,7 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * @throws QueryException * @throws ConstraintException */ - public function getAll() + public function getAll(): QueryResult { $query = /** @lang SQL */ 'SELECT PL.id, @@ -114,9 +114,9 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * @throws QueryException * @throws ConstraintException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { - if (empty($ids)) { + if (count($ids) === 0) { return new QueryResult(); } @@ -161,9 +161,9 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -181,7 +181,7 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * * @return void */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -195,7 +195,7 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * @throws QueryException * @throws ConstraintException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(PublicLinkListData::class); @@ -223,7 +223,7 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt INNER JOIN Client ON Account.clientId = Client.id'); $queryData->setOrder('PublicLink.dateExpire DESC'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere('User.login LIKE ? OR Account.name LIKE ? OR Client.name LIKE ?'); $search = '%' . $itemSearchData->getSeachString() . '%'; @@ -250,7 +250,7 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * @throws QueryException * @throws ConstraintException */ - public function create($itemData) + public function create($itemData): QueryResult { if ($this->checkDuplicatedOnAdd($itemData)) { throw new DuplicatedItemException(__u('Link already created')); @@ -294,7 +294,7 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT id FROM PublicLink WHERE itemId = ? LIMIT 1'); @@ -310,7 +310,7 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * * @return void */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { throw new RuntimeException('Not implemented'); } @@ -324,7 +324,7 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * @throws ConstraintException * @throws QueryException */ - public function addLinkView(PublicLinkData $publicLinkData) + public function addLinkView(PublicLinkData $publicLinkData): int { $query = /** @lang SQL */ 'UPDATE PublicLink @@ -354,7 +354,7 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * @throws ConstraintException * @throws QueryException */ - public function update($itemData) + public function update($itemData): int { $query = /** @lang SQL */ 'UPDATE PublicLink @@ -402,7 +402,7 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * @throws ConstraintException * @throws QueryException */ - public function refresh(PublicLinkData $publicLinkData) + public function refresh(PublicLinkData $publicLinkData): int { $query = /** @lang SQL */ 'UPDATE PublicLink @@ -436,7 +436,7 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * @throws QueryException * @throws ConstraintException */ - public function getById($id) + public function getById(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT PL.id, @@ -476,7 +476,7 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * @throws ConstraintException * @throws QueryException */ - public function getByHash($hash) + public function getByHash(string $hash): QueryResult { $query = /** @lang SQL */ 'SELECT PL.id, @@ -519,7 +519,7 @@ final class PublicLinkRepository extends Repository implements RepositoryItemInt * @throws ConstraintException * @throws QueryException */ - public function getHashForItem($itemId) + public function getHashForItem(int $itemId): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(PublicLinkData::class); diff --git a/lib/SP/Repositories/Repository.php b/lib/SP/Repositories/Repository.php index bce481e9..7aa2bac5 100644 --- a/lib/SP/Repositories/Repository.php +++ b/lib/SP/Repositories/Repository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories; @@ -34,21 +34,9 @@ use SP\Storage\Database\Database; */ abstract class Repository { - /** - * @var ContextInterface - */ - protected $context; - /** - * @var Database - */ - protected $db; + protected ContextInterface $context; + protected Database $db; - /** - * Repository constructor. - * - * @param Database $database - * @param ContextInterface $session - */ final public function __construct(Database $database, ContextInterface $session) { $this->db = $database; diff --git a/lib/SP/Repositories/RepositoryItemInterface.php b/lib/SP/Repositories/RepositoryInterface.php similarity index 73% rename from lib/SP/Repositories/RepositoryItemInterface.php rename to lib/SP/Repositories/RepositoryInterface.php index b6bb677b..f4fb2998 100644 --- a/lib/SP/Repositories/RepositoryItemInterface.php +++ b/lib/SP/Repositories/RepositoryInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,19 +19,20 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories; use SP\DataModel\ItemSearchData; +use SP\Storage\Database\QueryResult; /** * Interface RepositoryItemInterface * * @package SP\Repositories */ -interface RepositoryItemInterface +interface RepositoryInterface { /** * Creates an item @@ -54,9 +55,9 @@ interface RepositoryItemInterface /** * Deletes an item * - * @param $id + * @param int $id */ - public function delete($id); + public function delete(int $id); /** * Returns the item for given id @@ -65,12 +66,10 @@ interface RepositoryItemInterface * * @return mixed */ - public function getById($id); + public function getById(int $id); /** * Returns all the items - * - * @return array */ public function getAll(); @@ -79,18 +78,18 @@ interface RepositoryItemInterface * * @param array $ids * - * @return array + * @return QueryResult */ - public function getByIdBatch(array $ids); + public function getByIdBatch(array $ids): QueryResult; /** * Deletes all the items for given ids * * @param array $ids * - * @return $this + * @return int */ - public function deleteByIdBatch(array $ids); + public function deleteByIdBatch(array $ids): int; /** * Checks whether the item is in use or not @@ -99,7 +98,7 @@ interface RepositoryItemInterface * * @return bool */ - public function checkInUse($id); + public function checkInUse(int $id): bool; /** * Checks whether the item is duplicated on updating @@ -108,7 +107,7 @@ interface RepositoryItemInterface * * @return bool */ - public function checkDuplicatedOnUpdate($itemData); + public function checkDuplicatedOnUpdate($itemData): bool; /** * Checks whether the item is duplicated on adding @@ -117,14 +116,14 @@ interface RepositoryItemInterface * * @return bool */ - public function checkDuplicatedOnAdd($itemData); + public function checkDuplicatedOnAdd($itemData): bool; /** * Searches for items by a given filter * - * @param ItemSearchData $SearchData + * @param ItemSearchData $itemSearchData * * @return mixed */ - public function search(ItemSearchData $SearchData); + public function search(ItemSearchData $itemSearchData); } \ No newline at end of file diff --git a/lib/SP/Repositories/RepositoryItemTrait.php b/lib/SP/Repositories/RepositoryItemTrait.php index c67e44ca..8b8ecab9 100644 --- a/lib/SP/Repositories/RepositoryItemTrait.php +++ b/lib/SP/Repositories/RepositoryItemTrait.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories; use Exception; +use RuntimeException; use SP\DataModel\DataModelInterface; use SP\Storage\Database\DatabaseUtil; use SP\Storage\Database\DBStorageInterface; @@ -39,14 +40,23 @@ trait RepositoryItemTrait /** * Eliminar elementos en lotes * - * @param $ids + * @param int[] $ids * - * @return array + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function deleteBatch(array $ids) + public function deleteBatch(array $ids): array { - /** @var RepositoryItemInterface $this */ - $items = $this->getByIdBatch($ids); + if (!class_implements($this, RepositoryInterface::class)) { + throw new RuntimeException( + sprintf( + 'This class must implement %s', + RepositoryInterface::class + ) + ); + } + + $items = $this->getByIdBatch($ids)->getDataAsArray(); /** @var DataModelInterface[] $items */ foreach ($items as $key => $item) { @@ -65,31 +75,39 @@ trait RepositoryItemTrait * * Esta función crear un hash para detectar nombres de elementos duplicados mediante * la eliminación de carácteres especiales y capitalización - * - * @param string $name - * @param DBStorageInterface $DBStorage - * - * @return string con el hash generado */ - protected function makeItemHash($name, DBStorageInterface $DBStorage) + protected function makeItemHash( + string $name, + DBStorageInterface $DBStorage + ): string { $charsSrc = ['.', ' ', '_', ', ', '-', ';', '\'', '"', ':', '(', ')', '|', '/']; $databaseUtil = new DatabaseUtil($DBStorage); - return md5(strtolower(str_replace($charsSrc, '', $databaseUtil->escape($name)))); + return md5( + strtolower( + str_replace($charsSrc, '', $databaseUtil->escape($name)) + ) + ); } /** * Devuelve una cadena con los parámetros para una consulta SQL desde un array * * @param array $items - * @param string $string Cadena a utilizar para los parámetros + * @param string $placeholder Cadena a utilizar para los parámetros * * @return string */ - protected function getParamsFromArray(array $items, $string = '?') + protected function getParamsFromArray( + array $items, + string $placeholder = '?' + ): string { - return implode(',', array_fill(0, count($items), $string)); + return implode( + ',', + array_fill(0, count($items), $placeholder) + ); } } \ No newline at end of file diff --git a/lib/SP/Repositories/Tag/TagRepository.php b/lib/SP/Repositories/Tag/TagRepository.php index 4aa4a9e2..78831fe4 100644 --- a/lib/SP/Repositories/Tag/TagRepository.php +++ b/lib/SP/Repositories/Tag/TagRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Tag; @@ -30,7 +30,7 @@ use SP\DataModel\ItemSearchData; use SP\DataModel\TagData; use SP\Repositories\DuplicatedItemException; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -40,7 +40,7 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\Tag */ -final class TagRepository extends Repository implements RepositoryItemInterface +final class TagRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; @@ -54,7 +54,7 @@ final class TagRepository extends Repository implements RepositoryItemInterface * @throws QueryException * @throws DuplicatedItemException */ - public function create($itemData) + public function create($itemData): int { if ($this->checkDuplicatedOnAdd($itemData)) { throw new DuplicatedItemException(__u('Duplicated tag')); @@ -80,7 +80,7 @@ final class TagRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT id FROM Tag WHERE `name` = ? OR `hash` = ?'); @@ -102,7 +102,7 @@ final class TagRepository extends Repository implements RepositoryItemInterface * @throws QueryException * @throws DuplicatedItemException */ - public function update($itemData) + public function update($itemData): int { if ($this->checkDuplicatedOnUpdate($itemData)) { throw new DuplicatedItemException(__u('Duplicated tag')); @@ -129,7 +129,7 @@ final class TagRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT `hash` FROM Tag WHERE (`name` = ? OR `hash` = ?) AND id <> ?'); @@ -151,7 +151,7 @@ final class TagRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(TagData::class); @@ -170,7 +170,7 @@ final class TagRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function getByName($name) + public function getByName(string $name): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(TagData::class); @@ -187,7 +187,7 @@ final class TagRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): array { $queryData = new QueryData(); $queryData->setMapClassName(TagData::class); @@ -201,14 +201,14 @@ final class TagRepository extends Repository implements RepositoryItemInterface * * @param array $ids * - * @return TagData[] - * @throws ConstraintException - * @throws QueryException + * @return \SP\Storage\Database\QueryResult + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { - if (empty($ids)) { - return []; + if (count($ids) === 0) { + return new QueryResult(); } $query = /** @lang SQL */ @@ -219,7 +219,7 @@ final class TagRepository extends Repository implements RepositoryItemInterface $queryData->setQuery($query); $queryData->setParams($ids); - return $this->db->doSelect($queryData)->getDataAsArray(); + return $this->db->doSelect($queryData); } /** @@ -231,9 +231,9 @@ final class TagRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -248,13 +248,13 @@ final class TagRepository extends Repository implements RepositoryItemInterface /** * Deletes an item * - * @param $id + * @param int $id * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM Tag WHERE id = ? LIMIT 1'); @@ -273,7 +273,7 @@ final class TagRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function checkInUse($id) + public function checkInUse(int $id): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT tagId FROM AccountToTag WHERE tagId = ?'); @@ -291,7 +291,7 @@ final class TagRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setSelect('id, name'); diff --git a/lib/SP/Repositories/Track/TrackRepository.php b/lib/SP/Repositories/Track/TrackRepository.php index 7357fec2..1ffe5d98 100644 --- a/lib/SP/Repositories/Track/TrackRepository.php +++ b/lib/SP/Repositories/Track/TrackRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Track; @@ -47,7 +47,7 @@ final class TrackRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function add(TrackRequest $trackRequest) + public function add(TrackRequest $trackRequest): int { $query = /** @lang SQL */ 'INSERT INTO Track SET @@ -77,7 +77,7 @@ final class TrackRepository extends Repository * @throws QueryException * @throws ConstraintException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM Track WHERE id = ? LIMIT 1'); @@ -94,7 +94,7 @@ final class TrackRepository extends Repository * @throws QueryException * @throws ConstraintException */ - public function unlock($id) + public function unlock(int $id): int { $queryData = new QueryData(); $queryData->setQuery('UPDATE Track SET timeUnlock = UNIX_TIMESTAMP() WHERE id = ?'); @@ -111,7 +111,7 @@ final class TrackRepository extends Repository * @throws QueryException * @throws ConstraintException */ - public function clear() + public function clear(): bool { $queryData = new QueryData(); $queryData->setQuery('TRUNCATE TABLE Track'); @@ -127,7 +127,7 @@ final class TrackRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT id, @@ -153,7 +153,7 @@ final class TrackRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $query = /** @lang SQL */ 'SELECT id, @@ -180,7 +180,7 @@ final class TrackRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function getTracksForClientFromTime(TrackRequest $trackRequest) + public function getTracksForClientFromTime(TrackRequest $trackRequest): QueryResult { $query = /** @lang SQL */ 'SELECT id, userId @@ -213,7 +213,7 @@ final class TrackRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setSelect(' diff --git a/lib/SP/Repositories/Track/TrackRequest.php b/lib/SP/Repositories/Track/TrackRequest.php index 29d86dc0..b1454734 100644 --- a/lib/SP/Repositories/Track/TrackRequest.php +++ b/lib/SP/Repositories/Track/TrackRequest.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\Track; @@ -34,33 +34,30 @@ use SP\Http\Address; */ final class TrackRequest { + public int $time; + public string $source; + public ?int $userId = null; + private ?string $ipv6 = null; + private ?string $ipv4 = null; + /** - * @var int + * @param int $time + * @param string $source + * @param int|null $userId */ - public $time; - /** - * @var string - */ - public $source; - /** - * @var int - */ - public $userId; - /** - * @var string - */ - protected $ipv6; - /** - * @var string - */ - protected $ipv4; + public function __construct(int $time, string $source, ?int $userId = null) + { + $this->time = $time; + $this->source = $source; + $this->userId = $userId; + } /** * @param string $address * * @throws InvalidArgumentException */ - public function setTrackIp($address) + public function setTrackIp(string $address): void { $binary = Address::toBinary($address); $length = strlen($binary); @@ -75,7 +72,7 @@ final class TrackRequest /** * @return string */ - public function getIpv6() + public function getIpv6(): ?string { return $this->ipv6; } @@ -83,7 +80,7 @@ final class TrackRequest /** * @return string */ - public function getIpv4() + public function getIpv4(): ?string { return $this->ipv4; } diff --git a/lib/SP/Repositories/User/UserPassRecoverRepository.php b/lib/SP/Repositories/User/UserPassRecoverRepository.php index c25a10af..38844476 100644 --- a/lib/SP/Repositories/User/UserPassRecoverRepository.php +++ b/lib/SP/Repositories/User/UserPassRecoverRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\User; @@ -48,7 +48,7 @@ final class UserPassRecoverRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function getAttemptsByUserId($userId, $time) + public function getAttemptsByUserId(int $userId, int $time): int { $query = /** @lang SQL */ 'SELECT userId @@ -59,7 +59,7 @@ final class UserPassRecoverRepository extends Repository $queryData = new QueryData(); $queryData->setQuery($query); - $queryData->setParams([(int)$userId, (int)$time]); + $queryData->setParams([$userId, $time]); return $this->db->doSelect($queryData)->getNumRows(); } @@ -74,7 +74,7 @@ final class UserPassRecoverRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function add($userId, $hash) + public function add(int $userId, string $hash): int { $query = /** @lang SQL */ 'INSERT INTO UserPassRecover SET @@ -100,7 +100,7 @@ final class UserPassRecoverRepository extends Repository * @return int * @throws SPException */ - public function toggleUsedByHash($hash, $time) + public function toggleUsedByHash(string $hash, int $time): int { $query = /** @lang SQL */ 'UPDATE UserPassRecover SET used = 1 @@ -111,7 +111,7 @@ final class UserPassRecoverRepository extends Repository $queryData = new QueryData(); $queryData->setQuery($query); - $queryData->setParams([$hash, (int)$time]); + $queryData->setParams([$hash, $time]); $queryData->setOnErrorMessage(__u('Error while checking hash')); return $this->db->doQuery($queryData)->getAffectedNumRows(); @@ -120,14 +120,14 @@ final class UserPassRecoverRepository extends Repository /** * Comprobar el hash de recuperación de clave. * - * @param $hash - * @param $time + * @param string $hash + * @param int $time * * @return QueryResult - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getUserIdForHash($hash, $time) + public function getUserIdForHash(string $hash, int $time): QueryResult { $query = /** @lang SQL */ 'SELECT userId @@ -139,7 +139,7 @@ final class UserPassRecoverRepository extends Repository $queryData = new QueryData(); $queryData->setQuery($query); - $queryData->setParams([$hash, (int)$time]); + $queryData->setParams([$hash, $time]); return $this->db->doSelect($queryData); } diff --git a/lib/SP/Repositories/User/UserRepository.php b/lib/SP/Repositories/User/UserRepository.php index a0729ce1..768a72e9 100644 --- a/lib/SP/Repositories/User/UserRepository.php +++ b/lib/SP/Repositories/User/UserRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\User; @@ -33,7 +33,7 @@ use SP\DataModel\UserData; use SP\DataModel\UserPreferencesData; use SP\Repositories\DuplicatedItemException; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Services\User\UpdatePassRequest; use SP\Storage\Database\QueryData; @@ -44,7 +44,7 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\User */ -final class UserRepository extends Repository implements RepositoryItemInterface +final class UserRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; @@ -58,7 +58,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws QueryException * @throws DuplicatedItemException */ - public function update($itemData) + public function update($itemData): int { if ($this->checkDuplicatedOnUpdate($itemData)) { throw new DuplicatedItemException(__u('Duplicated user login/email')); @@ -112,7 +112,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { $query = /** @lang SQL */ 'SELECT id @@ -143,7 +143,10 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function updatePassById($id, UpdatePassRequest $passRequest) + public function updatePassById( + int $id, + UpdatePassRequest $passRequest + ): int { $query = /** @lang SQL */ 'UPDATE User SET @@ -159,8 +162,8 @@ final class UserRepository extends Repository implements RepositoryItemInterface $queryData->setQuery($query); $queryData->setParams([ $passRequest->getPass(), - $passRequest->getisChangePass(), - $passRequest->getisChangedPass(), + (int)$passRequest->getisChangePass(), + (int)$passRequest->getisChangedPass(), $id ]); $queryData->setOnErrorMessage(__u('Error while updating the password')); @@ -171,13 +174,13 @@ final class UserRepository extends Repository implements RepositoryItemInterface /** * Deletes an item * - * @param $id + * @param int $id * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM User WHERE id = ? LIMIT 1'); @@ -196,7 +199,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws QueryException * @throws ConstraintException */ - public function getById($id) + public function getById(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT U.id, @@ -244,7 +247,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws QueryException * @throws ConstraintException */ - public function getAll() + public function getAll(): array { $query = /** @lang SQL */ 'SELECT U.id, @@ -285,14 +288,14 @@ final class UserRepository extends Repository implements RepositoryItemInterface * * @param array $ids * - * @return UserData[] - * @throws QueryException - * @throws ConstraintException + * @return \SP\Storage\Database\QueryResult + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { - if (empty($ids)) { - return []; + if (count($ids) === 0) { + return new QueryResult(); } $query = /** @lang SQL */ @@ -330,7 +333,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface $queryData->setQuery($query); $queryData->setParams($ids); - return $this->db->doSelect($queryData)->getDataAsArray(); + return $this->db->doSelect($queryData); } /** @@ -342,9 +345,9 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -363,7 +366,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * * @return void */ - public function checkInUse($id) + public function checkInUse(int $id): bool { throw new RuntimeException('Not implemented'); } @@ -377,7 +380,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws QueryException * @throws ConstraintException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setSelect('User.id, @@ -395,8 +398,10 @@ final class UserRepository extends Repository implements RepositoryItemInterface INNER JOIN UserGroup ON User.userGroupId = UserGroup.id'); $queryData->setOrder('User.name'); - if ($itemSearchData->getSeachString() !== '') { - if ($this->context->getUserData()->getIsAdminApp()) { + $isAdminApp = $this->context->getUserData()->getIsAdminApp(); + + if (!empty($itemSearchData->getSeachString())) { + if ($isAdminApp) { $queryData->setWhere('User.name LIKE ? OR User.login LIKE ?'); } else { $queryData->setWhere('User.name LIKE ? OR User.login LIKE ? AND User.isAdminApp = 0'); @@ -405,7 +410,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface $search = '%' . $itemSearchData->getSeachString() . '%'; $queryData->addParam($search); $queryData->addParam($search); - } elseif (!$this->context->getUserData()->getIsAdminApp()) { + } elseif (!$isAdminApp) { $queryData->setWhere('User.isAdminApp = 0'); } @@ -425,7 +430,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @return int * @throws SPException */ - public function create($itemData) + public function create($itemData): int { if ($this->checkDuplicatedOnAdd($itemData)) { throw new DuplicatedItemException(__u('Duplicated user login/email')); @@ -486,7 +491,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { $query = /** @lang SQL */ 'SELECT id @@ -513,7 +518,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function getByLogin($login) + public function getByLogin(string $login): QueryResult { $query = /** @lang SQL */ 'SELECT U.id, @@ -561,7 +566,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function getBasicInfo() + public function getBasicInfo(): QueryResult { $query = /** @lang SQL */ 'SELECT U.id, @@ -586,15 +591,19 @@ final class UserRepository extends Repository implements RepositoryItemInterface /** * Updates user's master password * - * @param $id - * @param $pass - * @param $key + * @param int $id + * @param string $pass + * @param string $key * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function updateMasterPassById($id, $pass, $key) + public function updateMasterPassById( + int $id, + string $pass, + string $key + ): int { $query = /** @lang SQL */ 'UPDATE User SET @@ -621,7 +630,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws QueryException * @throws ConstraintException */ - public function updateLastLoginById($id) + public function updateLastLoginById(int $id): int { $queryData = new QueryData(); $queryData->setQuery('UPDATE User SET lastLogin = NOW(), loginCount = loginCount + 1 WHERE id = ? LIMIT 1'); @@ -631,13 +640,13 @@ final class UserRepository extends Repository implements RepositoryItemInterface } /** - * @param $login + * @param string $login * * @return bool - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function checkExistsByLogin($login) + public function checkExistsByLogin(string $login): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT id FROM User WHERE UPPER(login) = UPPER(?) OR UPPER(ssoLogin) = UPPER(?) LIMIT 1'); @@ -653,7 +662,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function updateOnLogin(UserData $itemData) + public function updateOnLogin(UserData $itemData): int { $query = 'UPDATE User SET pass = ?, @@ -690,7 +699,10 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function updatePreferencesById($id, UserPreferencesData $userPreferencesData) + public function updatePreferencesById( + int $id, + UserPreferencesData $userPreferencesData + ): int { $queryData = new QueryData(); $queryData->setQuery('UPDATE User SET preferences = ? WHERE id = ? LIMIT 1'); @@ -703,13 +715,13 @@ final class UserRepository extends Repository implements RepositoryItemInterface /** * Obtener el email de los usuarios de un grupo * - * @param $groupId + * @param int $groupId * * @return QueryResult - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getUserEmailForGroup($groupId) + public function getUserEmailForGroup(int $groupId): QueryResult { $query = /** @lang SQL */ 'SELECT U.id, U.login, U.name, U.email @@ -737,7 +749,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * * @TODO create unit test */ - public function getUserEmail() + public function getUserEmail(): QueryResult { $query = /** @lang SQL */ 'SELECT id, login, `name`, email @@ -755,14 +767,14 @@ final class UserRepository extends Repository implements RepositoryItemInterface /** * Return the email of the given user's id * - * @param array $ids + * @param int[] $ids * * @return QueryResult * @throws ConstraintException * @throws QueryException * @TODO create unit test */ - public function getUserEmailById(array $ids) + public function getUserEmailById(array $ids): QueryResult { $query = /** @lang SQL */ 'SELECT id, login, `name`, email @@ -788,7 +800,7 @@ final class UserRepository extends Repository implements RepositoryItemInterface * @throws ConstraintException * @throws QueryException */ - public function getUsageForUser($id) + public function getUsageForUser(int $id): QueryResult { $query = 'SELECT * FROM (SELECT A.id, diff --git a/lib/SP/Repositories/UserGroup/UserGroupRepository.php b/lib/SP/Repositories/UserGroup/UserGroupRepository.php index 1262db40..d8c384d8 100644 --- a/lib/SP/Repositories/UserGroup/UserGroupRepository.php +++ b/lib/SP/Repositories/UserGroup/UserGroupRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\UserGroup; @@ -31,7 +31,7 @@ use SP\DataModel\ItemSearchData; use SP\DataModel\UserGroupData; use SP\Repositories\DuplicatedItemException; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -41,20 +41,20 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\UserGroup */ -final class UserGroupRepository extends Repository implements RepositoryItemInterface +final class UserGroupRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; /** * Deletes an item * - * @param $id + * @param int $id * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM UserGroup WHERE id = ? LIMIT 1'); @@ -73,7 +73,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function checkInUse($id) + public function checkInUse(int $id): bool { $query = /** @lang SQL */ 'SELECT userGroupId @@ -84,7 +84,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte $queryData = new QueryData(); $queryData->setQuery($query); - $queryData->setParams([(int)$id, (int)$id]); + $queryData->setParams([$id, $id]); return $this->db->doSelect($queryData)->getNumRows() > 0; } @@ -98,7 +98,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function getUsage($id) + public function getUsage(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT userGroupId, "User" AS ref @@ -129,7 +129,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function getUsageByUsers($id) + public function getUsageByUsers(int $id): QueryResult { $query = /** @lang SQL */ 'SELECT U.id, login, `name`, ref @@ -150,7 +150,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte $queryData = new QueryData(); $queryData->setQuery($query); - $queryData->addParams([(int)$id, (int)$id]); + $queryData->addParams([$id, $id]); return $this->db->doSelect($queryData); } @@ -164,7 +164,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(UserGroupData::class); @@ -183,7 +183,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function getByName($name) + public function getByName(string $name): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(UserGroupData::class); @@ -200,7 +200,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(UserGroupData::class); @@ -214,14 +214,14 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte * * @param array $ids * - * @return UserGroupData[] - * @throws ConstraintException - * @throws QueryException + * @return \SP\Storage\Database\QueryResult + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { - if (empty($ids)) { - return []; + if (count($ids) === 0) { + return new QueryResult(); } $query = /** @lang SQL */ @@ -232,21 +232,21 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte $queryData->setQuery($query); $queryData->setParams($ids); - return $this->db->doSelect($queryData)->getDataAsArray(); + return $this->db->doSelect($queryData); } /** * Deletes all the items for given ids * - * @param array $ids + * @param int[] $ids * * @return int * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -266,7 +266,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(UserGroupData::class); @@ -274,7 +274,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte $queryData->setFrom('UserGroup'); $queryData->setOrder('name'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere('name LIKE ? OR description LIKE ?'); $search = '%' . $itemSearchData->getSeachString() . '%'; @@ -300,7 +300,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function create($itemData) + public function create($itemData): int { if ($this->checkDuplicatedOnAdd($itemData)) { throw new DuplicatedItemException(__u('Duplicated group name')); @@ -326,7 +326,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT `name` FROM UserGroup WHERE UPPER(`name`) = UPPER(?)'); @@ -345,7 +345,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte * @throws QueryException * @throws DuplicatedItemException */ - public function update($itemData) + public function update($itemData): int { if ($this->checkDuplicatedOnUpdate($itemData)) { throw new DuplicatedItemException(__u('Duplicated group name')); @@ -372,7 +372,7 @@ final class UserGroupRepository extends Repository implements RepositoryItemInte * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT `name` FROM UserGroup WHERE UPPER(`name`) = UPPER(?) AND id <> ?'); diff --git a/lib/SP/Repositories/UserGroup/UserToUserGroupRepository.php b/lib/SP/Repositories/UserGroup/UserToUserGroupRepository.php index 969178e7..d2180881 100644 --- a/lib/SP/Repositories/UserGroup/UserToUserGroupRepository.php +++ b/lib/SP/Repositories/UserGroup/UserToUserGroupRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\UserGroup; @@ -44,14 +44,14 @@ final class UserToUserGroupRepository extends Repository /** * Checks whether the user is included in the group * - * @param $groupId - * @param $userId + * @param int $groupId + * @param int $userId * * @return bool * @throws ConstraintException * @throws QueryException */ - public function checkUserInGroup($groupId, $userId) + public function checkUserInGroup(int $groupId, int $userId): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = ? AND userId = ?'); @@ -63,13 +63,13 @@ final class UserToUserGroupRepository extends Repository /** * Returns the groups which the user belongs to * - * @param $userId + * @param int $userId * * @return QueryResult - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getGroupsForUser($userId) + public function getGroupsForUser(int $userId): QueryResult { $queryData = new QueryData(); $queryData->setQuery('SELECT userGroupId FROM UserToUserGroup WHERE userId = ?'); @@ -88,7 +88,7 @@ final class UserToUserGroupRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function update($id, array $users) + public function update(int $id, array $users): int { $this->delete($id); return $this->add($id, $users); @@ -103,7 +103,7 @@ final class UserToUserGroupRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM UserToUserGroup WHERE userGroupId = ?'); @@ -123,9 +123,9 @@ final class UserToUserGroupRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function add($groupId, array $users) + public function add(int $groupId, array $users): int { - if (empty($users)) { + if (count($users) === 0) { return 0; } @@ -154,7 +154,7 @@ final class UserToUserGroupRepository extends Repository * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(UserToUserGroupData::class); diff --git a/lib/SP/Repositories/UserProfile/UserProfileRepository.php b/lib/SP/Repositories/UserProfile/UserProfileRepository.php index 57e201aa..180c32fc 100644 --- a/lib/SP/Repositories/UserProfile/UserProfileRepository.php +++ b/lib/SP/Repositories/UserProfile/UserProfileRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Repositories\UserProfile; @@ -30,7 +30,7 @@ use SP\DataModel\ItemSearchData; use SP\DataModel\UserProfileData; use SP\Repositories\DuplicatedItemException; use SP\Repositories\Repository; -use SP\Repositories\RepositoryItemInterface; +use SP\Repositories\RepositoryInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; use SP\Storage\Database\QueryResult; @@ -40,7 +40,7 @@ use SP\Storage\Database\QueryResult; * * @package SP\Repositories\UserProfile */ -final class UserProfileRepository extends Repository implements RepositoryItemInterface +final class UserProfileRepository extends Repository implements RepositoryInterface { use RepositoryItemTrait; @@ -53,7 +53,7 @@ final class UserProfileRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function getUsersForProfile($id) + public function getUsersForProfile(int $id): QueryResult { $queryData = new QueryData(); $queryData->setQuery('SELECT id, login FROM User WHERE userProfileId = ?'); @@ -65,13 +65,13 @@ final class UserProfileRepository extends Repository implements RepositoryItemIn /** * Deletes an item * - * @param $id + * @param int $id * * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function delete($id) + public function delete(int $id): int { $queryData = new QueryData(); $queryData->setQuery('DELETE FROM UserProfile WHERE id = ? LIMIT 1'); @@ -90,7 +90,7 @@ final class UserProfileRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function checkInUse($id) + public function checkInUse(int $id): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT userProfileId FROM User WHERE userProfileId = ?'); @@ -108,7 +108,7 @@ final class UserProfileRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(UserProfileData::class); @@ -125,7 +125,7 @@ final class UserProfileRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): QueryResult { $queryData = new QueryData(); $queryData->setMapClassName(UserProfileData::class); @@ -139,14 +139,14 @@ final class UserProfileRepository extends Repository implements RepositoryItemIn * * @param array $ids * - * @return UserProfileData[] - * @throws ConstraintException - * @throws QueryException + * @return \SP\Storage\Database\QueryResult + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): QueryResult { - if (empty($ids)) { - return []; + if (count($ids) === 0) { + return new QueryResult(); } $query = /** @lang SQL */ @@ -157,21 +157,21 @@ final class UserProfileRepository extends Repository implements RepositoryItemIn $queryData->setQuery($query); $queryData->setParams($ids); - return $this->db->doSelect($queryData)->getDataAsArray(); + return $this->db->doSelect($queryData); } /** * Deletes all the items for given ids * - * @param array $ids + * @param int[] $ids * * @return int * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (empty($ids)) { + if (count($ids) === 0) { return 0; } @@ -192,14 +192,14 @@ final class UserProfileRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $queryData = new QueryData(); $queryData->setSelect('id, name'); $queryData->setFrom('UserProfile'); $queryData->setOrder('name'); - if ($itemSearchData->getSeachString() !== '') { + if (!empty($itemSearchData->getSeachString())) { $queryData->setWhere('name LIKE ?'); $search = '%' . $itemSearchData->getSeachString() . '%'; @@ -224,7 +224,7 @@ final class UserProfileRepository extends Repository implements RepositoryItemIn * @throws QueryException * @throws DuplicatedItemException */ - public function create($itemData) + public function create($itemData): int { if ($this->checkDuplicatedOnAdd($itemData)) { throw new DuplicatedItemException(__u('Duplicated profile name')); @@ -250,7 +250,7 @@ final class UserProfileRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnAdd($itemData) + public function checkDuplicatedOnAdd($itemData): bool { $queryData = new QueryData(); $queryData->setQuery('SELECT `name` FROM UserProfile WHERE UPPER(`name`) = ?'); @@ -264,12 +264,12 @@ final class UserProfileRepository extends Repository implements RepositoryItemIn * * @param UserProfileData $itemData * - * @return bool - * @throws ConstraintException - * @throws QueryException - * @throws DuplicatedItemException + * @return int + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\DuplicatedItemException */ - public function update($itemData) + public function update($itemData): int { if ($this->checkDuplicatedOnUpdate($itemData)) { throw new DuplicatedItemException(__u('Duplicated profile name')); @@ -299,7 +299,7 @@ final class UserProfileRepository extends Repository implements RepositoryItemIn * @throws ConstraintException * @throws QueryException */ - public function checkDuplicatedOnUpdate($itemData) + public function checkDuplicatedOnUpdate($itemData): bool { $query = /** @lang SQL */ 'SELECT `name` diff --git a/lib/SP/Services/Account/AccountAcl.php b/lib/SP/Services/Account/AccountAcl.php index f31f5743..1769c8fb 100644 --- a/lib/SP/Services/Account/AccountAcl.php +++ b/lib/SP/Services/Account/AccountAcl.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,146 +19,57 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; -use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; /** * Class AccountAcl * - * @package SP\Account + * @package SP\Services\Account */ final class AccountAcl { - /** - * @var bool - */ - private $userInGroups = false; - /** - * @var bool - */ - private $userInUsers = false; - /** - * @var bool - */ - private $resultView = false; - /** - * @var bool - */ - private $resultEdit = false; - /** - * @var bool - */ - private $modified = false; - /** - * @var bool - */ - private $showView = false; - /** - * @var bool - */ - private $showHistory = false; - /** - * @var bool - */ - private $showDetails = false; - /** - * @var bool - */ - private $showPass = false; - /** - * @var bool - */ - private $showFiles = false; - /** - * @var bool - */ - private $showViewPass = false; - /** - * @var bool - */ - private $showSave = false; - /** - * @var bool - */ - private $showEdit = false; - /** - * @var bool - */ - private $showEditPass = false; - /** - * @var bool - */ - private $showDelete = false; - /** - * @var bool - */ - private $showRestore = false; - /** - * @var bool - */ - private $showLink = false; - /** - * @var bool - */ - private $showCopy = false; - /** - * @var bool - */ - private $showPermission = false; - /** - * @var bool - */ - private $compiledAccountAccess = false; - /** - * @var bool - */ - private $compiledShowAccess = false; - /** - * @var int - */ - private $accountId; - /** - * @var int - */ - private $actionId; - /** - * @var int - */ - private $time = 0; - /** - * @var bool - */ - private $isHistory; + private bool $userInGroups = false; + private bool $userInUsers = false; + private bool $resultView = false; + private bool $resultEdit = false; + private bool $modified = false; + private bool $showView = false; + private bool $showHistory = false; + private bool $showDetails = false; + private bool $showPass = false; + private bool $showFiles = false; + private bool $showViewPass = false; + private bool $showSave = false; + private bool $showEdit = false; + private bool $showEditPass = false; + private bool $showDelete = false; + private bool $showRestore = false; + private bool $showLink = false; + private bool $showCopy = false; + private bool $showPermission = false; + private bool $compiledAccountAccess = false; + private bool $compiledShowAccess = false; + private ?int $accountId = null; + private int $actionId; + private int $time = 0; + private bool $isHistory; - /** - * AccountAcl constructor. - * - * @param int $actionId - * @param bool $isHistory - */ - public function __construct($actionId, $isHistory = false) + public function __construct(int $actionId, bool $isHistory = false) { - $this->actionId = (int)$actionId; + $this->actionId = $actionId; $this->isHistory = $isHistory; } - /** - * @return bool - */ public function isUserInGroups(): bool { return $this->userInGroups; } - /** - * @param bool $userInGroups - * - * @return AccountAcl - */ public function setUserInGroups(bool $userInGroups): AccountAcl { $this->userInGroups = $userInGroups; @@ -166,19 +77,11 @@ final class AccountAcl return $this; } - /** - * @return bool - */ public function isUserInUsers(): bool { return $this->userInUsers; } - /** - * @param bool $userInUsers - * - * @return AccountAcl - */ public function setUserInUsers(bool $userInUsers): AccountAcl { $this->userInUsers = $userInUsers; @@ -186,19 +89,11 @@ final class AccountAcl return $this; } - /** - * @return bool - */ public function isResultView(): bool { return $this->resultView; } - /** - * @param bool $resultView - * - * @return AccountAcl - */ public function setResultView(bool $resultView): AccountAcl { $this->resultView = $resultView; @@ -206,19 +101,11 @@ final class AccountAcl return $this; } - /** - * @return bool - */ public function isResultEdit(): bool { return $this->resultEdit; } - /** - * @param bool $resultEdit - * - * @return AccountAcl - */ public function setResultEdit(bool $resultEdit): AccountAcl { $this->resultEdit = $resultEdit; @@ -226,21 +113,14 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowDetails(): bool { - return $this->resultView && ($this->actionId === Acl::ACCOUNT_VIEW - || $this->actionId === Acl::ACCOUNT_HISTORY_VIEW - || $this->actionId === Acl::ACCOUNT_DELETE); + return $this->resultView + && ($this->actionId === ActionsInterface::ACCOUNT_VIEW + || $this->actionId === ActionsInterface::ACCOUNT_HISTORY_VIEW + || $this->actionId === ActionsInterface::ACCOUNT_DELETE); } - /** - * @param bool $showDetails - * - * @return AccountAcl - */ public function setShowDetails(bool $showDetails): AccountAcl { $this->showDetails = $showDetails; @@ -248,20 +128,12 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowPass(): bool { - return ($this->actionId === Acl::ACCOUNT_CREATE - || $this->actionId === Acl::ACCOUNT_COPY); + return ($this->actionId === ActionsInterface::ACCOUNT_CREATE + || $this->actionId === ActionsInterface::ACCOUNT_COPY); } - /** - * @param bool $showPass - * - * @return AccountAcl - */ public function setShowPass(bool $showPass): AccountAcl { $this->showPass = $showPass; @@ -269,22 +141,14 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowFiles(): bool { return $this->showFiles - && ($this->actionId === Acl::ACCOUNT_EDIT - || $this->actionId === Acl::ACCOUNT_VIEW - || $this->actionId === Acl::ACCOUNT_HISTORY_VIEW); + && ($this->actionId === ActionsInterface::ACCOUNT_EDIT + || $this->actionId === ActionsInterface::ACCOUNT_VIEW + || $this->actionId === ActionsInterface::ACCOUNT_HISTORY_VIEW); } - /** - * @param bool $showFiles - * - * @return AccountAcl - */ public function setShowFiles(bool $showFiles): AccountAcl { $this->showFiles = $this->resultView && $showFiles; @@ -292,24 +156,16 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowViewPass(): bool { return $this->showViewPass - && ($this->actionId === Acl::ACCOUNT_SEARCH - || $this->actionId === Acl::ACCOUNT_VIEW - || $this->actionId === Acl::ACCOUNT_VIEW_PASS - || $this->actionId === Acl::ACCOUNT_HISTORY_VIEW - || $this->actionId === Acl::ACCOUNT_EDIT); + && ($this->actionId === ActionsInterface::ACCOUNT_SEARCH + || $this->actionId === ActionsInterface::ACCOUNT_VIEW + || $this->actionId === ActionsInterface::ACCOUNT_VIEW_PASS + || $this->actionId === ActionsInterface::ACCOUNT_HISTORY_VIEW + || $this->actionId === ActionsInterface::ACCOUNT_EDIT); } - /** - * @param bool $showViewPass - * - * @return AccountAcl - */ public function setShowViewPass(bool $showViewPass): AccountAcl { $this->showViewPass = $this->resultView && $showViewPass; @@ -317,21 +173,13 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowSave(): bool { - return $this->actionId === Acl::ACCOUNT_EDIT - || $this->actionId === Acl::ACCOUNT_CREATE - || $this->actionId === Acl::ACCOUNT_COPY; + return $this->actionId === ActionsInterface::ACCOUNT_EDIT + || $this->actionId === ActionsInterface::ACCOUNT_CREATE + || $this->actionId === ActionsInterface::ACCOUNT_COPY; } - /** - * @param bool $showSave - * - * @return AccountAcl - */ public function setShowSave(bool $showSave): AccountAcl { $this->showSave = $showSave; @@ -339,21 +187,13 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowEdit(): bool { return $this->showEdit - && ($this->actionId === Acl::ACCOUNT_SEARCH - || $this->actionId === Acl::ACCOUNT_VIEW); + && ($this->actionId === ActionsInterface::ACCOUNT_SEARCH + || $this->actionId === ActionsInterface::ACCOUNT_VIEW); } - /** - * @param bool $showEdit - * - * @return AccountAcl - */ public function setShowEdit(bool $showEdit): AccountAcl { $this->showEdit = $this->resultEdit && $showEdit && !$this->isHistory; @@ -361,21 +201,13 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowEditPass(): bool { return $this->showEditPass - && ($this->actionId === Acl::ACCOUNT_EDIT - || $this->actionId === Acl::ACCOUNT_VIEW); + && ($this->actionId === ActionsInterface::ACCOUNT_EDIT + || $this->actionId === ActionsInterface::ACCOUNT_VIEW); } - /** - * @param bool $showEditPass - * - * @return AccountAcl - */ public function setShowEditPass(bool $showEditPass): AccountAcl { $this->showEditPass = $this->resultEdit && $showEditPass && !$this->isHistory; @@ -383,22 +215,14 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowDelete(): bool { return $this->showDelete - && ($this->actionId === Acl::ACCOUNT_SEARCH - || $this->actionId === Acl::ACCOUNT_DELETE - || $this->actionId === Acl::ACCOUNT_EDIT); + && ($this->actionId === ActionsInterface::ACCOUNT_SEARCH + || $this->actionId === ActionsInterface::ACCOUNT_DELETE + || $this->actionId === ActionsInterface::ACCOUNT_EDIT); } - /** - * @param bool $showDelete - * - * @return AccountAcl - */ public function setShowDelete(bool $showDelete): AccountAcl { $this->showDelete = $this->resultEdit && $showDelete; @@ -406,19 +230,11 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowRestore(): bool { - return $this->actionId === Acl::ACCOUNT_HISTORY_VIEW && $this->showRestore; + return $this->actionId === ActionsInterface::ACCOUNT_HISTORY_VIEW && $this->showRestore; } - /** - * @param bool $showRestore - * - * @return AccountAcl - */ public function setShowRestore(bool $showRestore): AccountAcl { $this->showRestore = $this->resultEdit && $showRestore; @@ -426,19 +242,11 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowLink(): bool { return $this->showLink; } - /** - * @param bool $showLink - * - * @return AccountAcl - */ public function setShowLink(bool $showLink): AccountAcl { $this->showLink = $showLink; @@ -446,21 +254,13 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowHistory(): bool { return $this->showHistory - && ($this->actionId === Acl::ACCOUNT_VIEW - || $this->actionId === Acl::ACCOUNT_HISTORY_VIEW); + && ($this->actionId === ActionsInterface::ACCOUNT_VIEW + || $this->actionId === ActionsInterface::ACCOUNT_HISTORY_VIEW); } - /** - * @param bool $showHistory - * - * @return AccountAcl - */ public function setShowHistory(bool $showHistory): AccountAcl { $this->showHistory = $showHistory; @@ -468,60 +268,37 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShow(): bool { return ($this->showView || $this->showEdit || $this->showViewPass || $this->showCopy || $this->showDelete); } - /** - * @return int - */ public function getActionId(): int { return $this->actionId; } - /** - * @param int $actionId - * - * @return AccountAcl - */ - public function setActionId($actionId): AccountAcl + public function setActionId(int $actionId): AccountAcl { - $this->actionId = (int)$actionId; + $this->actionId = $actionId; return $this; } - /** - * @return int - */ public function getTime(): int { return $this->time; } - /** - * @param int $time - * - * @return AccountAcl - */ - public function setTime($time): AccountAcl + public function setTime(int $time): AccountAcl { - $this->time = (int)$time; + $this->time = $time; return $this; } /** * Comprueba los permisos de acceso a una cuenta. - * - * @param int $actionId - * - * @return bool */ public function checkAccountAccess(int $actionId): bool { @@ -530,35 +307,27 @@ final class AccountAcl } switch ($actionId) { - case Acl::ACCOUNT_VIEW: - case Acl::ACCOUNT_SEARCH: - case Acl::ACCOUNT_VIEW_PASS: - case Acl::ACCOUNT_HISTORY_VIEW: - case Acl::ACCOUNT_COPY: + case ActionsInterface::ACCOUNT_VIEW + || ActionsInterface::ACCOUNT_SEARCH + || ActionsInterface::ACCOUNT_VIEW_PASS + || ActionsInterface::ACCOUNT_HISTORY_VIEW + || ActionsInterface::ACCOUNT_COPY: return $this->resultView; - case Acl::ACCOUNT_EDIT: - case Acl::ACCOUNT_DELETE: - case Acl::ACCOUNT_EDIT_PASS: - case Acl::ACCOUNT_EDIT_RESTORE: + case ActionsInterface::ACCOUNT_EDIT + || ActionsInterface::ACCOUNT_DELETE + || ActionsInterface::ACCOUNT_EDIT_PASS + || ActionsInterface::ACCOUNT_EDIT_RESTORE: return $this->resultEdit; default: return false; } } - /** - * @return boolean - */ public function isModified(): bool { return $this->modified; } - /** - * @param boolean $modified - * - * @return AccountAcl - */ public function setModified(bool $modified): AccountAcl { $this->modified = $modified; @@ -566,19 +335,11 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowView(): bool { return $this->showView; } - /** - * @param bool $showView - * - * @return AccountAcl - */ public function setShowView(bool $showView): AccountAcl { $this->showView = $this->resultView && $showView; @@ -586,22 +347,14 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowCopy(): bool { return $this->showCopy - && ($this->actionId === Acl::ACCOUNT_SEARCH - || $this->actionId === Acl::ACCOUNT_VIEW - || $this->actionId === Acl::ACCOUNT_EDIT); + && ($this->actionId === ActionsInterface::ACCOUNT_SEARCH + || $this->actionId === ActionsInterface::ACCOUNT_VIEW + || $this->actionId === ActionsInterface::ACCOUNT_EDIT); } - /** - * @param bool $showCopy - * - * @return AccountAcl - */ public function setShowCopy(bool $showCopy): AccountAcl { $this->showCopy = $this->resultView && $showCopy; @@ -609,19 +362,11 @@ final class AccountAcl return $this; } - /** - * @return boolean - */ public function isShowPermission(): bool { return $this->showPermission; } - /** - * @param bool $showPermission - * - * @return AccountAcl - */ public function setShowPermission(bool $showPermission): AccountAcl { $this->showPermission = $showPermission; @@ -629,39 +374,23 @@ final class AccountAcl return $this; } - /** - * @return int - */ - public function getAccountId(): int + public function getAccountId(): ?int { return $this->accountId; } - /** - * @param int $accountId - * - * @return AccountAcl - */ - public function setAccountId($accountId): AccountAcl + public function setAccountId(int $accountId): AccountAcl { - $this->accountId = (int)$accountId; + $this->accountId = $accountId; return $this; } - /** - * @return bool - */ public function isHistory(): bool { return $this->isHistory; } - /** - * @param bool $isHistory - * - * @return AccountAcl - */ public function setIsHistory(bool $isHistory): AccountAcl { $this->isHistory = $isHistory; @@ -669,47 +398,31 @@ final class AccountAcl return $this; } - /** - * @return bool - */ public function isCompiledShowAccess(): bool { return $this->compiledShowAccess; } - /** - * @param bool $compiledShowAccess - * - * @return AccountAcl - */ public function setCompiledShowAccess(bool $compiledShowAccess): AccountAcl { - $this->compiledShowAccess = (bool)$compiledShowAccess; + $this->compiledShowAccess = $compiledShowAccess; return $this; } - /** - * @return bool - */ public function isCompiledAccountAccess(): bool { return $this->compiledAccountAccess; } - /** - * @param bool $compiledAccountAccess - * - * @return AccountAcl - */ public function setCompiledAccountAccess(bool $compiledAccountAccess): AccountAcl { - $this->compiledAccountAccess = (bool)$compiledAccountAccess; + $this->compiledAccountAccess = $compiledAccountAccess; return $this; } - public function reset() + public function reset(): void { foreach ($this as $property => $value) { if (strpos($property, 'show') === 0) { diff --git a/lib/SP/Services/Account/AccountAclService.php b/lib/SP/Services/Account/AccountAclService.php index bb0a9cc3..41bf8672 100644 --- a/lib/SP/Services/Account/AccountAclService.php +++ b/lib/SP/Services/Account/AccountAclService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\FileNotFoundException; use SP\Core\Exceptions\QueryException; @@ -48,34 +49,19 @@ final class AccountAclService extends Service /** * ACL's file base path */ - const ACL_PATH = CACHE_PATH . DIRECTORY_SEPARATOR . 'accountAcl' . DIRECTORY_SEPARATOR; - /** - * @var bool - */ - public static $useCache = true; - /** - * @var AccountAclDto - */ - private $accountAclDto; - /** - * @var AccountAcl - */ - private $accountAcl; - /** - * @var Acl - */ - private $acl; - /** - * @var UserLoginResponse - */ - private $userData; + public const ACL_PATH = CACHE_PATH . DIRECTORY_SEPARATOR . 'accountAcl' . DIRECTORY_SEPARATOR; + public static bool $useCache = true; + private ?AccountAclDto $accountAclDto = null; + private ?AccountAcl $accountAcl = null; + private ?Acl $acl = null; + private ?UserLoginResponse $userData = null; /** * @param $userId * * @return bool */ - public static function clearAcl($userId) + public static function clearAcl($userId): bool { logger(sprintf('Clearing ACL for user ID: %d', $userId)); @@ -105,10 +91,17 @@ final class AccountAclService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAcl($actionId, ?AccountAclDto $accountAclDto = null, $isHistory = false) + public function getAcl( + int $actionId, + ?AccountAclDto $accountAclDto = null, + bool $isHistory = false + ): AccountAcl { $this->accountAcl = new AccountAcl($actionId, $isHistory); - $this->accountAcl->setShowPermission(self::getShowPermission($this->context->getUserData(), $this->context->getUserProfile())); + $this->accountAcl->setShowPermission( + self::getShowPermission($this->context->getUserData(), + $this->context->getUserProfile()) + ); if ($accountAclDto !== null) { $this->accountAclDto = $accountAclDto; @@ -116,8 +109,10 @@ final class AccountAclService extends Service $accountAcl = $this->getAclFromCache($accountAclDto->getAccountId(), $actionId); if (self::$useCache && null !== $accountAcl) { - $this->accountAcl->setModified(($accountAclDto->getDateEdit() > $accountAcl->getTime() - || $this->userData->getLastUpdate() > $accountAcl->getTime())); + $this->accountAcl->setModified(( + $accountAclDto->getDateEdit() > $accountAcl->getTime() + || $this->userData->getLastUpdate() > $accountAcl->getTime() + )); if (!$this->accountAcl->isModified()) { logger('Account ACL HIT'); @@ -144,7 +139,10 @@ final class AccountAclService extends Service * * @return bool */ - public static function getShowPermission(UserLoginResponse $userData, ProfileData $profileData) + public static function getShowPermission( + UserLoginResponse $userData, + ProfileData $profileData + ): bool { return $userData->getIsAdminApp() || $userData->getIsAdminAcc() @@ -159,7 +157,7 @@ final class AccountAclService extends Service * * @return AccountAcl */ - public function getAclFromCache($accountId, $actionId) + public function getAclFromCache(int $accountId, int $actionId): ?AccountAcl { try { $acl = FileCache::factory($this->getCacheFileForAcl($accountId, $actionId)) @@ -181,10 +179,16 @@ final class AccountAclService extends Service * * @return string */ - public function getCacheFileForAcl($accountId, $actionId) + public function getCacheFileForAcl(int $accountId, int $actionId): string { $userId = $this->context->getUserData()->getId(); - return self::ACL_PATH . $userId . DIRECTORY_SEPARATOR . $accountId . DIRECTORY_SEPARATOR . md5($userId . $accountId . $actionId) . '.cache'; + return self::ACL_PATH + . $userId + . DIRECTORY_SEPARATOR + . $accountId + . DIRECTORY_SEPARATOR + . md5($userId . $accountId . $actionId) + . '.cache'; } /** @@ -194,7 +198,7 @@ final class AccountAclService extends Service * @throws ConstraintException * @throws QueryException */ - private function updateAcl() + private function updateAcl(): AccountAcl { if ($this->checkComponents()) { $this->makeAcl(); @@ -210,7 +214,7 @@ final class AccountAclService extends Service /** * @return bool */ - private function checkComponents() + private function checkComponents(): bool { return null !== $this->accountAclDto; } @@ -221,7 +225,7 @@ final class AccountAclService extends Service * @throws ConstraintException * @throws QueryException */ - private function makeAcl() + private function makeAcl(): void { $this->compileAccountAccess(); $this->accountAcl->setCompiledAccountAccess(true); @@ -236,7 +240,7 @@ final class AccountAclService extends Service * @throws ConstraintException * @throws QueryException */ - private function compileAccountAccess() + private function compileAccountAccess(): void { $this->accountAcl->setResultView(false); $this->accountAcl->setResultEdit(false); @@ -268,9 +272,12 @@ final class AccountAclService extends Service $userToUserGroupService = $this->dic->get(UserToUserGroupService::class); // Groups in whinch the user is listed in - $userGroups = array_map(function ($value) { - return (int)$value->userGroupId; - }, $userToUserGroupService->getGroupsForUser($this->userData->getId())); + $userGroups = array_map( + static function ($value) { + return (int)$value->userGroupId; + }, + $userToUserGroupService->getGroupsForUser($this->userData->getId()) + ); // Check out if user groups match with account's main group if ($this->getUserGroupsInMainGroup($userGroups)) { @@ -282,7 +289,11 @@ final class AccountAclService extends Service } // Check out if user groups match with account's secondary groups - $userGroupsInSecondaryUserGroups = $this->getUserGroupsInSecondaryGroups($userGroups, $this->userData->getUserGroupId()); + $userGroupsInSecondaryUserGroups = + $this->getUserGroupsInSecondaryGroups( + $userGroups, + $this->userData->getUserGroupId() + ); $this->accountAcl->setUserInGroups(count($userGroupsInSecondaryUserGroups) > 0); @@ -295,15 +306,18 @@ final class AccountAclService extends Service /** * Checks if the user is listed in the account users * - * @param $userId + * @param int $userId * * @return array */ - private function getUserInSecondaryUsers($userId) + private function getUserInSecondaryUsers(int $userId): array { - return array_values(array_filter($this->accountAclDto->getUsersId(), function ($value) use ($userId) { - return (int)$value->id === $userId; - })); + return array_values(array_filter( + $this->accountAclDto->getUsersId(), + static function ($value) use ($userId) { + return (int)$value->id === $userId; + } + )); } /** @@ -313,10 +327,10 @@ final class AccountAclService extends Service * * @return bool */ - private function getUserGroupsInMainGroup(array $userGroups) + private function getUserGroupsInMainGroup(array $userGroups): bool { // Comprobar si el usuario está vinculado desde el grupo principal de la cuenta - return in_array($this->accountAclDto->getUserGroupId(), $userGroups); + return in_array($this->accountAclDto->getUserGroupId(), $userGroups, true); } /** @@ -326,57 +340,59 @@ final class AccountAclService extends Service * @param array $userGroups * @param int $userGroupId * - * @return bool|array + * @return array */ - private function getUserGroupsInSecondaryGroups(array $userGroups, $userGroupId) + private function getUserGroupsInSecondaryGroups(array $userGroups, int $userGroupId): array { $isAccountFullGroupAccess = $this->config->getConfigData()->isAccountFullGroupAccess(); // Comprobar si el grupo del usuario está vinculado desde los grupos secundarios de la cuenta - return array_values(array_filter($this->accountAclDto->getUserGroupsId(), - function ($value) use ($userGroupId, $isAccountFullGroupAccess, $userGroups) { + return array_values(array_filter( + $this->accountAclDto->getUserGroupsId(), + static function ($value) use ($userGroupId, $isAccountFullGroupAccess, $userGroups) { return (int)$value->id === $userGroupId // o... permitir los grupos que no sean el principal del usuario? || ($isAccountFullGroupAccess // Comprobar si el usuario está vinculado desde los grupos secundarios de la cuenta - && in_array((int)$value->id, $userGroups)); - })); + && in_array((int)$value->id, $userGroups, true)); + } + )); } /** * compileShowAccess */ - private function compileShowAccess() + private function compileShowAccess(): void { // Mostrar historial - $this->accountAcl->setShowHistory($this->acl->checkUserAccess(Acl::ACCOUNT_HISTORY_VIEW)); + $this->accountAcl->setShowHistory($this->acl->checkUserAccess(ActionsInterface::ACCOUNT_HISTORY_VIEW)); // Mostrar lista archivos - $this->accountAcl->setShowFiles($this->acl->checkUserAccess(Acl::ACCOUNT_FILE)); + $this->accountAcl->setShowFiles($this->acl->checkUserAccess(ActionsInterface::ACCOUNT_FILE)); // Mostrar acción de ver clave - $this->accountAcl->setShowViewPass($this->acl->checkUserAccess(Acl::ACCOUNT_VIEW_PASS)); + $this->accountAcl->setShowViewPass($this->acl->checkUserAccess(ActionsInterface::ACCOUNT_VIEW_PASS)); // Mostrar acción de editar - $this->accountAcl->setShowEdit($this->acl->checkUserAccess(Acl::ACCOUNT_EDIT)); + $this->accountAcl->setShowEdit($this->acl->checkUserAccess(ActionsInterface::ACCOUNT_EDIT)); // Mostrar acción de editar clave - $this->accountAcl->setShowEditPass($this->acl->checkUserAccess(Acl::ACCOUNT_EDIT_PASS)); + $this->accountAcl->setShowEditPass($this->acl->checkUserAccess(ActionsInterface::ACCOUNT_EDIT_PASS)); // Mostrar acción de eliminar - $this->accountAcl->setShowDelete($this->acl->checkUserAccess(Acl::ACCOUNT_DELETE)); + $this->accountAcl->setShowDelete($this->acl->checkUserAccess(ActionsInterface::ACCOUNT_DELETE)); // Mostrar acción de restaurar - $this->accountAcl->setShowRestore($this->acl->checkUserAccess(Acl::ACCOUNT_EDIT)); + $this->accountAcl->setShowRestore($this->acl->checkUserAccess(ActionsInterface::ACCOUNT_EDIT)); // Mostrar acción de enlace público - $this->accountAcl->setShowLink($this->acl->checkUserAccess(Acl::PUBLICLINK_CREATE)); + $this->accountAcl->setShowLink($this->acl->checkUserAccess(ActionsInterface::PUBLICLINK_CREATE)); // Mostrar acción de ver cuenta - $this->accountAcl->setShowView($this->acl->checkUserAccess(Acl::ACCOUNT_VIEW)); + $this->accountAcl->setShowView($this->acl->checkUserAccess(ActionsInterface::ACCOUNT_VIEW)); // Mostrar acción de copiar cuenta - $this->accountAcl->setShowCopy($this->acl->checkUserAccess(Acl::ACCOUNT_COPY)); + $this->accountAcl->setShowCopy($this->acl->checkUserAccess(ActionsInterface::ACCOUNT_COPY)); } /** @@ -386,7 +402,7 @@ final class AccountAclService extends Service * * @return null|FileCacheInterface */ - public function saveAclInCache(AccountAcl $accountAcl) + public function saveAclInCache(AccountAcl $accountAcl): ?FileCacheInterface { try { return FileCache::factory($this->getCacheFileForAcl($accountAcl->getAccountId(), $accountAcl->getActionId())) @@ -396,7 +412,7 @@ final class AccountAclService extends Service } } - protected function initialize() + protected function initialize(): void { $this->acl = $this->dic->get(Acl::class); $this->userData = $this->context->getUserData(); diff --git a/lib/SP/Services/Account/AccountBulkRequest.php b/lib/SP/Services/Account/AccountBulkRequest.php index 6541278d..f4275dcf 100644 --- a/lib/SP/Services/Account/AccountBulkRequest.php +++ b/lib/SP/Services/Account/AccountBulkRequest.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; @@ -32,23 +32,14 @@ namespace SP\Services\Account; */ final class AccountBulkRequest { - /** - * @var array - */ - private $itemsId; - /** - * @var AccountRequest - */ - private $accountRequest; - /** - * @var bool - */ - private $deleteHistory = false; + private array $itemsId; + private AccountRequest $accountRequest; + private bool $deleteHistory = false; /** * AccountBulkRequest constructor. * - * @param array $itemsId + * @param int[] $itemsId * @param AccountRequest $accountRequest */ public function __construct(array $itemsId, AccountRequest $accountRequest) @@ -59,41 +50,27 @@ final class AccountBulkRequest $this->setUp(); } - private function setUp() + private function setUp(): void { $this->accountRequest->changeUserGroup = $this->accountRequest->userGroupId > 0; $this->accountRequest->changePermissions = true; } - /** - * @return bool - */ public function isDeleteHistory(): bool { return $this->deleteHistory; } - /** - * @param bool $deleteHistory - */ - public function setDeleteHistory(bool $deleteHistory) + public function setDeleteHistory(bool $deleteHistory): void { $this->deleteHistory = $deleteHistory; } - /** - * @return array - */ public function getItemsId(): array { return $this->itemsId; } - /** - * @param int $id - * - * @return AccountRequest - */ public function getAccountRequestForId(int $id): AccountRequest { $request = clone $this->accountRequest; diff --git a/lib/SP/Services/Account/AccountCryptService.php b/lib/SP/Services/Account/AccountCryptService.php index 4a9cee02..fe4719a2 100644 --- a/lib/SP/Services/Account/AccountCryptService.php +++ b/lib/SP/Services/Account/AccountCryptService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; @@ -45,27 +45,16 @@ use SP\Util\Util; */ final class AccountCryptService extends Service { - /** - * @var AccountService - */ - private $accountService; - /** - * @var AccountHistoryService - */ - private $accountHistoryService; - /** - * @var UpdateMasterPassRequest - */ - private $request; + private ?AccountService $accountService = null; + private ?AccountHistoryService $accountHistoryService = null; + private ?UpdateMasterPassRequest $request = null; /** * Actualiza las claves de todas las cuentas con la nueva clave maestra. * - * @param UpdateMasterPassRequest $updateMasterPassRequest - * * @throws ServiceException */ - public function updateMasterPassword(UpdateMasterPassRequest $updateMasterPassRequest) + public function updateMasterPassword(UpdateMasterPassRequest $updateMasterPassRequest): void { $this->request = $updateMasterPassRequest; @@ -103,20 +92,17 @@ final class AccountCryptService extends Service throw new ServiceException( __u('Error while updating the accounts\' passwords'), - ServiceException::ERROR, + SPException::ERROR, null, $e->getCode(), $e); } } - /** - * @param array $accounts - * @param callable $passUpdater - * - * @return EventMessage - */ - private function processAccounts(array $accounts, callable $passUpdater) + private function processAccounts( + array $accounts, + callable $passUpdater + ): EventMessage { set_time_limit(0); @@ -215,11 +201,11 @@ final class AccountCryptService extends Service /** * Actualiza las claves de todas las cuentas con la nueva clave maestra. * - * @param UpdateMasterPassRequest $updateMasterPassRequest - * * @throws ServiceException */ - public function updateHistoryMasterPassword(UpdateMasterPassRequest $updateMasterPassRequest) + public function updateHistoryMasterPassword( + UpdateMasterPassRequest $updateMasterPassRequest + ): void { $this->request = $updateMasterPassRequest; @@ -269,7 +255,7 @@ final class AccountCryptService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->accountService = $this->dic->get(AccountService::class); $this->accountHistoryService = $this->dic->get(AccountHistoryService::class); diff --git a/lib/SP/Services/Account/AccountFileService.php b/lib/SP/Services/Account/AccountFileService.php index 89e27423..91153f15 100644 --- a/lib/SP/Services/Account/AccountFileService.php +++ b/lib/SP/Services/Account/AccountFileService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; @@ -30,6 +30,7 @@ use SP\Core\Exceptions\CheckException; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\InvalidImageException; use SP\Core\Exceptions\QueryException; +use SP\Core\Exceptions\SPException; use SP\DataModel\FileData; use SP\DataModel\FileExtData; use SP\DataModel\ItemSearchData; @@ -48,22 +49,16 @@ use SP\Util\ImageUtil; */ final class AccountFileService extends Service { - /** - * @var AccountFileRepository - */ - protected $accountFileRepository; + protected ?AccountFileRepository $accountFileRepository = null; /** * Creates an item * - * @param FileData $itemData - * - * @return int * @throws InvalidImageException * @throws ConstraintException * @throws QueryException */ - public function create($itemData) + public function create(FileData $itemData): int { if (FileUtil::isImage($itemData)) { try { @@ -82,13 +77,10 @@ final class AccountFileService extends Service } /** - * @param $id - * - * @return FileExtData - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getInfoById($id) + public function getInfoById(int $id): ?FileExtData { return $this->accountFileRepository->getInfoById($id)->getData(); } @@ -96,13 +88,11 @@ final class AccountFileService extends Service /** * Returns the item for given id * - * @param int $id - * - * @return FileExtData - * @throws ConstraintException - * @throws QueryException + * @return mixed|null + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getById($id) + public function getById(int $id) { return $this->accountFileRepository->getById($id)->getData(); } @@ -114,7 +104,7 @@ final class AccountFileService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): array { return $this->accountFileRepository->getAll()->getDataAsArray(); } @@ -122,13 +112,13 @@ final class AccountFileService extends Service /** * Returns all the items for given ids * - * @param array $ids + * @param int[] $ids * * @return FileExtData[] * @throws ConstraintException * @throws QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): array { return $this->accountFileRepository->getByIdBatch($ids)->getDataAsArray(); } @@ -136,17 +126,21 @@ final class AccountFileService extends Service /** * Deletes all the items for given ids * - * @param array $ids + * @param int[] $ids * - * @return int * @throws ServiceException * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (($count = $this->accountFileRepository->deleteByIdBatch($ids)) !== count($ids)) { - throw new ServiceException(__u('Error while deleting the files'), ServiceException::WARNING); + $count = $this->accountFileRepository->deleteByIdBatch($ids); + + if ($count !== count($ids)) { + throw new ServiceException( + __u('Error while deleting the files'), + SPException::WARNING + ); } return $count; @@ -155,14 +149,11 @@ final class AccountFileService extends Service /** * Deletes an item * - * @param $id - * - * @return AccountFileService - * @throws NoSuchItemException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function delete($id) + public function delete(int $id): AccountFileService { if ($this->accountFileRepository->delete($id) === 0) { throw new NoSuchItemException(__u('File not found')); @@ -174,13 +165,10 @@ final class AccountFileService extends Service /** * Searches for items by a given filter * - * @param ItemSearchData $searchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $searchData) + public function search(ItemSearchData $searchData): QueryResult { return $this->accountFileRepository->search($searchData); } @@ -188,13 +176,11 @@ final class AccountFileService extends Service /** * Returns the item for given id * - * @param int $id - * * @return FileData[] * @throws ConstraintException * @throws QueryException */ - public function getByAccountId($id) + public function getByAccountId(int $id): array { return $this->accountFileRepository->getByAccountId($id)->getDataAsArray(); } @@ -203,7 +189,7 @@ final class AccountFileService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->accountFileRepository = $this->dic->get(AccountFileRepository::class); } diff --git a/lib/SP/Services/Account/AccountFilterUser.php b/lib/SP/Services/Account/AccountFilterUser.php index 988963d7..f3902892 100644 --- a/lib/SP/Services/Account/AccountFilterUser.php +++ b/lib/SP/Services/Account/AccountFilterUser.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Context\ContextInterface; use SP\DataModel\ProfileData; use SP\Mvc\Model\QueryCondition; @@ -34,35 +34,18 @@ defined('APP_ROOT') || die(); /** * Class AccountUtil con utilidades para la gestión de cuentas - * - * @package SP */ final class AccountFilterUser { - /** - * @var ProfileData - */ - private $userProfile; - /** - * @var ConfigData - */ - private $configData; - /** - * @var UserLoginResponse - */ - private $userData; - /** - * @var ContextInterface - */ - private $context; + private ?ProfileData $userProfile = null; + private ConfigDataInterface $configData; + private ?UserLoginResponse $userData = null; + private ContextInterface $context; - /** - * AccountFilterUser constructor. - * - * @param ContextInterface $context - * @param ConfigData $configData - */ - public function __construct(ContextInterface $context, ConfigData $configData) + public function __construct( + ContextInterface $context, + ConfigDataInterface $configData + ) { $this->context = $context; $this->configData = $configData; @@ -70,12 +53,8 @@ final class AccountFilterUser /** * Devuelve el filtro para la consulta SQL de cuentas que un usuario puede acceder - * - * @param bool $useGlobalSearch - * - * @return QueryCondition */ - public function getFilterHistory($useGlobalSearch = false) + public function getFilterHistory(bool $useGlobalSearch = false): QueryCondition { $this->setUp(); @@ -117,7 +96,7 @@ final class AccountFilterUser /** * setUp */ - private function setUp() + private function setUp(): void { $this->userData = $this->context->getUserData(); $this->userProfile = $this->context->getUserProfile(); @@ -125,12 +104,8 @@ final class AccountFilterUser /** * Devuelve el filtro para la consulta SQL de cuentas que un usuario puede acceder - * - * @param bool $useGlobalSearch - * - * @return QueryCondition */ - public function getFilter($useGlobalSearch = false) + public function getFilter(bool $useGlobalSearch = false): QueryCondition { $this->setUp(); diff --git a/lib/SP/Services/Account/AccountHistoryService.php b/lib/SP/Services/Account/AccountHistoryService.php index bce9fc98..b71647bc 100644 --- a/lib/SP/Services/Account/AccountHistoryService.php +++ b/lib/SP/Services/Account/AccountHistoryService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; @@ -48,29 +48,17 @@ use SP\Storage\Database\QueryResult; */ final class AccountHistoryService extends Service { - /** - * @var AccountHistoryRepository - */ - protected $accountHistoryRepository; - /** - * @var AccountToUserGroupRepository - */ - protected $accountToUserGroupRepository; - /** - * @var AccountToUserRepository - */ - protected $accountToUserRepository; + protected ?AccountHistoryRepository $accountHistoryRepository = null; + protected ?AccountToUserGroupRepository $accountToUserGroupRepository = null; + protected ?AccountToUserRepository $accountToUserRepository = null; /** * Returns the item for given id * - * @param int $id - * - * @return AccountHistoryData * @throws SPException * @throws SPException */ - public function getById($id) + public function getById(int $id): AccountHistoryData { $results = $this->accountHistoryRepository->getById($id); @@ -84,25 +72,19 @@ final class AccountHistoryService extends Service /** * Obtiene el listado del histórico de una cuenta. * - * @param $id - * * @return array Con los registros con id como clave y fecha - usuario como valor - * @throws QueryException - * @throws ConstraintException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getHistoryForAccount($id) + public function getHistoryForAccount(int $id): array { return self::mapHistoryForDateSelect($this->accountHistoryRepository->getHistoryForAccount($id)->getDataAsArray()); } /** * Masps history items to fill in a date select - * - * @param array $history - * - * @return array */ - private static function mapHistoryForDateSelect(array $history) + private static function mapHistoryForDateSelect(array $history): array { $items = []; @@ -115,43 +97,36 @@ final class AccountHistoryService extends Service } $items[$item->id] = $date; - }; + } return $items; } /** - * @param $id - * * @return ItemData[] - * @throws QueryException - * @throws ConstraintException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getUsersByAccountId($id) + public function getUsersByAccountId(int $id): array { return $this->accountToUserRepository->getUsersByAccountId($id)->getDataAsArray(); } /** - * @param $id - * * @return ItemData[] - * @throws QueryException - * @throws ConstraintException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getUserGroupsByAccountId($id) + public function getUserGroupsByAccountId(int $id): array { return $this->accountToUserGroupRepository->getUserGroupsByAccountId($id)->getDataAsArray(); } /** - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws QueryException * @throws ConstraintException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->accountHistoryRepository->search($itemSearchData); } @@ -159,23 +134,19 @@ final class AccountHistoryService extends Service /** * Crea una nueva cuenta en la BBDD * - * @param AccountHistoryCreateDto $dto - * - * @return bool - * @throws QueryException - * @throws ConstraintException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function create(AccountHistoryCreateDto $dto) + public function create(AccountHistoryCreateDto $dto): int { return $this->accountHistoryRepository->create($dto); } /** - * @return array * @throws QueryException * @throws ConstraintException */ - public function getAccountsPassData() + public function getAccountsPassData(): array { return $this->accountHistoryRepository->getAccountsPassData()->getDataAsArray(); } @@ -183,13 +154,11 @@ final class AccountHistoryService extends Service /** * Elimina los datos de una cuenta en la BBDD. * - * @param array|int $id - * * @throws QueryException * @throws ServiceException * @throws ConstraintException */ - public function delete($id) + public function delete(int $id): void { if ($this->accountHistoryRepository->delete($id) === 0) { throw new ServiceException(__u('Error while deleting the account')); @@ -199,13 +168,13 @@ final class AccountHistoryService extends Service /** * Deletes all the items for given ids * - * @param array $ids + * @param int[] $ids * * @return int * @throws QueryException * @throws ConstraintException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { return $this->accountHistoryRepository->deleteByIdBatch($ids); } @@ -213,24 +182,24 @@ final class AccountHistoryService extends Service /** * Deletes all the items for given accounts id * - * @param array $ids + * @param int[] $ids * * @return int * @throws QueryException * @throws ConstraintException */ - public function deleteByAccountIdBatch(array $ids) + public function deleteByAccountIdBatch(array $ids): int { return $this->accountHistoryRepository->deleteByAccountIdBatch($ids); } /** - * @param AccountPasswordRequest $accountRequest - * * @throws SPException * @throws ConstraintException */ - public function updatePasswordMasterPass(AccountPasswordRequest $accountRequest) + public function updatePasswordMasterPass( + AccountPasswordRequest $accountRequest + ): void { if ($this->accountHistoryRepository->updatePassword($accountRequest) !== 1) { throw new ServiceException(__u('Error while updating the password')); @@ -240,11 +209,10 @@ final class AccountHistoryService extends Service /** * Returns all the items * - * @return array * @throws QueryException * @throws ConstraintException */ - public function getAll() + public function getAll(): array { return $this->accountHistoryRepository->getAll()->getDataAsArray(); } @@ -253,7 +221,7 @@ final class AccountHistoryService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->accountHistoryRepository = $this->dic->get(AccountHistoryRepository::class); $this->accountToUserRepository = $this->dic->get(AccountToUserRepository::class); diff --git a/lib/SP/Services/Account/AccountInterface.php b/lib/SP/Services/Account/AccountInterface.php deleted file mode 100644 index dce1cd2d..00000000 --- a/lib/SP/Services/Account/AccountInterface.php +++ /dev/null @@ -1,56 +0,0 @@ -. - */ - -namespace SP\Services\Account; - -use SP\DataModel\AccountData; -use SP\DataModel\AccountExtData; -use SP\DataModel\AccountHistoryData; - -defined('APP_ROOT') || die(); - -/** - * Interface AccountInterface con la definición de métodos comunes a las cuentas - */ -interface AccountInterface -{ - /** - * @return AccountExtData|AccountData|AccountHistoryData - */ - public function getData(); - - /** - * @param bool $encryptPass Si se encripta la clave de la cuenta - * - * @return mixed - */ - public function createAccount($encryptPass = true); - - /** - * @param $id - * - * @return mixed - */ - public function deleteAccount($id); -} \ No newline at end of file diff --git a/lib/SP/Services/Account/AccountPasswordRequest.php b/lib/SP/Services/Account/AccountPasswordRequest.php index a8e4e7c3..c390f8f9 100644 --- a/lib/SP/Services/Account/AccountPasswordRequest.php +++ b/lib/SP/Services/Account/AccountPasswordRequest.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; @@ -31,20 +31,8 @@ namespace SP\Services\Account; */ final class AccountPasswordRequest { - /** - * @var int - */ - public $id; - /** - * @var string - */ - public $pass; - /** - * @var string - */ - public $key; - /** - * @var string - */ - public $hash; + public ?int $id = null; + public ?string $pass = null; + public ?string $key = null; + public ?string $hash = null; } \ No newline at end of file diff --git a/lib/SP/Services/Account/AccountPresetService.php b/lib/SP/Services/Account/AccountPresetService.php index c64f4bd0..a5d74c0e 100644 --- a/lib/SP/Services/Account/AccountPresetService.php +++ b/lib/SP/Services/Account/AccountPresetService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\NoSuchPropertyException; use SP\Core\Exceptions\QueryException; @@ -42,36 +42,25 @@ use SP\Services\ItemPreset\ItemPresetService; */ final class AccountPresetService { - /** - * @var ItemPresetService - */ - private $itemPresetService; - /** - * @var ConfigData - */ - private $configData; + private ItemPresetService $itemPresetService; + private ConfigDataInterface $configData; - /** - * AccountPreset constructor. - * - * @param ItemPresetService $itemPresetService - * @param ConfigData $configData - */ - public function __construct(ItemPresetService $itemPresetService, ConfigData $configData) + public function __construct( + ItemPresetService $itemPresetService, + ConfigDataInterface $configData + ) { $this->itemPresetService = $itemPresetService; $this->configData = $configData; } /** - * @param AccountRequest $accountRequest - * * @throws ValidationException * @throws ConstraintException * @throws NoSuchPropertyException * @throws QueryException */ - public function checkPasswordPreset(AccountRequest $accountRequest) + public function checkPasswordPreset(AccountRequest $accountRequest): void { $itemPreset = $this->itemPresetService->getForCurrentUser(ItemPresetInterface::ITEM_TYPE_ACCOUNT_PASSWORD); diff --git a/lib/SP/Services/Account/AccountRequest.php b/lib/SP/Services/Account/AccountRequest.php index c09789ef..791af65a 100644 --- a/lib/SP/Services/Account/AccountRequest.php +++ b/lib/SP/Services/Account/AccountRequest.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; @@ -31,112 +31,31 @@ namespace SP\Services\Account; */ final class AccountRequest { - /** - * @var int - */ - public $id; - /** - * @var string - */ - public $name; - /** - * @var int - */ - public $clientId; - /** - * @var int - */ - public $categoryId; - /** - * @var string - */ - public $login; - /** - * @var string - */ - public $url; - /** - * @var string - */ - public $notes; - /** - * @var int - */ - public $userId; - /** - * @var int - */ - public $userGroupId; - /** - * @var int - */ - public $userEditId; - /** - * @var int - */ - public $otherUserEdit; - /** - * @var int - */ - public $otherUserGroupEdit; - /** - * @var string - */ - public $pass; - /** - * @var string - */ - public $key; - /** - * @var int - */ - public $isPrivate; - /** - * @var int - */ - public $isPrivateGroup; - /** - * @var int - */ - public $passDateChange; - /** - * @var int - */ - public $parentId; - /** - * @var array - */ - public $usersView; - /** - * @var array - */ - public $usersEdit; - /** - * @var array - */ - public $userGroupsView; - /** - * @var array - */ - public $userGroupsEdit; - /** - * @var array - */ - public $tags; - /** - * @var bool - */ - public $changeOwner = false; - /** - * @var bool - */ - public $changeUserGroup = false; - /** - * @var bool - */ - public $changePermissions = false; - /** - * @var bool - */ - public $updateTags = false; + public ?int $id = null; + public ?string $name = null; + public ?int $clientId = null; + public ?int $categoryId = null; + public ?string $login = null; + public ?string $url = null; + public ?string $notes = null; + public ?int $userId = null; + public ?int $userGroupId = null; + public ?int $userEditId = null; + public ?int $otherUserEdit = null; + public ?int $otherUserGroupEdit = null; + public ?string $pass = null; + public ?string $key = null; + public ?int $isPrivate = null; + public ?int $isPrivateGroup = null; + public ?int $passDateChange = null; + public ?int $parentId = null; + public ?array $usersView = null; + public ?array $usersEdit = null; + public ?array $userGroupsView = null; + public ?array $userGroupsEdit = null; + public ?array $tags = null; + public ?bool $changeOwner = false; + public ?bool $changeUserGroup = false; + public ?bool $changePermissions = false; + public ?bool $updateTags = false; } \ No newline at end of file diff --git a/lib/SP/Services/Account/AccountSearchFilter.php b/lib/SP/Services/Account/AccountSearchFilter.php index 17c9cddf..c7e914c1 100644 --- a/lib/SP/Services/Account/AccountSearchFilter.php +++ b/lib/SP/Services/Account/AccountSearchFilter.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; @@ -37,288 +37,164 @@ final class AccountSearchFilter /** * Constantes de ordenación */ - const SORT_DIR_ASC = 0; - const SORT_DIR_DESC = 1; - const SORT_LOGIN = 3; - const SORT_URL = 4; - const SORT_CATEGORY = 2; - const SORT_CLIENT = 5; - const SORT_NAME = 1; - const SORT_DEFAULT = 0; + public const SORT_DIR_ASC = 0; + public const SORT_DIR_DESC = 1; + public const SORT_LOGIN = 3; + public const SORT_URL = 4; + public const SORT_CATEGORY = 2; + public const SORT_CLIENT = 5; + public const SORT_NAME = 1; + public const SORT_DEFAULT = 0; /** - * @var int El número de registros de la última consulta + * @var int|null El número de registros de la última consulta */ - public static $queryNumRows; + public static ?int $queryNumRows; + private bool $globalSearch = false; + private ?string $txtSearch = null; /** - * @var bool + * @var string|null Search string without special filters */ - private $globalSearch = false; - /** - * @var string - */ - private $txtSearch; - /** - * @var string Search string without special filters - */ - private $cleanTxtSearch; - /** - * @var int - */ - private $clientId; - /** - * @var int - */ - private $categoryId; - /** - * @var array - */ - private $tagsId; - /** - * @var int - */ - private $sortOrder = self::SORT_DEFAULT; - /** - * @var int - */ - private $sortKey = self::SORT_DIR_ASC; - /** - * @var int - */ - private $limitStart = 0; - /** - * @var int - */ - private $limitCount; - /** - * @var bool - */ - private $sortViews; - /** - * @var bool - */ - private $searchFavorites = false; - /** - * @var QueryCondition - */ - private $stringFilters; - /** - * @var string - */ - private $filterOperator; + private ?string $cleanTxtSearch = null; + private ?int $clientId = null; + private ?int $categoryId = null; + private ?array $tagsId = null; + private int $sortOrder = self::SORT_DEFAULT; + private int $sortKey = self::SORT_DIR_ASC; + private int $limitStart = 0; + private ?int $limitCount = null; + private ?bool $sortViews = null; + private bool $searchFavorites = false; + private ?QueryCondition $stringFilters = null; + private ?string $filterOperator = null; - /** - * @return boolean - */ - public function isSearchFavorites() + public function isSearchFavorites(): bool { return $this->searchFavorites; } - /** - * @param boolean $searchFavorites - * - * @return $this - */ - public function setSearchFavorites($searchFavorites) + public function setSearchFavorites(bool $searchFavorites): AccountSearchFilter { - $this->searchFavorites = (bool)$searchFavorites; + $this->searchFavorites = $searchFavorites; return $this; } - /** - * @return int - */ - public function getGlobalSearch() + public function getGlobalSearch(): bool { return $this->globalSearch; } - /** - * @param int $globalSearch - * - * @return $this - */ - public function setGlobalSearch($globalSearch) + public function setGlobalSearch(bool $globalSearch): AccountSearchFilter { $this->globalSearch = $globalSearch; return $this; } - /** - * @return string - */ - public function getTxtSearch() + public function getTxtSearch(): ?string { return $this->txtSearch; } - /** - * @param string $txtSearch - * - * @return $this - */ - public function setTxtSearch($txtSearch) + public function setTxtSearch(?string $txtSearch): AccountSearchFilter { $this->txtSearch = $txtSearch; return $this; } - /** - * @return int - */ - public function getClientId() + public function getClientId(): ?int { return $this->clientId; } - /** - * @param int $clientId - * - * @return $this - */ - public function setClientId($clientId) + public function setClientId(?int $clientId): AccountSearchFilter { $this->clientId = $clientId; return $this; } - /** - * @return int - */ - public function getCategoryId() + public function getCategoryId(): ?int { return $this->categoryId; } - /** - * @param int $categoryId - * - * @return $this - */ - public function setCategoryId($categoryId) + public function setCategoryId(?int $categoryId): AccountSearchFilter { $this->categoryId = $categoryId; return $this; } - /** - * @return int - */ - public function getSortOrder() + public function getSortOrder(): int { return $this->sortOrder; } - /** - * @param int $sortOrder - * - * @return $this - */ - public function setSortOrder($sortOrder) + public function setSortOrder(int $sortOrder): AccountSearchFilter { $this->sortOrder = $sortOrder; return $this; } - /** - * @return int - */ - public function getLimitStart() + public function getLimitStart(): int { return $this->limitStart; } - /** - * @param int $limitStart - * - * @return $this - */ - public function setLimitStart($limitStart) + public function setLimitStart(int $limitStart): AccountSearchFilter { $this->limitStart = $limitStart; return $this; } - /** - * @return int - */ - public function getLimitCount() + public function getLimitCount(): ?int { return $this->limitCount; } - /** - * @param int $limitCount - * - * @return $this - */ - public function setLimitCount($limitCount) + public function setLimitCount(?int $limitCount): AccountSearchFilter { $this->limitCount = $limitCount; return $this; } - /** - * @return array - */ - public function getTagsId() + public function getTagsId(): ?array { - return $this->tagsId ?: []; + return $this->tagsId; } - /** - * @param array $tagsId - * - * @return $this - */ - public function setTagsId($tagsId) + public function setTagsId(?array $tagsId): AccountSearchFilter { - if (is_array($tagsId)) { - $this->tagsId = $tagsId; - } + $this->tagsId = $tagsId; return $this; } - /** - * @return bool - */ - public function hasTags() + public function hasTags(): bool { - return !empty($this->tagsId); + return null !== $this->tagsId && count($this->tagsId) !== 0; } - /** - * @return QueryCondition - */ - public function getStringFilters() + public function getStringFilters(): QueryCondition { - return $this->stringFilters ?: new QueryCondition(); + return $this->stringFilters ?? new QueryCondition(); } - /** - * @param QueryCondition $stringFilters - */ - public function setStringFilters(QueryCondition $stringFilters) + public function setStringFilters(?QueryCondition $stringFilters): void { $this->stringFilters = $stringFilters; } /** * Devuelve la cadena de ordenación de la consulta - * - * @return string */ - public function getOrderString() + public function getOrderString(): string { switch ($this->sortKey) { case self::SORT_NAME: @@ -347,78 +223,51 @@ final class AccountSearchFilter $this->setSortOrder(self::SORT_DIR_DESC); } - $orderDir = ($this->sortOrder === self::SORT_DIR_ASC) ? 'ASC' : 'DESC'; + $orderDir = $this->sortOrder === self::SORT_DIR_ASC ? 'ASC' : 'DESC'; + return sprintf('%s %s', implode(',', $orderKey), $orderDir); } - /** - * @return boolean - */ - public function isSortViews() + public function isSortViews(): bool { - return $this->sortViews; + return $this->sortViews ?? false; } - /** - * @param boolean $sortViews - * - * @return $this - */ - public function setSortViews($sortViews) - { - $this->sortViews = $sortViews; - - return $this; - } - - /** - * @return int - */ - public function getSortKey() + public function getSortKey(): int { return $this->sortKey; } - /** - * @param int $sortKey - * - * @return $this - */ - public function setSortKey($sortKey) + public function setSortKey(int $sortKey): AccountSearchFilter { $this->sortKey = $sortKey; return $this; } - /** - * @return string - */ - public function getCleanTxtSearch() + public function setSortViews(?bool $sortViews): AccountSearchFilter + { + $this->sortViews = $sortViews; + + return $this; + } + + public function getCleanTxtSearch(): ?string { return $this->cleanTxtSearch; } - /** - * @param string $cleanTxtSearch - */ - public function setCleanTxtSearch($cleanTxtSearch) + public function setCleanTxtSearch(?string $cleanTxtSearch): void { $this->cleanTxtSearch = $cleanTxtSearch; } - /** - * @return string - */ - public function getFilterOperator() + public function getFilterOperator(): string { - return $this->filterOperator ?: QueryCondition::CONDITION_AND; + return $this->filterOperator ?? QueryCondition::CONDITION_AND; } - /** - * @param string $filterOperator - */ - public function setFilterOperator($filterOperator) + public function setFilterOperator(?string $filterOperator): void { $this->filterOperator = $filterOperator; } @@ -426,7 +275,7 @@ final class AccountSearchFilter /** * Resets internal variables */ - public function reset() + public function reset(): void { self::$queryNumRows = null; $this->categoryId = null; diff --git a/lib/SP/Services/Account/AccountSearchItem.php b/lib/SP/Services/Account/AccountSearchItem.php index 80619f75..a0cc55fa 100644 --- a/lib/SP/Services/Account/AccountSearchItem.php +++ b/lib/SP/Services/Account/AccountSearchItem.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; @@ -27,7 +27,7 @@ namespace SP\Services\Account; defined('APP_ROOT') || die(); use SP\Bootstrap; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\DataModel\AccountSearchVData; use SP\DataModel\ItemData; use SP\Html\Html; @@ -40,207 +40,111 @@ use SP\Services\PublicLink\PublicLinkService; */ final class AccountSearchItem { - /** - * @var bool - */ - public static $accountLink = false; - /** - * @var bool - */ - public static $topNavbar = false; - /** - * @var bool - */ - public static $optionalActions = false; - /** - * @var bool - */ - public static $showTags = false; - /** - * @var bool - */ - public static $requestEnabled = true; - /** - * @var bool - */ - public static $wikiEnabled = false; - /** - * @var bool - */ - public static $dokuWikiEnabled = false; - /** - * @var bool - */ - public static $publicLinkEnabled = false; - /** - * @var bool - */ - public static $isDemoMode = false; + public static bool $accountLink = false; + public static bool $topNavbar = false; + public static bool $optionalActions = false; + public static bool $showTags = false; + public static bool $requestEnabled = true; + public static bool $wikiEnabled = false; + public static bool $dokuWikiEnabled = false; + public static bool $publicLinkEnabled = false; + public static bool $isDemoMode = false; + protected AccountSearchVData $accountSearchVData; + protected ?string $color = null; + protected ?string $link = null; + protected bool $favorite = false; + protected int $textMaxLength = 60; /** - * @var AccountSearchVData + * @var ItemData[]|null */ - protected $accountSearchVData; + protected ?array $users = null; /** - * @var string + * @var ItemData[]|null */ - protected $color; + protected ?array $tags = null; /** - * @var string + * @var ItemData[]|null */ - protected $link; - /** - * @var bool - */ - protected $url_islink = false; - /** - * @var string - */ - protected $numFiles; - /** - * @var bool - */ - protected $favorite = false; - /** - * @var int - */ - protected $textMaxLength = 60; - /** - * @var ItemData[] - */ - protected $users; - /** - * @var ItemData[] - */ - protected $tags; - /** - * @var ItemData[] - */ - protected $userGroups; - /** - * @var ConfigData - */ - private $configData; - /** - * @var AccountAcl - */ - private $accountAcl; + protected ?array $userGroups = null; + private ConfigDataInterface $configData; + private AccountAcl $accountAcl; - /** - * AccountsSearchItem constructor. - * - * @param AccountSearchVData $accountSearchVData - * @param AccountAcl $accountAcl - * @param ConfigData $configData - */ - public function __construct(AccountSearchVData $accountSearchVData, AccountAcl $accountAcl, ConfigData $configData) + public function __construct( + AccountSearchVData $accountSearchVData, + AccountAcl $accountAcl, + ConfigDataInterface $configData + ) { $this->accountSearchVData = $accountSearchVData; $this->accountAcl = $accountAcl; $this->configData = $configData; } - /** - * @return boolean - */ - public function isFavorite() + public function isFavorite(): bool { return $this->favorite; } - /** - * @param boolean $favorite - */ - public function setFavorite($favorite) + public function setFavorite(bool $favorite): void { $this->favorite = $favorite; } - /** - * @return boolean - */ - public function isShowRequest() + public function isShowRequest(): bool { - return (!$this->accountAcl->isShow() && self::$requestEnabled); + return !$this->accountAcl->isShow() && self::$requestEnabled; } - /** - * @return bool - */ - public function isShowCopyPass() + public function isShowCopyPass(): bool { - return ($this->accountAcl->isShowViewPass() && !$this->configData->isAccountPassToImage()); + return $this->accountAcl->isShowViewPass() + && !$this->configData->isAccountPassToImage(); } - /** - * @return bool - */ - public function isShowViewPass() + public function isShowViewPass(): bool { return $this->accountAcl->isShowViewPass(); } - - /** - * @return bool - */ - public function isShowOptional() + public function isShowOptional(): bool { return ($this->accountAcl->isShow() && !self::$optionalActions); } - /** - * @param int $textMaxLength - */ - public function setTextMaxLength($textMaxLength) + public function setTextMaxLength(int $textMaxLength): void { $this->textMaxLength = $textMaxLength; } - /** - * @return string - */ - public function getShortUrl() + public function getShortUrl(): string { return Html::truncate($this->accountSearchVData->getUrl(), $this->textMaxLength); } - /** - * @return boolean - */ - public function isUrlIslink() + public function isUrlIslink(): bool { - return preg_match('#^\w+://#i', $this->accountSearchVData->getUrl()); + return preg_match('#^\w+://#i', $this->accountSearchVData->getUrl()) === 1; } - /** - * @return string - */ - public function getShortLogin() + public function getShortLogin(): string { return Html::truncate($this->accountSearchVData->getLogin(), $this->textMaxLength); } - /** - * @return string - */ - public function getShortClientName() + public function getShortClientName(): string { return Html::truncate($this->accountSearchVData->getClientName(), $this->textMaxLength / 3); } - /** - * @return string - */ - public function getClientLink() + public function getClientLink(): ?string { - return self::$wikiEnabled ? $this->configData->getWikiSearchurl() . $this->accountSearchVData->getClientName() : null; + return self::$wikiEnabled + ? $this->configData->getWikiSearchurl() . $this->accountSearchVData->getClientName() + : null; } - /** - * @return string - */ - public function getPublicLink() + public function getPublicLink(): ?string { if (self::$publicLinkEnabled && $this->accountSearchVData->getPublicLinkHash() !== null @@ -253,42 +157,27 @@ final class AccountSearchItem return null; } - /** - * @return string - */ - public function getColor() + public function getColor(): ?string { return $this->color; } - /** - * @param string $color - */ - public function setColor($color) + public function setColor(string $color): void { $this->color = $color; } - /** - * @return string - */ - public function getLink() + public function getLink(): ?string { return $this->link; } - /** - * @param string $link - */ - public function setLink($link) + public function setLink(string $link): void { $this->link = $link; } - /** - * @return array - */ - public function getAccesses() + public function getAccesses(): array { $accesses = [ '(G*) ' . $this->accountSearchVData->getUserGroupName() . '', @@ -298,85 +187,63 @@ final class AccountSearchItem $userLabel = $this->accountSearchVData->getOtherUserEdit() === 1 ? 'U+' : 'U'; $userGroupLabel = $this->accountSearchVData->getOtherUserGroupEdit() === 1 ? 'G+' : 'G'; - foreach ($this->userGroups as $group) { - $accesses[] = sprintf('(%s) %s', $userGroupLabel, $group->getName()); + foreach ($this->userGroups ?? [] as $group) { + $accesses[] = sprintf( + '(%s) %s', + $userGroupLabel, + $group->getName() + ); } - foreach ($this->users as $user) { - $accesses[] = sprintf('(%s) %s', $userLabel, $user->login); + foreach ($this->users ?? [] as $user) { + $accesses[] = sprintf( + '(%s) %s', + $userLabel, + $user->login + ); } return $accesses; } - /** - * @return string - */ - public function getNumFiles() + public function getNumFiles(): int { - return $this->configData->isFilesEnabled() ? $this->accountSearchVData->getNumFiles() : 0; + return $this->configData->isFilesEnabled() + ? $this->accountSearchVData->getNumFiles() + : 0; } - /** - * @param string $numFiles - */ - public function setNumFiles($numFiles) - { - $this->numFiles = $numFiles; - } - - /** - * @return boolean - */ - public function isShow() + public function isShow(): bool { return $this->accountAcl->isShow(); } - /** - * @return boolean - */ - public function isShowView() + public function isShowView(): bool { return $this->accountAcl->isShowView(); } - /** - * @return boolean - */ - public function isShowEdit() + public function isShowEdit(): bool { return $this->accountAcl->isShowEdit(); } - /** - * @return boolean - */ - public function isShowCopy() + public function isShowCopy(): bool { return $this->accountAcl->isShowCopy(); } - /** - * @return boolean - */ - public function isShowDelete() + public function isShowDelete(): bool { return $this->accountAcl->isShowDelete(); } - /** - * @return AccountSearchVData - */ - public function getAccountSearchVData() + public function getAccountSearchVData(): AccountSearchVData { return $this->accountSearchVData; } - /** - * @return string - */ - public function getShortNotes() + public function getShortNotes(): string { if ($this->accountSearchVData->getNotes()) { return nl2br(htmlspecialchars(Html::truncate($this->accountSearchVData->getNotes(), 300), ENT_QUOTES)); @@ -387,10 +254,8 @@ final class AccountSearchItem /** * Develve si la clave ha caducado - * - * @return bool */ - public function isPasswordExpired() + public function isPasswordExpired(): bool { return $this->configData->isAccountExpireEnabled() && $this->accountSearchVData->getPassDateChange() > 0 @@ -400,7 +265,7 @@ final class AccountSearchItem /** * @param ItemData[] $userGroups */ - public function setUserGroups(array $userGroups) + public function setUserGroups(array $userGroups): void { $this->userGroups = $userGroups; } @@ -408,7 +273,7 @@ final class AccountSearchItem /** * @param ItemData[] $users */ - public function setUsers(array $users) + public function setUsers(array $users): void { $this->users = $users; } @@ -416,26 +281,24 @@ final class AccountSearchItem /** * @return ItemData[] */ - public function getTags() + public function getTags(): array { - return $this->tags; + return $this->tags ?? []; } /** * @param ItemData[] $tags */ - public function setTags(array $tags) + public function setTags(array $tags): void { $this->tags = $tags; } - /** - * @param $wikiFilter - * - * @return bool - */ - public function isWikiMatch($wikiFilter) + public function isWikiMatch(string $wikiFilter): bool { - return preg_match('/^' . $wikiFilter . '/i', $this->accountSearchVData->getName()) === 1; + return preg_match( + '/^' . $wikiFilter . '/i', + $this->accountSearchVData->getName() + ) === 1; } } \ No newline at end of file diff --git a/lib/SP/Services/Account/AccountSearchService.php b/lib/SP/Services/Account/AccountSearchService.php index fd400d8c..2d7ba328 100644 --- a/lib/SP/Services/Account/AccountSearchService.php +++ b/lib/SP/Services/Account/AccountSearchService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; @@ -27,8 +27,8 @@ namespace SP\Services\Account; use Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; -use SP\Config\ConfigData; -use SP\Core\Acl\Acl; +use SP\Config\ConfigDataInterface; +use SP\Core\Acl\ActionsInterface; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; use SP\Core\Exceptions\SPException; @@ -59,7 +59,7 @@ final class AccountSearchService extends Service /** * Regex filters for special searching */ - const FILTERS = [ + private const FILTERS = [ 'condition' => [ 'subject' => ['is', 'not'], 'condition' => ['expired', 'private'] @@ -74,17 +74,12 @@ final class AccountSearchService extends Service ] ]; - const COLORS_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'colors.cache'; - - /** - * Cache expire time - */ - const CACHE_EXPIRE = 86400; + private const COLORS_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'colors.cache'; /** * Colores para resaltar las cuentas */ - const COLORS = [ + private const COLORS = [ '2196F3', '03A9F4', '00BCD4', @@ -103,81 +98,57 @@ final class AccountSearchService extends Service '673AB7', '3F51B5', ]; - /** - * @var AccountFilterUser - */ - private $accountFilterUser; - /** - * @var AccountAclService - */ - private $accountAclService; - /** - * @var ConfigData - */ - private $configData; - /** - * @var AccountToTagRepository - */ - private $accountToTagRepository; - /** - * @var AccountToUserRepository - */ - private $accountToUserRepository; - /** - * @var AccountToUserGroupRepository - */ - private $accountToUserGroupRepository; - /** - * @var FileCacheInterface - */ - private $colorCache; - /** - * @var array - */ - private $accountColor; - /** - * @var AccountRepository - */ - private $accountRepository; - /** - * @var string - */ - private $cleanString; - /** - * @var string - */ - private $filterOperator; + private ?AccountFilterUser $accountFilterUser = null; + private ?AccountAclService $accountAclService = null; + private ?ConfigDataInterface $configData = null; + private ?AccountToTagRepository $accountToTagRepository = null; + private ?AccountToUserRepository $accountToUserRepository = null; + private ?AccountToUserGroupRepository $accountToUserGroupRepository = null; + private ?FileCacheInterface $colorCache = null; + private ?array $accountColor = null; + private ?AccountRepository $accountRepository = null; + private ?string $cleanString = null; + private ?string $filterOperator = null; /** * Procesar los resultados de la búsqueda y crear la variable que contiene los datos de cada cuenta * a mostrar. * - * @param AccountSearchFilter $accountSearchFilter - * - * @return QueryResult * @throws ConstraintException * @throws QueryException * @throws SPException */ - public function processSearchResults(AccountSearchFilter $accountSearchFilter) + public function processSearchResults( + AccountSearchFilter $accountSearchFilter + ): QueryResult { - $accountSearchFilter->setStringFilters($this->analyzeQueryFilters($accountSearchFilter->getTxtSearch())); + if (!empty($accountSearchFilter->getTxtSearch())) { + $accountSearchFilter->setStringFilters($this->analyzeQueryFilters($accountSearchFilter->getTxtSearch())); + } - if ($accountSearchFilter->getFilterOperator() === null - || $this->filterOperator !== null + if ($this->filterOperator !== null + || $accountSearchFilter->getFilterOperator() === null ) { $accountSearchFilter->setFilterOperator($this->filterOperator); } - $accountSearchFilter->setCleanTxtSearch($this->cleanString); + if (!empty($this->cleanString)) { + $accountSearchFilter->setCleanTxtSearch($this->cleanString); + } - $queryResult = $this->accountRepository->getByFilter($accountSearchFilter, $this->accountFilterUser->getFilter($accountSearchFilter->getGlobalSearch())); + $queryResult = $this->accountRepository->getByFilter( + $accountSearchFilter, + $this->accountFilterUser->getFilter($accountSearchFilter->getGlobalSearch()) + ); // Variables de configuración $maxTextLength = $this->configData->isResultsAsCards() ? 40 : 60; - $accountLinkEnabled = $this->context->getUserData()->getPreferences()->isAccountLink() || $this->configData->isAccountLink(); - $favorites = $this->dic->get(AccountToFavoriteService::class)->getForUserId($this->context->getUserData()->getId()); + $accountLinkEnabled = $this->context->getUserData() + ->getPreferences() + ->isAccountLink() || $this->configData->isAccountLink(); + $favorites = $this->dic->get(AccountToFavoriteService::class) + ->getForUserId($this->context->getUserData()->getId()); $accountsData = []; @@ -187,23 +158,39 @@ final class AccountSearchService extends Service // Obtener la ACL de la cuenta $accountAcl = $this->accountAclService->getAcl( - Acl::ACCOUNT_SEARCH, - AccountAclDto::makeFromAccountSearch($accountSearchData, $cache->getUsers(), $cache->getUserGroups()) + ActionsInterface::ACCOUNT_SEARCH, + AccountAclDto::makeFromAccountSearch( + $accountSearchData, + $cache->getUsers(), + $cache->getUserGroups() + ) ); // Propiedades de búsqueda de cada cuenta - $accountsSearchItem = new AccountSearchItem($accountSearchData, $accountAcl, $this->configData); + $accountsSearchItem = new AccountSearchItem( + $accountSearchData, + $accountAcl, + $this->configData + ); if (!$accountSearchData->getIsPrivate()) { $accountsSearchItem->setUsers($cache->getUsers()); $accountsSearchItem->setUserGroups($cache->getUserGroups()); } - $accountsSearchItem->setTags($this->accountToTagRepository->getTagsByAccountId($accountSearchData->getId())->getDataAsArray()); + $accountsSearchItem->setTags( + $this->accountToTagRepository + ->getTagsByAccountId($accountSearchData->getId()) + ->getDataAsArray() + ); $accountsSearchItem->setTextMaxLength($maxTextLength); - $accountsSearchItem->setColor($this->pickAccountColor($accountSearchData->getClientId())); + $accountsSearchItem->setColor( + $this->pickAccountColor($accountSearchData->getClientId()) + ); $accountsSearchItem->setLink($accountLinkEnabled); - $accountsSearchItem->setFavorite(isset($favorites[$accountSearchData->getId()])); + $accountsSearchItem->setFavorite( + isset($favorites[$accountSearchData->getId()]) + ); $accountsData[] = $accountsSearchItem; } @@ -214,14 +201,8 @@ final class AccountSearchService extends Service /** * Analizar la cadena de consulta por eqituetas especiales y devolver un objeto * QueryCondition con los filtros - * - * @param $string - * - * @return QueryCondition - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface */ - public function analyzeQueryFilters($string) + public function analyzeQueryFilters(string $string): QueryCondition { $this->cleanString = null; $this->filterOperator = null; @@ -247,35 +228,49 @@ final class AccountSearchService extends Service ); if (!empty($filtersAndValues)) { - $filtersItem = array_filter($filtersAndValues, function ($value, $key) { - return in_array($key, self::FILTERS['items']['subject'], true) - && $value !== ''; - }, ARRAY_FILTER_USE_BOTH); + $filtersItem = array_filter( + $filtersAndValues, + static function ($value, $key) { + return in_array($key, self::FILTERS['items']['subject'], true) + && $value !== ''; + }, + ARRAY_FILTER_USE_BOTH + ); if (!empty($filtersItem)) { $this->processFilterItems($filtersItem, $queryCondition); } - $filtersOperator = array_filter($filtersAndValues, function ($value, $key) { - return in_array($key, self::FILTERS['operator']['subject'], true) - && in_array($value, self::FILTERS['operator']['condition'], true); - }, ARRAY_FILTER_USE_BOTH); + $filtersOperator = array_filter( + $filtersAndValues, + static function ($value, $key) { + return in_array($key, self::FILTERS['operator']['subject'], true) + && in_array($value, self::FILTERS['operator']['condition'], true); + }, + ARRAY_FILTER_USE_BOTH + ); if (!empty($filtersOperator)) { $this->processFilterOperator($filtersOperator); } - $filtersCondition = array_filter(array_map(function ($subject, $condition) { - if (in_array($subject, self::FILTERS['condition']['subject'], true) - && in_array($condition, self::FILTERS['condition']['condition'], true) - ) { - return $subject . ':' . $condition; - } + $filtersCondition = array_filter( + array_map( + static function ($subject, $condition) { + if (in_array($subject, self::FILTERS['condition']['subject'], true) + && in_array($condition, self::FILTERS['condition']['condition'], true) + ) { + return $subject . ':' . $condition; + } - return null; - }, $filters['filter_subject'], $filters['filter_condition'])); + return null; + }, + $filters['filter_subject'], + $filters['filter_condition'] + ) + ); - if (!empty($filtersCondition)) { + if (count($filtersCondition) !== 0) { $this->processFilterIs($filtersCondition, $queryCondition); } } @@ -284,17 +279,17 @@ final class AccountSearchService extends Service return $queryCondition; } - /** - * @param array $filters - * @param QueryCondition $queryCondition - */ - private function processFilterItems(array $filters, QueryCondition $queryCondition) + private function processFilterItems( + array $filters, + QueryCondition $queryCondition + ): void { foreach ($filters as $filter => $text) { try { switch ($filter) { case 'user': - $userData = $this->dic->get(UserService::class)->getByLogin(Filter::safeSearchString($text)); + $userData = $this->dic->get(UserService::class) + ->getByLogin(Filter::safeSearchString($text)); if (is_object($userData)) { $queryCondition->addFilter( @@ -312,7 +307,8 @@ final class AccountSearchService extends Service [$text, $text]); break; case 'group': - $userGroupData = $this->dic->get(UserGroupService::class)->getByName(Filter::safeSearchString($text)); + $userGroupData = $this->dic->get(UserGroupService::class) + ->getByName(Filter::safeSearchString($text)); if (is_object($userGroupData)) { $queryCondition->addFilter( @@ -321,22 +317,40 @@ final class AccountSearchService extends Service } break; case 'maingroup': - $queryCondition->addFilter('Account.userGroupName LIKE ?', ['%' . Filter::safeSearchString($text) . '%']); + $queryCondition->addFilter( + 'Account.userGroupName LIKE ?', + ['%' . Filter::safeSearchString($text) . '%'] + ); break; case 'file': - $queryCondition->addFilter('Account.id IN (SELECT AccountFile.accountId FROM AccountFile WHERE AccountFile.name LIKE ?)', ['%' . $text . '%']); + $queryCondition->addFilter( + 'Account.id IN (SELECT AccountFile.accountId FROM AccountFile WHERE AccountFile.name LIKE ?)', + ['%' . $text . '%'] + ); break; case 'id': - $queryCondition->addFilter('Account.id = ?', [(int)$text]); + $queryCondition->addFilter( + 'Account.id = ?', + [(int)$text] + ); break; case 'client': - $queryCondition->addFilter('Account.clientName LIKE ?', ['%' . Filter::safeSearchString($text) . '%']); + $queryCondition->addFilter( + 'Account.clientName LIKE ?', + ['%' . Filter::safeSearchString($text) . '%'] + ); break; case 'category': - $queryCondition->addFilter('Account.categoryName LIKE ?', ['%' . Filter::safeSearchString($text) . '%']); + $queryCondition->addFilter( + 'Account.categoryName LIKE ?', + ['%' . Filter::safeSearchString($text) . '%'] + ); break; case 'name_regex': - $queryCondition->addFilter('Account.name REGEXP ?', [$text]); + $queryCondition->addFilter( + 'Account.name REGEXP ?', + [$text] + ); break; } } catch (Exception $e) { @@ -345,10 +359,7 @@ final class AccountSearchService extends Service } } - /** - * @param array $filters - */ - private function processFilterOperator(array $filters) + private function processFilterOperator(array $filters): void { switch ($filters['op']) { case 'and': @@ -360,11 +371,10 @@ final class AccountSearchService extends Service } } - /** - * @param array $filters - * @param QueryCondition $queryCondition - */ - private function processFilterIs(array $filters, QueryCondition $queryCondition) + private function processFilterIs( + array $filters, + QueryCondition $queryCondition + ): void { foreach ($filters as $filter) { switch ($filter) { @@ -394,13 +404,12 @@ final class AccountSearchService extends Service /** * Devolver los accesos desde la caché * - * @param AccountSearchVData $accountSearchData - * - * @return AccountCache * @throws ConstraintException * @throws QueryException */ - protected function getCacheForAccount(AccountSearchVData $accountSearchData) + protected function getCacheForAccount( + AccountSearchVData $accountSearchData + ): AccountCache { $accountId = $accountSearchData->getId(); @@ -409,7 +418,7 @@ final class AccountSearchService extends Service $hasCache = $cache !== null; - if ($cache === false + if ($hasCache === false || !isset($cache[$accountId]) || $cache[$accountId]->getTime() < (int)strtotime($accountSearchData->getDateEdit()) ) { @@ -430,12 +439,11 @@ final class AccountSearchService extends Service * Seleccionar un color para la cuenta * * @param int $id El id del elemento a asignar - * - * @return string */ - private function pickAccountColor($id) + private function pickAccountColor(int $id): string { - if ($this->accountColor !== null && isset($this->accountColor[$id])) { + if ($this->accountColor !== null + && isset($this->accountColor[$id])) { return $this->accountColor[$id]; } @@ -455,10 +463,7 @@ final class AccountSearchService extends Service } } - /** - * @return string - */ - public function getCleanString() + public function getCleanString(): ?string { return $this->cleanString; } @@ -467,7 +472,7 @@ final class AccountSearchService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->accountRepository = $this->dic->get(AccountRepository::class); $this->accountToTagRepository = $this->dic->get(AccountToTagRepository::class); @@ -484,7 +489,7 @@ final class AccountSearchService extends Service /** * Load colors from cache */ - private function loadColors() + private function loadColors(): void { try { $this->accountColor = $this->colorCache->load(); diff --git a/lib/SP/Services/Account/AccountService.php b/lib/SP/Services/Account/AccountService.php index 458eeb6e..8e7e8165 100644 --- a/lib/SP/Services/Account/AccountService.php +++ b/lib/SP/Services/Account/AccountService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; @@ -42,6 +42,7 @@ use SP\DataModel\Dto\AccountHistoryCreateDto; use SP\DataModel\ItemPreset\AccountPermission; use SP\DataModel\ItemPreset\AccountPrivate; use SP\DataModel\ItemSearchData; +use SP\DataModel\ProfileData; use SP\Repositories\Account\AccountRepository; use SP\Repositories\Account\AccountToTagRepository; use SP\Repositories\Account\AccountToUserGroupRepository; @@ -54,7 +55,6 @@ use SP\Services\Service; use SP\Services\ServiceException; use SP\Services\ServiceItemTrait; use SP\Storage\Database\QueryResult; -use stdClass; /** * Class AccountService @@ -65,102 +65,78 @@ final class AccountService extends Service implements AccountServiceInterface { use ServiceItemTrait; - /** - * @var AccountRepository - */ - protected $accountRepository; - /** - * @var AccountToUserGroupRepository - */ - protected $accountToUserGroupRepository; - /** - * @var AccountToUserRepository - */ - protected $accountToUserRepository; - /** - * @var AccountToTagRepository - */ - protected $accountToTagRepository; - /** - * @var ItemPresetService - */ - protected $itemPresetService; + protected ?AccountRepository $accountRepository = null; + protected ?AccountToUserGroupRepository $accountToUserGroupRepository = null; + protected ?AccountToUserRepository $accountToUserRepository = null; + protected ?AccountToTagRepository $accountToTagRepository = null; + protected ?ItemPresetService $itemPresetService = null; /** - * @param AccountDetailsResponse $accountDetailsResponse - * - * @return AccountService * @throws QueryException * @throws ConstraintException */ - public function withUsersById(AccountDetailsResponse $accountDetailsResponse) + public function withUsersById(AccountDetailsResponse $accountDetailsResponse): AccountService { - $accountDetailsResponse->setUsers($this->accountToUserRepository->getUsersByAccountId($accountDetailsResponse->getId())->getDataAsArray()); + $accountDetailsResponse->setUsers( + $this->accountToUserRepository->getUsersByAccountId($accountDetailsResponse->getId()) + ->getDataAsArray() + ); return $this; } /** - * @param AccountDetailsResponse $accountDetailsResponse - * - * @return AccountService * @throws QueryException * @throws ConstraintException */ - public function withUserGroupsById(AccountDetailsResponse $accountDetailsResponse) + public function withUserGroupsById(AccountDetailsResponse $accountDetailsResponse): AccountService { - $accountDetailsResponse->setUserGroups($this->accountToUserGroupRepository->getUserGroupsByAccountId($accountDetailsResponse->getId())->getDataAsArray()); + $accountDetailsResponse->setUserGroups( + $this->accountToUserGroupRepository->getUserGroupsByAccountId($accountDetailsResponse->getId()) + ->getDataAsArray() + ); return $this; } /** - * @param AccountDetailsResponse $accountDetailsResponse - * - * @return AccountService * @throws QueryException * @throws ConstraintException */ - public function withTagsById(AccountDetailsResponse $accountDetailsResponse) + public function withTagsById(AccountDetailsResponse $accountDetailsResponse): AccountService { - $accountDetailsResponse->setTags($this->accountToTagRepository->getTagsByAccountId($accountDetailsResponse->getId())->getDataAsArray()); + $accountDetailsResponse->setTags( + $this->accountToTagRepository->getTagsByAccountId($accountDetailsResponse->getId()) + ->getDataAsArray() + ); return $this; } /** - * @param $id - * - * @return bool - * @throws QueryException - * @throws ConstraintException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function incrementViewCounter($id) + public function incrementViewCounter(int $id): bool { return $this->accountRepository->incrementViewCounter($id); } /** - * @param $id - * - * @return bool * @throws QueryException * @throws ConstraintException */ - public function incrementDecryptCounter($id) + public function incrementDecryptCounter(int $id): bool { return $this->accountRepository->incrementDecryptCounter($id); } /** - * @param $id - * - * @return AccountPassData - * @throws QueryException - * @throws ConstraintException - * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function getPasswordForId($id) + public function getPasswordForId(int $id): AccountPassData { $queryFilter = $this->dic->get(AccountFilterUser::class)->getFilter(); @@ -174,15 +150,12 @@ final class AccountService extends Service implements AccountServiceInterface } /** - * @param AccountRequest $accountRequest - * - * @return int * @throws QueryException * @throws SPException * @throws ConstraintException * @throws NoSuchPropertyException */ - public function create(AccountRequest $accountRequest) + public function create(AccountRequest $accountRequest): int { $userData = $this->context->getUserData(); @@ -223,13 +196,9 @@ final class AccountService extends Service implements AccountServiceInterface /** * Devolver los datos de la clave encriptados * - * @param string $pass - * @param string $masterPass Clave maestra a utilizar - * - * @return array - * @throws ServiceException + * @throws \SP\Services\ServiceException */ - public function getPasswordEncrypted($pass, $masterPass = null) + public function getPasswordEncrypted(string $pass, ?string $masterPass = null): array { try { if ($masterPass === null) { @@ -254,14 +223,12 @@ final class AccountService extends Service implements AccountServiceInterface } /** - * @param AccountRequest $accountRequest - * * @throws QueryException * @throws ConstraintException * @throws NoSuchPropertyException * @throws NoSuchItemException */ - private function setPresetPrivate(AccountRequest $accountRequest) + private function setPresetPrivate(AccountRequest $accountRequest): void { $userData = $this->context->getUserData(); $itemPreset = $this->itemPresetService->getForCurrentUser(ItemPresetInterface::ITEM_TYPE_ACCOUNT_PRIVATE); @@ -288,14 +255,11 @@ final class AccountService extends Service implements AccountServiceInterface } /** - * @param int $id - * - * @return AccountDetailsResponse * @throws QueryException * @throws NoSuchItemException * @throws ConstraintException */ - public function getById($id) + public function getById(int $id): AccountDetailsResponse { $result = $this->accountRepository->getById($id); @@ -308,41 +272,39 @@ final class AccountService extends Service implements AccountServiceInterface /** * Adds external items to the account - * - * @param AccountRequest $accountRequest */ - private function addItems(AccountRequest $accountRequest) + private function addItems(AccountRequest $accountRequest): void { try { if ($accountRequest->changePermissions) { if (is_array($accountRequest->userGroupsView) - && !empty($accountRequest->userGroupsView) + && count($accountRequest->userGroupsView) !== 0 ) { $this->accountToUserGroupRepository->addByType($accountRequest, false); } if (is_array($accountRequest->userGroupsEdit) - && !empty($accountRequest->userGroupsEdit) + && count($accountRequest->userGroupsEdit) !== 0 ) { $this->accountToUserGroupRepository->addByType($accountRequest, true); } if (is_array($accountRequest->usersView) - && !empty($accountRequest->usersView) + && count($accountRequest->usersView) !== 0 ) { $this->accountToUserRepository->addByType($accountRequest, false); } if (is_array($accountRequest->usersEdit) - && !empty($accountRequest->usersEdit) + && count($accountRequest->usersEdit) !== 0 ) { $this->accountToUserRepository->addByType($accountRequest, true); } } if (is_array($accountRequest->tags) - && !empty($accountRequest->tags) + && count($accountRequest->tags) !== 0 ) { $this->accountToTagRepository->add($accountRequest); } @@ -352,13 +314,11 @@ final class AccountService extends Service implements AccountServiceInterface } /** - * @param int $accountId - * * @throws QueryException * @throws ConstraintException * @throws NoSuchPropertyException */ - private function addPresetPermissions(int $accountId) + private function addPresetPermissions(int $accountId): void { $itemPresetData = $this->itemPresetService->getForCurrentUser(ItemPresetInterface::ITEM_TYPE_ACCOUNT_PERMISSION); @@ -394,13 +354,10 @@ final class AccountService extends Service implements AccountServiceInterface } /** - * @param AccountHistoryData $data - * - * @return int * @throws QueryException * @throws ConstraintException */ - public function createFromHistory(AccountHistoryData $data) + public function createFromHistory(AccountHistoryData $data): int { $accountRequest = new AccountRequest(); $accountRequest->name = $data->getName(); @@ -424,59 +381,55 @@ final class AccountService extends Service implements AccountServiceInterface /** * Updates external items for the account * - * @param AccountRequest $accountRequest - * * @throws Exception */ - public function update(AccountRequest $accountRequest) + public function update(AccountRequest $accountRequest): void { - $this->transactionAware(function () use ($accountRequest) { - $userData = $this->context->getUserData(); - $userProfile = $this->context->getUserProfile(); + $this->transactionAware( + function () use ($accountRequest) { + $userData = $this->context->getUserData(); + $userProfile = $this->context->getUserProfile() ?? new ProfileData(); - $accountRequest->changePermissions = - AccountAclService::getShowPermission($userData, $userProfile); + $accountRequest->changePermissions = + AccountAclService::getShowPermission($userData, $userProfile); - if ($accountRequest->changePermissions) { - $account = $this->getById($accountRequest->id)->getAccountVData(); + if ($accountRequest->changePermissions) { + $account = $this->getById($accountRequest->id)->getAccountVData(); - $accountRequest->changeOwner = $accountRequest->userId > 0 - && ($userData->getIsAdminApp() - || $userData->getIsAdminAcc() - || ($userProfile->isAccPermission() - && $userData->getId() === $account->getUserId())); + $accountRequest->changeOwner = $accountRequest->userId > 0 + && ($userData->getIsAdminApp() + || $userData->getIsAdminAcc() + || ($userProfile->isAccPermission() + && $userData->getId() === $account->getUserId())); - $accountRequest->changeUserGroup = $accountRequest->userGroupId > 0 - && ($userData->getIsAdminApp() - || $userData->getIsAdminAcc() - || ($userProfile->isAccPermission() - && ($userData->getUserGroupId() === $account->getUserGroupId()) - || $userData->getId() === $account->getUserId())); + $accountRequest->changeUserGroup = $accountRequest->userGroupId > 0 + && ($userData->getIsAdminApp() + || $userData->getIsAdminAcc() + || (($userProfile->isAccPermission() + && ($userData->getUserGroupId() === $account->getUserGroupId())) + || $userData->getId() === $account->getUserId())); + } + + $this->addHistory($accountRequest->id); + + $this->setPresetPrivate($accountRequest); + + $this->accountRepository->update($accountRequest); + + $this->updateItems($accountRequest); + + $this->addPresetPermissions($accountRequest->id); } - - $this->addHistory($accountRequest->id); - - $this->setPresetPrivate($accountRequest); - - $this->accountRepository->update($accountRequest); - - $this->updateItems($accountRequest); - - $this->addPresetPermissions($accountRequest->id); - }); + ); } /** - * @param int $accountId - * @param bool $isDelete - * - * @return bool * @throws NoSuchItemException * @throws QueryException * @throws ServiceException * @throws ConstraintException */ - private function addHistory($accountId, $isDelete = false) + private function addHistory(int $accountId, bool $isDelete = false): int { $accountHistoryRepository = $this->dic->get(AccountHistoryService::class); $configService = $this->dic->get(ConfigService::class); @@ -493,12 +446,10 @@ final class AccountService extends Service implements AccountServiceInterface /** * Updates external items for the account * - * @param AccountRequest $accountRequest - * * @throws QueryException * @throws ConstraintException */ - private function updateItems(AccountRequest $accountRequest) + private function updateItems(AccountRequest $accountRequest): void { if ($accountRequest->changePermissions) { if ($accountRequest->userGroupsView !== null) { @@ -546,31 +497,29 @@ final class AccountService extends Service implements AccountServiceInterface /** * Update accounts in bulk mode * - * @param AccountBulkRequest $request - * * @throws ServiceException */ - public function updateBulk(AccountBulkRequest $request) + public function updateBulk(AccountBulkRequest $request): void { - $this->transactionAware(function () use ($request) { - foreach ($request->getItemsId() as $itemId) { - $accountRequest = $request->getAccountRequestForId($itemId); + $this->transactionAware( + function () use ($request) { + foreach ($request->getItemsId() as $itemId) { + $accountRequest = $request->getAccountRequestForId($itemId); - $this->addHistory($accountRequest->id); + $this->addHistory($accountRequest->id); - $this->accountRepository->updateBulk($accountRequest); + $this->accountRepository->updateBulk($accountRequest); - $this->updateItems($accountRequest); + $this->updateItems($accountRequest); + } } - }); + ); } /** - * @param AccountRequest $accountRequest - * * @throws Exception */ - public function editPassword(AccountRequest $accountRequest) + public function editPassword(AccountRequest $accountRequest): void { $this->transactionAware(function () use ($accountRequest) { $this->addHistory($accountRequest->id); @@ -587,41 +536,37 @@ final class AccountService extends Service implements AccountServiceInterface /** * Updates an already encrypted password data from a master password changing action * - * @param AccountPasswordRequest $accountRequest - * - * @return bool * @throws ConstraintException * @throws QueryException */ - public function updatePasswordMasterPass(AccountPasswordRequest $accountRequest) + public function updatePasswordMasterPass(AccountPasswordRequest $accountRequest): bool { return $this->accountRepository->updatePassword($accountRequest); } /** - * @param $historyId - * @param $accountId + * @param int $historyId + * @param int $accountId * - * @throws Exception + * @throws \SP\Services\ServiceException */ - public function editRestore($historyId, $accountId) + public function editRestore(int $historyId, int $accountId): void { - $this->transactionAware(function () use ($historyId, $accountId) { - $this->addHistory($accountId); + $this->transactionAware( + function () use ($historyId, $accountId) { + $this->addHistory($accountId); - if (!$this->accountRepository->editRestore($historyId, $this->context->getUserData()->getId())) { - throw new ServiceException(__u('Error on restoring the account')); + if (!$this->accountRepository->editRestore($historyId, $this->context->getUserData()->getId())) { + throw new ServiceException(__u('Error on restoring the account')); + } } - }); + ); } /** - * @param $id - * - * @return AccountService - * @throws ServiceException + * @throws \SP\Services\ServiceException */ - public function delete($id) + public function delete(int $id): AccountService { $this->transactionAware(function () use ($id) { $this->addHistory($id, 1); @@ -635,13 +580,12 @@ final class AccountService extends Service implements AccountServiceInterface } /** - * @param array $ids + * @param int[] $ids * - * @return AccountService * @throws SPException * @throws ServiceException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): AccountService { if ($this->accountRepository->deleteByIdBatch($ids) === 0) { throw new ServiceException(__u('Error while deleting the accounts')); @@ -651,13 +595,10 @@ final class AccountService extends Service implements AccountServiceInterface } /** - * @param $accountId - * - * @return array * @throws QueryException * @throws ConstraintException */ - public function getForUser($accountId = null) + public function getForUser(int $accountId = null): array { $queryFilter = $this->dic->get(AccountFilterUser::class)->getFilter(); @@ -669,13 +610,10 @@ final class AccountService extends Service implements AccountServiceInterface } /** - * @param $accountId - * - * @return array * @throws QueryException * @throws ConstraintException */ - public function getLinked($accountId) + public function getLinked(int $accountId): array { $queryFilter = $this->dic->get(AccountFilterUser::class)->getFilter(); @@ -685,14 +623,11 @@ final class AccountService extends Service implements AccountServiceInterface } /** - * @param $id - * - * @return AccountPassData * @throws QueryException * @throws ConstraintException * @throws NoSuchItemException */ - public function getPasswordHistoryForId($id) + public function getPasswordHistoryForId(int $id): AccountPassData { $queryFilter = $this->dic->get(AccountFilterUser::class)->getFilterHistory(); $queryFilter->addFilter('AccountHistory.id = ?', [$id]); @@ -711,19 +646,16 @@ final class AccountService extends Service implements AccountServiceInterface * @throws QueryException * @throws ConstraintException */ - public function getAllBasic() + public function getAllBasic(): array { return $this->accountRepository->getAll()->getDataAsArray(); } /** - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws QueryException * @throws ConstraintException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->accountRepository->search($itemSearchData); } @@ -731,26 +663,22 @@ final class AccountService extends Service implements AccountServiceInterface /** * Devolver el número total de cuentas * - * @return stdClass - * @throws QueryException - * @throws ConstraintException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getTotalNumAccounts() + public function getTotalNumAccounts(): int { - return $this->accountRepository->getTotalNumAccounts()->num; + return (int)$this->accountRepository->getTotalNumAccounts()->num; } /** * Obtener los datos de una cuenta. * - * @param $id - * - * @return AccountExtData - * @throws QueryException - * @throws NoSuchItemException - * @throws ConstraintException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function getDataForLink($id) + public function getDataForLink(int $id): AccountExtData { $result = $this->accountRepository->getDataForLink($id); @@ -764,26 +692,22 @@ final class AccountService extends Service implements AccountServiceInterface /** * Obtener los datos relativos a la clave de todas las cuentas. * - * @return array Con los datos de la clave * @throws QueryException * @throws ConstraintException */ - public function getAccountsPassData() + public function getAccountsPassData(): array { - return $this->accountRepository->getAccountsPassData(); + return $this->accountRepository->getAccountsPassData()->getDataAsArray(); } /** * Obtener las cuentas de una búsqueda. * - * @param AccountSearchFilter $accountSearchFilter - * - * @return QueryResult * @throws QueryException * @throws SPException * @throws ConstraintException */ - public function getByFilter(AccountSearchFilter $accountSearchFilter) + public function getByFilter(AccountSearchFilter $accountSearchFilter): QueryResult { $accountFilterUser = $this->dic->get(AccountFilterUser::class); @@ -797,7 +721,7 @@ final class AccountService extends Service implements AccountServiceInterface * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->accountRepository = $this->dic->get(AccountRepository::class); $this->accountToUserRepository = $this->dic->get(AccountToUserRepository::class); diff --git a/lib/SP/Services/Account/AccountServiceInterface.php b/lib/SP/Services/Account/AccountServiceInterface.php index c29880cb..27c453b1 100644 --- a/lib/SP/Services/Account/AccountServiceInterface.php +++ b/lib/SP/Services/Account/AccountServiceInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; @@ -40,5 +40,5 @@ interface AccountServiceInterface * @return AccountDetailsResponse * @throws SPException */ - public function getById($id); + public function getById(int $id): AccountDetailsResponse; } \ No newline at end of file diff --git a/lib/SP/Services/Account/AccountToFavoriteService.php b/lib/SP/Services/Account/AccountToFavoriteService.php index d60d2671..6c718230 100644 --- a/lib/SP/Services/Account/AccountToFavoriteService.php +++ b/lib/SP/Services/Account/AccountToFavoriteService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; @@ -38,36 +38,28 @@ use SP\Services\Service; */ final class AccountToFavoriteService extends Service { - /** - * @var AccountToFavoriteRepository - */ - protected $accountFavoriteRepository; + protected ?AccountToFavoriteRepository $accountFavoriteRepository = null; /** * Obtener un array con los Ids de cuentas favoritas * - * @param $id int El Id de usuario - * - * @return array * @throws ConstraintException * @throws QueryException */ - public function getForUserId($id) + public function getForUserId(int $id): array { - return $this->accountFavoriteRepository->getForUserId($id)->getDataAsArray(); + return $this->accountFavoriteRepository + ->getForUserId($id) + ->getDataAsArray(); } /** * Añadir una cuenta a la lista de favoritos * - * @param $accountId int El Id de la cuenta - * @param $userId int El Id del usuario - * - * @return bool * @throws ConstraintException * @throws QueryException */ - public function add($accountId, $userId) + public function add(int $accountId, int $userId): int { return $this->accountFavoriteRepository->add($accountId, $userId); } @@ -75,14 +67,10 @@ final class AccountToFavoriteService extends Service /** * Eliminar una cuenta de la lista de favoritos * - * @param $accountId int El Id de la cuenta - * @param $userId int El Id del usuario - * - * @return int * @throws ConstraintException * @throws QueryException */ - public function delete($accountId, $userId) + public function delete(int $accountId, int $userId): int { return $this->accountFavoriteRepository->delete($accountId, $userId); } @@ -91,7 +79,7 @@ final class AccountToFavoriteService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->accountFavoriteRepository = $this->dic->get(AccountToFavoriteRepository::class); } diff --git a/lib/SP/Services/Account/AccountToTagService.php b/lib/SP/Services/Account/AccountToTagService.php index e79bdf8b..d61c1e02 100644 --- a/lib/SP/Services/Account/AccountToTagService.php +++ b/lib/SP/Services/Account/AccountToTagService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,15 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Account; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; -use SP\Core\Exceptions\ConstraintException; -use SP\Core\Exceptions\QueryException; use SP\DataModel\ItemData; use SP\Repositories\Account\AccountToTagRepository; use SP\Services\Service; @@ -39,28 +37,25 @@ use SP\Services\Service; */ final class AccountToTagService extends Service { - /** - * @var AccountToTagRepository - */ - protected $accountToTagRepository; + protected ?AccountToTagRepository $accountToTagRepository = null; /** - * @param $id - * * @return ItemData[] - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getTagsByAccountId($id) + public function getTagsByAccountId(int $id): array { - return $this->accountToTagRepository->getTagsByAccountId($id)->getDataAsArray(); + return $this->accountToTagRepository + ->getTagsByAccountId($id) + ->getDataAsArray(); } /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->accountToTagRepository = $this->dic->get(AccountToTagRepository::class); } diff --git a/lib/SP/Services/Api/ApiRequest.php b/lib/SP/Services/Api/ApiRequest.php index b86986fb..7921ff92 100644 --- a/lib/SP/Services/Api/ApiRequest.php +++ b/lib/SP/Services/Api/ApiRequest.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,11 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Api; +use JsonException; +use SP\Core\Exceptions\SPException; + /** * Class ApiRequest * @@ -31,27 +34,18 @@ namespace SP\Services\Api; */ final class ApiRequest { - /** - * @var string - */ - protected $method; - /** - * @var int - */ - protected $id; - /** - * @var ApiRequestData - */ - protected $data; + protected ?string $method = null; + protected ?int $id = null; + protected ?ApiRequestData $data = null; /** * ApiRequest constructor. * - * @param string $request + * @param string|null $request * - * @throws ApiRequestException + * @throws \SP\Services\Api\ApiRequestException */ - public function __construct($request = null) + public function __construct(?string $request = null) { if ($request === null) { $this->requestFromJsonData($this->getDataFromRequest()); @@ -65,34 +59,48 @@ final class ApiRequest * * Comprueba que el JSON esté bien formado * - * @param null $request + * @param string $request * * @return ApiRequest - * @throws ApiRequestException + * @throws \SP\Services\Api\ApiRequestException */ - public function requestFromJsonData($request) + public function requestFromJsonData(string $request): ApiRequest { - $data = json_decode($request, true); - - if ($data === null) { + try { + $data = json_decode( + $request, + true, + 512, + JSON_THROW_ON_ERROR + ); + } catch (JsonException $e) { throw new ApiRequestException( __u('Invalid data'), - ApiRequestException::ERROR, - json_last_error_msg(), + SPException::ERROR, + $e->getMessage(), JsonRpcResponse::PARSE_ERROR ); } - if (!isset($data['jsonrpc'], $data['method'], $data['params'], $data['id'], $data['params']['authToken'])) { + if (!isset( + $data['jsonrpc'], + $data['method'], + $data['id'], + $data['params']['authToken']) + ) { throw new ApiRequestException( __u('Invalid format'), - ApiRequestException::ERROR, + SPException::ERROR, null, JsonRpcResponse::INVALID_REQUEST ); } - $this->method = preg_replace('#[^a-z/]+#i', '', $data['method']); + $this->method = preg_replace( + '#[^a-z/]+#i', + '', + $data['method'] + ); $this->id = filter_var($data['id'], FILTER_VALIDATE_INT) ?: 1; $this->data = new ApiRequestData(); $this->data->replace($data['params']); @@ -104,14 +112,14 @@ final class ApiRequest * @return string * @throws ApiRequestException */ - public function getDataFromRequest() + public function getDataFromRequest(): string { $content = file_get_contents('php://input'); - if ($content === false || empty($content)) { + if (empty($content)) { throw new ApiRequestException( __u('Invalid data'), - ApiRequestException::ERROR, + SPException::ERROR, null, JsonRpcResponse::PARSE_ERROR ); @@ -136,7 +144,7 @@ final class ApiRequest * * @return bool */ - public function exists(string $key) + public function exists(string $key): bool { return $this->data->exists($key); } @@ -144,7 +152,7 @@ final class ApiRequest /** * @return string */ - public function getMethod() + public function getMethod(): string { return $this->method; } @@ -152,7 +160,7 @@ final class ApiRequest /** * @return int */ - public function getId() + public function getId(): int { return $this->id; } diff --git a/lib/SP/Services/Api/ApiRequestData.php b/lib/SP/Services/Api/ApiRequestData.php index 92c444a2..7c410797 100644 --- a/lib/SP/Services/Api/ApiRequestData.php +++ b/lib/SP/Services/Api/ApiRequestData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Api; diff --git a/lib/SP/Services/Api/ApiRequestException.php b/lib/SP/Services/Api/ApiRequestException.php index e5ef3213..ab0b432e 100644 --- a/lib/SP/Services/Api/ApiRequestException.php +++ b/lib/SP/Services/Api/ApiRequestException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Api; diff --git a/lib/SP/Services/Api/ApiResponse.php b/lib/SP/Services/Api/ApiResponse.php index bd152979..0fe74b43 100644 --- a/lib/SP/Services/Api/ApiResponse.php +++ b/lib/SP/Services/Api/ApiResponse.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Api; @@ -31,25 +31,13 @@ namespace SP\Services\Api; */ final class ApiResponse { - const RESULT_SUCCESS = 0; - const RESULT_ERROR = 1; + private const RESULT_SUCCESS = 0; + private const RESULT_ERROR = 1; - /** - * @var mixed - */ private $result; - /** - * @var int - */ - private $resultCode; - /** - * @var int - */ - private $itemId; - /** - * @var string - */ - private $resultMessage; + private ?int $resultCode = null; + private int $itemId; + private ?string $resultMessage = null; /** * ApiResponse constructor. @@ -65,12 +53,16 @@ final class ApiResponse /** * @param mixed $result - * @param int $itemId + * @param int|null $itemId * @param string|null $message * * @return ApiResponse */ - public static function makeSuccess($result, int $itemId = null, string $message = null) + public static function makeSuccess( + $result, + ?int $itemId = null, + string $message = null + ): ApiResponse { $out = new self($result, $itemId); $out->resultCode = self::RESULT_SUCCESS; @@ -85,7 +77,10 @@ final class ApiResponse * * @return ApiResponse */ - public static function makeError($result, string $message = null) + public static function makeError( + $result, + ?string $message = null + ): ApiResponse { $out = new self($result); $out->resultCode = self::RESULT_ERROR; @@ -97,7 +92,7 @@ final class ApiResponse /** * @return array */ - public function getResponse() + public function getResponse(): array { return [ 'itemId' => $this->itemId, diff --git a/lib/SP/Services/Api/ApiService.php b/lib/SP/Services/Api/ApiService.php index 71e19465..38e33b94 100644 --- a/lib/SP/Services/Api/ApiService.php +++ b/lib/SP/Services/Api/ApiService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Api; @@ -33,7 +33,6 @@ use SP\Core\Exceptions\InvalidArgumentException; use SP\Core\Exceptions\InvalidClassException; use SP\Core\Exceptions\SPException; use SP\DataModel\AuthTokenData; -use SP\Modules\Api\Controllers\Help\HelpInterface; use SP\Repositories\NoSuchItemException; use SP\Repositories\Track\TrackRequest; use SP\Services\AuthToken\AuthTokenService; @@ -51,45 +50,22 @@ use SP\Util\Filter; */ final class ApiService extends Service { - /** - * @var AuthTokenService - */ - private $authTokenService; - /** - * @var TrackService - */ - private $trackService; - /** - * @var ApiRequest - */ - private $apiRequest; - /** - * @var TrackRequest - */ - private $trackRequest; - /** - * @var AuthTokenData - */ - private $authTokenData; - /** - * @var HelpInterface - */ - private $helpClass; - /** - * @var bool - */ + private ?AuthTokenService $authTokenService = null; + private ?TrackService $trackService = null; + private ?ApiRequest $apiRequest = null; + private ?TrackRequest $trackRequest = null; + private ?AuthTokenData $authTokenData = null; + private ?string $helpClass = null; private $initialized = false; /** * Sets up API * - * @param int $actionId - * * @throws ServiceException * @throws SPException * @throws Exception */ - public function setup(int $actionId) + public function setup(int $actionId): void { $this->initialized = false; $this->apiRequest = $this->dic->get(ApiRequest::class); @@ -99,21 +75,25 @@ final class ApiService extends Service throw new ServiceException( __u('Attempts exceeded'), - ServiceException::ERROR, + SPException::ERROR, null, JsonRpcResponse::INTERNAL_ERROR ); } try { - $this->authTokenData = $this->authTokenService->getTokenByToken($actionId, $this->getParam('authToken')); + $this->authTokenData = $this->authTokenService + ->getTokenByToken( + $actionId, + $this->getParam('authToken') + ); } catch (NoSuchItemException $e) { logger($e->getMessage(), 'ERROR'); // For security reasons there won't be any hint about a not found token... throw new ServiceException( __u('Internal error'), - ServiceException::ERROR, + SPException::ERROR, null, JsonRpcResponse::INTERNAL_ERROR ); @@ -137,14 +117,14 @@ final class ApiService extends Service * * @throws ServiceException */ - private function addTracking() + private function addTracking(): void { try { $this->trackService->add($this->trackRequest); } catch (Exception $e) { throw new ServiceException( __u('Internal error'), - ServiceException::ERROR, + SPException::ERROR, null, JsonRpcResponse::INTERNAL_ERROR ); @@ -161,13 +141,17 @@ final class ApiService extends Service * @return mixed * @throws ServiceException */ - public function getParam($param, $required = false, $default = null) + public function getParam( + string $param, + bool $required = false, + $default = null + ) { if ($this->apiRequest === null || ($required && !$this->apiRequest->exists($param))) { throw new ServiceException( __u('Wrong parameters'), - ServiceException::ERROR, + SPException::ERROR, $this->getHelp($this->apiRequest->getMethod()), JsonRpcResponse::INVALID_PARAMS ); @@ -183,7 +167,7 @@ final class ApiService extends Service * * @return array */ - public function getHelp($action) + public function getHelp(string $action): array { if ($this->helpClass !== null) { return call_user_func([$this->helpClass, 'getHelpFor'], $action); @@ -195,13 +179,13 @@ final class ApiService extends Service /** * @throws ServiceException */ - private function accessDenied() + private function accessDenied(): void { $this->addTracking(); throw new ServiceException( __u('Unauthorized access'), - ServiceException::ERROR, + SPException::ERROR, null, JsonRpcResponse::INTERNAL_ERROR ); @@ -212,10 +196,12 @@ final class ApiService extends Service * * @throws SPException */ - private function setupUser() + private function setupUser(): void { - $userLoginResponse = UserService::mapUserLoginResponse($this->dic->get(UserService::class) - ->getById($this->authTokenData->getUserId())); + $userLoginResponse = UserService::mapUserLoginResponse( + $this->dic->get(UserService::class) + ->getById($this->authTokenData->getUserId()) + ); $userLoginResponse->getIsDisabled() && $this->accessDenied(); $this->context->setUserData($userLoginResponse); @@ -227,18 +213,20 @@ final class ApiService extends Service * @throws ServiceException * @throws ContextException */ - public function requireMasterPass() + public function requireMasterPass(): void { - $this->context->setTrasientKey('_masterpass', $this->getMasterPassFromVault()); + $this->context->setTrasientKey( + '_masterpass', + $this->getMasterPassFromVault() + ); } /** * Devolver la clave maestra * - * @return string * @throws ServiceException */ - private function getMasterPassFromVault() + private function getMasterPassFromVault(): string { try { $tokenPass = $this->getParam('tokenPass', true); @@ -250,18 +238,18 @@ final class ApiService extends Service if ($vault && ($pass = $vault->getData($tokenPass . $this->getParam('authToken')))) { return $pass; - } else { - throw new ServiceException( - __u('Internal error'), - ServiceException::ERROR, - __u('Invalid data'), - JsonRpcResponse::INTERNAL_ERROR - ); } + + throw new ServiceException( + __u('Internal error'), + SPException::ERROR, + __u('Invalid data'), + JsonRpcResponse::INTERNAL_ERROR + ); } catch (CryptoException $e) { throw new ServiceException( __u('Internal error'), - ServiceException::ERROR, + SPException::ERROR, $e->getMessage(), JsonRpcResponse::INTERNAL_ERROR ); @@ -269,40 +257,37 @@ final class ApiService extends Service } /** - * @param string $param - * @param bool $required - * @param mixed $default - * - * @return int * @throws ServiceException */ - public function getParamInt($param, $required = false, $default = null) + public function getParamInt( + string $param, + bool $required = false, + $default = null + ): int { return Filter::getInt($this->getParam($param, $required, $default)); } /** - * @param string $param - * @param bool $required - * @param mixed $default - * - * @return string * @throws ServiceException */ - public function getParamString($param, $required = false, $default = null) + public function getParamString( + string $param, + bool $required = false, + $default = null + ): string { return Filter::getString($this->getParam($param, $required, $default)); } /** - * @param string $param - * @param bool $required - * @param mixed $default - * - * @return array * @throws ServiceException */ - public function getParamArray($param, $required = false, $default = null) + public function getParamArray( + string $param, + bool $required = false, + $default = null): + ?array { $array = $this->getParam($param, $required, $default); @@ -310,78 +295,50 @@ final class ApiService extends Service return Filter::getArray($array); } - return $array; + return null; } /** - * @param string $param - * @param bool $required - * @param mixed $default - * - * @return int|string * @throws ServiceException */ - public function getParamEmail($param, $required = false, $default = null) - { - return Filter::getEmail($this->getParam($param, $required, $default)); - } - - /** - * @param string $param - * @param bool $required - * @param mixed $default - * - * @return string - * @throws ServiceException - */ - public function getParamRaw($param, $required = false, $default = null) + public function getParamRaw( + string $param, + bool $required = false, + $default = null + ): string { return Filter::getRaw($this->getParam($param, $required, $default)); } /** - * @return string * @throws ServiceException */ - public function getMasterPass() + public function getMasterPass(): string { return $this->getMasterKeyFromContext(); } - /** - * @param ApiRequest $apiRequest - * - * @return ApiService - */ - public function setApiRequest(ApiRequest $apiRequest) + public function setApiRequest(ApiRequest $apiRequest): ApiService { $this->apiRequest = $apiRequest; return $this; } - /** - * @return int - */ - public function getRequestId() + public function getRequestId(): int { return $this->apiRequest->getId(); } - /** - * @return bool - */ public function isInitialized(): bool { return $this->initialized; } /** - * @param string $helpClass - * * @throws InvalidClassException */ - public function setHelpClass(string $helpClass) + public function setHelpClass(string $helpClass): void { if (class_exists($helpClass)) { $this->helpClass = $helpClass; @@ -394,7 +351,7 @@ final class ApiService extends Service /** * @throws InvalidArgumentException */ - protected function initialize() + protected function initialize(): void { $this->authTokenService = $this->dic->get(AuthTokenService::class); $this->trackService = $this->dic->get(TrackService::class); diff --git a/lib/SP/Services/Api/JsonRpcResponse.php b/lib/SP/Services/Api/JsonRpcResponse.php index 644988a6..d369bb12 100644 --- a/lib/SP/Services/Api/JsonRpcResponse.php +++ b/lib/SP/Services/Api/JsonRpcResponse.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Api; @@ -35,12 +35,12 @@ use SP\Http\Json; */ final class JsonRpcResponse { - const PARSE_ERROR = -32700; - const INVALID_REQUEST = -32600; - const METHOD_NOT_FOUND = -32601; - const INVALID_PARAMS = -32602; - const INTERNAL_ERROR = -32603; - const SERVER_ERROR = -32000; + public const PARSE_ERROR = -32700; + public const INVALID_REQUEST = -32600; + public const METHOD_NOT_FOUND = -32601; + public const INVALID_PARAMS = -32602; + public const INTERNAL_ERROR = -32603; + public const SERVER_ERROR = -32000; /** * @param ApiResponse $apiResponse @@ -49,7 +49,10 @@ final class JsonRpcResponse * @return string * @throws SPException */ - public static function getResponse(ApiResponse $apiResponse, int $id) + public static function getResponse( + ApiResponse $apiResponse, + int $id + ): string { return Json::getJson([ 'jsonrpc' => '2.0', @@ -58,13 +61,7 @@ final class JsonRpcResponse ], JSON_UNESCAPED_SLASHES); } - /** - * @param Exception $e - * @param int $id - * - * @return string - */ - public static function getResponseException(Exception $e, int $id) + public static function getResponseException(Exception $e, int $id): string { $data = ($e instanceof SPException) ? $e->getHint() : null; @@ -72,14 +69,19 @@ final class JsonRpcResponse } /** - * @param string $message - * @param int $code - * @param int $id - * @param mixed $data + * @param string $message + * @param int $code + * @param int $id + * @param mixed|null $data * * @return string */ - public static function getResponseError(string $message, int $code, int $id, $data = null) + public static function getResponseError( + string $message, + int $code, + int $id, + $data = null + ): string { return json_encode([ 'jsonrpc' => '2.0', diff --git a/lib/SP/Services/Auth/AuthException.php b/lib/SP/Services/Auth/AuthException.php index d2e0b2ae..7c123d77 100644 --- a/lib/SP/Services/Auth/AuthException.php +++ b/lib/SP/Services/Auth/AuthException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Auth; diff --git a/lib/SP/Services/Auth/LoginResponse.php b/lib/SP/Services/Auth/LoginResponse.php index edb6478e..5ad180b4 100644 --- a/lib/SP/Services/Auth/LoginResponse.php +++ b/lib/SP/Services/Auth/LoginResponse.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Auth; @@ -31,39 +31,27 @@ namespace SP\Services\Auth; */ final class LoginResponse { - /** - * @var int - */ - private $status; - /** - * @var string - */ - private $redirect; + private int $status; + private ?string $redirect = null; /** * LoginResponse constructor. * - * @param int $status - * @param string $redirect + * @param int $status + * @param string|null $redirect */ - public function __construct($status, $redirect = null) + public function __construct(int $status, ?string $redirect = null) { $this->status = $status; $this->redirect = $redirect; } - /** - * @return int - */ - public function getStatus() + public function getStatus(): int { return $this->status; } - /** - * @return string - */ - public function getRedirect() + public function getRedirect(): ?string { return $this->redirect; } diff --git a/lib/SP/Services/Auth/LoginService.php b/lib/SP/Services/Auth/LoginService.php index be38640f..b7e5bc93 100644 --- a/lib/SP/Services/Auth/LoginService.php +++ b/lib/SP/Services/Auth/LoginService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Auth; @@ -31,7 +31,7 @@ use Defuse\Crypto\Exception\EnvironmentIsBrokenException; use Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; @@ -72,51 +72,24 @@ final class LoginService extends Service /** * Estados */ - const STATUS_INVALID_LOGIN = 1; - const STATUS_INVALID_MASTER_PASS = 2; - const STATUS_USER_DISABLED = 3; - const STATUS_NEED_OLD_PASS = 5; - const STATUS_MAX_ATTEMPTS_EXCEEDED = 6; - const STATUS_PASS_RESET = 7; - const STATUS_PASS = 0; - const STATUS_NONE = 100; + private const STATUS_INVALID_LOGIN = 1; + private const STATUS_INVALID_MASTER_PASS = 2; + private const STATUS_USER_DISABLED = 3; + private const STATUS_NEED_OLD_PASS = 5; + private const STATUS_MAX_ATTEMPTS_EXCEEDED = 6; + private const STATUS_PASS_RESET = 7; + private const STATUS_PASS = 0; + private const STATUS_NONE = 100; - /** - * @var UserLoginData - */ - private $userLoginData; - /** - * @var ConfigData - */ - private $configData; - /** - * @var ThemeInterface - */ - private $theme; - /** - * @var UserService - */ - private $userService; - /** - * @var Language - */ - private $language; - /** - * @var TrackService - */ - private $trackService; - /** - * @var TrackRequest - */ - private $trackRequest; - /** - * @var string - */ - private $from; - /** - * @var Request - */ - private $request; + private ?UserLoginData $userLoginData = null; + private ?ConfigDataInterface $configData = null; + private ?ThemeInterface $theme = null; + private ?UserService $userService = null; + private ?Language $language = null; + private ?TrackService $trackService = null; + private ?TrackRequest $trackRequest = null; + private ?string $from = null; + private ?Request $request = null; /** * Ejecutar las acciones de login @@ -135,7 +108,7 @@ final class LoginService extends Service * @uses LoginService::authLdap() * */ - public function doLogin() + public function doLogin(): LoginResponse { $this->userLoginData->setLoginUser($this->request->analyzeString('user')); $this->userLoginData->setLoginPass($this->request->analyzeEncrypted('pass')); @@ -145,13 +118,14 @@ final class LoginService extends Service throw new AuthException( __u('Attempts exceeded'), - AuthException::INFO, + SPException::INFO, null, self::STATUS_MAX_ATTEMPTS_EXCEEDED ); } - $result = $this->dic->get(AuthProvider::class)->doAuth($this->userLoginData); + $result = $this->dic->get(AuthProvider::class) + ->doAuth($this->userLoginData); if ($result !== false) { // Ejecutar la acción asociada al tipo de autentificación @@ -169,7 +143,7 @@ final class LoginService extends Service throw new AuthException( __u('Wrong login'), - AuthException::INFO, + SPException::INFO, __FUNCTION__, self::STATUS_INVALID_LOGIN ); @@ -186,7 +160,7 @@ final class LoginService extends Service $uri = new Uri('index.php'); - if ($this->from) { + if (!empty($this->from)) { $uri->addParam('r', $this->from); } else { $uri->addParam('r', 'index'); @@ -200,14 +174,14 @@ final class LoginService extends Service * * @throws AuthException */ - private function addTracking() + private function addTracking(): void { try { $this->trackService->add($this->trackRequest); } catch (Exception $e) { throw new AuthException( __u('Internal error'), - AuthException::ERROR, + SPException::ERROR, null, Service::STATUS_INTERNAL_ERROR ); @@ -225,7 +199,7 @@ final class LoginService extends Service * @throws QueryException * @throws AuthException */ - private function checkUser() + private function checkUser(): LoginResponse { $userLoginResponse = $this->userLoginData->getUserLoginResponse(); @@ -243,7 +217,7 @@ final class LoginService extends Service throw new AuthException( __u('User disabled'), - AuthException::INFO, + SPException::INFO, null, self::STATUS_USER_DISABLED ); @@ -265,7 +239,10 @@ final class LoginService extends Service $uri = new Uri('index.php'); $uri->addParam('r', 'userPassReset/reset/' . $hash); - return new LoginResponse(self::STATUS_PASS_RESET, $uri->getUri()); + return new LoginResponse( + self::STATUS_PASS_RESET, + $uri->getUri() + ); } } @@ -280,7 +257,7 @@ final class LoginService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - private function loadMasterPass() + private function loadMasterPass(): void { $temporaryMasterPass = $this->dic->get(TemporaryMasterPassService::class); $userPassService = $this->dic->get(UserPassService::class); @@ -314,7 +291,7 @@ final class LoginService extends Service throw new AuthException( __u('Wrong master password'), - AuthException::INFO, + SPException::INFO, null, self::STATUS_INVALID_MASTER_PASS ); @@ -340,7 +317,7 @@ final class LoginService extends Service throw new AuthException( __u('Wrong master password'), - AuthException::INFO, + SPException::INFO, null, self::STATUS_INVALID_MASTER_PASS ); @@ -356,11 +333,10 @@ final class LoginService extends Service case UserPassService::MPASS_CHECKOLD: throw new AuthException( __u('Your previous password is needed'), - AuthException::INFO, + SPException::INFO, null, self::STATUS_NEED_OLD_PASS ); - break; case UserPassService::MPASS_NOTSET: case UserPassService::MPASS_CHANGED: case UserPassService::MPASS_WRONG: @@ -368,11 +344,10 @@ final class LoginService extends Service throw new AuthException( __u('The Master Password either is not saved or is wrong'), - AuthException::INFO, + SPException::INFO, null, self::STATUS_INVALID_MASTER_PASS ); - break; } } } catch (CryptoException $e) { @@ -380,7 +355,7 @@ final class LoginService extends Service throw new AuthException( __u('Internal error'), - AuthException::ERROR, + SPException::ERROR, $e->getMessage(), Service::STATUS_INTERNAL_ERROR, $e @@ -397,7 +372,7 @@ final class LoginService extends Service * @throws QueryException * @throws NoSuchItemException */ - private function setUserSession() + private function setUserSession(): void { $userLoginResponse = $this->userLoginData->getUserLoginResponse(); @@ -410,7 +385,11 @@ final class LoginService extends Service // Cargar las variables de ussuario en la sesión $this->context->setUserData($userLoginResponse); - $this->context->setUserProfile($this->dic->get(UserProfileService::class)->getById($userLoginResponse->getUserProfileId())->getProfile()); + $this->context->setUserProfile( + $this->dic->get(UserProfileService::class) + ->getById($userLoginResponse->getUserProfileId()) + ->getProfile() + ); $this->context->setLocale($userLoginResponse->getPreferences()->getLang()); if ($this->configData->isDemoEnabled()) { @@ -427,7 +406,7 @@ final class LoginService extends Service /** * Cargar las preferencias del usuario y comprobar si usa 2FA */ - private function loadUserPreferences() + private function loadUserPreferences(): void { $this->language->setLanguage(true); @@ -444,15 +423,15 @@ final class LoginService extends Service /** * Limpiar datos de usuario */ - private function cleanUserData() + private function cleanUserData(): void { $this->userLoginData->setUserLoginResponse(); } /** - * @param string $from + * @param string|null $from */ - public function setFrom($from) + public function setFrom(?string $from): void { $this->from = $from; } @@ -462,7 +441,7 @@ final class LoginService extends Service * @throws NotFoundExceptionInterface * @throws InvalidArgumentException */ - protected function initialize() + protected function initialize(): void { $this->configData = $this->config->getConfigData(); $this->theme = $this->dic->get(ThemeInterface::class); @@ -470,7 +449,6 @@ final class LoginService extends Service $this->language = $this->dic->get(Language::class); $this->trackService = $this->dic->get(TrackService::class); $this->request = $this->dic->get(Request::class); - $this->userLoginData = new UserLoginData(); $this->trackRequest = $this->trackService->getTrackRequest(__CLASS__); } @@ -484,7 +462,7 @@ final class LoginService extends Service * @throws SPException * @throws AuthException */ - private function authLdap(LdapAuthData $authData) + private function authLdap(LdapAuthData $authData): bool { if ($authData->getStatusCode() > LdapCode::SUCCESS) { $eventMessage = EventMessage::factory() @@ -504,7 +482,7 @@ final class LoginService extends Service throw new AuthException( __u('Wrong login'), - AuthException::INFO, + SPException::INFO, __FUNCTION__, self::STATUS_INVALID_LOGIN ); @@ -520,7 +498,7 @@ final class LoginService extends Service throw new AuthException( __u('Account expired'), - AuthException::INFO, + SPException::INFO, __FUNCTION__, self::STATUS_USER_DISABLED ); @@ -536,7 +514,7 @@ final class LoginService extends Service throw new AuthException( __u('User has no associated groups'), - AuthException::INFO, + SPException::INFO, __FUNCTION__, self::STATUS_USER_DISABLED ); @@ -564,7 +542,7 @@ final class LoginService extends Service throw new AuthException( __u('Internal error'), - AuthException::INFO, + SPException::INFO, __FUNCTION__, Service::STATUS_INTERNAL_ERROR ); @@ -591,7 +569,7 @@ final class LoginService extends Service $userLoginRequest->setEmail($authData->getEmail()); $userLoginRequest->setName($authData->getName()); - $userLoginRequest->setIsLdap(1); + $userLoginRequest->setIsLdap(true); // Verificamos si el usuario existe en la BBDD if ($this->userService->checkExistsByLogin($this->userLoginData->getLoginUser())) { @@ -604,7 +582,7 @@ final class LoginService extends Service } catch (Exception $e) { throw new AuthException( __u('Internal error'), - AuthException::ERROR, + SPException::ERROR, __FUNCTION__, Service::STATUS_INTERNAL_ERROR, $e @@ -623,7 +601,7 @@ final class LoginService extends Service * @throws SPException * @throws AuthException */ - private function authDatabase(DatabaseAuthData $authData) + private function authDatabase(DatabaseAuthData $authData): bool { $eventMessage = EventMessage::factory() ->addDetail(__u('Type'), __FUNCTION__) @@ -653,7 +631,7 @@ final class LoginService extends Service throw new AuthException( __u('Wrong login'), - AuthException::INFO, + SPException::INFO, __FUNCTION__, self::STATUS_INVALID_LOGIN ); @@ -675,7 +653,7 @@ final class LoginService extends Service * @return bool * @throws AuthException */ - private function authBrowser(BrowserAuthData $authData) + private function authBrowser(BrowserAuthData $authData): bool { $authType = $this->request->getServer('AUTH_TYPE') ?: __('N/A'); @@ -708,7 +686,7 @@ final class LoginService extends Service throw new AuthException( __u('Wrong login'), - AuthException::INFO, + SPException::INFO, __FUNCTION__, self::STATUS_INVALID_LOGIN ); @@ -733,7 +711,7 @@ final class LoginService extends Service } catch (Exception $e) { throw new AuthException( __u('Internal error'), - AuthException::ERROR, + SPException::ERROR, __FUNCTION__, Service::STATUS_INTERNAL_ERROR, $e diff --git a/lib/SP/Services/AuthToken/AuthTokenService.php b/lib/SP/Services/AuthToken/AuthTokenService.php index 0632bf77..030ffeb6 100644 --- a/lib/SP/Services/AuthToken/AuthTokenService.php +++ b/lib/SP/Services/AuthToken/AuthTokenService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\AuthToken; @@ -55,31 +55,28 @@ final class AuthTokenService extends Service { use ServiceItemTrait; - const SECURED_ACTIONS = [ + private const SECURED_ACTIONS = [ ActionsInterface::ACCOUNT_VIEW_PASS, ActionsInterface::ACCOUNT_EDIT_PASS, ActionsInterface::ACCOUNT_CREATE ]; - const CAN_USE_SECURE_TOKEN_ACTIONS = [ + private const CAN_USE_SECURE_TOKEN_ACTIONS = [ ActionsInterface::ACCOUNT_VIEW, ActionsInterface::CATEGORY_VIEW, ActionsInterface::CLIENT_VIEW, ]; - /** - * @var AuthTokenRepository - */ - protected $authTokenRepository; + protected ?AuthTokenRepository $authTokenRepository = null; /** * Devuelver un array de acciones posibles para los tokens * * @return array */ - public static function getTokenActions() + public static function getTokenActions(): array { - $actions = [ + return [ ActionsInterface::ACCOUNT_SEARCH => Acl::getActionInfo(ActionsInterface::ACCOUNT_SEARCH), ActionsInterface::ACCOUNT_VIEW => Acl::getActionInfo(ActionsInterface::ACCOUNT_VIEW), ActionsInterface::ACCOUNT_VIEW_PASS => Acl::getActionInfo(ActionsInterface::ACCOUNT_VIEW_PASS), @@ -110,43 +107,32 @@ final class AuthTokenService extends Service ActionsInterface::CONFIG_BACKUP_RUN => Acl::getActionInfo(ActionsInterface::CONFIG_BACKUP_RUN), ActionsInterface::CONFIG_EXPORT_RUN => Acl::getActionInfo(ActionsInterface::CONFIG_EXPORT_RUN) ]; - - return $actions; } /** - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->authTokenRepository->search($itemSearchData); } /** - * @param $id - * - * @return AuthTokenData - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getById($id) + public function getById(int $id): AuthTokenData { return $this->authTokenRepository->getById($id)->getData(); } /** - * @param $id - * - * @return AuthTokenService - * @throws ConstraintException - * @throws QueryException - * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function delete($id) + public function delete(int $id): AuthTokenService { if ($this->authTokenRepository->delete($id) === 0) { throw new NoSuchItemException(__u('Token not found')); @@ -158,33 +144,32 @@ final class AuthTokenService extends Service /** * Deletes all the items for given ids * - * @param array $ids - * - * @return bool * @throws ServiceException * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (($count = $this->authTokenRepository->deleteByIdBatch($ids)) !== count($ids)) { - throw new ServiceException(__u('Error while removing the tokens'), ServiceException::WARNING); + $count = $this->authTokenRepository->deleteByIdBatch($ids); + + if ($count !== count($ids)) { + throw new ServiceException( + __u('Error while removing the tokens'), + SPException::WARNING + ); } return $count; } /** - * @param $itemData - * - * @return mixed * @throws SPException * @throws CryptoException * @throws EnvironmentIsBrokenException * @throws ConstraintException * @throws QueryException */ - public function create($itemData) + public function create($itemData): int { return $this->authTokenRepository->create($this->injectSecureData($itemData)); } @@ -192,26 +177,28 @@ final class AuthTokenService extends Service /** * Injects secure data for token * - * @param AuthTokenData $authTokenData - * @param string $token - * - * @return AuthTokenData * @throws ServiceException * @throws CryptoException * @throws EnvironmentIsBrokenException * @throws ConstraintException * @throws QueryException */ - private function injectSecureData(AuthTokenData $authTokenData, $token = null) + private function injectSecureData( + AuthTokenData $authTokenData, + ?string $token = null + ): AuthTokenData { if ($token === null) { - $token = $this->authTokenRepository->getTokenByUserId($authTokenData->getUserId()) ?: $this->generateToken(); + $token = $this->authTokenRepository + ->getTokenByUserId($authTokenData->getUserId()) ?: $this->generateToken(); } if (self::isSecuredAction($authTokenData->getActionId()) || self::canUseSecureTokenAction($authTokenData->getActionId()) ) { - $authTokenData->setVault($this->getSecureData($token, $authTokenData->getHash())); + $authTokenData->setVault( + $this->getSecureData($token, $authTokenData->getHash()) + ); $authTokenData->setHash(Hash::hashKey($authTokenData->getHash())); } else { $authTokenData->setHash(null); @@ -226,30 +213,19 @@ final class AuthTokenService extends Service /** * Generar un token de acceso * - * @return string * @throws EnvironmentIsBrokenException */ - private function generateToken() + private function generateToken(): string { return PasswordUtil::generateRandomBytes(32); } - /** - * @param int $action - * - * @return bool - */ - public static function isSecuredAction(int $action) + public static function isSecuredAction(int $action): bool { return in_array($action, self::SECURED_ACTIONS, true); } - /** - * @param int $action - * - * @return bool - */ - public static function canUseSecureTokenAction(int $action) + public static function canUseSecureTokenAction(int $action): bool { return in_array($action, self::CAN_USE_SECURE_TOKEN_ACTIONS, true); } @@ -257,46 +233,54 @@ final class AuthTokenService extends Service /** * Generar la llave segura del token * - * @param string $token - * @param string $key - * - * @return Vault * @throws ServiceException * @throws CryptoException */ - private function getSecureData($token, $key) + private function getSecureData(string $token, string $key): Vault { - return (new Vault())->saveData($this->getMasterKeyFromContext(), $key . $token); + return (new Vault())->saveData( + $this->getMasterKeyFromContext(), + $key . $token + ); } /** - * @param AuthTokenData $itemData - * * @throws Exception */ - public function refreshAndUpdate(AuthTokenData $itemData) + public function refreshAndUpdate(AuthTokenData $itemData): void { - $this->transactionAware(function () use ($itemData) { - $token = $this->generateToken(); - $vault = serialize($this->getSecureData($token, $itemData->getHash())); + $this->transactionAware( + function () use ($itemData) { + $token = $this->generateToken(); + $vault = serialize( + $this->getSecureData($token, $itemData->getHash()) + ); - $this->authTokenRepository->refreshTokenByUserId($itemData->getUserId(), $token); - $this->authTokenRepository->refreshVaultByUserId($itemData->getUserId(), $vault, Hash::hashKey($itemData->getHash())); + $this->authTokenRepository->refreshTokenByUserId( + $itemData->getUserId(), + $token + ); + $this->authTokenRepository->refreshVaultByUserId( + $itemData->getUserId(), + $vault, + Hash::hashKey($itemData->getHash()) + ); - $this->update($itemData, $token); - }); + $this->update($itemData, $token); + } + ); } /** - * @param AuthTokenData $itemData - * @param string $token - * - * @throws SPException - * @throws CryptoException - * @throws ConstraintException - * @throws QueryException + * @throws \Defuse\Crypto\Exception\CryptoException + * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\DuplicatedItemException + * @throws \SP\Repositories\NoSuchItemException + * @throws \SP\Services\ServiceException */ - public function update(AuthTokenData $itemData, $token = null) + public function update(AuthTokenData $itemData, ?string $token = null): void { if ($this->authTokenRepository->update($this->injectSecureData($itemData, $token)) === 0) { throw new NoSuchItemException(__u('Token not found')); @@ -304,13 +288,11 @@ final class AuthTokenService extends Service } /** - * @param AuthTokenData $itemData - * * @throws SPException * @throws ConstraintException * @throws QueryException */ - public function updateRaw(AuthTokenData $itemData) + public function updateRaw(AuthTokenData $itemData): void { if ($this->authTokenRepository->update($itemData) === 0) { throw new NoSuchItemException(__u('Token not found')); @@ -320,15 +302,11 @@ final class AuthTokenService extends Service /** * Devolver los datos de un token * - * @param $actionId int El id de la accion - * @param $token string El token de seguridad - * - * @return false|AuthTokenData * @throws ConstraintException * @throws NoSuchItemException * @throws QueryException */ - public function getTokenByToken($actionId, $token) + public function getTokenByToken(int $actionId, string $token) { $result = $this->authTokenRepository->getTokenByToken($actionId, $token); @@ -344,7 +322,7 @@ final class AuthTokenService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAllBasic() + public function getAllBasic(): array { return $this->authTokenRepository->getAll()->getDataAsArray(); } @@ -353,7 +331,7 @@ final class AuthTokenService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->authTokenRepository = $this->dic->get(AuthTokenRepository::class); } diff --git a/lib/SP/Services/Backup/FileBackupService.php b/lib/SP/Services/Backup/FileBackupService.php index 4e552dcb..e5a93cd4 100644 --- a/lib/SP/Services/Backup/FileBackupService.php +++ b/lib/SP/Services/Backup/FileBackupService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Backup; @@ -28,13 +28,11 @@ use Exception; use PDO; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\AppInfoInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\CheckException; -use SP\Core\Exceptions\ConstraintException; -use SP\Core\Exceptions\QueryException; use SP\Core\Exceptions\SPException; use SP\Core\PhpExtensionChecker; use SP\Services\Service; @@ -56,39 +54,19 @@ final class FileBackupService extends Service { private const BACKUP_EXCLUDE_REGEX = '#^(?!.*(backup|cache|temp|vendor|tests))(.*)$#i'; - /** - * @var ConfigData - */ - private $configData; - /** - * @var string - */ - private $path; - /** - * @var string - */ - private $backupFileApp; - /** - * @var string - */ - private $backupFileDb; - /** - * @var PhpExtensionChecker - */ - private $extensionChecker; - /** - * @var string - */ - private $hash; + private ?ConfigDataInterface $configData = null; + private ?string $path = null; + private ?string $backupFileApp = null; + private ?string $backupFileDb = null; + private ?PhpExtensionChecker $extensionChecker = null; + private ?string $hash = null; /** * Realizar backup de la BBDD y aplicación. * - * @param string $path - * * @throws ServiceException */ - public function doBackup(string $path) + public function doBackup(string $path): void { set_time_limit(0); @@ -109,7 +87,7 @@ final class FileBackupService extends Service new Event($this, EventMessage::factory()->addDescription(__u('Make Backup')))); - $this->backupTables(new FileHandler($this->backupFileDb), '*'); + $this->backupTables(new FileHandler($this->backupFileDb)); if (!$this->backupApp() && !$this->backupAppLegacyLinux() @@ -137,7 +115,6 @@ final class FileBackupService extends Service /** * Comprobar y crear el directorio de backups. * - * @return void * @throws ServiceException */ private function checkBackupDir(): void @@ -157,14 +134,11 @@ final class FileBackupService extends Service } - /** - * @param string $path - * @param string $hash - * @param bool $compressed - * - * @return string - */ - public static function getAppBackupFilename(string $path, string $hash, bool $compressed = false) + public static function getAppBackupFilename( + string $path, + string $hash, + bool $compressed = false + ): string { $file = $path . DIRECTORY_SEPARATOR . AppInfoInterface::APP_NAME . '_app-' . $hash; @@ -175,14 +149,11 @@ final class FileBackupService extends Service return $file; } - /** - * @param string $path - * @param string $hash - * @param bool $compressed - * - * @return string - */ - public static function getDbBackupFilename(string $path, string $hash, bool $compressed = false) + public static function getDbBackupFilename( + string $path, + string $hash, + bool $compressed = false + ): string { $file = $path . DIRECTORY_SEPARATOR . AppInfoInterface::APP_NAME . '_db-' . $hash; @@ -196,32 +167,36 @@ final class FileBackupService extends Service /** * Eliminar las copias de seguridad anteriores */ - private function deleteOldBackups() + private function deleteOldBackups(): void { $path = $this->path . DIRECTORY_SEPARATOR . AppInfoInterface::APP_NAME; - array_map(function ($file) { - return @unlink($file); - }, array_merge( - glob($path . '_db-*'), - glob($path . '_app-*'), - glob($path . '*.sql') - )); + array_map( + static function ($file) { + return @unlink($file); + }, + array_merge( + glob($path . '_db-*'), + glob($path . '_app-*'), + glob($path . '*.sql') + ) + ); } /** * Backup de las tablas de la BBDD. * Utilizar '*' para toda la BBDD o 'table1 table2 table3...' * - * @param FileHandler $fileHandler - * @param string|array $tables - * - * @throws ConstraintException - * @throws QueryException - * @throws FileException - * @throws CheckException + * @throws \SP\Core\Exceptions\CheckException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Storage\Database\DatabaseException + * @throws \SP\Storage\File\FileException */ - private function backupTables(FileHandler $fileHandler, $tables = '*') + private function backupTables( + FileHandler $fileHandler, + string $tables = '*' + ): void { $this->eventDispatcher->notifyEvent('run.backup.process', new Event($this, @@ -236,7 +211,7 @@ final class FileBackupService extends Service $queryData = new QueryData(); if ($tables === '*') { - $resTables = DatabaseUtil::$tables; + $resTables = DatabaseUtil::TABLES; } else { $resTables = is_array($tables) ? $tables : explode(',', $tables); } @@ -305,7 +280,7 @@ final class FileBackupService extends Service $numColumns = $queryRes->columnCount(); - while ($row = $queryRes->fetch(PDO::FETCH_NUM, PDO::FETCH_ORI_NEXT)) { + while ($row = $queryRes->fetch(PDO::FETCH_NUM)) { $fileHandler->write('INSERT INTO `' . $tableName . '` VALUES('); $field = 1; @@ -351,7 +326,6 @@ final class FileBackupService extends Service /** * Realizar un backup de la aplicación y comprimirlo. * - * @return bool * @throws CheckException * @throws FileException */ @@ -372,14 +346,15 @@ final class FileBackupService extends Service /** * Realizar un backup de la aplicación y comprimirlo usando aplicaciones del SO Linux. * - * @return int Con el código de salida del comando ejecutado * @throws ServiceException */ - private function backupAppLegacyLinux() + private function backupAppLegacyLinux(): int { if (Checks::checkIsWindows()) { throw new ServiceException( - __u('This operation is only available on Linux environments'), ServiceException::INFO); + __u('This operation is only available on Linux environments'), + SPException::INFO + ); } $this->eventDispatcher->notifyEvent('run.backup.process', @@ -387,15 +362,18 @@ final class FileBackupService extends Service ->addDescription(__u('Copying application'))) ); - $command = 'tar czf ' . $this->backupFileApp . ArchiveHandler::COMPRESS_EXTENSION . ' ' . BASE_PATH . ' --exclude "' . $this->path . '" 2>&1'; + $command = sprintf( + 'tar czf %s%s %s --exclude "%s" 2>&1', + $this->backupFileApp, + ArchiveHandler::COMPRESS_EXTENSION, + BASE_PATH, + $this->path + ); exec($command, $resOut, $resBakApp); return $resBakApp; } - /** - * @return string - */ public function getHash(): string { return $this->hash; @@ -405,7 +383,7 @@ final class FileBackupService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->configData = $this->config->getConfigData(); $this->extensionChecker = $this->dic->get(PhpExtensionChecker::class); diff --git a/lib/SP/Services/Category/CategoryService.php b/lib/SP/Services/Category/CategoryService.php index da8353b5..1990298a 100644 --- a/lib/SP/Services/Category/CategoryService.php +++ b/lib/SP/Services/Category/CategoryService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Category; @@ -48,37 +48,28 @@ final class CategoryService extends Service { use ServiceItemTrait; - /** - * @var CategoryRepository - */ - protected $categoryRepository; + protected ?CategoryRepository $categoryRepository = null; /** - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->categoryRepository->search($itemSearchData); } /** - * @param int $id - * - * @return CategoryData * @throws NoSuchItemException * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): CategoryData { $result = $this->categoryRepository->getById($id); if ($result->getNumRows() === 0) { - throw new NoSuchItemException(__u('Category not found'), NoSuchItemException::INFO); + throw new NoSuchItemException(__u('Category not found'), SPException::INFO); } return $result->getData(); @@ -87,14 +78,11 @@ final class CategoryService extends Service /** * Returns the item for given id * - * @param string $name - * - * @return CategoryData * @throws ConstraintException * @throws QueryException * @throws NoSuchItemException */ - public function getByName($name) + public function getByName(string $name): CategoryData { $result = $this->categoryRepository->getByName($name); @@ -106,14 +94,11 @@ final class CategoryService extends Service } /** - * @param $id - * - * @return $this - * @throws ConstraintException - * @throws QueryException - * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function delete($id) + public function delete(int $id): CategoryService { if ($this->categoryRepository->delete($id) === 0) { throw new NoSuchItemException(__u('Category not found'), NoSuchItemException::INFO); @@ -125,43 +110,39 @@ final class CategoryService extends Service /** * Deletes all the items for given ids * - * @param array $ids - * - * @return int * @throws ServiceException * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (($count = $this->categoryRepository->deleteByIdBatch($ids)) !== count($ids)) { - throw new ServiceException(__u('Error while deleting categories'), ServiceException::WARNING); + $count = $this->categoryRepository->deleteByIdBatch($ids); + + if ($count !== count($ids)) { + throw new ServiceException( + __u('Error while deleting categories'), + SPException::WARNING + ); } return $count; } /** - * @param $itemData - * - * @return int * @throws SPException * @throws DuplicatedItemException */ - public function create($itemData) + public function create(CategoryData $itemData): int { return $this->categoryRepository->create($itemData); } /** - * @param $itemData - * - * @return int * @throws SPException * @throws ConstraintException * @throws QueryException */ - public function update($itemData) + public function update(CategoryData $itemData): int { return $this->categoryRepository->update($itemData); } @@ -173,7 +154,7 @@ final class CategoryService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAllBasic() + public function getAllBasic(): array { return $this->categoryRepository->getAll()->getDataAsArray(); } @@ -182,7 +163,7 @@ final class CategoryService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->categoryRepository = $this->dic->get(CategoryRepository::class); } diff --git a/lib/SP/Services/Client/ClientService.php b/lib/SP/Services/Client/ClientService.php index 921a907b..56df6e6c 100644 --- a/lib/SP/Services/Client/ClientService.php +++ b/lib/SP/Services/Client/ClientService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Client; @@ -50,35 +50,31 @@ final class ClientService extends Service { use ServiceItemTrait; - /** - * @var ClientRepository - */ - protected $clientRepository; + protected ?ClientRepository $clientRepository = null; /** - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->clientRepository->search($itemSearchData); } /** - * @param int $id - * - * @return ClientData * @throws NoSuchItemException * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): ClientData { - if (($result = $this->clientRepository->getById($id))->getNumRows() === 0) { - throw new NoSuchItemException(__u('Client not found'), NoSuchItemException::INFO); + $result = $this->clientRepository->getById($id); + + if ($result->getNumRows() === 0) { + throw new NoSuchItemException + (__u('Client not found'), + SPException::INFO + ); } return $result->getData(); @@ -87,75 +83,78 @@ final class ClientService extends Service /** * Returns the item for given name * - * @param string $name - * - * @return ClientData * @throws ConstraintException * @throws QueryException * @throws NoSuchItemException */ - public function getByName($name) + public function getByName(string $name): ClientData { if (($result = $this->clientRepository->getByName($name))->getNumRows() === 0) { - throw new NoSuchItemException(__u('Client not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Client not found'), + SPException::INFO + ); } return $result->getData(); } /** - * @param $id - * - * @return $this - * @throws SPException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function delete($id) + public function delete(int $id): ClientService { if ($this->clientRepository->delete($id) === 0) { - throw new NoSuchItemException(__u('Client not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Client not found'), + SPException::INFO + ); } return $this; } /** - * @param array $ids + * @param int[] $ids * - * @return int * @throws ServiceException * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (($count = $this->clientRepository->deleteByIdBatch($ids)) !== count($ids)) { - throw new ServiceException(__u('Error while deleting the clients'), ServiceException::WARNING); + $count = $this->clientRepository->deleteByIdBatch($ids); + + if ($count !== count($ids)) { + throw new ServiceException( + __u('Error while deleting the clients'), + SPException::WARNING + ); } return $count; } /** - * @param $itemData - * - * @return int * @throws SPException * @throws DuplicatedItemException */ - public function create($itemData) + public function create($itemData): int { return $this->clientRepository->create($itemData); } /** - * @param $itemData + * @param ClientData $itemData * * @return int * @throws SPException * @throws ConstraintException * @throws QueryException */ - public function update($itemData) + public function update(ClientData $itemData): int { return $this->clientRepository->update($itemData); } @@ -167,7 +166,7 @@ final class ClientService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAllBasic() + public function getAllBasic(): array { return $this->clientRepository->getAll()->getDataAsArray(); } @@ -179,16 +178,20 @@ final class ClientService extends Service * @throws QueryException * @throws ConstraintException */ - public function getAllForUser() + public function getAllForUser(): array { - return $this->clientRepository->getAllForFilter($this->dic->get(AccountFilterUser::class)->getFilter())->getDataAsArray(); + return $this->clientRepository + ->getAllForFilter( + $this->dic->get(AccountFilterUser::class)->getFilter() + ) + ->getDataAsArray(); } /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->clientRepository = $this->dic->get(ClientRepository::class); } diff --git a/lib/SP/Services/Config/ConfigBackupService.php b/lib/SP/Services/Config/ConfigBackupService.php index 1022bf2b..6fed6eec 100644 --- a/lib/SP/Services/Config/ConfigBackupService.php +++ b/lib/SP/Services/Config/ConfigBackupService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,14 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Config; use Exception; -use RuntimeException; use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Exceptions\SPException; use SP\Http\Json; use SP\Repositories\NoSuchItemException; @@ -42,61 +42,45 @@ use SP\Util\Util; */ final class ConfigBackupService extends Service { - /** - * @var ConfigService - */ - protected $configService; + protected ?ConfigService $configService = null; /** - * @param string $configData - * - * @return string * @throws SPException */ public static function configToJson(string $configData): string { - return Json::getJson(Util::unserialize(ConfigData::class, $configData), JSON_PRETTY_PRINT); - } - - /** - * @param string $configData - */ - public static function configToXml(string $configData) - { - throw new RuntimeException('Not implemented'); + return Json::getJson( + Util::unserialize(ConfigData::class, $configData), + JSON_PRETTY_PRINT + ); } /** * Backs up the config data into the database - * - * @param ConfigData $configData */ - public function backup(ConfigData $configData) + public function backup(ConfigDataInterface $configData): void { try { - $this->configService->save('config_backup', $this->packConfigData($configData)); + $this->configService->save( + 'config_backup', + $this->packConfigData($configData) + ); $this->configService->save('config_backup_date', time()); } catch (Exception $e) { processException($e); } } - /** - * @param ConfigData $configData - * - * @return string - */ - private function packConfigData(ConfigData $configData) + private function packConfigData(ConfigDataInterface $configData): string { return bin2hex(gzcompress(serialize($configData))); } /** - * @return ConfigData * @throws FileException * @throws ServiceException */ - public function restore() + public function restore(): ConfigDataInterface { return $this->config->saveConfig( Util::unserialize(ConfigData::class, $this->getBackup()) @@ -104,7 +88,6 @@ final class ConfigBackupService extends Service } /** - * @return ConfigData * @throws ServiceException */ public function getBackup(): string @@ -124,7 +107,7 @@ final class ConfigBackupService extends Service } } - protected function initialize() + protected function initialize(): void { $this->configService = $this->dic->get(ConfigService::class); } diff --git a/lib/SP/Services/Config/ConfigService.php b/lib/SP/Services/Config/ConfigService.php index 36fb2976..548e90a3 100644 --- a/lib/SP/Services/Config/ConfigService.php +++ b/lib/SP/Services/Config/ConfigService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Config; @@ -29,6 +29,7 @@ use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; +use SP\Core\Exceptions\SPException; use SP\DataModel\ConfigData; use SP\DataModel\Dto\ConfigRequest; use SP\Repositories\Config\ConfigRepository; @@ -43,25 +44,24 @@ use SP\Services\ServiceException; */ final class ConfigService extends Service { - /** - * @var ConfigRepository - */ - protected $configRepository; + protected ?ConfigRepository $configRepository = null; /** - * @param string $param - * @param mixed $default - * - * @return mixed * @throws NoSuchItemException * @throws ServiceException */ - public function getByParam($param, $default = null) + public function getByParam(string $param, $default = null) { try { $result = $this->configRepository->getByParam($param); } catch (Exception $e) { - throw new ServiceException($e->getMessage(), ServiceException::ERROR, null, $e->getCode(), $e); + throw new ServiceException( + $e->getMessage(), + SPException::ERROR, + null, + $e->getCode(), + $e + ); } @@ -82,46 +82,45 @@ final class ConfigService extends Service } /** - * @param ConfigData $configData - * - * @return int * @throws ConstraintException * @throws QueryException */ - public function create(ConfigData $configData) + public function create(ConfigData $configData): int { return $this->configRepository->create($configData); } /** - * @param ConfigRequest $configRequest - * * @throws ServiceException */ - public function saveBatch(ConfigRequest $configRequest) + public function saveBatch(ConfigRequest $configRequest): void { try { - $this->transactionAware(function () use ($configRequest) { - foreach ($configRequest->getData() as $param => $value) { - $this->save($param, $value); + $this->transactionAware( + function () use ($configRequest) { + foreach ($configRequest->getData() as $param => $value) { + $this->save($param, $value); + } } - }); + ); } catch (Exception $e) { processException($e); - throw new ServiceException($e->getMessage(), ServiceException::ERROR, null, $e->getCode(), $e); + throw new ServiceException( + $e->getMessage(), + SPException::ERROR, + null, + $e->getCode(), + $e + ); } } /** - * @param string $param - * @param string $value - * - * @return bool * @throws ConstraintException * @throws QueryException */ - public function save($param, $value) + public function save(string $param, $value): bool { if (!$this->configRepository->has($param)) { return $this->configRepository->create(new ConfigData($param, $value)); @@ -137,23 +136,22 @@ final class ConfigService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): array { return $this->configRepository->getAll()->getDataAsArray(); } /** - * @param $param - * - * @return void - * @throws ConstraintException - * @throws NoSuchItemException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function deleteByParam($param) + public function deleteByParam(string $param): void { if ($this->configRepository->deleteByParam($param) === 0) { - throw new NoSuchItemException(sprintf(__('Parameter not found (%s)'), $param)); + throw new NoSuchItemException( + sprintf(__('Parameter not found (%s)'), $param) + ); } } @@ -161,7 +159,7 @@ final class ConfigService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->configRepository = $this->dic->get(ConfigRepository::class); } diff --git a/lib/SP/Services/Crypt/MasterPassService.php b/lib/SP/Services/Crypt/MasterPassService.php index c178d461..8e90d6b2 100644 --- a/lib/SP/Services/Crypt/MasterPassService.php +++ b/lib/SP/Services/Crypt/MasterPassService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Crypt; @@ -44,72 +44,58 @@ use SP\Services\ServiceException; */ final class MasterPassService extends Service { - const PARAM_MASTER_PASS_TIME = 'lastupdatempass'; - const PARAM_MASTER_PASS_HASH = 'masterPwd'; + public const PARAM_MASTER_PASS_TIME = 'lastupdatempass'; + public const PARAM_MASTER_PASS_HASH = 'masterPwd'; + + protected ?ConfigService $configService = null; + protected ?AccountCryptService $accountCryptService = null; + protected ?CustomFieldCryptService $customFieldCryptService = null; /** - * @var ConfigService - */ - protected $configService; - /** - * @var AccountCryptService - */ - protected $accountCryptService; - /** - * @var CustomFieldCryptService - */ - protected $customFieldCryptService; - - /** - * @param int $userMPassTime - * - * @return bool * @throws ServiceException * @throws NoSuchItemException */ - public function checkUserUpdateMPass($userMPassTime) + public function checkUserUpdateMPass(int $userMPassTime): bool { return $userMPassTime >= $this->configService->getByParam(self::PARAM_MASTER_PASS_TIME, 0); } /** - * @param string $masterPassword - * - * @return bool * @throws ServiceException * @throws NoSuchItemException */ - public function checkMasterPassword($masterPassword) + public function checkMasterPassword(string $masterPassword): bool { - return Hash::checkHashKey($masterPassword, $this->configService->getByParam(self::PARAM_MASTER_PASS_HASH)); + return Hash::checkHashKey( + $masterPassword, + $this->configService->getByParam(self::PARAM_MASTER_PASS_HASH) + ); } /** - * @param UpdateMasterPassRequest $request - * * @throws Exception */ - public function changeMasterPassword(UpdateMasterPassRequest $request) + public function changeMasterPassword(UpdateMasterPassRequest $request): void { - $this->transactionAware(function () use ($request) { - $this->accountCryptService->updateMasterPassword($request); + $this->transactionAware( + function () use ($request) { + $this->accountCryptService->updateMasterPassword($request); - $this->accountCryptService->updateHistoryMasterPassword($request); + $this->accountCryptService->updateHistoryMasterPassword($request); - $this->customFieldCryptService->updateMasterPassword($request); + $this->customFieldCryptService->updateMasterPassword($request); - $this->updateConfig($request->getHash()); - }); + $this->updateConfig($request->getHash()); + } + ); } /** - * @param $hash - * * @throws ConstraintException * @throws QueryException */ - public function updateConfig($hash) + public function updateConfig($hash): void { $this->configService->save(self::PARAM_MASTER_PASS_HASH, $hash); $this->configService->save(self::PARAM_MASTER_PASS_TIME, time()); @@ -119,7 +105,7 @@ final class MasterPassService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->configService = $this->dic->get(ConfigService::class); $this->accountCryptService = $this->dic->get(AccountCryptService::class); diff --git a/lib/SP/Services/Crypt/SecureSessionService.php b/lib/SP/Services/Crypt/SecureSessionService.php index 517a17f2..40e504c0 100644 --- a/lib/SP/Services/Crypt/SecureSessionService.php +++ b/lib/SP/Services/Crypt/SecureSessionService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Crypt; @@ -41,25 +41,13 @@ use SP\Storage\File\FileException; */ final class SecureSessionService extends Service { - const CACHE_EXPIRE_TIME = 86400; - const CACHE_PATH = CACHE_PATH . DIRECTORY_SEPARATOR . 'secure_session'; + private const CACHE_EXPIRE_TIME = 86400; + private const CACHE_PATH = CACHE_PATH . DIRECTORY_SEPARATOR . 'secure_session'; - /** - * @var string - */ - protected $seed; - /** - * @var Request - */ - protected $request; - /** - * @var UUIDCookie - */ - protected $cookie; - /** - * @var string - */ - private $filename; + protected ?string $seed = null; + protected ?Request $request = null; + protected ?UUIDCookie $cookie = null; + private ?string $filename = null; /** * Returns the encryption key @@ -96,12 +84,11 @@ final class SecureSessionService extends Service /** * Returns an unique filename from a browser cookie * - * @return string * @throws ServiceException */ - private function getFileNameFromCookie() + private function getFileNameFromCookie(): string { - if (!$this->filename) { + if (empty($this->filename)) { if (($uuid = $this->cookie->loadCookie($this->seed)) === false && ($uuid = $this->cookie->createCookie($this->seed)) === false ) { @@ -124,7 +111,11 @@ final class SecureSessionService extends Service try { $securedKey = Key::createNewRandomKey(); - FileCache::factory($this->getFileNameFromCookie())->save((new Vault())->saveData($securedKey->saveToAsciiSafeString(), $this->getCypher())); + FileCache::factory($this->getFileNameFromCookie()) + ->save( + (new Vault())->saveData($securedKey->saveToAsciiSafeString(), + $this->getCypher()) + ); logger('Saved session key'); @@ -138,28 +129,27 @@ final class SecureSessionService extends Service /** * Returns the key to be used for encrypting the session data - * - * @return string */ - private function getCypher() + private function getCypher(): string { - return hash_pbkdf2('sha1', - sha1($this->request->getHeader('User-Agent') . $this->request->getClientAddress()), + return hash_pbkdf2( + 'sha1', + sha1( + $this->request->getHeader('User-Agent') . + $this->request->getClientAddress() + ), $this->seed, 500, 32 ); } - /** - * @return string - */ public function getFilename(): string { return $this->filename; } - protected function initialize() + protected function initialize(): void { $this->request = $this->dic->get(Request::class); $this->seed = $this->config->getConfigData()->getPasswordSalt(); diff --git a/lib/SP/Services/Crypt/TemporaryMasterPassService.php b/lib/SP/Services/Crypt/TemporaryMasterPassService.php index 4f83eb9a..7b4a3b12 100644 --- a/lib/SP/Services/Crypt/TemporaryMasterPassService.php +++ b/lib/SP/Services/Crypt/TemporaryMasterPassService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Crypt; @@ -33,8 +33,6 @@ use SP\Core\Crypt\Crypt; use SP\Core\Crypt\Hash; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; -use SP\Core\Exceptions\ConstraintException; -use SP\Core\Exceptions\QueryException; use SP\Core\Messages\MailMessage; use SP\DataModel\Dto\ConfigRequest; use SP\Repositories\NoSuchItemException; @@ -55,24 +53,18 @@ final class TemporaryMasterPassService extends Service /** * Número máximo de intentos */ - const MAX_ATTEMPTS = 50; + public const MAX_ATTEMPTS = 50; /** * Parámetros de configuración */ - const PARAM_PASS = 'tempmaster_pass'; - const PARAM_KEY = 'tempmaster_passkey'; - const PARAM_HASH = 'tempmaster_passhash'; - const PARAM_TIME = 'tempmaster_passtime'; - const PARAM_MAX_TIME = 'tempmaster_maxtime'; - const PARAM_ATTEMPTS = 'tempmaster_attempts'; - /** - * @var ConfigService - */ - protected $configService; - /** - * @var int - */ - protected $maxTime; + private const PARAM_PASS = 'tempmaster_pass'; + private const PARAM_KEY = 'tempmaster_passkey'; + private const PARAM_HASH = 'tempmaster_passhash'; + public const PARAM_TIME = 'tempmaster_passtime'; + public const PARAM_MAX_TIME = 'tempmaster_maxtime'; + public const PARAM_ATTEMPTS = 'tempmaster_attempts'; + protected ?ConfigService $configService = null; + protected ?int $maxTime = null; /** * Crea una clave temporal para encriptar la clave maestra y guardarla. @@ -82,7 +74,7 @@ final class TemporaryMasterPassService extends Service * @return string * @throws ServiceException */ - public function create($maxTime = 14400) + public function create(int $maxTime = 14400): string { try { $this->maxTime = time() + $maxTime; @@ -104,7 +96,8 @@ final class TemporaryMasterPassService extends Service // Guardar la clave temporal hasta que finalice la sesión $this->context->setTemporaryMasterPass($randomKey); - $this->eventDispatcher->notifyEvent('create.tempMasterPassword', + $this->eventDispatcher->notifyEvent( + 'create.tempMasterPassword', new Event($this, EventMessage::factory() ->addDescription(__u('Generate temporary password'))) ); @@ -125,7 +118,7 @@ final class TemporaryMasterPassService extends Service * @return bool * @throws ServiceException */ - public function checkTempMasterPass($pass) + public function checkTempMasterPass(string $pass): bool { try { $isValid = false; @@ -133,8 +126,13 @@ final class TemporaryMasterPassService extends Service // Comprobar si el tiempo de validez o los intentos se han superado if ($passMaxTime === 0) { - $this->eventDispatcher->notifyEvent('check.tempMasterPassword', - new Event($this, EventMessage::factory()->addDescription(__u('Temporary password expired'))) + $this->eventDispatcher->notifyEvent( + 'check.tempMasterPassword', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Temporary password expired')) + ) ); return $isValid; @@ -143,18 +141,24 @@ final class TemporaryMasterPassService extends Service $passTime = (int)$this->configService->getByParam(self::PARAM_TIME); $attempts = (int)$this->configService->getByParam(self::PARAM_ATTEMPTS); - if ((!empty($passTime) && time() > $passMaxTime) - || $attempts >= self::MAX_ATTEMPTS + if ($attempts >= self::MAX_ATTEMPTS + || (!empty($passTime) && time() > $passMaxTime) ) { $this->expire(); return $isValid; } - $isValid = Hash::checkHashKey($pass, $this->configService->getByParam(self::PARAM_HASH)); + $isValid = Hash::checkHashKey( + $pass, + $this->configService->getByParam(self::PARAM_HASH) + ); if (!$isValid) { - $this->configService->save(self::PARAM_ATTEMPTS, $attempts + 1); + $this->configService->save( + self::PARAM_ATTEMPTS, + $attempts + 1 + ); } return $isValid; @@ -170,7 +174,7 @@ final class TemporaryMasterPassService extends Service /** * @throws ServiceException */ - protected function expire() + protected function expire(): void { $configRequest = new ConfigRequest(); $configRequest->add(self::PARAM_PASS, ''); @@ -182,74 +186,65 @@ final class TemporaryMasterPassService extends Service $this->configService->saveBatch($configRequest); - $this->eventDispatcher->notifyEvent('expire.tempMasterPassword', + $this->eventDispatcher->notifyEvent( + 'expire.tempMasterPassword', new Event($this, EventMessage::factory() ->addDescription(__u('Temporary password expired'))) ); } /** - * @param $groupId - * @param $key - * - * @throws ServiceException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException + * @throws \PHPMailer\PHPMailer\Exception */ - public function sendByEmailForGroup($groupId, $key) + public function sendByEmailForGroup(int $groupId, string $key): void { $mailMessage = $this->getMessageForEmail($key); - $emails = array_map(function ($value) { - return $value->email; - }, $this->dic->get(UserService::class)->getUserEmailForGroup($groupId)); + $emails = array_map( + static function ($value) { + return $value->email; + }, + $this->dic->get(UserService::class)->getUserEmailForGroup($groupId) + ); $this->dic->get(MailService::class) ->sendBatch($mailMessage->getTitle(), $emails, $mailMessage); } - /** - * @param $key - * - * @throws ServiceException - * @throws ConstraintException - * @throws QueryException - */ - public function sendByEmailForAllUsers($key) - { - $mailMessage = $this->getMessageForEmail($key); - - $emails = array_map(function ($value) { - return $value->email; - }, $this->dic->get(UserService::class)->getUserEmailForAll()); - - $this->dic->get(MailService::class) - ->sendBatch($mailMessage->getTitle(), $emails, $mailMessage); - } - - /** - * @param $key - * - * @return MailMessage - */ - private function getMessageForEmail($key) + private function getMessageForEmail(string $key): MailMessage { $mailMessage = new MailMessage(); $mailMessage->setTitle(sprintf(__('%s Master Password'), AppInfoInterface::APP_NAME)); $mailMessage->addDescription(__('A new sysPass master password has been generated, so next time you log into the application it will be requested.')); $mailMessage->addDescription(sprintf(__('The new Master Password is: %s'), $key)); - $mailMessage->addDescription(sprintf(__('This password will be valid until: %s'), date('r', $this->getMaxTime()))); + $mailMessage->addDescription(sprintf(__('This password will be valid until: %s'), date('r', $this->maxTime))); $mailMessage->addDescription(__('Please, don\'t forget to log in as soon as possible to save the changes.')); return $mailMessage; } /** - * @return int + * @throws \PHPMailer\PHPMailer\Exception + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException */ - public function getMaxTime() + public function sendByEmailForAllUsers(string $key): void { - return $this->maxTime; + $mailMessage = $this->getMessageForEmail($key); + + $emails = array_map( + static function ($value) { + return $value->email; + }, + $this->dic->get(UserService::class)->getUserEmailForAll() + ); + + $this->dic->get(MailService::class) + ->sendBatch($mailMessage->getTitle(), $emails, $mailMessage); } /** @@ -262,18 +257,20 @@ final class TemporaryMasterPassService extends Service * @throws ServiceException * @throws CryptoException */ - public function getUsingKey($key) + public function getUsingKey(string $key): string { - return Crypt::decrypt($this->configService->getByParam(self::PARAM_PASS), + return Crypt::decrypt( + $this->configService->getByParam(self::PARAM_PASS), $this->configService->getByParam(self::PARAM_KEY), - $key); + $key + ); } /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->configService = $this->dic->get(ConfigService::class); } diff --git a/lib/SP/Services/Crypt/UpdateMasterPassRequest.php b/lib/SP/Services/Crypt/UpdateMasterPassRequest.php index 6f7b5779..7764f9f0 100644 --- a/lib/SP/Services/Crypt/UpdateMasterPassRequest.php +++ b/lib/SP/Services/Crypt/UpdateMasterPassRequest.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Crypt; @@ -35,36 +35,26 @@ use SP\Services\Task\Task; */ final class UpdateMasterPassRequest { - /** - * @var string - */ - private $currentMasterPass; - /** - * @var string - */ - private $newMasterPass; - /** - * @var Task - */ - private $task; - /** - * @var string - */ - private $hash; - /** - * @var string - */ - private $currentHash; + private string $currentMasterPass; + private string $newMasterPass; + private ?Task $task = null; + private string $hash; + private string $currentHash; /** * UpdateMasterPassRequest constructor. * - * @param string $currentMasterPass - * @param string $newMasterPass - * @param string $currentHash - * @param Task $task + * @param string $currentMasterPass + * @param string $newMasterPass + * @param string $currentHash + * @param \SP\Services\Task\Task|null $task */ - public function __construct($currentMasterPass, $newMasterPass, $currentHash, Task $task = null) + public function __construct( + string $currentMasterPass, + string $newMasterPass, + string $currentHash, + ?Task $task = null + ) { $this->currentMasterPass = $currentMasterPass; $this->newMasterPass = $newMasterPass; @@ -73,50 +63,32 @@ final class UpdateMasterPassRequest $this->currentHash = $currentHash; } - /** - * @return string - */ - public function getCurrentMasterPass() + public function getCurrentMasterPass(): string { return $this->currentMasterPass; } - /** - * @return string - */ - public function getNewMasterPass() + public function getNewMasterPass(): string { return $this->newMasterPass; } - /** - * @return Task - */ - public function getTask() + public function getTask(): ?Task { return $this->task; } - /** - * @return bool - */ - public function useTask() + public function useTask(): bool { return $this->task !== null; } - /** - * @return string - */ - public function getHash() + public function getHash(): string { return $this->hash; } - /** - * @return string - */ - public function getCurrentHash() + public function getCurrentHash(): string { return $this->currentHash; } diff --git a/lib/SP/Services/CustomField/CustomFieldCryptService.php b/lib/SP/Services/CustomField/CustomFieldCryptService.php index 5105ec14..a9d5691a 100644 --- a/lib/SP/Services/CustomField/CustomFieldCryptService.php +++ b/lib/SP/Services/CustomField/CustomFieldCryptService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\CustomField; @@ -34,6 +34,7 @@ use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; +use SP\Core\Exceptions\SPException; use SP\DataModel\CustomFieldData; use SP\Services\Crypt\UpdateMasterPassRequest; use SP\Services\Service; @@ -47,22 +48,46 @@ use SP\Services\Task\TaskFactory; */ final class CustomFieldCryptService extends Service { - /** - * @var CustomFieldService - */ - protected $customFieldService; - /** - * @var UpdateMasterPassRequest - */ - protected $request; + protected ?CustomFieldService $customFieldService = null; + protected ?UpdateMasterPassRequest $request = null; /** - * @param callable $decryptor + * Actualizar los datos encriptados con una nueva clave * + * @param UpdateMasterPassRequest $request + * + * @throws ServiceException + */ + public function updateMasterPassword(UpdateMasterPassRequest $request): void + { + try { + $this->request = $request; + + $this->processUpdateMasterPassword( + function (CustomFieldData $customFieldData) { + return Crypt::decrypt( + $customFieldData->getData(), + $customFieldData->getKey(), + $this->request->getCurrentMasterPass()); + } + ); + } catch (Exception $e) { + $this->eventDispatcher->notifyEvent('exception', new Event($e)); + + throw new ServiceException( + __u('Error while updating the custom fields data'), + SPException::ERROR, + null, + $e->getCode(), + $e); + } + } + + /** * @throws ConstraintException * @throws QueryException */ - protected function processUpdateMasterPassword(callable $decryptor) + protected function processUpdateMasterPassword(callable $decryptor): void { $customFields = $this->customFieldService->getAllEncrypted(); @@ -85,8 +110,10 @@ final class CustomFieldCryptService extends Service $task = $this->request->getTask(); TaskFactory::update($task, - TaskFactory::createMessage($task->getTaskId(), __('Update Master Password')) - ->setMessage(__('Updating encrypted data'))); + TaskFactory::createMessage( + $task->getTaskId(), + __('Update Master Password') + )->setMessage(__('Updating encrypted data'))); } $errors = []; @@ -96,7 +123,10 @@ final class CustomFieldCryptService extends Service try { $customField->setData($decryptor($customField)); - $this->customFieldService->updateMasterPass($customField, $this->request->getNewMasterPass()); + $this->customFieldService->updateMasterPass( + $customField, + $this->request->getNewMasterPass() + ); $success[] = $customField->getId(); } catch (Exception $e) { @@ -116,41 +146,11 @@ final class CustomFieldCryptService extends Service ); } - /** - * Actualizar los datos encriptados con una nueva clave - * - * @param UpdateMasterPassRequest $request - * - * @throws ServiceException - */ - public function updateMasterPassword(UpdateMasterPassRequest $request) - { - try { - $this->request = $request; - - $this->processUpdateMasterPassword(function (CustomFieldData $customFieldData) { - return Crypt::decrypt( - $customFieldData->getData(), - $customFieldData->getKey(), - $this->request->getCurrentMasterPass()); - }); - } catch (Exception $e) { - $this->eventDispatcher->notifyEvent('exception', new Event($e)); - - throw new ServiceException( - __u('Error while updating the custom fields data'), - ServiceException::ERROR, - null, - $e->getCode(), - $e); - } - } - /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->customFieldService = $this->dic->get(CustomFieldService::class); } diff --git a/lib/SP/Services/CustomField/CustomFieldDefService.php b/lib/SP/Services/CustomField/CustomFieldDefService.php index acad7e2d..29c414d1 100644 --- a/lib/SP/Services/CustomField/CustomFieldDefService.php +++ b/lib/SP/Services/CustomField/CustomFieldDefService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\CustomField; @@ -29,6 +29,7 @@ use Psr\Container\NotFoundExceptionInterface; use SP\Core\Acl\ActionsInterface; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; +use SP\Core\Exceptions\SPException; use SP\DataModel\CustomFieldDefinitionData; use SP\DataModel\ItemSearchData; use SP\Repositories\CustomField\CustomFieldDefRepository; @@ -47,14 +48,7 @@ final class CustomFieldDefService extends Service { use ServiceItemTrait; - /** - * @var CustomFieldDefRepository - */ - protected $customFieldDefRepository; - /** - * @var CustomFieldService - */ - protected $customFieldService; + protected ?CustomFieldDefRepository $customFieldDefRepository = null; /** * @param $id @@ -65,55 +59,50 @@ final class CustomFieldDefService extends Service { $modules = self::getFieldModules(); - return isset($modules[$id]) ? $modules[$id] : $id; + return $modules[$id] ?? $id; } /** * Devuelve los módulos disponibles para los campos personalizados - * - * @return array */ - public static function getFieldModules() + public static function getFieldModules(): array { - $modules = [ + return [ ActionsInterface::ACCOUNT => __('Accounts'), ActionsInterface::CATEGORY => __('Categories'), ActionsInterface::CLIENT => __('Clients'), ActionsInterface::USER => __('Users'), ActionsInterface::GROUP => __('Groups') ]; - - return $modules; } /** - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->customFieldDefRepository->search($itemSearchData); } /** - * @param $id - * - * @return CustomFieldDefService - * @throws ServiceException + * @throws \SP\Services\ServiceException */ - public function delete($id) + public function delete(int $id): CustomFieldDefService { - $this->transactionAware(function () use ($id) { - $this->dic->get(CustomFieldService::class) - ->deleteCustomFieldDefinitionData($id); + $this->transactionAware( + function () use ($id) { + $this->dic->get(CustomFieldService::class) + ->deleteCustomFieldDefinitionData($id); - if ($this->customFieldDefRepository->delete($id) === 0) { - throw new NoSuchItemException(__u('Field not found'), NoSuchItemException::INFO); + if ($this->customFieldDefRepository->delete($id) === 0) { + throw new NoSuchItemException( + __u('Field not found'), + SPException::INFO + ); + } } - }); + ); return $this; } @@ -121,78 +110,77 @@ final class CustomFieldDefService extends Service /** * Deletes all the items for given ids * - * @param array $ids + * @param int[] $ids * * @throws ServiceException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): void { - $this->transactionAware(function () use ($ids) { - $this->dic->get(CustomFieldService::class) - ->deleteCustomFieldDefinitionDataBatch($ids); + $this->transactionAware( + function () use ($ids) { + $this->dic->get(CustomFieldService::class) + ->deleteCustomFieldDefinitionDataBatch($ids); - if ($this->customFieldDefRepository->deleteByIdBatch($ids) !== count($ids)) { - throw new ServiceException(__u('Error while deleting the fields'), ServiceException::WARNING); + if ($this->customFieldDefRepository->deleteByIdBatch($ids) !== count($ids)) { + throw new ServiceException( + __u('Error while deleting the fields'), + SPException::WARNING + ); + } } - }); + ); } /** - * @param $itemData + * @param \SP\DataModel\CustomFieldDefinitionData $itemData * - * @return mixed - * @throws ConstraintException - * @throws QueryException + * @return int + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function create($itemData) + public function create(CustomFieldDefinitionData $itemData): int { return $this->customFieldDefRepository->create($itemData); } /** - * @param CustomFieldDefinitionData $itemData - * - * @return mixed * @throws ServiceException */ public function update(CustomFieldDefinitionData $itemData) { - return $this->transactionAware(function () use ($itemData) { - $customFieldDefinitionData = $this->getById($itemData->getId()); + return $this->transactionAware( + function () use ($itemData) { + $customFieldDefinitionData = $this->getById($itemData->getId()); - // Delete the data used by the items using the previous definition - if ($customFieldDefinitionData->getModuleId() !== $itemData->moduleId) { - $this->dic->get(CustomFieldService::class) - ->deleteCustomFieldDefinitionData($customFieldDefinitionData->getId()); - } + // Delete the data used by the items using the previous definition + if ($customFieldDefinitionData->getModuleId() !== $itemData->moduleId) { + $this->dic->get(CustomFieldService::class) + ->deleteCustomFieldDefinitionData($customFieldDefinitionData->getId()); + } - if ($this->customFieldDefRepository->update($itemData) !== 1) { - throw new ServiceException(__u('Error while updating the custom field')); + if ($this->customFieldDefRepository->update($itemData) !== 1) { + throw new ServiceException(__u('Error while updating the custom field')); + } } - }); + ); } /** - * @param $id - * - * @return CustomFieldDefinitionData - * @throws ConstraintException - * @throws QueryException - * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function getById($id) + public function getById(int $id): CustomFieldDefinitionData { return $this->customFieldDefRepository->getById($id); } /** - * @param CustomFieldDefinitionData $itemData - * * @throws ServiceException * @throws ConstraintException * @throws QueryException */ - public function updateRaw(CustomFieldDefinitionData $itemData) + public function updateRaw(CustomFieldDefinitionData $itemData): void { if ($this->customFieldDefRepository->update($itemData) !== 1) { throw new ServiceException(__u('Error while updating the custom field')); @@ -206,7 +194,7 @@ final class CustomFieldDefService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAllBasic() + public function getAllBasic(): array { return $this->customFieldDefRepository->getAll()->getDataAsArray(); } @@ -215,7 +203,7 @@ final class CustomFieldDefService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->customFieldDefRepository = $this->dic->get(CustomFieldDefRepository::class); } diff --git a/lib/SP/Services/CustomField/CustomFieldItem.php b/lib/SP/Services/CustomField/CustomFieldItem.php index 3b6b9801..b4dccb82 100644 --- a/lib/SP/Services/CustomField/CustomFieldItem.php +++ b/lib/SP/Services/CustomField/CustomFieldItem.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,17 +19,19 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\CustomField; +use JsonSerializable; + /** * Class CustomFieldItem * * @package SP\Services\CustomField */ -final class CustomFieldItem implements \JsonSerializable +final class CustomFieldItem implements JsonSerializable { public $required = false; public $showInList = false; diff --git a/lib/SP/Services/CustomField/CustomFieldService.php b/lib/SP/Services/CustomField/CustomFieldService.php index b552b69a..6a62b7dc 100644 --- a/lib/SP/Services/CustomField/CustomFieldService.php +++ b/lib/SP/Services/CustomField/CustomFieldService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\CustomField; @@ -44,41 +44,33 @@ use SP\Services\ServiceException; */ final class CustomFieldService extends Service { - /** - * @var CustomFieldRepository - */ - protected $customFieldRepository; - /** - * @var CustomFieldDefService - */ - protected $customFieldDefService; + protected ?CustomFieldRepository $customFieldRepository = null; + protected ?CustomFieldDefService $customFieldDefService = null; /** * Returns the form Id for a given name - * - * @param $name - * - * @return string */ - public static function getFormIdForName($name) + public static function getFormIdForName(string $name): string { - return 'cf_' . strtolower(preg_replace('/\W*/', '', $name)); + return sprintf( + 'cf_%s', + strtolower(preg_replace('/\W*/', '', $name)) + ); } /** * Desencriptar y formatear los datos del campo * - * @param string $data - * @param string $key - * - * @return string * @throws CryptoException * @throws ServiceException */ - public function decryptData($data, $key) + public function decryptData(string $data, string $key): string { if (!empty($data) && !empty($key)) { - return self::formatValue(Crypt::decrypt($data, $key, $this->getMasterKeyFromContext())); + return self::formatValue( + Crypt::decrypt($data, $key, + $this->getMasterKeyFromContext()) + ); } return ''; @@ -91,10 +83,14 @@ final class CustomFieldService extends Service * * @return string */ - public static function formatValue($value) + public static function formatValue(string $value): string { if (preg_match('#https?://#', $value)) { - return '' . $value . ''; + return sprintf( + '%s', + $value, + $value + ); } return $value; @@ -103,36 +99,35 @@ final class CustomFieldService extends Service /** * Returns the module's item for given id * - * @param $moduleId - * @param $itemId - * - * @return array - * @throws QueryException - * @throws ConstraintException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getForModuleAndItemId($moduleId, $itemId) + public function getForModuleAndItemId(int $moduleId, ?int $itemId): array { - return $this->customFieldRepository->getForModuleAndItemId($moduleId, $itemId)->getDataAsArray(); + return $this->customFieldRepository + ->getForModuleAndItemId($moduleId, $itemId) + ->getDataAsArray(); } /** * Updates an item * - * @param CustomFieldData $customFieldData - * - * @return bool * @throws CryptoException * @throws QueryException * @throws ConstraintException * @throws SPException */ - public function updateOrCreateData(CustomFieldData $customFieldData) + public function updateOrCreateData(CustomFieldData $customFieldData): bool { $exists = $this->customFieldRepository->checkExists($customFieldData); // Deletes item's custom field data if value is left blank if ($exists && empty($customFieldData->getData())) { - return $this->deleteCustomFieldData($customFieldData->getId(), $customFieldData->getModuleId(), $customFieldData->getDefinitionId()) === 1; + return $this->deleteCustomFieldData( + $customFieldData->getId(), + $customFieldData->getModuleId(), + $customFieldData->getDefinitionId() + ) === 1; } // Create item's custom field data if value is set @@ -150,35 +145,31 @@ final class CustomFieldService extends Service /** * Eliminar los datos de los campos personalizados del módulo * - * @param int $itemId - * @param int $moduleId - * @param int $definitionId - * - * @return int * @throws SPException */ - public function deleteCustomFieldData($itemId, $moduleId, $definitionId = null) + public function deleteCustomFieldData( + int $itemId, + int $moduleId, + ?int $definitionId = null + ): int { if ($definitionId === null) { return $this->customFieldRepository->deleteCustomFieldData($itemId, $moduleId); - } else { - return $this->customFieldRepository->deleteCustomFieldDataForDefinition($itemId, $moduleId, $definitionId); } + + return $this->customFieldRepository->deleteCustomFieldDataForDefinition($itemId, $moduleId, $definitionId); } /** * Creates an item * - * @param CustomFieldData $customFieldData - * - * @return bool * @throws CryptoException * @throws QueryException * @throws ServiceException * @throws ConstraintException * @throws NoSuchItemException */ - public function create(CustomFieldData $customFieldData) + public function create(CustomFieldData $customFieldData): bool { if (empty($customFieldData->getData())) { return true; @@ -192,37 +183,42 @@ final class CustomFieldService extends Service } /** - * @param CustomFieldData $customFieldData - * @param null $key - * - * @throws CryptoException - * @throws ServiceException + * @throws \Defuse\Crypto\Exception\CryptoException + * @throws \SP\Services\ServiceException */ - protected function setSecureData(CustomFieldData $customFieldData, $key = null) + protected function setSecureData( + CustomFieldData $customFieldData, + ?string $key = null + ): void { $key = $key ?: $this->getMasterKeyFromContext(); $securedKey = Crypt::makeSecuredKey($key); if (strlen($securedKey) > 1000) { - throw new ServiceException(__u('Internal error'), SPException::ERROR); + throw new ServiceException( + __u('Internal error'), + SPException::ERROR + ); } - $customFieldData->setData(Crypt::encrypt($customFieldData->getData(), $securedKey, $key)); + $customFieldData->setData(Crypt::encrypt( + $customFieldData->getData(), + $securedKey, + $key + )); $customFieldData->setKey($securedKey); } /** * Eliminar los datos de los campos personalizados del módulo * - * @param int $definitionId - * - * @return int * @throws QueryException * @throws ConstraintException */ - public function deleteCustomFieldDefinitionData($definitionId) + public function deleteCustomFieldDefinitionData(int $definitionId): int { - return $this->customFieldRepository->deleteCustomFieldDefinitionData($definitionId); + return $this->customFieldRepository + ->deleteCustomFieldDefinitionData($definitionId); } /** @@ -235,38 +231,39 @@ final class CustomFieldService extends Service * @throws QueryException * @throws ConstraintException */ - public function deleteCustomFieldDataBatch(array $ids, $moduleId) + public function deleteCustomFieldDataBatch(array $ids, int $moduleId): bool { - return $this->customFieldRepository->deleteCustomFieldDataBatch($ids, $moduleId); + return $this->customFieldRepository + ->deleteCustomFieldDataBatch($ids, $moduleId); } /** * Eliminar los datos de los elementos de una definición * - * @param array $definitionIds + * @param int[] $definitionIds * * @return int * @throws ConstraintException * @throws QueryException */ - public function deleteCustomFieldDefinitionDataBatch(array $definitionIds) + public function deleteCustomFieldDefinitionDataBatch(array $definitionIds): int { - return $this->customFieldRepository->deleteCustomFieldDefinitionDataBatch($definitionIds); + return $this->customFieldRepository + ->deleteCustomFieldDefinitionDataBatch($definitionIds); } /** * Updates an item * - * @param CustomFieldData $customFieldData - * @param string $masterPass - * - * @return bool - * @throws CryptoException - * @throws QueryException - * @throws ServiceException - * @throws ConstraintException + * @throws \Defuse\Crypto\Exception\CryptoException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException */ - public function updateMasterPass(CustomFieldData $customFieldData, $masterPass) + public function updateMasterPass( + CustomFieldData $customFieldData, + string $masterPass + ): int { $this->setSecureData($customFieldData, $masterPass); @@ -278,7 +275,7 @@ final class CustomFieldService extends Service * @throws QueryException * @throws ConstraintException */ - public function getAll() + public function getAll(): array { return $this->customFieldRepository->getAll()->getDataAsArray(); } @@ -288,7 +285,7 @@ final class CustomFieldService extends Service * @throws QueryException * @throws ConstraintException */ - public function getAllEncrypted() + public function getAllEncrypted(): array { return $this->customFieldRepository->getAllEncrypted()->getDataAsArray(); } @@ -297,7 +294,7 @@ final class CustomFieldService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->customFieldRepository = $this->dic->get(CustomFieldRepository::class); $this->customFieldDefService = $this->dic->get(CustomFieldDefService::class); diff --git a/lib/SP/Services/CustomField/CustomFieldTypeService.php b/lib/SP/Services/CustomField/CustomFieldTypeService.php index 921df05e..c90c9bb2 100644 --- a/lib/SP/Services/CustomField/CustomFieldTypeService.php +++ b/lib/SP/Services/CustomField/CustomFieldTypeService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\CustomField; @@ -41,10 +41,7 @@ final class CustomFieldTypeService extends Service { use ServiceItemTrait; - /** - * @var CustomFieldTypeRepository - */ - protected $customFieldTypeRepository; + protected ?CustomFieldTypeRepository $customFieldTypeRepository = null; /** * Get all items from the service's repository @@ -53,7 +50,7 @@ final class CustomFieldTypeService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAllBasic() + public function getAllBasic(): array { return $this->getAll(); } @@ -65,20 +62,17 @@ final class CustomFieldTypeService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): array { return $this->customFieldTypeRepository->getAll()->getDataAsArray(); } /** - * @param $id - * - * @return mixed - * @throws ConstraintException - * @throws QueryException - * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function getById($id) + public function getById(int $id) { $result = $this->customFieldTypeRepository->getById($id); @@ -89,7 +83,7 @@ final class CustomFieldTypeService extends Service return $result->getData(); } - protected function initialize() + protected function initialize(): void { $this->customFieldTypeRepository = $this->dic->get(CustomFieldTypeRepository::class); } diff --git a/lib/SP/Services/EventLog/EventlogService.php b/lib/SP/Services/EventLog/EventlogService.php index a2c42fde..fe38cff6 100644 --- a/lib/SP/Services/EventLog/EventlogService.php +++ b/lib/SP/Services/EventLog/EventlogService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\EventLog; @@ -43,46 +43,33 @@ use SP\Storage\Database\QueryResult; */ final class EventlogService extends Service { - /** - * @var EventlogRepository - */ - protected $eventLogRepository; - /** - * @var Request - */ - protected $request; + protected ?EventlogRepository $eventLogRepository = null; + protected ?Request $request = null; /** - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->eventLogRepository->search($itemSearchData); } /** - * @return bool * @throws ConstraintException * @throws QueryException * @throws SPException */ - public function clear() + public function clear(): bool { return $this->eventLogRepository->clear(); } /** - * @param EventlogData $eventlogData - * - * @return int * @throws ConstraintException * @throws QueryException */ - public function create(EventlogData $eventlogData) + public function create(EventlogData $eventlogData): int { $userData = $this->context->getUserData(); @@ -97,7 +84,7 @@ final class EventlogService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->eventLogRepository = $this->dic->get(EventlogRepository::class); $this->request = $this->dic->get(Request::class); diff --git a/lib/SP/Services/Export/VerifyResult.php b/lib/SP/Services/Export/VerifyResult.php index 1cb0c080..26f91726 100644 --- a/lib/SP/Services/Export/VerifyResult.php +++ b/lib/SP/Services/Export/VerifyResult.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Export; @@ -32,26 +32,10 @@ namespace SP\Services\Export; */ final class VerifyResult { - /** - * @var string - */ - private $version; - /** - * @var bool - */ - private $encrypted = false; - /** - * @var array - */ - private $nodes; + private string $version; + private bool $encrypted; + private array $nodes; - /** - * VerifyResult constructor. - * - * @param string $version - * @param bool $encrypted - * @param array $nodes - */ public function __construct(string $version, bool $encrypted, array $nodes) { $this->version = $version; @@ -59,25 +43,16 @@ final class VerifyResult $this->nodes = $nodes; } - /** - * @return string - */ public function getVersion(): string { return $this->version; } - /** - * @return bool - */ public function isEncrypted(): bool { return $this->encrypted; } - /** - * @return array - */ public function getNodes(): array { return $this->nodes; diff --git a/lib/SP/Services/Export/XmlExportService.php b/lib/SP/Services/Export/XmlExportService.php index 94f02ae9..205f01a4 100644 --- a/lib/SP/Services/Export/XmlExportService.php +++ b/lib/SP/Services/Export/XmlExportService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Export; @@ -30,13 +30,14 @@ use DOMXPath; use Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\AppInfoInterface; use SP\Core\Crypt\Crypt; use SP\Core\Crypt\Hash; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\CheckException; +use SP\Core\Exceptions\SPException; use SP\Core\PhpExtensionChecker; use SP\DataModel\CategoryData; use SP\Services\Account\AccountService; @@ -60,49 +61,25 @@ defined('APP_ROOT') || die(); */ final class XmlExportService extends Service { - /** - * @var ConfigData - */ - private $configData; - /** - * @var - */ - private $extensionChecker; - /** - * @var DOMDocument - */ - private $xml; - /** - * @var DOMElement - */ - private $root; - /** - * @var string - */ - private $exportPass; - /** - * @var bool - */ - private $encrypted = false; - /** - * @var string - */ - private $exportPath; - /** - * @var string - */ - private $exportFile; + private ?ConfigDataInterface $configData = null; + private ?PhpExtensionChecker $extensionChecker = null; + private ?DOMDocument $xml = null; + private ?DOMElement $root = null; + private ?string $exportPass = null; + private bool $encrypted = false; + private ?string $exportPath = null; + private ?string $exportFile = null; /** * Realiza la exportación de las cuentas a XML * - * @param string $exportPath - * @param string $pass string La clave de exportación + * @param string $exportPath + * @param string|null $pass La clave de exportación * - * @throws ServiceException - * @throws FileException + * @throws \SP\Services\ServiceException + * @throws \SP\Storage\File\FileException */ - public function doExport(string $exportPath, string $pass = null) + public function doExport(string $exportPath, ?string $pass = null): void { set_time_limit(0); @@ -118,16 +95,18 @@ final class XmlExportService extends Service } /** - * @param string $exportPath - * * @throws ServiceException */ - private function setExportPath(string $exportPath) + private function setExportPath(string $exportPath): void { if (!is_dir($exportPath) - && @mkdir($exportPath, 0700, true) === false + && !mkdir($exportPath, 0700, true) + && !is_dir($exportPath) ) { - throw new ServiceException(sprintf(__('Unable to create the directory (%s)'), $exportPath)); + throw new ServiceException(sprintf( + __('Unable to create the directory (%s)'), + $exportPath + )); } $this->exportPath = $exportPath; @@ -136,7 +115,6 @@ final class XmlExportService extends Service /** * Genera el nombre del archivo usado para la exportación. * - * @return string * @throws FileException */ private function generateExportFilename(): string @@ -149,34 +127,43 @@ final class XmlExportService extends Service return self::getExportFilename($this->exportPath, $hash); } - /** - * @param string $path - * @param string $hash - * @param bool $compressed - * - * @return string - */ - public static function getExportFilename(string $path, string $hash, bool $compressed = false) + public static function getExportFilename( + string $path, + string $hash, + bool $compressed = false + ): string { - $file = $path . DIRECTORY_SEPARATOR . AppInfoInterface::APP_NAME . '_export-' . $hash; + $file = sprintf( + '%s%s%s_export-%s', + $path, + DIRECTORY_SEPARATOR, + AppInfoInterface::APP_NAME, + $hash + ); if ($compressed) { return $file . ArchiveHandler::COMPRESS_EXTENSION; } - return $file . '.xml'; + return sprintf('%s.xml', $file); } /** * Eliminar los archivos de exportación anteriores */ - private function deleteOldExports() + private function deleteOldExports(): void { $path = $this->exportPath . DIRECTORY_SEPARATOR . AppInfoInterface::APP_NAME; - array_map(function ($file) { - return @unlink($file); - }, array_merge(glob($path . '_export-*'), glob($path . '*.xml'))); + array_map( + static function ($file) { + return @unlink($file); + }, + array_merge( + glob($path . '_export-*'), + glob($path . '*.xml') + ) + ); } /** @@ -186,7 +173,7 @@ final class XmlExportService extends Service * @throws NotFoundExceptionInterface * @throws ServiceException */ - private function makeXML() + private function makeXML(): void { try { $this->createRoot(); @@ -202,7 +189,7 @@ final class XmlExportService extends Service } catch (Exception $e) { throw new ServiceException( __u('Error while exporting'), - ServiceException::ERROR, + SPException::ERROR, __u('Please check out the event log for more details'), $e->getCode(), $e @@ -215,13 +202,17 @@ final class XmlExportService extends Service * * @throws ServiceException */ - private function createRoot() + private function createRoot(): void { try { $this->xml = new DOMDocument('1.0', 'UTF-8'); $this->root = $this->xml->appendChild($this->xml->createElement('Root')); } catch (Exception $e) { - throw new ServiceException($e->getMessage(), ServiceException::ERROR, __FUNCTION__); + throw new ServiceException( + $e->getMessage(), + SPException::ERROR, + __FUNCTION__ + ); } } @@ -230,7 +221,7 @@ final class XmlExportService extends Service * * @throws ServiceException */ - private function createMeta() + private function createMeta(): void { try { $userData = $this->context->getUserData(); @@ -252,7 +243,11 @@ final class XmlExportService extends Service $this->root->appendChild($nodeMeta); } catch (Exception $e) { - throw new ServiceException($e->getMessage(), ServiceException::ERROR, __FUNCTION__); + throw new ServiceException( + $e->getMessage(), + SPException::ERROR, + __FUNCTION__ + ); } } @@ -263,10 +258,11 @@ final class XmlExportService extends Service * @throws NotFoundExceptionInterface * @throws ServiceException */ - private function createCategories() + private function createCategories(): void { try { - $this->eventDispatcher->notifyEvent('run.export.process.category', + $this->eventDispatcher->notifyEvent( + 'run.export.process.category', new Event($this, EventMessage::factory() ->addDescription(__u('Exporting categories'))) ); @@ -300,7 +296,11 @@ final class XmlExportService extends Service $this->appendNode($nodeCategories); } catch (Exception $e) { - throw new ServiceException($e->getMessage(), ServiceException::ERROR, __FUNCTION__); + throw new ServiceException( + $e->getMessage(), + SPException::ERROR, + __FUNCTION__ + ); } } @@ -311,7 +311,7 @@ final class XmlExportService extends Service * * @throws ServiceException */ - private function appendNode(DOMElement $node) + private function appendNode(DOMElement $node): void { try { // Si se utiliza clave de encriptación los datos se encriptan en un nuevo nodo: @@ -351,7 +351,11 @@ final class XmlExportService extends Service $this->root->appendChild($node); } } catch (Exception $e) { - throw new ServiceException($e->getMessage(), ServiceException::ERROR, __FUNCTION__); + throw new ServiceException( + $e->getMessage(), + SPException::ERROR, + __FUNCTION__ + ); } } @@ -360,9 +364,9 @@ final class XmlExportService extends Service * * @param $data string Los datos a escapar * - * @return mixed + * @return string */ - private function escapeChars($data) + private function escapeChars(string $data): string { $arrStrFrom = ['&', '<', '>', '"', '\'']; $arrStrTo = ['&', '<', '>', '"', ''']; @@ -378,10 +382,11 @@ final class XmlExportService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - private function createClients() + private function createClients(): void { try { - $this->eventDispatcher->notifyEvent('run.export.process.client', + $this->eventDispatcher->notifyEvent( + 'run.export.process.client', new Event($this, EventMessage::factory() ->addDescription(__u('Exporting clients'))) ); @@ -413,7 +418,11 @@ final class XmlExportService extends Service $this->appendNode($nodeClients); } catch (Exception $e) { - throw new ServiceException($e->getMessage(), ServiceException::ERROR, __FUNCTION__); + throw new ServiceException( + $e->getMessage(), + SPException::ERROR, + __FUNCTION__ + ); } } @@ -424,10 +433,11 @@ final class XmlExportService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - private function createTags() + private function createTags(): void { try { - $this->eventDispatcher->notifyEvent('run.export.process.tag', + $this->eventDispatcher->notifyEvent( + 'run.export.process.tag', new Event($this, EventMessage::factory() ->addDescription(__u('Exporting tags'))) ); @@ -457,7 +467,11 @@ final class XmlExportService extends Service $this->appendNode($nodeTags); } catch (Exception $e) { - throw new ServiceException($e->getMessage(), ServiceException::ERROR, __FUNCTION__); + throw new ServiceException( + $e->getMessage(), + SPException::ERROR, + __FUNCTION__ + ); } } @@ -468,10 +482,11 @@ final class XmlExportService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - private function createAccounts() + private function createAccounts(): void { try { - $this->eventDispatcher->notifyEvent('run.export.process.account', + $this->eventDispatcher->notifyEvent( + 'run.export.process.account', new Event($this, EventMessage::factory() ->addDescription(__u('Exporting accounts'))) ); @@ -525,7 +540,11 @@ final class XmlExportService extends Service $this->appendNode($nodeAccounts); } catch (Exception $e) { - throw new ServiceException($e->getMessage(), ServiceException::ERROR, __FUNCTION__); + throw new ServiceException( + $e->getMessage(), + SPException::ERROR, + __FUNCTION__ + ); } } @@ -534,7 +553,7 @@ final class XmlExportService extends Service * * @throws ServiceException */ - private function createHash() + private function createHash(): void { try { $hash = self::generateHashFromNodes($this->xml); @@ -551,15 +570,14 @@ final class XmlExportService extends Service ->item(0) ->appendChild($hashNode); } catch (Exception $e) { - throw new ServiceException($e->getMessage(), ServiceException::ERROR, __FUNCTION__); + throw new ServiceException( + $e->getMessage(), + SPException::ERROR, + __FUNCTION__ + ); } } - /** - * @param DOMDocument $document - * - * @return string - */ public static function generateHashFromNodes(DOMDocument $document): string { $data = ''; @@ -576,7 +594,7 @@ final class XmlExportService extends Service * * @throws ServiceException */ - private function writeXML() + private function writeXML(): void { try { $this->xml->formatOutput = true; @@ -586,7 +604,11 @@ final class XmlExportService extends Service throw new ServiceException(__u('Error while creating the XML file')); } } catch (Exception $e) { - throw new ServiceException($e->getMessage(), ServiceException::ERROR, __FUNCTION__); + throw new ServiceException( + $e->getMessage(), + SPException::ERROR, + __FUNCTION__ + ); } } @@ -594,7 +616,7 @@ final class XmlExportService extends Service * @throws CheckException * @throws FileException */ - public function createArchive() + public function createArchive(): void { $archive = new ArchiveHandler($this->exportFile, $this->extensionChecker); $archive->compressFile($this->exportFile); @@ -603,17 +625,11 @@ final class XmlExportService extends Service $file->delete(); } - /** - * @return string - */ public function getExportFile(): string { return $this->exportFile; } - /** - * @return bool - */ public function isEncrypted(): bool { return $this->encrypted; @@ -623,26 +639,9 @@ final class XmlExportService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->extensionChecker = $this->dic->get(PhpExtensionChecker::class); $this->configData = $this->config->getConfigData(); } - - /** - * Devuelve el código XML de un nodo - * - * @param $node string El nodo a devolver - * - * @return string - * @throws ServiceException - */ - private function getNodeXML($node) - { - try { - return $this->xml->saveXML($this->root->getElementsByTagName($node)->item(0)); - } catch (Exception $e) { - throw new ServiceException($e->getMessage(), ServiceException::ERROR, __FUNCTION__); - } - } } \ No newline at end of file diff --git a/lib/SP/Services/Export/XmlVerifyService.php b/lib/SP/Services/Export/XmlVerifyService.php index f00f1407..d382110e 100644 --- a/lib/SP/Services/Export/XmlVerifyService.php +++ b/lib/SP/Services/Export/XmlVerifyService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Export; @@ -48,25 +48,13 @@ use SP\Util\VersionUtil; */ final class XmlVerifyService extends Service { - const NODES = ['Category', 'Client', 'Tag', 'Account']; - const XML_MIN_VERSION = [2, 1, 0, 0]; - /** - * @var DOMDocument - */ - private $xml; - /** - * @var string - */ - private $xmlFile; - /** - * @var string - */ - private $password; + private const NODES = ['Category', 'Client', 'Tag', 'Account']; + private const XML_MIN_VERSION = [2, 1, 0, 0]; + private ?DOMDocument $xml = null; + private ?string $xmlFile = null; + private ?string $password = null; /** - * @param string $xmlFile - * - * @return VerifyResult * @throws FileException * @throws ImportException * @throws ServiceException @@ -83,26 +71,31 @@ final class XmlVerifyService extends Service self::checkVersion($version); - self::checkXmlHash($this->xml, $this->config->getConfigData()->getPasswordSalt()); + self::checkXmlHash( + $this->xml, + $this->config->getConfigData()->getPasswordSalt() + ); - return new VerifyResult($version, false, $this->countItemNodes($this->xml)); + return new VerifyResult( + $version, + false, + $this->countItemNodes($this->xml) + ); } /** * @throws FileException * @throws ImportException */ - private function setup() + private function setup(): void { $this->xml = (new XmlFileImport(FileImport::fromFilesystem($this->xmlFile)))->getXmlDOM(); } /** - * @param DOMDocument $document - * * @throws ServiceException */ - public static function validateSchema(DOMDocument $document) + public static function validateSchema(DOMDocument $document): void { if (!$document->schemaValidate(XML_SCHEMA)) { throw new ServiceException('Invalid XML schema'); @@ -118,44 +111,44 @@ final class XmlVerifyService extends Service } /** - * @param string $version - * - * @return void * @throws ServiceException */ - public static function checkVersion(string $version) + public static function checkVersion(string $version): void { if (VersionUtil::checkVersion($version, self::XML_MIN_VERSION)) { - throw new ServiceException(sprintf('Sorry, this XML version is not compatible. Please use >= %s', - VersionUtil::normalizeVersionForCompare(self::XML_MIN_VERSION)) + throw new ServiceException( + sprintf( + 'Sorry, this XML version is not compatible. Please use >= %s', + VersionUtil::normalizeVersionForCompare(self::XML_MIN_VERSION) + ) ); } } /** * Obtener la versión del XML - * - * @param DOMDocument $document - * @param string $key - * - * @return bool */ - public static function checkXmlHash(DOMDocument $document, string $key) + public static function checkXmlHash( + DOMDocument $document, + string $key + ): bool { $DOMXPath = new DOMXPath($document); $hash = $DOMXPath->query('/Root/Meta/Hash'); $sign = $DOMXPath->query('/Root/Meta/Hash/@sign'); if ($hash->length === 1 && $sign->length === 1) { - return Hash::checkMessage($hash->item(0)->nodeValue, $key, $sign->item(0)->nodeValue); + return Hash::checkMessage( + $hash->item(0)->nodeValue, + $key, + $sign->item(0)->nodeValue + ); } - return $hash === XmlExportService::generateHashFromNodes($document); + return (string)$hash === XmlExportService::generateHashFromNodes($document); } /** - * @param DOMDocument $document - * * @return int[] */ private function countItemNodes(DOMDocument $document): array @@ -163,22 +156,21 @@ final class XmlVerifyService extends Service $result = []; foreach (self::NODES as $node) { - $result[$node] = (int)$document->getElementsByTagName($node)->length; + $result[$node] = $document->getElementsByTagName($node)->length; } return $result; } /** - * @param string $xmlFile - * @param string $password - * - * @return VerifyResult * @throws FileException * @throws ImportException * @throws ServiceException */ - public function verifyEncrypted(string $xmlFile, string $password): VerifyResult + public function verifyEncrypted( + string $xmlFile, + string $password + ): VerifyResult { $this->xmlFile = $xmlFile; $this->password = $password; @@ -205,7 +197,7 @@ final class XmlVerifyService extends Service /** * @throws ServiceException */ - private function checkPassword() + private function checkPassword(): void { $hash = $this->xml ->getElementsByTagName('Encrypted') @@ -219,10 +211,8 @@ final class XmlVerifyService extends Service /** * Verificar si existen datos encriptados - * - * @return bool */ - private function detectEncrypted() + private function detectEncrypted(): bool { return $this->xml->getElementsByTagName('Encrypted')->length > 0; } @@ -237,14 +227,21 @@ final class XmlVerifyService extends Service $xpath = new DOMXPath($this->xml); $dataNodes = $xpath->query('/Root/Encrypted/Data'); - $decode = VersionUtil::checkVersion($this->getXmlVersion(), '320.0'); + $decode = VersionUtil::checkVersion( + $this->getXmlVersion(), + '320.0' + ); /** @var $node DOMElement */ foreach ($dataNodes as $node) { $data = $decode ? base64_decode($node->nodeValue) : $node->nodeValue; try { - $xmlDecrypted = Crypt::decrypt($data, $node->getAttribute('key'), $this->password); + $xmlDecrypted = Crypt::decrypt( + $data, + $node->getAttribute('key'), + $this->password + ); } catch (CryptoException $e) { throw new ServiceException(__u('Wrong encryption password')); } @@ -255,7 +252,9 @@ final class XmlVerifyService extends Service throw new ServiceException(__u('Error loading XML data')); } - $this->xml->documentElement->appendChild($this->xml->importNode($newXmlData->documentElement, true)); + $this->xml->documentElement->appendChild( + $this->xml->importNode($newXmlData->documentElement, true) + ); } // Remove the encrypted data after processing diff --git a/lib/SP/Services/Import/CsvImport.php b/lib/SP/Services/Import/CsvImport.php index 948dd732..2cb58a93 100644 --- a/lib/SP/Services/Import/CsvImport.php +++ b/lib/SP/Services/Import/CsvImport.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Import; @@ -44,9 +44,10 @@ final class CsvImport extends CsvImportBase implements ImportInterface * @throws ImportException * @throws FileException */ - public function doImport() + public function doImport(): ImportInterface { - $this->eventDispatcher->notifyEvent('run.import.csv', + $this->eventDispatcher->notifyEvent( + 'run.import.csv', new Event($this, EventMessage::factory() ->addDescription(sprintf(__('Detected format: %s'), 'CSV'))) ); diff --git a/lib/SP/Services/Import/CsvImportBase.php b/lib/SP/Services/Import/CsvImportBase.php index c953b750..0a02e7be 100644 --- a/lib/SP/Services/Import/CsvImportBase.php +++ b/lib/SP/Services/Import/CsvImportBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Import; @@ -29,6 +29,7 @@ use Psr\Container\ContainerInterface; use SP\Core\Events\Event; use SP\Core\Events\EventDispatcher; use SP\Core\Events\EventMessage; +use SP\Core\Exceptions\SPException; use SP\DataModel\CategoryData; use SP\DataModel\ClientData; use SP\Services\Account\AccountRequest; @@ -49,30 +50,12 @@ abstract class CsvImportBase { use ImportTrait; - /** - * @var int - */ - protected $numFields = 7; - /** - * @var array - */ - protected $mapFields = []; - /** - * @var FileImport - */ - protected $fileImport; - /** - * @var EventDispatcher - */ + protected int $numFields = 7; + protected array $mapFields = []; + protected FileImport $fileImport; protected $eventDispatcher; - /** - * @var array - */ - protected $categories = []; - /** - * @var array - */ - protected $clients = []; + protected array $categories = []; + protected array $clients = []; /** * ImportBase constructor. @@ -82,7 +65,11 @@ abstract class CsvImportBase * @param ImportParams $importParams * */ - public function __construct(ContainerInterface $dic, FileImport $fileImport, ImportParams $importParams) + public function __construct( + ContainerInterface $dic, + FileImport $fileImport, + ImportParams $importParams + ) { $this->fileImport = $fileImport; $this->importParams = $importParams; @@ -97,7 +84,7 @@ abstract class CsvImportBase /** * @param int $numFields */ - public function setNumFields($numFields) + public function setNumFields(int $numFields): void { $this->numFields = $numFields; } @@ -105,18 +92,23 @@ abstract class CsvImportBase /** * @param array $mapFields */ - public function setMapFields($mapFields) + public function setMapFields(array $mapFields): void { $this->mapFields = $mapFields; } + public function getEventDispatcher(): EventDispatcher + { + return $this->eventDispatcher; + } + /** * Obtener los datos de las entradas de sysPass y crearlas * * @throws ImportException * @throws FileException */ - protected function processAccounts() + protected function processAccounts(): void { $line = 0; @@ -130,13 +122,21 @@ abstract class CsvImportBase if ($numfields !== $this->numFields) { throw new ImportException( sprintf(__('Wrong number of fields (%d)'), $numfields), - ImportException::ERROR, + SPException::ERROR, sprintf(__('Please, check the CSV file format in line %s'), $line) ); } // Asignar los valores del array a variables - list($accountName, $clientName, $categoryName, $url, $login, $password, $notes) = $fields; + [ + $accountName, + $clientName, + $categoryName, + $url, + $login, + $password, + $notes + ] = $fields; try { if (empty($clientName) || empty($categoryName)) { @@ -144,8 +144,12 @@ abstract class CsvImportBase } // Obtener los ids de cliente y categoría - $clientId = $this->addClient(new ClientData(null, $clientName)); - $categoryId = $this->addCategory(new CategoryData(null, $categoryName)); + $clientId = $this->addClient( + new ClientData(null, $clientName) + ); + $categoryId = $this->addCategory( + new CategoryData(null, $categoryName) + ); // Crear la nueva cuenta $accountRequest = new AccountRequest(); @@ -159,7 +163,8 @@ abstract class CsvImportBase $this->addAccount($accountRequest); - $this->eventDispatcher->notifyEvent('run.import.csv.process.account', + $this->eventDispatcher->notifyEvent( + 'run.import.csv.process.account', new Event($this, EventMessage::factory() ->addDetail(__u('Account imported'), $accountName) ->addDetail(__u('Client'), $clientName)) @@ -167,7 +172,8 @@ abstract class CsvImportBase } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', + $this->eventDispatcher->notifyEvent( + 'exception', new Event($e, EventMessage::factory() ->addDetail(__u('Error while importing the account'), $accountName) ->addDetail(__u('Error while processing line'), $line)) @@ -180,7 +186,7 @@ abstract class CsvImportBase if ($line === 0) { throw new ImportException( sprintf(__('Wrong number of fields (%d)'), 0), - ImportException::ERROR, + SPException::ERROR, sprintf(__('Please, check the CSV file format in line %s'), 0) ); } diff --git a/lib/SP/Services/Import/FileImport.php b/lib/SP/Services/Import/FileImport.php index f85f3a59..3ceefefc 100644 --- a/lib/SP/Services/Import/FileImport.php +++ b/lib/SP/Services/Import/FileImport.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Import; @@ -39,10 +39,7 @@ defined('APP_ROOT') || die(); */ final class FileImport { - /** - * @var FileHandler - */ - private $fileHandler; + private FileHandler $fileHandler; /** * FileImport constructor. @@ -55,14 +52,13 @@ final class FileImport } /** - * @param string $filename - * @param Request $request - * - * @return FileImport * @throws FileException * @throws SPException */ - public static function fromRequest(string $filename, Request $request) + public static function fromRequest( + string $filename, + Request $request + ): FileImport { return new self(self::checkFile($request->getFile($filename))); } @@ -70,18 +66,18 @@ final class FileImport /** * Leer los datos del archivo. * - * @param array $file con los datos del archivo + * @param array|null $file con los datos del archivo * * @return FileHandler - * @throws FileException - * @throws SPException + * @throws \SP\Services\Import\ImportException + * @throws \SP\Storage\File\FileException */ - private static function checkFile($file): FileHandler + private static function checkFile(?array $file): FileHandler { if (!is_array($file)) { throw new FileException( __u('File successfully uploaded'), - FileException::ERROR, + SPException::ERROR, __u('Please check the web server user permissions') ); } @@ -90,21 +86,23 @@ final class FileImport $fileHandler = new FileHandler($file['tmp_name']); $fileHandler->checkFileExists(); - if (!in_array($fileHandler->getFileType(), ImportService::ALLOWED_MIME)) { + if (!in_array( + $fileHandler->getFileType(), + ImportService::ALLOWED_MIME)) { throw new ImportException( __u('File type not allowed'), - ImportException::ERROR, + SPException::ERROR, sprintf(__('MIME type: %s'), $fileHandler->getFileType()) ); } return $fileHandler; } catch (FileException $e) { - logger('Max. upload size: ' . Util::getMaxUpload()); + logger(sprintf('Max. upload size: %s', Util::getMaxUpload())); throw new FileException( __u('Internal error while reading the file'), - FileException::ERROR, + SPException::ERROR, __u('Please, check PHP configuration for upload files'), $e->getCode(), $e @@ -112,29 +110,20 @@ final class FileImport } } - /** - * @param string $path - * - * @return FileImport - */ - public static function fromFilesystem(string $path) + public static function fromFilesystem(string $path): FileImport { return new self(new FileHandler($path)); } - /** - * @return string - */ - public function getFilePath() + public function getFilePath(): string { return $this->fileHandler->getFile(); } /** - * @return string * @throws FileException */ - public function getFileType() + public function getFileType(): string { return $this->fileHandler->getFileType(); } @@ -154,7 +143,7 @@ final class FileImport /** * Activar la autodetección de fin de línea */ - protected function autodetectEOL() + protected function autodetectEOL(): void { ini_set('auto_detect_line_endings', true); } @@ -171,9 +160,6 @@ final class FileImport return $this->fileHandler->readToString(); } - /** - * @return FileHandler - */ public function getFileHandler(): FileHandler { return $this->fileHandler; diff --git a/lib/SP/Services/Import/ImportException.php b/lib/SP/Services/Import/ImportException.php index 59a340f6..699309e7 100644 --- a/lib/SP/Services/Import/ImportException.php +++ b/lib/SP/Services/Import/ImportException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Import; diff --git a/lib/SP/Services/Import/ImportInterface.php b/lib/SP/Services/Import/ImportInterface.php index 17c3d71b..fad98834 100644 --- a/lib/SP/Services/Import/ImportInterface.php +++ b/lib/SP/Services/Import/ImportInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Import; @@ -36,12 +36,12 @@ interface ImportInterface * * @return ImportInterface */ - public function doImport(); + public function doImport(): ImportInterface; /** * Devolver el contador de objetos importados * * @return int */ - public function getCounter(); + public function getCounter(): int; } \ No newline at end of file diff --git a/lib/SP/Services/Import/ImportParams.php b/lib/SP/Services/Import/ImportParams.php index cf9f17b5..cf2dc8c8 100644 --- a/lib/SP/Services/Import/ImportParams.php +++ b/lib/SP/Services/Import/ImportParams.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Import; @@ -32,104 +32,59 @@ namespace SP\Services\Import; */ final class ImportParams { - /** - * @var string - */ - protected $importPwd; - /** - * @var string - */ - protected $importMasterPwd; - /** - * @var int - */ - protected $defaultUser = 0; - /** - * @var int - */ - protected $defaultGroup = 0; - /** - * @var string - */ - protected $csvDelimiter = ';'; + protected ?string $importPwd = null; + protected ?string $importMasterPwd = null; + protected int $defaultUser = 0; + protected int $defaultGroup = 0; + protected string $csvDelimiter = ';'; - /** - * @return string - */ - public function getImportPwd() + public function getImportPwd(): ?string { return $this->importPwd; } - /** - * @param string $importPwd - */ - public function setImportPwd($importPwd) + public function setImportPwd(string $importPwd): void { $this->importPwd = $importPwd; } - /** - * @return int - */ - public function getDefaultGroup() + public function getDefaultGroup(): int { return $this->defaultGroup; } - /** - * @param int $defaultGroup - */ - public function setDefaultGroup($defaultGroup) + public function setDefaultGroup(int $defaultGroup): void { - $this->defaultGroup = (int)$defaultGroup; + $this->defaultGroup = $defaultGroup; } - /** - * @return string - */ - public function getCsvDelimiter() + public function getCsvDelimiter(): string { return $this->csvDelimiter; } - /** - * @param string $csvDelimiter - */ - public function setCsvDelimiter($csvDelimiter) + public function setCsvDelimiter(string $csvDelimiter): void { $this->csvDelimiter = $csvDelimiter; } - /** - * @return string - */ - public function getImportMasterPwd() + public function getImportMasterPwd(): ?string { return $this->importMasterPwd; } - /** - * @param string $importMasterPwd - */ - public function setImportMasterPwd($importMasterPwd) + public function setImportMasterPwd(string $importMasterPwd): void { $this->importMasterPwd = $importMasterPwd; } - /** - * @return int - */ - public function getDefaultUser() + public function getDefaultUser(): int { return $this->defaultUser; } - /** - * @param int $defaultUser - */ - public function setDefaultUser($defaultUser) + public function setDefaultUser(int $defaultUser): void { - $this->defaultUser = (int)$defaultUser; + $this->defaultUser = $defaultUser; } } \ No newline at end of file diff --git a/lib/SP/Services/Import/ImportService.php b/lib/SP/Services/Import/ImportService.php index 3cfd0118..2acf93a9 100644 --- a/lib/SP/Services/Import/ImportService.php +++ b/lib/SP/Services/Import/ImportService.php @@ -5,7 +5,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -20,7 +20,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Import; @@ -28,6 +28,7 @@ namespace SP\Services\Import; use Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; +use SP\Core\Exceptions\SPException; use SP\Services\Service; use SP\Storage\File\FileException; @@ -38,7 +39,7 @@ defined('APP_ROOT') || die(); */ final class ImportService extends Service { - const ALLOWED_MIME = [ + public const ALLOWED_MIME = [ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel', 'text/plain', @@ -48,58 +49,61 @@ final class ImportService extends Service 'text/xml' ]; - /** - * @var ImportParams - */ - protected $importParams; - /** - * @var FileImport - */ - protected $fileImport; + protected ?ImportParams $importParams = null; + protected ?FileImport $fileImport = null; /** * Iniciar la importación de cuentas. * - * @param ImportParams $importParams - * @param FileImport $fileImport - * * @return int Returns the total number of imported items * @throws Exception * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function doImport(ImportParams $importParams, FileImport $fileImport) + public function doImport( + ImportParams $importParams, + FileImport $fileImport + ): int { $this->importParams = $importParams; $this->fileImport = $fileImport; - return $this->transactionAware(function () { - return $this->selectImportType() - ->doImport() - ->getCounter(); - }); + return $this->transactionAware( + function () { + return $this->selectImportType() + ->doImport() + ->getCounter(); + } + ); } /** - * @return ImportInterface * @throws ImportException * @throws FileException */ - protected function selectImportType() + protected function selectImportType(): ImportInterface { $fileType = $this->fileImport->getFileType(); switch ($fileType) { case 'text/plain': - return new CsvImport($this->dic, $this->fileImport, $this->importParams); + return new CsvImport( + $this->dic, + $this->fileImport, + $this->importParams + ); case 'text/xml': case 'application/xml': - return new XmlImport($this->dic, new XmlFileImport($this->fileImport), $this->importParams); + return new XmlImport( + $this->dic, + new XmlFileImport($this->fileImport), + $this->importParams + ); } throw new ImportException( sprintf(__('Mime type not supported ("%s")'), $fileType), - ImportException::ERROR, + SPException::ERROR, __u('Please, check the file format') ); } @@ -108,7 +112,7 @@ final class ImportService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { set_time_limit(0); } diff --git a/lib/SP/Services/Import/ImportTrait.php b/lib/SP/Services/Import/ImportTrait.php index 4e7efe1d..ad503bbf 100644 --- a/lib/SP/Services/Import/ImportTrait.php +++ b/lib/SP/Services/Import/ImportTrait.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Import; @@ -48,47 +48,23 @@ use SP\Services\Tag\TagService; */ trait ImportTrait { - /** - * @var ImportParams - */ - protected $importParams; - /** - * @var int - */ - protected $version = 0; + protected int $version = 0; /** * @var bool Indica si el hash de la clave suministrada es igual a la actual */ - protected $mPassValidHash = false; - /** - * @var int - */ - protected $counter = 0; - /** - * @var AccountService - */ - private $accountService; - /** - * @var CategoryService - */ - private $categoryService; - /** - * @var ClientService - */ - private $clientService; - /** - * @var TagService - */ - private $tagService; - /** - * @var array - */ - private $items; + protected bool $mPassValidHash = false; + protected int $counter = 0; + protected ImportParams $importParams; + private AccountService $accountService; + private CategoryService $categoryService; + private ClientService $clientService; + private TagService $tagService; + private array $items; /** * @return int */ - public function getCounter() + public function getCounter(): int { return $this->counter; } @@ -105,7 +81,7 @@ trait ImportTrait * @throws NoSuchPropertyException * @throws QueryException */ - protected function addAccount(AccountRequest $accountRequest) + protected function addAccount(AccountRequest $accountRequest): void { if (empty($accountRequest->categoryId)) { throw new ImportException(__u('Category Id not set. Unable to import account.')); @@ -118,11 +94,20 @@ trait ImportTrait $accountRequest->userId = $this->importParams->getDefaultUser(); $accountRequest->userGroupId = $this->importParams->getDefaultGroup(); - if ($this->mPassValidHash === false && !empty($this->importParams->getImportMasterPwd())) { + if ($this->mPassValidHash === false + && !empty($this->importParams->getImportMasterPwd())) { if ($this->version >= 210) { - $pass = Crypt::decrypt($accountRequest->pass, $accountRequest->key, $this->importParams->getImportMasterPwd()); + $pass = Crypt::decrypt( + $accountRequest->pass, + $accountRequest->key, + $this->importParams->getImportMasterPwd() + ); } else { - $pass = OldCrypt::getDecrypt($accountRequest->pass, $accountRequest->key, $this->importParams->getImportMasterPwd()); + $pass = OldCrypt::getDecrypt( + $accountRequest->pass, + $accountRequest->key, + $this->importParams->getImportMasterPwd() + ); } $accountRequest->pass = $pass; @@ -143,50 +128,50 @@ trait ImportTrait * @throws DuplicatedItemException * @throws SPException */ - protected function addCategory(CategoryData $categoryData) + protected function addCategory(CategoryData $categoryData): int { try { $categoryId = $this->getWorkingItem('category', $categoryData->getName()); - if ($categoryId === null) { - return $this->categoryService->create($categoryData); - } - - return $categoryId; + return $categoryId ?? $this->categoryService->create($categoryData); } catch (DuplicatedItemException $e) { $itemData = $this->categoryService->getByName($categoryData->getName()); - if (empty($itemData)) { + if ($itemData === null) { throw $e; } - return $this->addWorkingItem('category', $itemData->getName(), $itemData->getId()); + return $this->addWorkingItem( + 'category', + $itemData->getName(), + $itemData->getId() + ); } } /** - * @param string $type - * @param string $value + * @param string $type + * @param string|int $value * * @return int|null */ - protected function getWorkingItem($type, $value) + protected function getWorkingItem(string $type, $value): ?int { - if (!isset($this->items[$type][$value])) { - return null; - } - - return $this->items[$type][$value]; + return $this->items[$type][$value] ?? null; } /** - * @param string $type - * @param string $value - * @param int $id + * @param string $type + * @param string|int $value + * @param int $id * - * @return int|bool + * @return int */ - protected function addWorkingItem($type, $value, $id) + protected function addWorkingItem( + string $type, + $value, + int $id + ): int { if (isset($this->items[$type][$value])) { return $this->items[$type][$value]; @@ -206,24 +191,24 @@ trait ImportTrait * @throws DuplicatedItemException * @throws SPException */ - protected function addClient(ClientData $clientData) + protected function addClient(ClientData $clientData): int { try { $clientId = $this->getWorkingItem('client', $clientData->getName()); - if ($clientId === null) { - return $this->clientService->create($clientData); - } - - return $clientId; + return $clientId ?? $this->clientService->create($clientData); } catch (DuplicatedItemException $e) { $itemData = $this->clientService->getByName($clientData->getName()); - if (empty($itemData)) { + if ($itemData === null) { throw $e; } - return $this->addWorkingItem('client', $itemData->getName(), $itemData->getId()); + return $this->addWorkingItem( + 'client', + $itemData->getName(), + $itemData->getId() + ); } } @@ -235,24 +220,24 @@ trait ImportTrait * @return int * @throws SPException */ - protected function addTag(TagData $tagData) + protected function addTag(TagData $tagData): int { try { $tagId = $this->getWorkingItem('tag', $tagData->getName()); - if ($tagId === null) { - return $this->tagService->create($tagData); - } - - return $tagId; + return $tagId ?? $this->tagService->create($tagData); } catch (DuplicatedItemException $e) { $itemData = $this->tagService->getByName($tagData->getName()); - if (empty($itemData)) { + if ($itemData === null) { throw $e; } - return $this->addWorkingItem('tag', $itemData->getName(), $itemData->getId()); + return $this->addWorkingItem( + 'tag', + $itemData->getName(), + $itemData->getId() + ); } } } \ No newline at end of file diff --git a/lib/SP/Services/Import/KeepassImport.php b/lib/SP/Services/Import/KeepassImport.php index eb39bdc5..dde63bb2 100644 --- a/lib/SP/Services/Import/KeepassImport.php +++ b/lib/SP/Services/Import/KeepassImport.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Import; @@ -42,20 +42,17 @@ defined('APP_ROOT') || die(); */ final class KeepassImport extends XmlImportBase implements ImportInterface { - /** - * @var array - */ - private $items = []; + private array $items = []; /** * Iniciar la importación desde KeePass * - * @return ImportInterface * @throws SPException */ - public function doImport() + public function doImport(): ImportInterface { - $this->eventDispatcher->notifyEvent('run.import.keepass', + $this->eventDispatcher->notifyEvent( + 'run.import.keepass', new Event($this, EventMessage::factory() ->addDescription(__u('KeePass XML Import'))) ); @@ -70,11 +67,12 @@ final class KeepassImport extends XmlImportBase implements ImportInterface * * @throws SPException */ - private function process() + private function process(): void { $clientId = $this->addClient(new ClientData(null, 'KeePass')); - $this->eventDispatcher->notifyEvent('run.import.keepass.process.client', + $this->eventDispatcher->notifyEvent( + 'run.import.keepass.process.client', new Event($this, EventMessage::factory() ->addDetail(__u('Client added'), 'KeePass')) ); @@ -86,9 +84,12 @@ final class KeepassImport extends XmlImportBase implements ImportInterface /** @var AccountRequest[] $group */ foreach ($this->items as $group => $entry) { try { - $categoryId = $this->addCategory(new CategoryData(null, $group, 'KeePass')); + $categoryId = $this->addCategory( + new CategoryData(null, $group, 'KeePass') + ); - $this->eventDispatcher->notifyEvent('run.import.keepass.process.category', + $this->eventDispatcher->notifyEvent( + 'run.import.keepass.process.category', new Event($this, EventMessage::factory() ->addDetail(__u('Category imported'), $group)) ); @@ -100,7 +101,8 @@ final class KeepassImport extends XmlImportBase implements ImportInterface $this->addAccount($account); - $this->eventDispatcher->notifyEvent('run.import.keepass.process.account', + $this->eventDispatcher->notifyEvent( + 'run.import.keepass.process.account', new Event($this, EventMessage::factory() ->addDetail(__u('Account imported'), $account->name) ->addDetail(__u('Category'), $group)) @@ -110,7 +112,10 @@ final class KeepassImport extends XmlImportBase implements ImportInterface } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); } } } @@ -118,7 +123,7 @@ final class KeepassImport extends XmlImportBase implements ImportInterface /** * Gets the groups found */ - private function getGroups() + private function getGroups(): void { $DomXpath = new DOMXPath($this->xmlDOM); $tags = $DomXpath->query('/KeePassFile/Root/Group//Group'); @@ -126,7 +131,9 @@ final class KeepassImport extends XmlImportBase implements ImportInterface /** @var DOMElement[] $tags */ foreach ($tags as $tag) { if ($tag->nodeType === 1) { - $groupName = $DomXpath->query($tag->getNodePath() . '/Name')->item(0)->nodeValue; + $groupName = $DomXpath->query($tag->getNodePath() . '/Name') + ->item(0) + ->nodeValue; if (!isset($groups[$groupName])) { $this->items[$groupName] = []; @@ -138,7 +145,7 @@ final class KeepassImport extends XmlImportBase implements ImportInterface /** * Gets the entries found */ - private function getEntries() + private function getEntries(): void { $DomXpath = new DOMXPath($this->xmlDOM); $tags = $DomXpath->query('/KeePassFile/Root/Group//Entry[not(parent::History)]'); @@ -151,29 +158,28 @@ final class KeepassImport extends XmlImportBase implements ImportInterface /** @var DOMElement $key */ foreach ($DomXpath->query($path . '/String/Key') as $key) { - $value = $DomXpath->query($key->getNodePath() . '/../Value')->item(0)->nodeValue; + $value = $DomXpath->query($key->getNodePath() . '/../Value') + ->item(0) + ->nodeValue; $entryData[$key->nodeValue] = $value; } - $groupName = $DomXpath->query($path . '/../Name')->item(0)->nodeValue; + $groupName = $DomXpath->query($path . '/../Name') + ->item(0) + ->nodeValue; $this->items[$groupName][] = $this->mapEntryToAccount($entryData); } } } - /** - * @param array $entry - * - * @return AccountRequest - */ - private function mapEntryToAccount(array $entry) + private function mapEntryToAccount(array $entry): AccountRequest { $accountRequest = new AccountRequest(); $accountRequest->name = isset($entry['Title']) ? Filter::getString($entry['Title']) : ''; $accountRequest->login = isset($entry['UserName']) ? Filter::getString($entry['UserName']) : ''; - $accountRequest->pass = isset($entry['Password']) ? $entry['Password'] : ''; + $accountRequest->pass = $entry['Password'] ?? ''; $accountRequest->url = isset($entry['URL']) ? Filter::getString($entry['URL']) : ''; $accountRequest->notes = isset($entry['Notes']) ? Filter::getString($entry['Notes']) : ''; diff --git a/lib/SP/Services/Import/SyspassImport.php b/lib/SP/Services/Import/SyspassImport.php index 61170221..f3b4fb1e 100644 --- a/lib/SP/Services/Import/SyspassImport.php +++ b/lib/SP/Services/Import/SyspassImport.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Import; @@ -35,6 +35,7 @@ use SP\Core\Crypt\Hash; use SP\Core\Crypt\OldCrypt; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; +use SP\Core\Exceptions\SPException; use SP\DataModel\CategoryData; use SP\DataModel\ClientData; use SP\DataModel\TagData; @@ -52,13 +53,13 @@ final class SyspassImport extends XmlImportBase implements ImportInterface /** * Iniciar la importación desde sysPass. * - * @return ImportInterface * @throws ImportException */ - public function doImport() + public function doImport(): ImportInterface { try { - $this->eventDispatcher->notifyEvent('run.import.syspass', + $this->eventDispatcher->notifyEvent( + 'run.import.syspass', new Event($this, EventMessage::factory() ->addDescription(__u('sysPass XML Import'))) ); @@ -74,7 +75,10 @@ final class SyspassImport extends XmlImportBase implements ImportInterface if ($this->detectEncrypted()) { if ($this->importParams->getImportPwd() === '') { - throw new ImportException(__u('Encryption password not set'), ImportException::INFO); + throw new ImportException( + __u('Encryption password not set'), + SPException::INFO + ); } $this->processEncrypted(); @@ -97,7 +101,10 @@ final class SyspassImport extends XmlImportBase implements ImportInterface } catch (ImportException $e) { throw $e; } catch (Exception $e) { - throw new ImportException($e->getMessage(), ImportException::CRITICAL); + throw new ImportException( + $e->getMessage(), + SPException::CRITICAL + ); } } @@ -112,10 +119,8 @@ final class SyspassImport extends XmlImportBase implements ImportInterface /** * Verificar si existen datos encriptados - * - * @return bool */ - protected function detectEncrypted() + protected function detectEncrypted(): bool { return $this->xmlDOM ->getElementsByTagName('Encrypted')->length > 0; @@ -126,7 +131,7 @@ final class SyspassImport extends XmlImportBase implements ImportInterface * * @throws ImportException */ - protected function processEncrypted() + protected function processEncrypted(): void { $hash = $this->xmlDOM ->getElementsByTagName('Encrypted') @@ -164,8 +169,10 @@ final class SyspassImport extends XmlImportBase implements ImportInterface } catch (CryptoException $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', - new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); continue; } @@ -199,7 +206,7 @@ final class SyspassImport extends XmlImportBase implements ImportInterface /** * Checks XML file's data integrity using the signed hash */ - protected function checkIntegrity() + protected function checkIntegrity(): void { $key = $this->importParams->getImportPwd() ?: sha1($this->configData->getPasswordSalt()); @@ -218,7 +225,7 @@ final class SyspassImport extends XmlImportBase implements ImportInterface * * @throws ImportException */ - protected function processCategories() + protected function processCategories(): void { $this->getNodesData('Categories', 'Category', function (DOMElement $category) { @@ -238,9 +245,11 @@ final class SyspassImport extends XmlImportBase implements ImportInterface } try { - $this->addWorkingItem('category', + $this->addWorkingItem( + 'category', (int)$category->getAttribute('id'), - $this->addCategory($categoryData)); + $this->addCategory($categoryData) + ); $this->eventDispatcher->notifyEvent( 'run.import.syspass.process.category', @@ -250,7 +259,10 @@ final class SyspassImport extends XmlImportBase implements ImportInterface } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); } }); } @@ -260,7 +272,7 @@ final class SyspassImport extends XmlImportBase implements ImportInterface * * @throws ImportException */ - protected function processClients() + protected function processClients(): void { $this->getNodesData('Clients', 'Client', function (DOMElement $client) { @@ -280,9 +292,11 @@ final class SyspassImport extends XmlImportBase implements ImportInterface } try { - $this->addWorkingItem('client', + $this->addWorkingItem( + 'client', (int)$client->getAttribute('id'), - $this->addClient($clientData)); + $this->addClient($clientData) + ); $this->eventDispatcher->notifyEvent( 'run.import.syspass.process.client', @@ -292,8 +306,10 @@ final class SyspassImport extends XmlImportBase implements ImportInterface } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', - new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); } }); } @@ -304,7 +320,7 @@ final class SyspassImport extends XmlImportBase implements ImportInterface * @throws ImportException * @deprecated */ - protected function processCustomers() + protected function processCustomers(): void { $this->getNodesData('Customers', 'Customer', function (DOMElement $client) { @@ -324,9 +340,11 @@ final class SyspassImport extends XmlImportBase implements ImportInterface } try { - $this->addWorkingItem('client', + $this->addWorkingItem( + 'client', (int)$client->getAttribute('id'), - $this->addClient($clientData)); + $this->addClient($clientData) + ); $this->eventDispatcher->notifyEvent( 'run.import.syspass.process.customer', @@ -336,8 +354,10 @@ final class SyspassImport extends XmlImportBase implements ImportInterface } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', - new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); } }); } @@ -347,26 +367,25 @@ final class SyspassImport extends XmlImportBase implements ImportInterface * * @throws ImportException */ - protected function processTags() + protected function processTags(): void { $this->getNodesData('Tags', 'Tag', function (DOMElement $tag) { $tagData = new TagData(); foreach ($tag->childNodes as $node) { - if (isset($node->tagName)) { - switch ($node->tagName) { - case 'name': - $tagData->setName($node->nodeValue); - break; - } + if (isset($node->tagName) + && $node->tagName === 'name') { + $tagData->setName($node->nodeValue); } } try { - $this->addWorkingItem('tag', + $this->addWorkingItem( + 'tag', (int)$tag->getAttribute('id'), - $this->addTag($tagData)); + $this->addTag($tagData) + ); $this->eventDispatcher->notifyEvent( 'run.import.syspass.process.tag', @@ -376,8 +395,10 @@ final class SyspassImport extends XmlImportBase implements ImportInterface } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', - new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); } }, false); } @@ -387,7 +408,7 @@ final class SyspassImport extends XmlImportBase implements ImportInterface * * @throws ImportException */ - protected function processAccounts() + protected function processAccounts(): void { $this->getNodesData('Accounts', 'Account', function (DOMElement $account) { @@ -404,11 +425,19 @@ final class SyspassImport extends XmlImportBase implements ImportInterface $accountRequest->login = $node->nodeValue; break; case 'categoryId'; - $accountRequest->categoryId = $this->getWorkingItem('category', (int)$node->nodeValue); + $accountRequest->categoryId = + $this->getWorkingItem( + 'category', + (int)$node->nodeValue + ); break; case 'clientId'; case 'customerId'; - $accountRequest->clientId = $this->getWorkingItem('client', (int)$node->nodeValue); + $accountRequest->clientId = + $this->getWorkingItem( + 'client', + (int)$node->nodeValue + ); break; case 'url'; $accountRequest->url = $node->nodeValue; @@ -423,7 +452,8 @@ final class SyspassImport extends XmlImportBase implements ImportInterface $accountRequest->notes = $node->nodeValue; break; case 'tags': - $accountRequest->tags = $this->processAccountTags($node->childNodes); + $accountRequest->tags = + $this->processAccountTags($node->childNodes); } } } @@ -439,19 +469,18 @@ final class SyspassImport extends XmlImportBase implements ImportInterface } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); } }); } /** * Procesar las etiquetas de la cuenta - * - * @param DOMNodeList $nodes - * - * @return array */ - protected function processAccountTags(DOMNodeList $nodes) + protected function processAccountTags(DOMNodeList $nodes): array { $tags = []; @@ -459,7 +488,10 @@ final class SyspassImport extends XmlImportBase implements ImportInterface /** @var DOMElement $node */ foreach ($nodes as $node) { if (isset($node->tagName)) { - $tags[] = $this->getWorkingItem('tag', (int)$node->getAttribute('id')); + $tags[] = $this->getWorkingItem( + 'tag', + (int)$node->getAttribute('id') + ); } } } diff --git a/lib/SP/Services/Import/XmlFileImport.php b/lib/SP/Services/Import/XmlFileImport.php index 94bec659..e1c80813 100644 --- a/lib/SP/Services/Import/XmlFileImport.php +++ b/lib/SP/Services/Import/XmlFileImport.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Import; use DOMDocument; +use SP\Core\Exceptions\SPException; use SP\Storage\File\FileException; /** @@ -34,14 +35,8 @@ use SP\Storage\File\FileException; */ final class XmlFileImport { - /** - * @var FileImport - */ - protected $fileImport; - /** - * @var DOMDocument - */ - protected $xmlDOM; + protected FileImport $fileImport; + protected ?DOMDocument $xmlDOM = null; /** * XmlFileImport constructor. @@ -64,7 +59,7 @@ final class XmlFileImport * @throws ImportException * @throws FileException */ - protected function readXMLFile() + protected function readXMLFile(): void { libxml_use_internal_errors(true); @@ -80,7 +75,7 @@ final class XmlFileImport throw new ImportException( __u('Internal error'), - ImportException::ERROR, + SPException::ERROR, __u('Unable to process the XML file') ); } @@ -89,10 +84,9 @@ final class XmlFileImport /** * Detectar la aplicación que generó el XML. * - * @return string * @throws ImportException */ - public function detectXMLFormat() + public function detectXMLFormat(): string { $nodes = $this->xmlDOM->getElementsByTagName('Generator'); @@ -106,15 +100,12 @@ final class XmlFileImport throw new ImportException( __u('XML file not supported'), - ImportException::ERROR, + SPException::ERROR, __u('Unable to guess the application which data was exported from') ); } - /** - * @return DOMDocument - */ - public function getXmlDOM() + public function getXmlDOM(): DOMDocument { return $this->xmlDOM; } @@ -122,9 +113,9 @@ final class XmlFileImport /** * Leer la cabecera del archivo XML y obtener patrones de aplicaciones conocidas. */ - protected function parseFileHeader() + protected function parseFileHeader(): ?string { - if (($handle = @fopen($this->fileImport->getFilePath(), 'r')) !== false) { + if (($handle = @fopen($this->fileImport->getFilePath(), 'rb')) !== false) { // No. de líneas a leer como máximo $maxLines = 5; $count = 0; diff --git a/lib/SP/Services/Import/XmlImport.php b/lib/SP/Services/Import/XmlImport.php index d4402b1f..6b18de01 100644 --- a/lib/SP/Services/Import/XmlImport.php +++ b/lib/SP/Services/Import/XmlImport.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,15 +19,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Import; -use DI\Container; -use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; -use Psr\Container\NotFoundExceptionInterface; use SP\Core\Exceptions\SPException; defined('APP_ROOT') || die(); @@ -40,18 +37,9 @@ defined('APP_ROOT') || die(); */ final class XmlImport implements ImportInterface { - /** - * @var FileImport - */ - protected $xmlFileImport; - /** - * @var ImportParams - */ - protected $importParams; - /** - * @var Container - */ - private $dic; + protected XmlFileImport $xmlFileImport; + protected ImportParams $importParams; + private ContainerInterface $dic; /** * XmlImport constructor. @@ -60,7 +48,11 @@ final class XmlImport implements ImportInterface * @param XmlFileImport $xmlFileImport * @param ImportParams $importParams */ - public function __construct(ContainerInterface $dic, XmlFileImport $xmlFileImport, ImportParams $importParams) + public function __construct( + ContainerInterface $dic, + XmlFileImport $xmlFileImport, + ImportParams $importParams + ) { $this->xmlFileImport = $xmlFileImport; $this->importParams = $importParams; @@ -70,11 +62,10 @@ final class XmlImport implements ImportInterface /** * Iniciar la importación desde XML. * - * @return ImportInterface * @throws ImportException * @throws SPException */ - public function doImport() + public function doImport(): ImportInterface { $format = $this->xmlFileImport->detectXMLFormat(); @@ -82,20 +73,26 @@ final class XmlImport implements ImportInterface } /** - * @param $format + * @param string $format * * @return KeepassImport|SyspassImport - * @throws ImportException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface + * @throws \SP\Services\Import\ImportException */ - protected function selectImportType($format) + protected function selectImportType(string $format) { switch ($format) { case 'syspass': - return new SyspassImport($this->dic, $this->xmlFileImport, $this->importParams); + return new SyspassImport( + $this->dic, + $this->xmlFileImport, + $this->importParams + ); case 'keepass': - return new KeepassImport($this->dic, $this->xmlFileImport, $this->importParams); + return new KeepassImport( + $this->dic, + $this->xmlFileImport, + $this->importParams + ); } throw new ImportException(__u('Format not detected')); @@ -104,7 +101,7 @@ final class XmlImport implements ImportInterface /** * @throws ImportException */ - public function getCounter() + public function getCounter(): int { throw new ImportException(__u('Not implemented')); } diff --git a/lib/SP/Services/Import/XmlImportBase.php b/lib/SP/Services/Import/XmlImportBase.php index fae323c1..1029006c 100644 --- a/lib/SP/Services/Import/XmlImportBase.php +++ b/lib/SP/Services/Import/XmlImportBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,18 +19,20 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Import; -use DI\Container; use DOMDocument; use DOMElement; use Psr\Container\ContainerExceptionInterface; +use Psr\Container\ContainerInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Events\EventDispatcher; +use SP\Core\Exceptions\SPException; use SP\Services\Account\AccountService; use SP\Services\Category\CategoryService; use SP\Services\Client\ClientService; @@ -46,38 +48,23 @@ abstract class XmlImportBase { use ImportTrait; - /** - * @var XmlFileImport - */ - protected $xmlFileImport; - /** - * @var DOMDocument - */ - protected $xmlDOM; - /** - * @var EventDispatcher - */ - protected $eventDispatcher; - /** - * @var ConfigService - */ - protected $configService; - /** - * @var ConfigData - */ - protected $configData; + protected XmlFileImport $xmlFileImport; + protected DOMDocument $xmlDOM; + protected EventDispatcher $eventDispatcher; + protected ConfigService $configService; + protected ConfigDataInterface $configData; /** * ImportBase constructor. * - * @param Container $dic - * @param XmlFileImport $xmlFileImport - * @param ImportParams $importParams - * * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function __construct(Container $dic, XmlFileImport $xmlFileImport, ImportParams $importParams) + public function __construct( + ContainerInterface $dic, + XmlFileImport $xmlFileImport, + ImportParams $importParams + ) { $this->xmlFileImport = $xmlFileImport; $this->importParams = $importParams; @@ -102,13 +89,21 @@ abstract class XmlImportBase * * @throws ImportException */ - protected function getNodesData($nodeName, $childNodeName, $callback, $required = true) + protected function getNodesData( + string $nodeName, + string $childNodeName, + callable $callback, + bool $required = true + ): void { $nodeList = $this->xmlDOM->getElementsByTagName($nodeName); if ($nodeList->length > 0) { if (!is_callable($callback)) { - throw new ImportException(__u('Invalid Method'), ImportException::WARNING); + throw new ImportException( + __u('Invalid Method'), + SPException::WARNING + ); } /** @var DOMElement $nodes */ @@ -121,7 +116,7 @@ abstract class XmlImportBase } elseif ($required === true) { throw new ImportException( __u('Invalid XML format'), - ImportException::WARNING, + SPException::WARNING, sprintf(__('"%s" node doesn\'t exist'), $nodeName) ); } diff --git a/lib/SP/Services/Import/XmlImportTrait.php b/lib/SP/Services/Import/XmlImportTrait.php deleted file mode 100644 index af64ce33..00000000 --- a/lib/SP/Services/Import/XmlImportTrait.php +++ /dev/null @@ -1,91 +0,0 @@ -. - */ - -namespace SP\Services\Import; - -use DOMDocument; -use DOMElement; -use SP\Core\Exceptions\SPException; - -defined('APP_ROOT') || die(); - -/** - * Trait XmlImportTrait para manejar archivos de importación en formato XML - * - * @package SP - */ -trait XmlImportTrait -{ - /** - * @var DOMDocument - */ - protected $xmlDOM; - - /** - * @param DOMDocument $xmlDOM - */ - public function setXmlDOM($xmlDOM) - { - $this->xmlDOM =& $xmlDOM; - } - - /** - * Obtener los datos de los nodos - * - * @param string $nodeName Nombre del nodo principal - * @param string $childNodeName Nombre de los nodos hijos - * @param string $callback Método a ejecutar - * @param bool $required Indica si el nodo es requerido - * - * @throws ImportException - */ - protected function getNodesData($nodeName, $childNodeName, $callback, $required = true) - { - $ParentNode = $this->xmlDOM->getElementsByTagName($nodeName); - - if ($ParentNode->length === 0) { - if ($required === true) { - throw new ImportException( - __u('Invalid XML format'), - SPException::WARNING, - sprintf(__('"%s" node doesn\'t exist'), $nodeName) - ); - } - - return; - } - - if (!is_callable([$this, $callback])) { - throw new ImportException(__u('Invalid Method'), SPException::WARNING); - } - - /** @var DOMElement $nodes */ - foreach ($ParentNode as $nodes) { - /** @var DOMElement $Account */ - foreach ($nodes->getElementsByTagName($childNodeName) as $node) { - $this->$callback($node); - } - } - } -} \ No newline at end of file diff --git a/lib/SP/Services/Install/DatabaseSetupInterface.php b/lib/SP/Services/Install/DatabaseSetupInterface.php index 0a7c0a62..3f692948 100644 --- a/lib/SP/Services/Install/DatabaseSetupInterface.php +++ b/lib/SP/Services/Install/DatabaseSetupInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Install; @@ -53,7 +53,7 @@ interface DatabaseSetupInterface * @param string $user * @param string $pass */ - public function createDBUser($user, $pass); + public function createDBUser(string $user, string $pass); /** * Crear la base de datos diff --git a/lib/SP/Services/Install/InstallData.php b/lib/SP/Services/Install/InstallData.php index c4b7ad47..0db55c66 100644 --- a/lib/SP/Services/Install/InstallData.php +++ b/lib/SP/Services/Install/InstallData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Install; @@ -31,303 +31,168 @@ namespace SP\Services\Install; */ final class InstallData { - /** - * @var string Usuario de la BD - */ - private $dbUser; - /** - * @var string - */ - private $dbAdminUser = ''; - /** - * @var string Clave de la BD - */ - private $dbPass; - /** - * @var string - */ - private $dbAdminPass = ''; - /** - * @var string Nombre de la BD - */ - private $dbName = 'syspass'; - /** - * @var string Host de la BD - */ - private $dbHost = 'localhost'; - /** - * @var string - */ - private $dbSocket; - /** - * @var int - */ - private $dbPort = 0; - /** - * @var string Usuario 'admin' de sysPass - */ - private $adminLogin = ''; - /** - * @var string Clave del usuario 'admin' de sysPass - */ - private $adminPass = ''; - /** - * @var string Clave maestra de sysPass - */ - private $masterPassword = ''; - /** - * @var bool Activar/desactivar Modo hosting - */ - private $hostingMode = false; - /** - * @var string - */ - private $dbAuthHost = ''; - /** - * @var string - */ - private $dbAuthHostDns = ''; - /** - * @var string - */ - private $siteLang = 'en_US'; + private ?string $dbUser = null; + private ?string $dbAdminUser = null; + private ?string $dbPass = null; + private ?string $dbAdminPass = null; + private string $dbName = 'syspass'; + private string $dbHost = 'localhost'; + private ?string $dbSocket = null; + private int $dbPort = 0; + private ?string $adminLogin = null; + private ?string $adminPass = null; + private ?string $masterPassword = null; + private bool $hostingMode = false; + private ?string $dbAuthHost = null; + private ?string $dbAuthHostDns = null; + private string $siteLang = 'en_US'; - /** - * @return string - */ - public function getDbUser() + public function getDbUser(): ?string { return $this->dbUser; } - /** - * @param string $dbUser - */ - public function setDbUser($dbUser) + public function setDbUser(string $dbUser): void { $this->dbUser = $dbUser; } - /** - * @return string - */ - public function getDbPass() + public function getDbPass(): ?string { return $this->dbPass; } - /** - * @param string $dbPass - */ - public function setDbPass($dbPass) + public function setDbPass(string $dbPass): void { $this->dbPass = $dbPass; } - /** - * @return string - */ - public function getDbName() + public function getDbName(): string { return $this->dbName; } - /** - * @param string $dbName - */ - public function setDbName($dbName) + public function setDbName(string $dbName): void { $this->dbName = $dbName; } - /** - * @return string - */ - public function getDbHost() + public function getDbHost(): string { return $this->dbHost; } - /** - * @param string $dbHost - */ - public function setDbHost($dbHost) + public function setDbHost(string $dbHost): void { $this->dbHost = $dbHost; } - /** - * @return string - */ - public function getAdminLogin() + public function getAdminLogin(): ?string { return $this->adminLogin; } - /** - * @param string $adminLogin - */ - public function setAdminLogin($adminLogin) + public function setAdminLogin(string $adminLogin): void { $this->adminLogin = $adminLogin; } - /** - * @return string - */ - public function getAdminPass() + public function getAdminPass(): ?string { return $this->adminPass; } - /** - * @param string $adminPass - */ - public function setAdminPass($adminPass) + public function setAdminPass(string $adminPass): void { $this->adminPass = $adminPass; } - /** - * @return string - */ - public function getMasterPassword() + public function getMasterPassword(): ?string { return $this->masterPassword; } - /** - * @param string $masterPassword - */ - public function setMasterPassword($masterPassword) + public function setMasterPassword(string $masterPassword): void { $this->masterPassword = $masterPassword; } - /** - * @return boolean - */ - public function isHostingMode() + public function isHostingMode(): bool { return $this->hostingMode; } - /** - * @param boolean $hostingMode - */ - public function setHostingMode($hostingMode) + public function setHostingMode(bool $hostingMode): void { $this->hostingMode = $hostingMode; } - /** - * @return string - */ - public function getDbAuthHost() + public function getDbAuthHost(): ?string { return $this->dbAuthHost; } - /** - * @param string $dbAuthHost - */ - public function setDbAuthHost($dbAuthHost) + public function setDbAuthHost(string $dbAuthHost): void { $this->dbAuthHost = $dbAuthHost; } - /** - * @return int - */ - public function getDbPort() + public function getDbPort(): int { return $this->dbPort; } - /** - * @param int $dbPort - */ - public function setDbPort($dbPort) + public function setDbPort(int $dbPort): void { $this->dbPort = $dbPort; } - /** - * @return string - */ - public function getDbAdminUser() + public function getDbAdminUser(): ?string { return $this->dbAdminUser; } - /** - * @param string $dbAdminUser - */ - public function setDbAdminUser($dbAdminUser) + public function setDbAdminUser(string $dbAdminUser): void { $this->dbAdminUser = $dbAdminUser; } - /** - * @return string - */ - public function getDbAdminPass() + public function getDbAdminPass(): ?string { return $this->dbAdminPass; } - /** - * @param string $dbAdminPass - */ - public function setDbAdminPass($dbAdminPass) + public function setDbAdminPass(string $dbAdminPass): void { $this->dbAdminPass = $dbAdminPass; } - /** - * @return string - */ - public function getSiteLang() + public function getSiteLang(): string { return $this->siteLang; } - /** - * @param string $siteLang - */ - public function setSiteLang($siteLang) + public function setSiteLang(string $siteLang): void { $this->siteLang = $siteLang; } - /** - * @return string - */ - public function getDbAuthHostDns() + public function getDbAuthHostDns(): ?string { return $this->dbAuthHostDns; } - /** - * @param string $dbAuthHostDns - */ - public function setDbAuthHostDns($dbAuthHostDns) + public function setDbAuthHostDns(string $dbAuthHostDns): void { $this->dbAuthHostDns = $dbAuthHostDns; } - /** - * @return string - */ - public function getDbSocket() + public function getDbSocket(): ?string { return $this->dbSocket; } - /** - * @param string $dbSocket - */ - public function setDbSocket($dbSocket) + public function setDbSocket(string $dbSocket): void { $this->dbSocket = $dbSocket; } diff --git a/lib/SP/Services/Install/Installer.php b/lib/SP/Services/Install/Installer.php index e3039717..fbc6c0e4 100644 --- a/lib/SP/Services/Install/Installer.php +++ b/lib/SP/Services/Install/Installer.php @@ -5,7 +5,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -28,13 +28,14 @@ namespace SP\Services\Install; use Exception; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Crypt\Hash; use SP\Core\Events\EventDispatcher; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\InvalidArgumentException; use SP\Core\Exceptions\QueryException; use SP\Core\Exceptions\SPException; +use SP\DataModel\ConfigData; use SP\DataModel\ProfileData; use SP\DataModel\UserData; use SP\DataModel\UserGroupData; @@ -59,31 +60,16 @@ final class Installer extends Service /** * sysPass' version and build number */ - const VERSION = [3, 2, 2]; - const VERSION_TEXT = '3.2'; - const BUILD = 21031301; + public const VERSION = [3, 2, 2]; + public const VERSION_TEXT = '3.2'; + public const BUILD = 21031301; + + private ?DatabaseSetupInterface $dbs = null; + private ?Request $request = null; + private ?InstallData $installData = null; + private ?ConfigDataInterface $configData = null; /** - * @var DatabaseSetupInterface - */ - private $dbs; - /** - * @var Request - */ - private $request; - /** - * @var InstallData - */ - private $installData; - /** - * @var ConfigData - */ - private $configData; - - /** - * @param InstallData $installData - * - * @return static * @throws InvalidArgumentException * @throws SPException * @throws ContainerExceptionInterface @@ -102,7 +88,7 @@ final class Installer extends Service /** * @throws InvalidArgumentException */ - private function checkData() + private function checkData(): void { if (empty($this->installData->getAdminLogin())) { throw new InvalidArgumentException( @@ -139,7 +125,8 @@ final class Installer extends Service __u('An user with database administrative rights')); } - if (empty($this->installData->getDbAdminPass()) && APP_MODULE !== 'tests') { + if (APP_MODULE !== 'tests' + && empty($this->installData->getDbAdminPass())) { throw new InvalidArgumentException( __u('Please, enter the database password'), SPException::ERROR, @@ -177,7 +164,7 @@ final class Installer extends Service * @throws ConstraintException * @throws QueryException */ - private function install() + private function install(): void { $this->setupDbHost(); $this->setupConfig(); @@ -190,7 +177,7 @@ final class Installer extends Service $version = VersionUtil::getVersionStringNormalized(); $this->dic->get(ConfigService::class) - ->create(new \SP\DataModel\ConfigData('version', $version)); + ->create(new ConfigData('version', $version)); $this->configData->setInstalled(true); @@ -200,7 +187,7 @@ final class Installer extends Service /** * Setup database connection data */ - private function setupDbHost() + private function setupDbHost(): void { if (preg_match( '/^(?:(?P.*):(?P\d{1,5}))|^(?:unix:(?P.*))/', @@ -243,7 +230,7 @@ final class Installer extends Service /** * Setup sysPass config data */ - private function setupConfig() + private function setupConfig(): void { // Sets version and remove upgrade key $this->configData->setConfigVersion(VersionUtil::getVersionStringNormalized()); @@ -263,16 +250,12 @@ final class Installer extends Service } /** - * @param string $type - * * @throws SPException */ - private function setupDb($type = 'mysql') + private function setupDb(string $type = 'mysql'): void { - switch ($type) { - case 'mysql': - $this->dbs = new MySQL($this->installData, $this->configData); - break; + if ($type === 'mysql') { + $this->dbs = new MySQL($this->installData, $this->configData); } // Si no es modo hosting se crea un hash para la clave y un usuario con prefijo "sp_" para la DB @@ -294,9 +277,13 @@ final class Installer extends Service * * Updates the database storage interface in the dependency container */ - private function updateConnectionData() + private function updateConnectionData(): void { - $this->dic->set(DBStorageInterface::class, $this->dbs->createDbHandlerFromInstaller()); + // Ugly things... + $this->dic->set( + DBStorageInterface::class, + $this->dbs->createDbHandlerFromInstaller() + ); $this->dic->set( Database::class, new Database( @@ -311,7 +298,7 @@ final class Installer extends Service * * @throws SPException */ - private function saveMasterPassword() + private function saveMasterPassword(): void { try { // This service needs to be called after a successful database setup, since @@ -319,8 +306,18 @@ final class Installer extends Service // an incomplete database setup $configService = $this->dic->get(ConfigService::class); - $configService->create(new \SP\DataModel\ConfigData('masterPwd', Hash::hashKey($this->installData->getMasterPassword()))); - $configService->create(new \SP\DataModel\ConfigData('lastupdatempass', time())); + $configService->create( + new ConfigData( + 'masterPwd', + Hash::hashKey($this->installData->getMasterPassword()) + ) + ); + $configService->create( + new ConfigData( + 'lastupdatempass', + time() + ) + ); } catch (Exception $e) { processException($e); @@ -344,7 +341,7 @@ final class Installer extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - private function createAdminAccount() + private function createAdminAccount(): void { try { $userGroupData = new UserGroupData(); @@ -367,7 +364,11 @@ final class Installer extends Service $userData->setName('sysPass Admin'); $userData->setIsAdminApp(1); - $id = $userService->createWithMasterPass($userData, $this->installData->getAdminPass(), $this->installData->getMasterPassword()); + $id = $userService->createWithMasterPass( + $userData, + $this->installData->getAdminPass(), + $this->installData->getMasterPassword() + ); if ($id === 0) { throw new SPException(__u('Error while creating \'admin\' user')); @@ -387,10 +388,7 @@ final class Installer extends Service } } - /** - * initialize - */ - protected function initialize() + protected function initialize(): void { $this->configData = $this->config->getConfigData(); $this->request = $this->dic->get(Request::class); diff --git a/lib/SP/Services/Install/MySQL.php b/lib/SP/Services/Install/MySQL.php index 1a8314d8..d4220d74 100644 --- a/lib/SP/Services/Install/MySQL.php +++ b/lib/SP/Services/Install/MySQL.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,13 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Install; use PDOException; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Exceptions\SPException; use SP\Storage\Database\DatabaseConnectionData; use SP\Storage\Database\DatabaseUtil; @@ -43,28 +43,19 @@ use SP\Util\PasswordUtil; */ final class MySQL implements DatabaseSetupInterface { - /** - * @var InstallData - */ - protected $installData; - /** - * @var MySQLHandler - */ - protected $mysqlHandler; - /** - * @var ConfigData - */ - protected $configData; + protected InstallData $installData; + protected ConfigDataInterface $configData; + protected ?MySQLHandler $mysqlHandler = null; /** * MySQL constructor. * - * @param InstallData $installData - * @param ConfigData $configData - * * @throws SPException */ - public function __construct(InstallData $installData, ConfigData $configData) + public function __construct( + InstallData $installData, + ConfigDataInterface $configData + ) { $this->installData = $installData; $this->configData = $configData; @@ -80,7 +71,7 @@ final class MySQL implements DatabaseSetupInterface * * @throws SPException */ - public function connectDatabase() + public function connectDatabase(): void { try { $dbc = (new DatabaseConnectionData()) @@ -110,7 +101,7 @@ final class MySQL implements DatabaseSetupInterface */ public function setupDbUser() { - $user = substr(uniqid('sp_'), 0, 16); + $user = substr(uniqid('sp_', true), 0, 16); $pass = PasswordUtil::randomPassword(); try { @@ -149,12 +140,9 @@ final class MySQL implements DatabaseSetupInterface * Crear el usuario para conectar con la base de datos. * Esta función crea el usuario para conectar con la base de datos. * - * @param string $user - * @param string $pass - * * @throws SPException */ - public function createDBUser($user, $pass) + public function createDBUser(string $user, string $pass): void { if ($this->installData->isHostingMode()) { return; @@ -204,7 +192,7 @@ final class MySQL implements DatabaseSetupInterface * * @throws SPException */ - public function createDatabase() + public function createDatabase(): void { if (!$this->installData->isHostingMode()) { @@ -272,7 +260,10 @@ final class MySQL implements DatabaseSetupInterface try { // Commprobar si existe al seleccionarla $this->mysqlHandler->getConnectionSimple() - ->exec(sprintf('USE `%s`', $this->installData->getDbName())); + ->exec(sprintf( + 'USE `%s`', + $this->installData->getDbName() + )); } catch (PDOException $e) { throw new SPException( __u('The database does not exist'), @@ -286,10 +277,9 @@ final class MySQL implements DatabaseSetupInterface } /** - * @return bool * @throws SPException */ - public function checkDatabaseExist() + public function checkDatabaseExist(): bool { $sth = $this->mysqlHandler->getConnectionSimple() ->prepare('SELECT COUNT(*) FROM information_schema.schemata WHERE `schema_name` = ? LIMIT 1'); @@ -301,13 +291,17 @@ final class MySQL implements DatabaseSetupInterface /** * @throws SPException */ - public function rollback() + public function rollback(): void { $dbc = $this->mysqlHandler->getConnectionSimple(); if ($this->installData->isHostingMode()) { - foreach (DatabaseUtil::$tables as $table) { - $dbc->exec('DROP TABLE IF EXISTS `' . $this->installData->getDbName() . '`.`' . $table . '`'); + foreach (DatabaseUtil::TABLES as $table) { + $dbc->exec(sprintf( + 'DROP TABLE IF EXISTS `%s`.`%s`', + $this->installData->getDbName(), + $table + )); } } else { $dbc->exec(sprintf( @@ -335,7 +329,7 @@ final class MySQL implements DatabaseSetupInterface /** * @throws SPException */ - public function createDBStructure() + public function createDBStructure(): void { try { $dbc = $this->mysqlHandler->getConnectionSimple(); @@ -353,7 +347,13 @@ final class MySQL implements DatabaseSetupInterface } try { - $parser = new MySQLFileParser(new FileHandler(SQL_PATH . DIRECTORY_SEPARATOR . 'dbstructure.sql')); + $parser = new MySQLFileParser( + new FileHandler( + SQL_PATH . + DIRECTORY_SEPARATOR . + 'dbstructure.sql' + ) + ); foreach ($parser->parse() as $query) { $dbc->exec($query); @@ -390,7 +390,7 @@ final class MySQL implements DatabaseSetupInterface * * @throws SPException */ - public function checkConnection() + public function checkConnection(): void { $databaseUtil = new DatabaseUtil($this->mysqlHandler); @@ -405,17 +405,11 @@ final class MySQL implements DatabaseSetupInterface } } - /** - * @return DBStorageInterface - */ public function getDbHandler(): DBStorageInterface { return $this->mysqlHandler; } - /** - * @return DBStorageInterface - */ public function createDbHandlerFromInstaller(): DBStorageInterface { return new MySQLHandler(DatabaseConnectionData::getFromConfig($this->configData)); diff --git a/lib/SP/Services/ItemPreset/ItemPresetInterface.php b/lib/SP/Services/ItemPreset/ItemPresetInterface.php index 92316240..fe49bbc1 100644 --- a/lib/SP/Services/ItemPreset/ItemPresetInterface.php +++ b/lib/SP/Services/ItemPreset/ItemPresetInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\ItemPreset; @@ -31,9 +31,8 @@ namespace SP\Services\ItemPreset; */ interface ItemPresetInterface { - const ITEM_TYPE_ACCOUNT_PERMISSION = 'account.permission'; - const ITEM_TYPE_ACCOUNT_TAG = 'account.tag'; - const ITEM_TYPE_ACCOUNT_PASSWORD = 'account.password'; - const ITEM_TYPE_ACCOUNT_PRIVATE = 'account.private'; - const ITEM_TYPE_SESSION_TIMEOUT = 'session.timeout'; + public const ITEM_TYPE_ACCOUNT_PERMISSION = 'account.permission'; + public const ITEM_TYPE_ACCOUNT_PASSWORD = 'account.password'; + public const ITEM_TYPE_ACCOUNT_PRIVATE = 'account.private'; + public const ITEM_TYPE_SESSION_TIMEOUT = 'session.timeout'; } \ No newline at end of file diff --git a/lib/SP/Services/ItemPreset/ItemPresetRequest.php b/lib/SP/Services/ItemPreset/ItemPresetRequest.php index 02755365..03689f63 100644 --- a/lib/SP/Services/ItemPreset/ItemPresetRequest.php +++ b/lib/SP/Services/ItemPreset/ItemPresetRequest.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,14 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\ItemPreset; use SP\DataModel\ItemPresetData; - /** * Class ItemPresetRequest * @@ -34,20 +33,11 @@ use SP\DataModel\ItemPresetData; */ final class ItemPresetRequest { - /** - * @var ItemPresetData - */ - private $itemPresetData; - /** - * @var mixed - */ + private ItemPresetData $itemPresetData; private $data; /** * ItemPresetRequest constructor. - * - * @param ItemPresetData $itemPresetData - * @param mixed $data */ public function __construct(ItemPresetData $itemPresetData, $data) { @@ -55,9 +45,6 @@ final class ItemPresetRequest $this->data = $data; } - /** - * @return ItemPresetData - */ public function getItemPresetData(): ItemPresetData { return $this->itemPresetData; @@ -71,10 +58,7 @@ final class ItemPresetRequest return $this->data; } - /** - * @return ItemPresetData - */ - public function prepareToPersist() + public function prepareToPersist(): ItemPresetData { $this->itemPresetData->setData(serialize($this->data)); diff --git a/lib/SP/Services/ItemPreset/ItemPresetService.php b/lib/SP/Services/ItemPreset/ItemPresetService.php index 0fc973a5..64686cae 100644 --- a/lib/SP/Services/ItemPreset/ItemPresetService.php +++ b/lib/SP/Services/ItemPreset/ItemPresetService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,13 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\ItemPreset; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; +use SP\Core\Exceptions\SPException; use SP\DataModel\ItemPresetData; use SP\DataModel\ItemSearchData; use SP\Repositories\ItemPreset\ItemPresetRepository; @@ -41,46 +42,36 @@ use SP\Storage\Database\QueryResult; */ final class ItemPresetService extends Service { - /** - * @var ItemPresetRepository - */ - private $itemPresetRepository; + private ?ItemPresetRepository $itemPresetRepository = null; /** - * @param ItemPresetRequest $itemPresetRequest - * - * @return int * @throws ConstraintException * @throws QueryException */ - public function create(ItemPresetRequest $itemPresetRequest) + public function create(ItemPresetRequest $itemPresetRequest): int { - return $this->itemPresetRepository->create($itemPresetRequest->prepareToPersist()); + return $this->itemPresetRepository + ->create($itemPresetRequest->prepareToPersist()); } /** - * @param ItemPresetRequest $itemPresetRequest - * - * @return int * @throws ConstraintException * @throws QueryException */ - public function update(ItemPresetRequest $itemPresetRequest) + public function update(ItemPresetRequest $itemPresetRequest): int { - return $this->itemPresetRepository->update($itemPresetRequest->prepareToPersist()); + return $this->itemPresetRepository + ->update($itemPresetRequest->prepareToPersist()); } /** * Deletes an item * - * @param $id - * - * @return ItemPresetService - * @throws NoSuchItemException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function delete($id) + public function delete(int $id): ItemPresetService { if ($this->itemPresetRepository->delete($id) === 0) { throw new NoSuchItemException(__u('Value not found')); @@ -92,14 +83,11 @@ final class ItemPresetService extends Service /** * Returns the item for given id * - * @param int $id - * - * @return ItemPresetData * @throws NoSuchItemException * @throws ConstraintException * @throws QueryException */ - public function getById($id) + public function getById(int $id): ItemPresetData { $result = $this->itemPresetRepository->getById($id); @@ -117,7 +105,7 @@ final class ItemPresetService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): array { return $this->itemPresetRepository->getAll()->getDataAsArray(); } @@ -125,42 +113,40 @@ final class ItemPresetService extends Service /** * Searches for items by a given filter * - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->itemPresetRepository->search($itemSearchData); } /** - * @param string $type - * - * @return ItemPresetData * @throws ConstraintException * @throws QueryException */ - public function getForCurrentUser(string $type) + public function getForCurrentUser(string $type): ?ItemPresetData { $userData = $this->context->getUserData(); - return $this->getForUser($type, $userData->getId(), $userData->getUserGroupId(), $userData->getUserProfileId()); + return $this->getForUser( + $type, + $userData->getId(), + $userData->getUserGroupId(), + $userData->getUserProfileId() + ); } /** - * @param string $type - * @param int $userId - * @param int $userGroupId - * @param int $userProfileId - * - * @return ItemPresetData * @throws ConstraintException * @throws QueryException */ - public function getForUser(string $type, int $userId, int $userGroupId, int $userProfileId) + public function getForUser( + string $type, + int $userId, + int $userGroupId, + int $userProfileId + ): ?ItemPresetData { $result = $this->itemPresetRepository->getByFilter( $type, @@ -177,23 +163,27 @@ final class ItemPresetService extends Service } /** - * @param array $ids + * @param int[] $ids * - * @return int - * @throws ServiceException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (($count = $this->itemPresetRepository->deleteByIdBatch($ids)) !== count($ids)) { - throw new ServiceException(__u('Error while deleting the values'), ServiceException::WARNING); + $count = $this->itemPresetRepository->deleteByIdBatch($ids); + + if ($count !== count($ids)) { + throw new ServiceException( + __u('Error while deleting the values'), + SPException::WARNING + ); } return $count; } - protected function initialize() + protected function initialize(): void { $this->itemPresetRepository = $this->dic->get(ItemPresetRepository::class); } diff --git a/lib/SP/Services/Ldap/LdapCheckService.php b/lib/SP/Services/Ldap/LdapCheckService.php index e8eb9772..ff8439e3 100644 --- a/lib/SP/Services/Ldap/LdapCheckService.php +++ b/lib/SP/Services/Ldap/LdapCheckService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,13 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Ldap; use SP\Providers\Auth\Ldap\Ldap; use SP\Providers\Auth\Ldap\LdapException; +use SP\Providers\Auth\Ldap\LdapInterface; use SP\Providers\Auth\Ldap\LdapParams; use SP\Services\Service; @@ -36,28 +37,26 @@ use SP\Services\Service; */ final class LdapCheckService extends Service { - /** - * @var Ldap - */ - protected $ldap; + protected ?LdapInterface $ldap = null; /** * @param LdapParams $ldapParams * * @throws LdapException */ - public function checkConnection(LdapParams $ldapParams) + public function checkConnection(LdapParams $ldapParams): void { - $this->ldap = Ldap::factory($ldapParams, $this->eventDispatcher, true); + $this->ldap = Ldap::factory( + $ldapParams, + $this->eventDispatcher, + true + ); } /** - * @param bool $includeGroups - * - * @return array - * @throws LdapException + * @throws \SP\Providers\Auth\Ldap\LdapException */ - public function getObjects($includeGroups = true) + public function getObjects(bool $includeGroups = true): array { $ldapActions = $this->ldap->getLdapActions(); @@ -94,9 +93,12 @@ final class LdapCheckService extends Service ]; } - array_walk($data['results'], function ($value) use (&$data) { - $data['count'] += count($value['items']); - }); + array_walk( + $data['results'], + static function ($value) use (&$data) { + $data['count'] += count($value['items']); + } + ); return $data; } @@ -104,19 +106,22 @@ final class LdapCheckService extends Service /** * Obtener los datos de una búsqueda de LDAP de un atributo * - * @param array $data - * @param array $attributes + * @param array $data + * @param string[] $attributes * * @return array */ - public function ldapResultsMapper($data, $attributes = ['dn']) + public function ldapResultsMapper( + array $data, + array $attributes = ['dn'] + ): array { $out = []; foreach ($data as $result) { if (is_array($result)) { foreach ($result as $ldapAttribute => $value) { - if (in_array(strtolower($ldapAttribute), $attributes)) { + if (in_array(strtolower($ldapAttribute), $attributes, true)) { if (is_array($value)) { unset($value['count']); @@ -133,12 +138,9 @@ final class LdapCheckService extends Service } /** - * @param $filter - * - * @return array - * @throws LdapException + * @throws \SP\Providers\Auth\Ldap\LdapException */ - public function getObjectsByFilter($filter) + public function getObjectsByFilter(string $filter): array { $objects = $this->ldapResultsMapper( $this->ldap->getLdapActions()->getObjects($filter, ['dn']) diff --git a/lib/SP/Services/Ldap/LdapImportParams.php b/lib/SP/Services/Ldap/LdapImportParams.php index d7f5ef68..67bf19ad 100644 --- a/lib/SP/Services/Ldap/LdapImportParams.php +++ b/lib/SP/Services/Ldap/LdapImportParams.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Ldap; @@ -31,28 +31,10 @@ namespace SP\Services\Ldap; */ final class LdapImportParams { - /** - * @var int - */ - public $defaultUserGroup; - /** - * @var int - */ - public $defaultUserProfile; - /** - * @var string - */ - public $loginAttribute; - /** - * @var string - */ - public $userNameAttribute; - /** - * @var string - */ - public $userGroupNameAttribute; - /** - * @var string - */ - public $filter; + public ?int $defaultUserGroup = null; + public ?int $defaultUserProfile = null; + public ?string $loginAttribute = null; + public ?string $userNameAttribute = null; + public ?string $userGroupNameAttribute = null; + public ?string $filter = null; } \ No newline at end of file diff --git a/lib/SP/Services/Ldap/LdapImportService.php b/lib/SP/Services/Ldap/LdapImportService.php index 2b68fdda..eba1ac6a 100644 --- a/lib/SP/Services/Ldap/LdapImportService.php +++ b/lib/SP/Services/Ldap/LdapImportService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Ldap; @@ -44,39 +44,21 @@ use SP\Services\UserGroup\UserGroupService; */ final class LdapImportService extends Service { - /** - * @var int - */ - protected $totalObjects = 0; - /** - * @var int - */ - protected $syncedObjects = 0; - /** - * @var int - */ - protected $errorObjects = 0; + protected int $totalObjects = 0; + protected int $syncedObjects = 0; + protected int $errorObjects = 0; - /** - * @return int - */ - public function getTotalObjects() + public function getTotalObjects(): int { return $this->totalObjects; } - /** - * @return int - */ - public function getSyncedObjects() + public function getSyncedObjects(): int { return $this->syncedObjects; } - /** - * @return int - */ - public function getErrorObjects() + public function getErrorObjects(): int { return $this->errorObjects; } @@ -84,12 +66,12 @@ final class LdapImportService extends Service /** * Sincronizar usuarios de LDAP * - * @param LdapParams $ldapParams - * @param LdapImportParams $ldapImportParams - * * @throws LdapException */ - public function importGroups(LdapParams $ldapParams, LdapImportParams $ldapImportParams) + public function importGroups( + LdapParams $ldapParams, + LdapImportParams $ldapImportParams + ): void { $ldap = $this->getLdap($ldapParams); @@ -103,7 +85,8 @@ final class LdapImportService extends Service $numObjects = (int)$objects['count']; - $this->eventDispatcher->notifyEvent('import.ldap.groups', + $this->eventDispatcher->notifyEvent( + 'import.ldap.groups', new Event($this, EventMessage::factory() ->addDetail(__u('Objects found'), $numObjects)) ); @@ -121,10 +104,8 @@ final class LdapImportService extends Service $value = $values[0]; - switch (strtolower($attribute)) { - case $ldapImportParams->userGroupNameAttribute: - $userGroupData->setName($value); - break; + if (strtolower($attribute) === $ldapImportParams->userGroupNameAttribute) { + $userGroupData->setName($value); } } @@ -134,7 +115,8 @@ final class LdapImportService extends Service $userGroupService->create($userGroupData); - $this->eventDispatcher->notifyEvent('import.ldap.progress.groups', + $this->eventDispatcher->notifyEvent( + 'import.ldap.progress.groups', new Event($this, EventMessage::factory() ->addDetail(__u('Group'), sprintf('%s', $userGroupData->getName()))) ); @@ -143,7 +125,10 @@ final class LdapImportService extends Service } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); $this->errorObjects++; } @@ -154,23 +139,24 @@ final class LdapImportService extends Service } /** - * @param LdapParams $ldapParams - * - * @return LdapInterface - * @throws LdapException + * @throws \SP\Providers\Auth\Ldap\LdapException */ - protected function getLdap(LdapParams $ldapParams) + protected function getLdap(LdapParams $ldapParams): LdapInterface { - return Ldap::factory($ldapParams, $this->eventDispatcher, $this->config->getConfigData()->isDebug()); + return Ldap::factory( + $ldapParams, + $this->eventDispatcher, + $this->config->getConfigData()->isDebug() + ); } /** - * @param LdapParams $ldapParams - * @param LdapImportParams $ldapImportParams - * * @throws LdapException */ - public function importUsers(LdapParams $ldapParams, LdapImportParams $ldapImportParams) + public function importUsers( + LdapParams $ldapParams, + LdapImportParams $ldapImportParams + ): void { $ldap = $this->getLdap($ldapParams); @@ -184,7 +170,8 @@ final class LdapImportService extends Service $numObjects = (int)$objects['count']; - $this->eventDispatcher->notifyEvent('import.ldap.users', + $this->eventDispatcher->notifyEvent( + 'import.ldap.users', new Event($this, EventMessage::factory() ->addDetail(__u('Objects found'), $numObjects)) ); @@ -226,7 +213,8 @@ final class LdapImportService extends Service $userService->create($userData); - $this->eventDispatcher->notifyEvent('import.ldap.progress.users', + $this->eventDispatcher->notifyEvent( + 'import.ldap.progress.users', new Event($this, EventMessage::factory() ->addDetail(__u('User'), sprintf('%s (%s)', $userData->getName(), $userData->getLogin()))) ); @@ -235,7 +223,10 @@ final class LdapImportService extends Service } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); $this->errorObjects++; } diff --git a/lib/SP/Services/Mail/MailService.php b/lib/SP/Services/Mail/MailService.php index 95612bf1..11ab76b0 100644 --- a/lib/SP/Services/Mail/MailService.php +++ b/lib/SP/Services/Mail/MailService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Mail; @@ -30,6 +30,7 @@ use SP\Bootstrap; use SP\Core\AppInfoInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; +use SP\Core\Exceptions\SPException; use SP\Core\Messages\MailMessage; use SP\Html\Html; use SP\Providers\Mail\MailParams; @@ -45,23 +46,18 @@ use SP\Services\ServiceException; */ final class MailService extends Service { - /** - * @var PHPMailer - */ - protected $mailer; + protected ?PHPMailer $mailer = null; /** * Checks mail params by sending a test email * - * @param MailParams $mailParams - * @param string $to - * * @throws ServiceException */ - public function check(MailParams $mailParams, $to) + public function check(MailParams $mailParams, string $to): void { try { - $mailer = $this->dic->get(MailProvider::class)->getMailer($mailParams); + $mailer = $this->dic->get(MailProvider::class) + ->getMailer($mailParams); $mailMessage = new MailMessage(); $mailMessage->setTitle(__u('Mail test')); @@ -76,11 +72,14 @@ final class MailService extends Service } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); throw new ServiceException( __u('Error while sending the email'), - ServiceException::ERROR, + SPException::ERROR, $e->getMessage(), $e->getCode(), $e); @@ -89,15 +88,17 @@ final class MailService extends Service /** * Devolver el pie del email con la firma de la aplicación - * - * @return array */ - protected function getEmailFooter() + protected function getEmailFooter(): array { return [ '', '--', - sprintf('%s - %s', AppInfoInterface::APP_NAME, AppInfoInterface::APP_DESC), + sprintf( + '%s - %s', + AppInfoInterface::APP_NAME, + AppInfoInterface::APP_DESC + ), Html::anchorText(Bootstrap::$WEBURI) ]; } @@ -107,9 +108,13 @@ final class MailService extends Service * * @return string */ - protected function getSubjectForAction($action) + protected function getSubjectForAction($action): string { - return sprintf('%s - %s', AppInfoInterface::APP_NAME, $action); + return sprintf( + '%s - %s', + AppInfoInterface::APP_NAME, + $action + ); } /** @@ -117,9 +122,10 @@ final class MailService extends Service * @param array|string $to * @param MailMessage $mailMessage * - * @throws ServiceException + * @throws \PHPMailer\PHPMailer\Exception + * @throws \SP\Services\ServiceException */ - public function send($subject, $to, MailMessage $mailMessage) + public function send(string $subject, $to, MailMessage $mailMessage): void { $this->mailer->isHTML(); @@ -132,7 +138,8 @@ final class MailService extends Service } $this->mailer->Subject = $this->getSubjectForAction($subject); - $this->mailer->Body = $mailMessage->setFooter($this->getEmailFooter())->composeHtml(); + $this->mailer->Body = $mailMessage->setFooter($this->getEmailFooter()) + ->composeHtml(); $this->sendMail(); } @@ -140,7 +147,7 @@ final class MailService extends Service /** * @throws ServiceException */ - private function sendMail() + private function sendMail(): void { try { $this->mailer->send(); @@ -148,27 +155,40 @@ final class MailService extends Service $this->eventDispatcher->notifyEvent('send.mail', new Event($this, EventMessage::factory() ->addDescription(__u('Email sent')) - ->addDetail(__u('Recipient'), implode(',', array_map(function ($value) { - return $value[0]; - }, $this->mailer->getToAddresses())))) + ->addDetail( + __u('Recipient'), + implode( + ',', + array_map( + static function ($value) { + return $value[0]; + }, + $this->mailer->getToAddresses() + ) + ) + )) ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); throw new ServiceException(__u('Error while sending the email')); } } /** - * @param string $subject - * @param array $to - * @param MailMessage $mailMessage - * - * @throws ServiceException + * @throws \PHPMailer\PHPMailer\Exception + * @throws \SP\Services\ServiceException */ - public function sendBatch($subject, array $to, MailMessage $mailMessage) + public function sendBatch( + string $subject, + array $to, + MailMessage $mailMessage + ): void { $this->mailer->isHTML(); @@ -177,7 +197,8 @@ final class MailService extends Service } $this->mailer->Subject = $this->getSubjectForAction($subject); - $this->mailer->Body = $mailMessage->setFooter($this->getEmailFooter())->composeHtml(); + $this->mailer->Body = $mailMessage->setFooter($this->getEmailFooter()) + ->composeHtml(); $this->sendMail(); } @@ -185,7 +206,7 @@ final class MailService extends Service /** * @throws MailProviderException */ - protected function initialize() + protected function initialize(): void { if ($this->config->getConfigData()->isMailEnabled()) { $this->mailer = $this->dic->get(MailProvider::class) @@ -193,10 +214,7 @@ final class MailService extends Service } } - /** - * @return MailParams - */ - public function getParamsFromConfig() + public function getParamsFromConfig(): MailParams { $configData = $this->config->getConfigData(); diff --git a/lib/SP/Services/Notification/NotificationService.php b/lib/SP/Services/Notification/NotificationService.php index 65808684..da194d74 100644 --- a/lib/SP/Services/Notification/NotificationService.php +++ b/lib/SP/Services/Notification/NotificationService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Notification; @@ -28,6 +28,7 @@ use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; +use SP\Core\Exceptions\SPException; use SP\DataModel\ItemSearchData; use SP\DataModel\NotificationData; use SP\Repositories\NoSuchItemException; @@ -43,21 +44,15 @@ use SP\Storage\Database\QueryResult; */ final class NotificationService extends Service { - /** - * @var NotificationRepository - */ - protected $notificationRepository; + protected ?NotificationRepository $notificationRepository = null; /** * Creates an item * - * @param NotificationData $itemData - * - * @return int * @throws ConstraintException * @throws QueryException */ - public function create(NotificationData $itemData) + public function create(NotificationData $itemData): int { return $this->notificationRepository->create($itemData)->getLastId(); } @@ -65,13 +60,10 @@ final class NotificationService extends Service /** * Updates an item * - * @param NotificationData $itemData - * - * @return int * @throws ConstraintException * @throws QueryException */ - public function update(NotificationData $itemData) + public function update(NotificationData $itemData): int { return $this->notificationRepository->update($itemData); } @@ -79,31 +71,33 @@ final class NotificationService extends Service /** * Devolver los elementos con los ids especificados * - * @param array $ids + * @param int[] $ids * * @return NotificationData[] * @throws ConstraintException * @throws QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): array { - return $this->notificationRepository->getByIdBatch($ids)->getDataAsArray(); + return $this->notificationRepository + ->getByIdBatch($ids) + ->getDataAsArray(); } /** * Deletes an item preserving the sticky ones * - * @param $id - * - * @return NotificationService - * @throws NoSuchItemException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function delete($id) + public function delete(int $id): NotificationService { if ($this->notificationRepository->delete($id) === 0) { - throw new NoSuchItemException(__u('Notification not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Notification not found'), + SPException::INFO + ); } return $this; @@ -112,17 +106,17 @@ final class NotificationService extends Service /** * Deletes an item * - * @param $id - * - * @return NotificationService - * @throws ConstraintException - * @throws QueryException - * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function deleteAdmin($id) + public function deleteAdmin(int $id): NotificationService { if ($this->notificationRepository->deleteAdmin($id) === 0) { - throw new NoSuchItemException(__u('Notification not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Notification not found'), + SPException::INFO + ); } return $this; @@ -131,17 +125,21 @@ final class NotificationService extends Service /** * Deletes an item * - * @param array $ids + * @param int[] $ids * - * @return int * @throws ConstraintException * @throws QueryException * @throws ServiceException */ - public function deleteAdminBatch(array $ids) + public function deleteAdminBatch(array $ids): int { - if (($count = $this->notificationRepository->deleteAdminBatch($ids)) !== count($ids)) { - throw new ServiceException(__u('Error while deleting the notifications'), ServiceException::WARNING); + $count = $this->notificationRepository->deleteAdminBatch($ids); + + if ($count !== count($ids)) { + throw new ServiceException( + __u('Error while deleting the notifications'), + SPException::WARNING + ); } return $count; @@ -150,17 +148,21 @@ final class NotificationService extends Service /** * Deletes all the items for given ids * - * @param array $ids + * @param int[] $ids * - * @return int * @throws ConstraintException * @throws QueryException * @throws ServiceException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (($count = $this->notificationRepository->deleteByIdBatch($ids)) !== count($ids)) { - throw new ServiceException(__u('Error while deleting the notifications'), ServiceException::WARNING); + $count = $this->notificationRepository->deleteByIdBatch($ids); + + if ($count !== count($ids)) { + throw new ServiceException( + __u('Error while deleting the notifications'), + SPException::WARNING + ); } return $count; @@ -169,19 +171,19 @@ final class NotificationService extends Service /** * Returns the item for given id * - * @param int $id - * - * @return NotificationData * @throws ConstraintException * @throws QueryException * @throws NoSuchItemException */ - public function getById($id) + public function getById(int $id): NotificationData { $result = $this->notificationRepository->getById($id); if ($result->getNumRows() === 0) { - throw new NoSuchItemException(__u('Notification not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Notification not found'), + SPException::INFO + ); } return $result->getData(); @@ -194,7 +196,7 @@ final class NotificationService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): array { return $this->notificationRepository->getAll()->getDataAsArray(); } @@ -202,102 +204,103 @@ final class NotificationService extends Service /** * Marcar una notificación como leída * - * @param $id - * - * @throws ConstraintException - * @throws QueryException - * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function setCheckedById($id) + public function setCheckedById(int $id): void { if ($this->notificationRepository->setCheckedById($id) === 0) { - throw new NoSuchItemException(__u('Notification not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Notification not found'), + SPException::INFO + ); } } /** * Devolver las notificaciones de un usuario para una fecha y componente determinados * - * @param $component - * @param $id - * * @return NotificationData[] - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getForUserIdByDate($component, $id) + public function getForUserIdByDate(string $component, int $id): array { - return $this->notificationRepository->getForUserIdByDate($component, $id)->getDataAsArray(); + return $this->notificationRepository + ->getForUserIdByDate($component, $id) + ->getDataAsArray(); } /** - * @param $id - * * @return NotificationData[] * @throws ConstraintException * @throws QueryException */ - public function getAllForUserId($id) + public function getAllForUserId(int $id): array { - return $this->notificationRepository->getAllForUserId($id)->getDataAsArray(); + return $this->notificationRepository + ->getAllForUserId($id) + ->getDataAsArray(); } /** - * @param $id - * * @return NotificationData[] - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getAllActiveForUserId($id) + public function getAllActiveForUserId(int $id): array { if ($this->context->getUserData()->getIsAdminApp()) { - return $this->notificationRepository->getAllActiveForAdmin($id)->getDataAsArray(); + return $this->notificationRepository + ->getAllActiveForAdmin($id) + ->getDataAsArray(); } - return $this->notificationRepository->getAllActiveForUserId($id)->getDataAsArray(); + return $this->notificationRepository + ->getAllActiveForUserId($id) + ->getDataAsArray(); } /** * Searches for items by a given filter * - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { $userData = $this->context->getUserData(); if ($userData->getIsAdminApp()) { - return $this->notificationRepository->searchForAdmin($itemSearchData, $userData->getId()); + return $this->notificationRepository + ->searchForAdmin($itemSearchData, $userData->getId()); } - return $this->notificationRepository->searchForUserId($itemSearchData, $userData->getId()); + return $this->notificationRepository + ->searchForUserId($itemSearchData, $userData->getId()); } /** * Searches for items by a given filter * - * @param ItemSearchData $itemSearchData - * @param int $userId - * - * @return mixed * @throws ConstraintException * @throws QueryException */ - public function searchForUserId(ItemSearchData $itemSearchData, $userId) + public function searchForUserId( + ItemSearchData $itemSearchData, + int $userId + ): QueryResult { - return $this->notificationRepository->searchForUserId($itemSearchData, $userId); + return $this->notificationRepository + ->searchForUserId($itemSearchData, $userId); } /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->notificationRepository = $this->dic->get(NotificationRepository::class); } diff --git a/lib/SP/Services/Plugin/PluginDataService.php b/lib/SP/Services/Plugin/PluginDataService.php index 29f8eed0..65b875cf 100644 --- a/lib/SP/Services/Plugin/PluginDataService.php +++ b/lib/SP/Services/Plugin/PluginDataService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Plugin; @@ -28,6 +28,7 @@ use Defuse\Crypto\Exception\CryptoException; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\NoSuchPropertyException; use SP\Core\Exceptions\QueryException; +use SP\Core\Exceptions\SPException; use SP\Repositories\NoSuchItemException; use SP\Repositories\Plugin\PluginDataModel; use SP\Repositories\Plugin\PluginDataRepository; @@ -42,52 +43,41 @@ use SP\Storage\Database\QueryResult; */ final class PluginDataService extends Service { - /** - * @var PluginDataRepository - */ - protected $pluginRepository; + protected ?PluginDataRepository $pluginRepository = null; /** * Creates an item * - * @param PluginDataModel $itemData - * - * @return QueryResult * @throws CryptoException * @throws ConstraintException * @throws NoSuchPropertyException * @throws QueryException * @throws ServiceException */ - public function create(PluginDataModel $itemData) + public function create(PluginDataModel $itemData): QueryResult { - return $this->pluginRepository->create($itemData->encrypt($this->getMasterKeyFromContext())); + return $this->pluginRepository + ->create($itemData->encrypt($this->getMasterKeyFromContext())); } /** * Updates an item * - * @param PluginDataModel $itemData - * - * @return int * @throws CryptoException * @throws ConstraintException * @throws NoSuchPropertyException * @throws QueryException * @throws ServiceException */ - public function update(PluginDataModel $itemData) + public function update(PluginDataModel $itemData): int { - return $this->pluginRepository->update($itemData->encrypt($this->getMasterKeyFromContext())); + return $this->pluginRepository + ->update($itemData->encrypt($this->getMasterKeyFromContext())); } /** * Returns the item for given plugin and id * - * @param string $name - * @param int $id - * - * @return PluginDataModel * @throws NoSuchItemException * @throws CryptoException * @throws ConstraintException @@ -95,12 +85,15 @@ final class PluginDataService extends Service * @throws QueryException * @throws ServiceException */ - public function getByItemId(string $name, int $id) + public function getByItemId(string $name, int $id): PluginDataModel { $result = $this->pluginRepository->getByItemId($name, $id); if ($result->getNumRows() === 0) { - throw new NoSuchItemException(__u('Plugin\'s data not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Plugin\'s data not found'), + SPException::INFO + ); } /** @var PluginDataModel $itemData */ @@ -112,27 +105,34 @@ final class PluginDataService extends Service /** * Returns the item for given id * - * @param int $id - * * @return PluginDataModel[] - * @throws ConstraintException - * @throws QueryException - * @throws NoSuchItemException + * @throws \Defuse\Crypto\Exception\CryptoException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\NoSuchPropertyException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException + * @throws \SP\Services\ServiceException */ - public function getById($id) + public function getById(string $id): array { $result = $this->pluginRepository->getById($id); if ($result->getNumRows() === 0) { - throw new NoSuchItemException(__u('Plugin\'s data not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Plugin\'s data not found'), + SPException::INFO + ); } $data = $result->getDataAsArray(); - array_walk($data, function ($itemData) { - /** @var PluginDataModel $itemData */ - $itemData->decrypt($this->getMasterKeyFromContext()); - }); + array_walk( + $data, + function ($itemData) { + /** @var PluginDataModel $itemData */ + $itemData->decrypt($this->getMasterKeyFromContext()); + } + ); return $data; } @@ -141,17 +141,23 @@ final class PluginDataService extends Service * Returns all the items * * @return PluginDataModel[] - * @throws ConstraintException - * @throws QueryException + * @throws \Defuse\Crypto\Exception\CryptoException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\NoSuchPropertyException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException */ - public function getAll() + public function getAll(): array { $data = $this->pluginRepository->getAll()->getDataAsArray(); - array_walk($data, function ($itemData) { - /** @var PluginDataModel $itemData */ - $itemData->decrypt($this->getMasterKeyFromContext()); - }); + array_walk( + $data, + function ($itemData) { + /** @var PluginDataModel $itemData */ + $itemData->decrypt($this->getMasterKeyFromContext()); + } + ); return $data; } @@ -159,38 +165,38 @@ final class PluginDataService extends Service /** * Deletes an item * - * @param $id - * - * @throws NoSuchItemException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function delete($id) + public function delete(string $id): void { if ($this->pluginRepository->delete($id) === 0) { - throw new NoSuchItemException(__u('Plugin\'s data not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Plugin\'s data not found'), + SPException::INFO + ); } } /** * Deletes an item * - * @param string $name - * @param int $itemId - * - * @return void * @throws NoSuchItemException * @throws ConstraintException * @throws QueryException */ - public function deleteByItemId(string $name, int $itemId) + public function deleteByItemId(string $name, int $itemId): void { if ($this->pluginRepository->deleteByItemId($name, $itemId) === 0) { - throw new NoSuchItemException(__u('Plugin\'s data not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Plugin\'s data not found'), + SPException::INFO + ); } } - protected function initialize() + protected function initialize(): void { $this->pluginRepository = $this->dic->get(PluginDataRepository::class); } diff --git a/lib/SP/Services/Plugin/PluginService.php b/lib/SP/Services/Plugin/PluginService.php index 2d48b400..4b7c7aa9 100644 --- a/lib/SP/Services/Plugin/PluginService.php +++ b/lib/SP/Services/Plugin/PluginService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Plugin; @@ -43,21 +43,15 @@ use SP\Storage\Database\QueryResult; */ final class PluginService extends Service { - /** - * @var PluginRepository - */ - protected $pluginRepository; + protected PluginRepository $pluginRepository; /** * Creates an item * - * @param PluginModel $itemData - * - * @return int * @throws ConstraintException * @throws QueryException */ - public function create(PluginModel $itemData) + public function create(PluginModel $itemData): int { return $this->pluginRepository->create($itemData)->getLastId(); } @@ -65,13 +59,10 @@ final class PluginService extends Service /** * Updates an item * - * @param PluginModel $itemData - * - * @return mixed * @throws ConstraintException * @throws QueryException */ - public function update(PluginModel $itemData) + public function update(PluginModel $itemData): int { return $this->pluginRepository->update($itemData); } @@ -79,19 +70,19 @@ final class PluginService extends Service /** * Returns the item for given id * - * @param int $id - * - * @return PluginModel * @throws ConstraintException * @throws QueryException * @throws NoSuchItemException */ - public function getById($id) + public function getById(int $id): PluginModel { $result = $this->pluginRepository->getById($id); if ($result->getNumRows() === 0) { - throw new NoSuchItemException(__u('Plugin not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Plugin not found'), + SPException::INFO + ); } return $result->getData(); @@ -104,7 +95,7 @@ final class PluginService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): array { return $this->pluginRepository->getAll()->getDataAsArray(); } @@ -112,13 +103,13 @@ final class PluginService extends Service /** * Returns all the items for given ids * - * @param array $ids + * @param int[] $ids * * @return PluginModel[] * @throws ConstraintException * @throws QueryException */ - public function getByIdBatch(array $ids) + public function getByIdBatch(array $ids): array { return $this->pluginRepository->getByIdBatch($ids)->getDataAsArray(); } @@ -126,14 +117,14 @@ final class PluginService extends Service /** * Deletes all the items for given ids * - * @param array $ids + * @param int[] $ids * * @throws SPException * @throws ConstraintException * @throws QueryException * @throws SPException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): void { if ($this->pluginRepository->deleteByIdBatch($ids) !== count($ids)) { throw new ServiceException(__u('Error while deleting the plugins')); @@ -143,29 +134,27 @@ final class PluginService extends Service /** * Deletes an item * - * @param $id - * * @throws SPException * @throws ConstraintException * @throws QueryException */ - public function delete($id) + public function delete(int $id): void { if ($this->pluginRepository->delete($id) === 0) { - throw new NoSuchItemException(__u('Plugin not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Plugin not found'), + SPException::INFO + ); } } /** * Searches for items by a given filter * - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->pluginRepository->search($itemSearchData); } @@ -173,19 +162,19 @@ final class PluginService extends Service /** * Devuelve los datos de un plugin por su nombre * - * @param string $name - * - * @return PluginModel * @throws NoSuchItemException * @throws ConstraintException * @throws QueryException */ - public function getByName($name) + public function getByName(string $name): PluginModel { $result = $this->pluginRepository->getByName($name); if ($result->getNumRows() === 0) { - throw new NoSuchItemException(__u('Plugin not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Plugin not found'), + SPException::INFO + ); } return $result->getData(); @@ -194,87 +183,85 @@ final class PluginService extends Service /** * Cambiar el estado del plugin * - * @param $id - * @param $enabled - * - * @return void - * @throws NoSuchItemException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function toggleEnabled($id, $enabled) + public function toggleEnabled(int $id, bool $enabled): void { if ($this->pluginRepository->toggleEnabled($id, $enabled) === 0) { - throw new NoSuchItemException(__u('Plugin not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Plugin not found'), + SPException::INFO + ); } } /** * Cambiar el estado del plugin * - * @param $name - * @param $enabled - * - * @return void - * @throws NoSuchItemException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function toggleEnabledByName($name, $enabled) + public function toggleEnabledByName(string $name, bool $enabled): void { if ($this->pluginRepository->toggleEnabledByName($name, $enabled) === 0) { - throw new NoSuchItemException(__u('Plugin not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Plugin not found'), + SPException::INFO + ); } } /** * Cambiar el estado del plugin * - * @param $id - * @param $available - * - * @throws NoSuchItemException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function toggleAvailable($id, $available) + public function toggleAvailable(int $id, bool $available): void { if ($this->pluginRepository->toggleAvailable($id, $available) === 0) { - throw new NoSuchItemException(__u('Plugin not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Plugin not found'), + SPException::INFO + ); } } /** * Cambiar el estado del plugin * - * @param string $name - * @param int $available - * - * @throws NoSuchItemException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function toggleAvailableByName($name, $available) + public function toggleAvailableByName(string $name, bool $available): void { if ($this->pluginRepository->toggleAvailableByName($name, $available) === 0) { - throw new NoSuchItemException(__u('Plugin not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Plugin not found'), + SPException::INFO + ); } } /** * Restablecer los datos de un plugin * - * @param int $id Id del plugin - * - * @return bool * @throws NoSuchItemException * @throws ConstraintException * @throws QueryException */ - public function resetById($id) + public function resetById(int $id): bool { if (($count = $this->pluginRepository->resetById($id)) === 0) { - throw new NoSuchItemException(__u('Plugin not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Plugin not found'), + SPException::INFO + ); } return $count; @@ -287,12 +274,12 @@ final class PluginService extends Service * @throws ConstraintException * @throws QueryException */ - public function getEnabled() + public function getEnabled(): array { return $this->pluginRepository->getEnabled()->getDataAsArray(); } - protected function initialize() + protected function initialize(): void { $this->pluginRepository = $this->dic->get(PluginRepository::class); } diff --git a/lib/SP/Services/PublicLink/PublicLinkKey.php b/lib/SP/Services/PublicLink/PublicLinkKey.php index 2dab1244..9e5bf852 100644 --- a/lib/SP/Services/PublicLink/PublicLinkKey.php +++ b/lib/SP/Services/PublicLink/PublicLinkKey.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,11 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\PublicLink; -use Defuse\Crypto\Exception\EnvironmentIsBrokenException; use SP\Util\PasswordUtil; /** @@ -34,24 +33,15 @@ use SP\Util\PasswordUtil; */ final class PublicLinkKey { - /** - * @var string - */ - private $hash; - /** - * @var string - */ - private $salt; + private string $hash; + private string $salt; /** * PublicLinkKey constructor. * - * @param string $salt - * @param string $hash - * - * @throws EnvironmentIsBrokenException + * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException */ - public function __construct(string $salt, string $hash = null) + public function __construct(string $salt, ?string $hash = null) { $this->salt = $salt; @@ -62,25 +52,16 @@ final class PublicLinkKey } } - /** - * @return string - */ public function getKey(): string { return sha1($this->salt . $this->hash); } - /** - * @return string - */ public function getHash(): string { return $this->hash; } - /** - * @return string - */ public function getSalt(): string { return $this->salt; diff --git a/lib/SP/Services/PublicLink/PublicLinkService.php b/lib/SP/Services/PublicLink/PublicLinkService.php index ed51d4d4..6df48c21 100644 --- a/lib/SP/Services/PublicLink/PublicLinkService.php +++ b/lib/SP/Services/PublicLink/PublicLinkService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\PublicLink; @@ -59,69 +59,52 @@ final class PublicLinkService extends Service /** * Tipos de enlaces */ - const TYPE_ACCOUNT = 1; - /** - * @var PublicLinkRepository - */ - protected $publicLinkRepository; - /** - * @var Request - */ - protected $request; + public const TYPE_ACCOUNT = 1; + + protected ?PublicLinkRepository $publicLinkRepository = null; + protected ?Request $request = null; /** * Returns an HTTP URL for given hash - * - * @param $baseUrl - * @param $hash - * - * @return string */ - public static function getLinkForHash($baseUrl, $hash) + public static function getLinkForHash(string $baseUrl, string $hash): string { - return (new Uri($baseUrl))->addParam('r', 'account/viewLink/' . $hash)->getUri(); + return (new Uri($baseUrl)) + ->addParam('r', 'account/viewLink/' . $hash) + ->getUri(); } /** * Generar el hash para el enlace - * - * @return string */ - public static function createLinkHash() + public static function createLinkHash(): string { return hash('sha256', uniqid('sysPassPublicLink', true)); } - /** - * @param string $salt - * @param PublicLinkData $publicLinkData - * - * @return string - */ - public static function getKeyForHash($salt, PublicLinkData $publicLinkData) + public static function getKeyForHash( + string $salt, + PublicLinkData $publicLinkData + ): string { return sha1($salt . $publicLinkData->getHash()); } /** - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->publicLinkRepository->search($itemSearchData); } /** - * @param $id - * - * @return PublicLinkListData - * @throws SPException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function getById($id) + public function getById(int $id): PublicLinkListData { $result = $this->publicLinkRepository->getById($id); @@ -133,18 +116,15 @@ final class PublicLinkService extends Service } /** - * @param $id - * - * @return bool - * @throws SPException - * @throws CryptoException - * @throws EnvironmentIsBrokenException - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - * @throws ConstraintException - * @throws QueryException + * @throws \Defuse\Crypto\Exception\CryptoException + * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + * @throws \SP\Repositories\NoSuchItemException + * @throws \SP\Services\ServiceException */ - public function refresh($id) + public function refresh(int $id): bool { $result = $this->publicLinkRepository->getById($id); @@ -165,36 +145,36 @@ final class PublicLinkService extends Service } /** - * @param string|null $hash - * - * @return PublicLinkKey * @throws EnvironmentIsBrokenException */ - public function getPublicLinkKey(string $hash = null) + public function getPublicLinkKey(?string $hash = null): PublicLinkKey { - return new PublicLinkKey($this->config->getConfigData()->getPasswordSalt(), $hash); + return new PublicLinkKey( + $this->config->getConfigData()->getPasswordSalt(), + $hash + ); } /** * Obtener los datos de una cuenta y encriptarlos para el enlace * - * @param int $itemId - * @param PublicLinkKey $key - * - * @return Vault - * @throws NoSuchItemException - * @throws ServiceException - * @throws CryptoException - * @throws ConstraintException - * @throws QueryException + * @throws \Defuse\Crypto\Exception\CryptoException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException + * @throws \SP\Services\ServiceException */ - private function getSecuredLinkData($itemId, PublicLinkKey $key) + private function getSecuredLinkData(int $itemId, PublicLinkKey $key): string { // Obtener los datos de la cuenta $accountData = $this->dic->get(AccountService::class)->getDataForLink($itemId); // Desencriptar la clave de la cuenta - $accountData->setPass(Crypt::decrypt($accountData->getPass(), $accountData->getKey(), $this->getMasterKeyFromContext())); + $accountData->setPass(Crypt::decrypt( + $accountData->getPass(), + $accountData->getKey(), + $this->getMasterKeyFromContext()) + ); $accountData->setKey(null); return (new Vault())->saveData(serialize($accountData), $key->getKey())->getSerialized(); @@ -202,28 +182,24 @@ final class PublicLinkService extends Service /** * Devolver el tiempo de caducidad del enlace - * - * @param Config $config - * - * @return int */ - public static function calcDateExpire(Config $config) + public static function calcDateExpire(Config $config): int { return time() + $config->getConfigData()->getPublinksMaxTime(); } /** - * @param $id - * - * @return $this - * @throws NoSuchItemException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function delete($id) + public function delete(int $id): PublicLinkService { if ($this->publicLinkRepository->delete($id) === 0) { - throw new NoSuchItemException(__u('Link not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Link not found'), + SPException::INFO + ); } return $this; @@ -232,26 +208,27 @@ final class PublicLinkService extends Service /** * Deletes all the items for given ids * - * @param array $ids + * @param int[] $ids * - * @return bool * @throws ConstraintException * @throws QueryException * @throws ServiceException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (($count = $this->publicLinkRepository->deleteByIdBatch($ids)) !== count($ids)) { - throw new ServiceException(__u('Error while removing the links'), ServiceException::WARNING); + $count = $this->publicLinkRepository->deleteByIdBatch($ids); + + if ($count !== count($ids)) { + throw new ServiceException( + __u('Error while removing the links'), + SPException::WARNING + ); } return $count; } /** - * @param PublicLinkData $itemData - * - * @return int * @throws SPException * @throws CryptoException * @throws ContainerExceptionInterface @@ -259,7 +236,7 @@ final class PublicLinkService extends Service * @throws ConstraintException * @throws QueryException */ - public function create(PublicLinkData $itemData) + public function create(PublicLinkData $itemData): int { $key = $this->getPublicLinkKey(); @@ -279,7 +256,7 @@ final class PublicLinkService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAllBasic() + public function getAllBasic(): array { return $this->publicLinkRepository->getAll()->getDataAsArray(); } @@ -287,13 +264,11 @@ final class PublicLinkService extends Service /** * Incrementar el contador de visitas de un enlace * - * @param PublicLinkData $publicLinkData - * * @throws NoSuchItemException * @throws ConstraintException * @throws QueryException */ - public function addLinkView(PublicLinkData $publicLinkData) + public function addLinkView(PublicLinkData $publicLinkData): void { /** @var array $useInfo */ $useInfo = unserialize($publicLinkData->getUseInfo()); @@ -307,14 +282,8 @@ final class PublicLinkService extends Service /** * Actualizar la información de uso - * - * @param string $hash - * - * @param Request $request - * - * @return array */ - public static function getUseInfo($hash, Request $request) + public static function getUseInfo(string $hash, Request $request): array { return [ 'who' => $request->getClientAddress(true), @@ -326,12 +295,9 @@ final class PublicLinkService extends Service } /** - * @param $hash string - * - * @return bool|PublicLinkData * @throws SPException */ - public function getByHash($hash) + public function getByHash(string $hash): PublicLinkData { $result = $this->publicLinkRepository->getByHash($hash); @@ -345,14 +311,11 @@ final class PublicLinkService extends Service /** * Devolver el hash asociado a un elemento * - * @param int $itemId - * - * @return PublicLinkData * @throws ConstraintException * @throws QueryException * @throws NoSuchItemException */ - public function getHashForItem($itemId) + public function getHashForItem(int $itemId): PublicLinkData { $result = $this->publicLinkRepository->getHashForItem($itemId); @@ -366,14 +329,11 @@ final class PublicLinkService extends Service /** * Updates an item * - * @param PublicLinkData $itemData - * - * @return mixed * @throws SPException * @throws ConstraintException * @throws QueryException */ - public function update(PublicLinkData $itemData) + public function update(PublicLinkData $itemData): int { return $this->publicLinkRepository->update($itemData); } @@ -382,7 +342,7 @@ final class PublicLinkService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->publicLinkRepository = $this->dic->get(PublicLinkRepository::class); $this->request = $this->dic->get(Request::class); diff --git a/lib/SP/Services/Service.php b/lib/SP/Services/Service.php index 0db59973..25f89609 100644 --- a/lib/SP/Services/Service.php +++ b/lib/SP/Services/Service.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services; @@ -45,30 +45,13 @@ use SP\Storage\Database\Database; */ abstract class Service { - const STATUS_INTERNAL_ERROR = 1000; + protected const STATUS_INTERNAL_ERROR = 1000; - /** - * @var Config - */ - protected $config; - /** - * @var ContextInterface - */ - protected $context; - /** - * @var EventDispatcher - */ - protected $eventDispatcher; - /** - * @var ContainerInterface - */ - protected $dic; + protected Config $config; + protected ContextInterface $context; + protected EventDispatcher $eventDispatcher; + protected ContainerInterface $dic; - /** - * Service constructor. - * - * @param ContainerInterface $dic - */ public function __construct(ContainerInterface $dic) { $this->dic = $dic; @@ -84,9 +67,6 @@ abstract class Service /** * Bubbles a Closure in a database transaction * - * @param Closure $closure - * - * @return mixed * @throws ServiceException * @throws Exception */ @@ -106,7 +86,8 @@ abstract class Service logger('Transaction:Rollback'); - $this->eventDispatcher->notifyEvent('database.rollback', + $this->eventDispatcher->notifyEvent( + 'database.rollback', new Event($this, EventMessage::factory() ->addDescription(__u('Rollback'))) ); @@ -119,10 +100,9 @@ abstract class Service } /** - * @return string * @throws ServiceException */ - protected final function getMasterKeyFromContext(): String + final protected function getMasterKeyFromContext(): string { try { if ($this->context instanceof SessionContext) { @@ -144,11 +124,9 @@ abstract class Service } /** - * @param string $masterPass - * * @throws ServiceException */ - protected final function setMasterKeyInContext(string $masterPass) + final protected function setMasterKeyInContext(string $masterPass): void { try { if ($this->context instanceof SessionContext) { @@ -156,11 +134,7 @@ abstract class Service } else { $this->context->setTrasientKey('_masterpass', $masterPass); } - } catch (ContextException $e) { - logger($e->getMessage()); - - throw new ServiceException(__u('Error while setting master password in context')); - } catch (CryptoException $e) { + } catch (ContextException | CryptoException $e) { logger($e->getMessage()); throw new ServiceException(__u('Error while setting master password in context')); diff --git a/lib/SP/Services/ServiceException.php b/lib/SP/Services/ServiceException.php index c931c4c4..4351d3c6 100644 --- a/lib/SP/Services/ServiceException.php +++ b/lib/SP/Services/ServiceException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services; diff --git a/lib/SP/Services/ServiceItemInterface.php b/lib/SP/Services/ServiceItemInterface.php deleted file mode 100644 index 8ad53f5a..00000000 --- a/lib/SP/Services/ServiceItemInterface.php +++ /dev/null @@ -1,38 +0,0 @@ -. - */ - -namespace SP\Services; - -/** - * Interface ServiceItemInterface - * - * @package SP\Services - */ -interface ServiceItemInterface -{ - /** - * @return array - */ - public function getAll(); -} \ No newline at end of file diff --git a/lib/SP/Services/ServiceItemTrait.php b/lib/SP/Services/ServiceItemTrait.php index b8984e33..e985d27a 100644 --- a/lib/SP/Services/ServiceItemTrait.php +++ b/lib/SP/Services/ServiceItemTrait.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services; @@ -43,9 +43,11 @@ trait ServiceItemTrait * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public static function getItemsBasic() + public static function getItemsBasic(): array { - return Bootstrap::getContainer()->get(static::class)->getAllBasic(); + return Bootstrap::getContainer() + ->get(static::class) + ->getAllBasic(); } /** diff --git a/lib/SP/Services/Tag/TagService.php b/lib/SP/Services/Tag/TagService.php index 219efb9e..4dd909fd 100644 --- a/lib/SP/Services/Tag/TagService.php +++ b/lib/SP/Services/Tag/TagService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Tag; @@ -48,115 +48,105 @@ final class TagService extends Service { use ServiceItemTrait; - /** - * @var TagRepository - */ - protected $tagRepository; + protected ?TagRepository $tagRepository = null; /** - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->tagRepository->search($itemSearchData); } /** - * @param $id - * - * @return TagData - * @throws NoSuchItemException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function getById($id) + public function getById(int $id): TagData { $result = $this->tagRepository->getById($id); if ($result->getNumRows() === 0) { - throw new NoSuchItemException(__u('Tag not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Tag not found'), + SPException::INFO + ); } return $result->getData(); } /** - * @param string $name - * - * @return TagData * @throws NoSuchItemException * @throws ConstraintException * @throws QueryException */ - public function getByName($name) + public function getByName(string $name): TagData { $result = $this->tagRepository->getByName($name); if ($result->getNumRows() === 0) { - throw new NoSuchItemException(__u('Tag not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Tag not found'), + SPException::INFO + ); } return $result->getData(); } /** - * @param $id - * - * @return $this - * @throws ConstraintException - * @throws QueryException - * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function delete($id) + public function delete(int $id): TagService { if ($this->tagRepository->delete($id) === 0) { - throw new NoSuchItemException(__u('Tag not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Tag not found'), + SPException::INFO + ); } return $this; } /** - * @param array $ids + * @param int[] $ids * - * @return $this * @throws SPException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): TagService { if ($this->tagRepository->deleteByIdBatch($ids) !== count($ids)) { - throw new ServiceException(__u('Error while removing the tags'), ServiceException::WARNING); + throw new ServiceException( + __u('Error while removing the tags'), + SPException::WARNING + ); } return $this; } /** - * @param $itemData - * - * @return int * @throws ConstraintException * @throws QueryException * @throws DuplicatedItemException */ - public function create($itemData) + public function create(TagData $itemData): int { return $this->tagRepository->create($itemData); } /** - * @param $itemData - * - * @return int * @throws SPException * @throws ConstraintException * @throws QueryException */ - public function update($itemData) + public function update(TagData $itemData): int { return $this->tagRepository->update($itemData); } @@ -168,7 +158,7 @@ final class TagService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAllBasic() + public function getAllBasic(): array { return $this->tagRepository->getAll(); } @@ -177,7 +167,7 @@ final class TagService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->tagRepository = $this->dic->get(TagRepository::class); } diff --git a/lib/SP/Services/Task/Task.php b/lib/SP/Services/Task/Task.php index bcf55311..e167c95f 100644 --- a/lib/SP/Services/Task/Task.php +++ b/lib/SP/Services/Task/Task.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,11 +19,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Task; +use JsonException; use SP\Core\Context\SessionContext; use SP\Core\Messages\TaskMessage; use SP\Storage\File\FileException; @@ -40,31 +41,22 @@ final class Task /** * @var string Nombre de la tarea */ - private $name; + private string $name; /** * @var string ID de la tarea */ - private $taskId; - /** - * @var FileHandler - */ - private $fileOut; - /** - * @var FileHandler - */ - private $fileTask; + private string $taskId; + private ?FileHandler $fileOut = null; + private ?FileHandler $fileTask = null; /** * @var int Intérvalo en segundos */ - private $interval = 5; + private int $interval = 5; /** * @var bool Si se ha inicializado para escribir en el archivo */ - private $initialized = false; - /** - * @var string - */ - private $uid; + private bool $initialized; + private string $uid; /** * Task constructor. @@ -72,7 +64,7 @@ final class Task * @param string $name Nombre de la tarea * @param string $id */ - public function __construct($name, $id) + public function __construct(string $name, string $id) { $this->name = $name; $this->taskId = $id; @@ -82,16 +74,24 @@ final class Task /** * Comprobar si se puede escribir en el archivo - * - * @return bool */ - private function checkFile() + private function checkFile(): bool { $tempDir = Util::getTempDir(); if ($tempDir !== false) { - $this->fileOut = new FileHandler($tempDir . DIRECTORY_SEPARATOR . $this->taskId . '.out'); - $this->fileTask = new FileHandler($tempDir . DIRECTORY_SEPARATOR . $this->taskId . '.task'); + $this->fileOut = new FileHandler( + $tempDir . + DIRECTORY_SEPARATOR . + $this->taskId . + '.out' + ); + $this->fileTask = new FileHandler( + $tempDir . + DIRECTORY_SEPARATOR . + $this->taskId . + '.task' + ); $this->deleteTaskFiles(); @@ -104,42 +104,42 @@ final class Task /** * Eliminar los archivos de la tarea no usados */ - private function deleteTaskFiles() + private function deleteTaskFiles(): void { - $filesOut = dirname($this->fileOut->getFile()) . DIRECTORY_SEPARATOR . $this->taskId . '*.out'; - $filesTask = dirname($this->fileTask->getFile()) . DIRECTORY_SEPARATOR . $this->taskId . '*.task'; + $filesOut = + dirname($this->fileOut->getFile()) . + DIRECTORY_SEPARATOR . + $this->taskId . + '*.out'; + $filesTask = + dirname($this->fileTask->getFile()) . + DIRECTORY_SEPARATOR . + $this->taskId . + '*.task'; - array_map('unlink', array_merge(glob($filesOut), glob($filesTask))); + array_map( + 'unlink', + array_merge(glob($filesOut), glob($filesTask)) + ); } - /** - * @return string - */ - public function genUid() + public function genUid(): string { return md5($this->name . $this->taskId); } /** * Generar un ID de tarea - * - * @param $name - * - * @return string */ - public static function genTaskId($name) + public static function genTaskId(string $name): string { - return uniqid($name); + return uniqid($name, true); } /** * Escribir el tado de la tarea a un archivo - * - * @param TaskMessage $message - * - * @return bool */ - public function writeStatusAndFlush(TaskMessage $message) + public function writeStatusAndFlush(TaskMessage $message): bool { try { if ($this->initialized === true) { @@ -155,16 +155,14 @@ final class Task /** * Escribir un mensaje en el archivo de la tarea en formato JSON - * - * @param TaskMessage $message */ - public function writeJsonStatusAndFlush(TaskMessage $message) + public function writeJsonStatusAndFlush(TaskMessage $message): void { try { if ($this->initialized === true) { $this->fileOut->save($message->composeJson()); } - } catch (FileException $e) { + } catch (FileException | JsonException $e) { processException($e); } } @@ -172,7 +170,7 @@ final class Task /** * Iniciar la tarea */ - public function end() + public function end(): void { try { logger("End Task: {$this->name}"); @@ -190,45 +188,31 @@ final class Task * * @throws FileException */ - public function unregister() + public function unregister(): void { - logger("Unregister Task: {$this->name}"); + logger("Unregister Task: $this->name"); $this->fileTask->delete(); } - /** - * @return int - */ - public function getInterval() + public function getInterval(): int { return $this->interval; } - /** - * @param int $interval - * - * @return Task - */ - public function setInterval($interval) + public function setInterval(int $interval): Task { $this->interval = $interval; return $this; } - /** - * @return string - */ - public function getTaskId() + public function getTaskId(): string { return $this->taskId; } - /** - * @return FileHandler - */ - public function getFileOut(): FileHandler + public function getFileOut(): ?FileHandler { return $this->fileOut; } @@ -236,12 +220,11 @@ final class Task /** * Register a task * - * @return Task * @throws FileException */ - public function register() + public function register(): Task { - logger("Register Task: {$this->name}"); + logger("Register Task: $this->name"); $this->fileTask->save(serialize($this)); @@ -253,12 +236,11 @@ final class Task * * Session is locked in order to allow other scripts execution * - * @return Task * @throws FileException */ - public function registerSession() + public function registerSession(): Task { - logger("Register Task (session): {$this->name}"); + logger("Register Task (session): $this->name"); $this->fileTask->save(serialize($this)); @@ -267,18 +249,12 @@ final class Task return $this; } - /** - * @return string - */ public function getUid(): string { return $this->uid; } - /** - * @return FileHandler - */ - public function getFileTask(): FileHandler + public function getFileTask(): ?FileHandler { return $this->fileTask; } diff --git a/lib/SP/Services/Task/TaskFactory.php b/lib/SP/Services/Task/TaskFactory.php index fecd0cbd..c4068f71 100644 --- a/lib/SP/Services/Task/TaskFactory.php +++ b/lib/SP/Services/Task/TaskFactory.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Task; @@ -38,20 +38,18 @@ final class TaskFactory /** * @var Task[] */ - private static $tasks = []; + private static array $tasks = []; /** * Crear una tarea para la actualización de estado de la actualización * - * @param string $name - * @param string $id - * - * @param bool $hasSession - * - * @return Task * @throws FileException */ - public static function create($name, $id, $hasSession = true) + public static function create( + string $name, + string $id, + bool $hasSession = true + ): Task { $task = self::add((new Task($name, $id))); @@ -62,12 +60,7 @@ final class TaskFactory return $task->register(); } - /** - * @param Task $task - * - * @return Task - */ - private static function add(Task $task) + private static function add(Task $task): Task { if (!isset(self::$tasks[$task->getUid()])) { self::$tasks[$task->getUid()] = $task; @@ -80,10 +73,8 @@ final class TaskFactory /** * Finalizar la tarea - * - * @param Task $task */ - public static function end(Task $task) + public static function end(Task $task): void { self::get($task->getUid()) ->end(); @@ -91,12 +82,7 @@ final class TaskFactory self::delete($task->getUid()); } - /** - * @param $id - * - * @return Task - */ - private static function get($id) + private static function get(string $id): Task { if (isset(self::$tasks[$id])) { return self::$tasks[$id]; @@ -105,34 +91,25 @@ final class TaskFactory throw new RuntimeException('Task not registered'); } - /** - * @param $id - */ - private static function delete($id) + private static function delete(string $id): void { if (isset(self::$tasks[$id])) { unset(self::$tasks[$id]); } } - /** - * @param string $taskId - * @param string $task - * - * @return TaskMessage - */ - public static function createMessage($taskId, $task) + public static function createMessage( + string $taskId, + string $task + ): TaskMessage { return new TaskMessage($taskId, $task); } /** * Enviar un mensaje de actualización a la tarea - * - * @param Task $task - * @param TaskMessage $taskMessage */ - public static function update(Task $task, TaskMessage $taskMessage) + public static function update(Task $task, TaskMessage $taskMessage): void { self::get($task->getUid()) ->writeJsonStatusAndFlush($taskMessage); diff --git a/lib/SP/Services/Task/TaskService.php b/lib/SP/Services/Task/TaskService.php index 78c1730a..6742cd5d 100644 --- a/lib/SP/Services/Task/TaskService.php +++ b/lib/SP/Services/Task/TaskService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Task; @@ -41,41 +41,25 @@ final class TaskService extends Service /** * Time for waiting to initialization */ - const STARTUP_WAIT_TIME = 5; + private const STARTUP_WAIT_TIME = 5; /** * Initialization attempts */ - const STARTUP_WAIT_COUNT = 30; - /** - * @var Closure - */ - private $messagePusher; - /** - * @var Task - */ - private $task; - /** - * @var string - */ - private $taskDirectory; - /** - * @var string - */ - private $taskId; - /** - * @var FileHandler - */ - private $taskFile; + private const STARTUP_WAIT_COUNT = 30; + + private ?Closure $messagePusher = null; + private ?Task $task = null; + private ?string $taskDirectory = null; + private ?string $taskId = null; + private ?FileHandler $taskFile = null; /** * Track task status * - * @param string $taskId - * @param Closure $messagePusher - * - * @throws ServiceException + * @throws \JsonException + * @throws \SP\Services\ServiceException */ - public function trackStatus($taskId, Closure $messagePusher) + public function trackStatus(string $taskId, Closure $messagePusher): void { $this->taskId = $taskId; $this->taskDirectory = Util::getTempDir(); @@ -109,12 +93,15 @@ final class TaskService extends Service /** * Get a lock for task execution - * - * @return bool */ - private function getLock() + private function getLock(): bool { - $lockFile = new FileHandler($this->taskDirectory . DIRECTORY_SEPARATOR . $this->taskId . '.lock'); + $lockFile = new FileHandler( + $this->taskDirectory . + DIRECTORY_SEPARATOR . + $this->taskId . + '.lock' + ); try { if ($lockFile->getFileTime() + (self::STARTUP_WAIT_COUNT * self::STARTUP_WAIT_TIME) < time()) { @@ -137,10 +124,8 @@ final class TaskService extends Service /** * Check whether the task's file has been registered - * - * @return bool */ - private function checkTaskRegistered() + private function checkTaskRegistered(): bool { if (is_object($this->task)) { logger('Task detected: ' . $this->task->getTaskId()); @@ -149,7 +134,12 @@ final class TaskService extends Service } try { - $this->taskFile = new FileHandler($this->taskDirectory . DIRECTORY_SEPARATOR . $this->taskId . '.task'); + $this->taskFile = new FileHandler( + $this->taskDirectory . + DIRECTORY_SEPARATOR . + $this->taskId . + '.task' + ); $this->taskFile->checkFileExists(); $this->task = unserialize($this->taskFile->readToString()); @@ -161,8 +151,10 @@ final class TaskService extends Service /** * Read a task status and send it back to the browser (messagePusher) + * + * @throws \JsonException */ - private function readTaskStatus() + private function readTaskStatus(): void { logger('Tracking task status: ' . $this->task->getTaskId()); @@ -180,7 +172,10 @@ final class TaskService extends Service $this->messagePusher->call($this, $id, $content); $id++; } else { - $message = TaskFactory::createMessage($this->task->getTaskId(), __('Waiting for progress updating ...')); + $message = TaskFactory::createMessage( + $this->task->getTaskId(), + __('Waiting for progress updating ...') + ); logger($message->getTask()); @@ -198,8 +193,10 @@ final class TaskService extends Service $this->messagePusher->call( $this, $id, - TaskFactory::createMessage($this->task->getTaskId(), $e->getMessage()) - ->composeJson() + TaskFactory::createMessage( + $this->task->getTaskId(), + $e->getMessage() + )->composeJson() ); $failCount++; @@ -212,7 +209,7 @@ final class TaskService extends Service /** * Check whether the task's output file exists */ - private function checkTaskFile() + private function checkTaskFile(): bool { try { $this->taskFile->checkFileExists(); diff --git a/lib/SP/Services/Track/TrackService.php b/lib/SP/Services/Track/TrackService.php index 707fa650..5b77a587 100644 --- a/lib/SP/Services/Track/TrackService.php +++ b/lib/SP/Services/Track/TrackService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Track; @@ -52,43 +52,33 @@ final class TrackService extends Service /** * Tiempo para contador de intentos */ - const TIME_TRACKING = 600; - const TIME_TRACKING_MAX_ATTEMPTS = 10; - const TIME_SLEEP = 0.5; + public const TIME_TRACKING = 600; + public const TIME_TRACKING_MAX_ATTEMPTS = 10; + public const TIME_SLEEP = 0.5; + + protected ?TrackRepository $trackRepository = null; + protected ?Request $request = null; /** - * @var TrackRepository - */ - protected $trackRepository; - /** - * @var Request - */ - protected $request; - - /** - * @param string $source - * - * @return TrackRequest * @throws InvalidArgumentException */ - public function getTrackRequest($source) + public function getTrackRequest(string $source): TrackRequest { - $trackRequest = new TrackRequest(); - $trackRequest->time = time() - self::TIME_TRACKING; + $trackRequest = new TrackRequest( + time() - self::TIME_TRACKING, + $source + ); $trackRequest->setTrackIp($this->request->getClientAddress()); - $trackRequest->source = $source; return $trackRequest; } /** - * @param $id int - * * @throws QueryException * @throws ConstraintException * @throws NoSuchItemException */ - public function delete($id) + public function delete(int $id): void { if ($this->trackRepository->delete($id) === 0) { throw new NoSuchItemException(__u('Track not found')); @@ -96,13 +86,11 @@ final class TrackService extends Service } /** - * @param $id int - * * @throws QueryException * @throws ConstraintException * @throws NoSuchItemException */ - public function unlock($id) + public function unlock(int $id): void { if ($this->trackRepository->unlock($id) === 0) { throw new NoSuchItemException(__u('Track not found')); @@ -110,24 +98,20 @@ final class TrackService extends Service } /** - * @return bool * @throws ConstraintException * @throws QueryException */ - public function clear() + public function clear(): bool { return $this->trackRepository->clear(); } /** - * @param $id int - * - * @return TrackData * @throws ConstraintException * @throws QueryException * @throws NoSuchItemException */ - public function getById($id) + public function getById(int $id): TrackData { $result = $this->trackRepository->getById($id); @@ -143,7 +127,7 @@ final class TrackService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAll() + public function getAll(): array { return $this->trackRepository->getAll()->getDataAsArray(); } @@ -151,12 +135,10 @@ final class TrackService extends Service /** * Comprobar los intentos de login * - * @param TrackRequest $trackRequest - * * @return bool True if delay is performed, false otherwise * @throws Exception */ - public function checkTracking(TrackRequest $trackRequest) + public function checkTracking(TrackRequest $trackRequest): bool { try { $attempts = $this->getTracksForClientFromTime($trackRequest); @@ -188,26 +170,22 @@ final class TrackService extends Service /** * Devuelve los tracks de un cliente desde un tiempo y origen determinados * - * @param TrackRequest $trackRequest - * - * @return int * @throws ConstraintException * @throws QueryException */ - public function getTracksForClientFromTime(TrackRequest $trackRequest) + public function getTracksForClientFromTime(TrackRequest $trackRequest): int { - return $this->trackRepository->getTracksForClientFromTime($trackRequest)->getNumRows(); + return $this->trackRepository + ->getTracksForClientFromTime($trackRequest) + ->getNumRows(); } /** - * @param TrackRequest $trackRequest - * - * @return int * @throws ServiceException * @throws ConstraintException * @throws QueryException */ - public function add(TrackRequest $trackRequest) + public function add(TrackRequest $trackRequest): int { if ($trackRequest->getIpv4() === null && $trackRequest->getIpv6() === null @@ -217,7 +195,8 @@ final class TrackService extends Service $result = $this->trackRepository->add($trackRequest); - $this->eventDispatcher->notifyEvent('track.add', + $this->eventDispatcher->notifyEvent( + 'track.add', new Event($this, EventMessage::factory() ->addDescription($this->request->getClientAddress(true))) ); @@ -226,13 +205,10 @@ final class TrackService extends Service } /** - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->trackRepository->search($itemSearchData); } @@ -241,7 +217,7 @@ final class TrackService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->trackRepository = $this->dic->get(TrackRepository::class); $this->request = $this->dic->get(Request::class); diff --git a/lib/SP/Services/Upgrade/UpgradeAppService.php b/lib/SP/Services/Upgrade/UpgradeAppService.php index 9f47f337..87c33ac1 100644 --- a/lib/SP/Services/Upgrade/UpgradeAppService.php +++ b/lib/SP/Services/Upgrade/UpgradeAppService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,15 +19,16 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Upgrade; use Exception; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; +use SP\Core\Exceptions\SPException; use SP\Providers\Log\FileLogHandler; use SP\Services\Service; use SP\Storage\File\FileException; @@ -40,7 +41,7 @@ use SP\Util\VersionUtil; */ final class UpgradeAppService extends Service implements UpgradeInterface { - const UPGRADES = [ + private const UPGRADES = [ '300.18010101', '300.18072901', '300.18072902', @@ -48,26 +49,23 @@ final class UpgradeAppService extends Service implements UpgradeInterface '310.19042701' ]; - /** - * @param $version - * - * @return bool - */ - public static function needsUpgrade($version) + public static function needsUpgrade(string $version): bool { - return empty($version) || VersionUtil::checkVersion($version, self::UPGRADES); + return empty($version) + || VersionUtil::checkVersion($version, self::UPGRADES); } /** - * @param $version - * @param ConfigData $configData - * * @throws UpgradeException * @throws FileException */ - public function upgrade($version, ConfigData $configData) + public function upgrade( + string $version, + ConfigDataInterface $configData + ): void { - $this->eventDispatcher->notifyEvent('upgrade.app.start', + $this->eventDispatcher->notifyEvent( + 'upgrade.app.start', new Event($this, EventMessage::factory() ->addDescription(__u('Update Application'))) ); @@ -77,7 +75,7 @@ final class UpgradeAppService extends Service implements UpgradeInterface if ($this->applyUpgrade($appVersion) === false) { throw new UpgradeException( __u('Error while applying the application update'), - UpgradeException::CRITICAL, + SPException::CRITICAL, __u('Please, check the event log for more details') ); } @@ -90,7 +88,8 @@ final class UpgradeAppService extends Service implements UpgradeInterface } } - $this->eventDispatcher->notifyEvent('upgrade.app.end', + $this->eventDispatcher->notifyEvent( + 'upgrade.app.end', new Event($this, EventMessage::factory() ->addDescription(__u('Update Application'))) ); @@ -98,12 +97,8 @@ final class UpgradeAppService extends Service implements UpgradeInterface /** * Actualizaciones de la aplicación - * - * @param $version - * - * @return bool */ - private function applyUpgrade($version) + private function applyUpgrade(string $version): bool { try { switch ($version) { @@ -139,10 +134,7 @@ final class UpgradeAppService extends Service implements UpgradeInterface return false; } - /** - * initialize - */ - protected function initialize() + protected function initialize(): void { $this->eventDispatcher->attach($this->dic->get(FileLogHandler::class)); } diff --git a/lib/SP/Services/Upgrade/UpgradeAuthToken.php b/lib/SP/Services/Upgrade/UpgradeAuthToken.php index 3f9fa842..04866a2b 100644 --- a/lib/SP/Services/Upgrade/UpgradeAuthToken.php +++ b/lib/SP/Services/Upgrade/UpgradeAuthToken.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Upgrade; @@ -39,61 +39,61 @@ use SP\Services\Service; */ final class UpgradeAuthToken extends Service { - /** - * @var AuthTokenService - */ - private $authtokenService; + private ?AuthTokenService $authtokenService = null; /** * upgrade_300_18072901 * * @throws Exception */ - public function upgrade_300_18072901() + public function upgrade_300_18072901(): void { - $this->eventDispatcher->notifyEvent('upgrade.authToken.start', + $this->eventDispatcher->notifyEvent( + 'upgrade.authToken.start', new Event($this, EventMessage::factory() ->addDescription(__u('API authorizations update')) ->addDescription(__FUNCTION__)) ); try { - $this->transactionAware(function () { - foreach ($this->authtokenService->getAllBasic() as $item) { + $this->transactionAware( + function () { + foreach ($this->authtokenService->getAllBasic() as $item) { - $itemData = clone $item; - $itemData->setActionId($this->actionMapper($item->getActionId())); + $itemData = clone $item; + $itemData->setActionId($this->actionMapper($item->getActionId())); - $this->authtokenService->updateRaw($itemData); + $this->authtokenService->updateRaw($itemData); - $this->eventDispatcher->notifyEvent('upgrade.authToken.process', - new Event($this, EventMessage::factory() - ->addDescription(__u('Authorization updated')) - ->addDetail(__u('Authorization'), $item->getId())) - ); + $this->eventDispatcher->notifyEvent( + 'upgrade.authToken.process', + new Event($this, EventMessage::factory() + ->addDescription(__u('Authorization updated')) + ->addDetail(__u('Authorization'), $item->getId())) + ); + } } - }); + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); throw $e; } - $this->eventDispatcher->notifyEvent('upgrade.authToken.end', + $this->eventDispatcher->notifyEvent( + 'upgrade.authToken.end', new Event($this, EventMessage::factory() ->addDescription(__u('API authorizations update')) ->addDescription(__FUNCTION__)) ); } - /** - * @param int $moduleId - * - * @return int - */ - private function actionMapper(int $moduleId) + private function actionMapper(int $moduleId): int { switch ($moduleId) { case 1: @@ -145,7 +145,7 @@ final class UpgradeAuthToken extends Service return $moduleId; } - protected function initialize() + protected function initialize(): void { $this->authtokenService = $this->dic->get(AuthTokenService::class); } diff --git a/lib/SP/Services/Upgrade/UpgradeConfigService.php b/lib/SP/Services/Upgrade/UpgradeConfigService.php index 043dfe17..1369855f 100644 --- a/lib/SP/Services/Upgrade/UpgradeConfigService.php +++ b/lib/SP/Services/Upgrade/UpgradeConfigService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,13 +19,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Upgrade; use Exception; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\MimeTypes; @@ -45,7 +45,7 @@ final class UpgradeConfigService extends Service implements UpgradeInterface /** * @var array Versiones actualizables */ - const UPGRADES = [ + private const UPGRADES = [ '112.4', '130.16020501', '200.17011202', @@ -53,17 +53,9 @@ final class UpgradeConfigService extends Service implements UpgradeInterface '300.18112501', '320.20062801', ]; - /** - * @var ConfigData - */ - protected $configData; + protected ?ConfigDataInterface $configData = null; - /** - * @param $version - * - * @return bool - */ - public static function needsUpgrade($version) + public static function needsUpgrade(string $version): bool { return VersionUtil::checkVersion($version, self::UPGRADES); } @@ -71,17 +63,18 @@ final class UpgradeConfigService extends Service implements UpgradeInterface /** * Actualizar el archivo de configuración a formato XML * - * @param $version - * - * @throws UpgradeException + * @throws \SP\Services\Upgrade\UpgradeException */ - public function upgradeOldConfigFile($version) + public function upgradeOldConfigFile(string $version): void { $configData = $this->config->getConfigData(); $message = EventMessage::factory()->addDescription(__u('Update Configuration')); - $this->eventDispatcher->notifyEvent('upgrade.config.old.start', new Event($this, $message)); + $this->eventDispatcher->notifyEvent( + 'upgrade.config.old.start', + new Event($this, $message) + ); // Include the file, save the data from $CONFIG include OLD_CONFIG_FILE; @@ -89,7 +82,7 @@ final class UpgradeConfigService extends Service implements UpgradeInterface $message = EventMessage::factory(); if (isset($CONFIG) && is_array($CONFIG)) { - $paramMapper = function ($mapFrom, $mapTo) use ($CONFIG, $message, $configData) { + $paramMapper = static function ($mapFrom, $mapTo) use ($CONFIG, $message, $configData) { if (isset($CONFIG[$mapFrom])) { $message->addDetail(__u('Parameter'), $mapFrom); $configData->{$mapTo}($CONFIG[$mapFrom]); @@ -99,14 +92,11 @@ final class UpgradeConfigService extends Service implements UpgradeInterface foreach (self::getConfigParams() as $mapTo => $mapFrom) { if (method_exists($configData, $mapTo)) { if (is_array($mapFrom)) { - /** @var array $mapFrom */ foreach ($mapFrom as $param) { $paramMapper($mapFrom, $param); } - } else { - if (isset($CONFIG[$mapFrom])) { - $paramMapper($mapFrom, $mapTo); - } + } else if (isset($CONFIG[$mapFrom])) { + $paramMapper($mapFrom, $mapTo); } } } @@ -124,11 +114,15 @@ final class UpgradeConfigService extends Service implements UpgradeInterface $message->addDetail(__u('Version'), $version); - $this->eventDispatcher->notifyEvent('upgrade.config.old.end', new Event($this, $message)); + $this->eventDispatcher->notifyEvent( + 'upgrade.config.old.end', + new Event($this, $message) + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', + $this->eventDispatcher->notifyEvent( + 'exception', new Event($this, EventMessage::factory() ->addDescription(__u('Error while updating the configuration')) ->addDetail(__u('File'), $oldFile)) @@ -140,10 +134,8 @@ final class UpgradeConfigService extends Service implements UpgradeInterface /** * Devuelve array de métodos y parámetros de configuración - * - * @return array */ - private static function getConfigParams() + private static function getConfigParams(): array { return [ 'setAccountCount' => 'account_count', @@ -204,17 +196,18 @@ final class UpgradeConfigService extends Service implements UpgradeInterface /** * Migrar valores de configuración. * - * @param $version - * @param ConfigData $configData - * * @throws FileException */ - public function upgrade($version, ConfigData $configData) + public function upgrade(string $version, ConfigDataInterface $configData): void { $this->configData = $configData; - $message = EventMessage::factory()->addDescription(__u('Update Configuration')); - $this->eventDispatcher->notifyEvent('upgrade.config.start', new Event($this, $message)); + $message = EventMessage::factory() + ->addDescription(__u('Update Configuration')); + $this->eventDispatcher->notifyEvent( + 'upgrade.config.start', + new Event($this, $message) + ); foreach (self::UPGRADES as $upgradeVersion) { if (VersionUtil::checkVersion($version, $upgradeVersion)) { @@ -222,15 +215,13 @@ final class UpgradeConfigService extends Service implements UpgradeInterface } } - $this->eventDispatcher->notifyEvent('upgrade.config.end', new Event($this, $message)); + $this->eventDispatcher->notifyEvent( + 'upgrade.config.end', + new Event($this, $message) + ); } - /** - * @param $version - * - * @throws FileException - */ - private function applyUpgrade($version) + private function applyUpgrade(string $version): void { switch ($version) { case '200.17011202': @@ -249,18 +240,17 @@ final class UpgradeConfigService extends Service implements UpgradeInterface } /** - * @param $version - * - * @throws FileException + * @throws \SP\Storage\File\FileException */ - private function upgrade_200_17011202($version) + private function upgrade_200_17011202(string $version): void { $this->configData->setSiteTheme('material-blue'); $this->configData->setConfigVersion($version); $this->config->saveConfig($this->configData, false); - $this->eventDispatcher->notifyEvent('upgrade.config.process', + $this->eventDispatcher->notifyEvent( + 'upgrade.config.process', new Event($this, EventMessage::factory() ->addDescription(__u('Update Configuration')) ->addDetail(__u('Version'), $version)) @@ -268,13 +258,14 @@ final class UpgradeConfigService extends Service implements UpgradeInterface } /** - * @param $version - * * @throws FileException */ - private function upgrade_300_18111001($version) + private function upgrade_300_18111001(string $version): void { - $extensions = array_map('strtolower', $this->configData->getFilesAllowedExts()); + $extensions = array_map( + 'strtolower', + $this->configData->getFilesAllowedExts() + ); $mimeTypes = $this->dic->get(MimeTypes::class)->getMimeTypes(); $configMimeTypes = []; @@ -286,7 +277,8 @@ final class UpgradeConfigService extends Service implements UpgradeInterface $configMimeTypes[] = $mimeType['type']; $exists = true; - $this->eventDispatcher->notifyEvent('upgrade.config.process', + $this->eventDispatcher->notifyEvent( + 'upgrade.config.process', new Event($this, EventMessage::factory() ->addDescription(__u('MIME type set for this extension')) ->addDetail(__u('MIME type'), $mimeType['type']) @@ -296,7 +288,8 @@ final class UpgradeConfigService extends Service implements UpgradeInterface } if (!$exists) { - $this->eventDispatcher->notifyEvent('upgrade.config.process', + $this->eventDispatcher->notifyEvent( + 'upgrade.config.process', new Event($this, EventMessage::factory() ->addDescription(__u('MIME type not found for this extension')) ->addDetail(__u('Extension'), $extension)) @@ -309,7 +302,8 @@ final class UpgradeConfigService extends Service implements UpgradeInterface $this->config->saveConfig($this->configData, false); - $this->eventDispatcher->notifyEvent('upgrade.config.process', + $this->eventDispatcher->notifyEvent( + 'upgrade.config.process', new Event($this, EventMessage::factory() ->addDescription(__u('Update Configuration')) ->addDetail(__u('Version'), $version)) @@ -317,11 +311,9 @@ final class UpgradeConfigService extends Service implements UpgradeInterface } /** - * @param $version - * - * @throws FileException + * @throws \SP\Storage\File\FileException */ - private function upgrade_300_18112501($version) + private function upgrade_300_18112501(string $version): void { if ($this->configData->isLdapEnabled()) { if ($this->configData->get('ldapAds')) { @@ -334,7 +326,8 @@ final class UpgradeConfigService extends Service implements UpgradeInterface $this->config->saveConfig($this->configData, false); - $this->eventDispatcher->notifyEvent('upgrade.config.process', + $this->eventDispatcher->notifyEvent( + 'upgrade.config.process', new Event($this, EventMessage::factory() ->addDescription(__u('Update Configuration')) ->addDetail(__u('Version'), $version)) @@ -343,11 +336,9 @@ final class UpgradeConfigService extends Service implements UpgradeInterface } /** - * @param $version - * - * @throws FileException + * @throws \SP\Storage\File\FileException */ - private function upgrade_320_20062801($version) + private function upgrade_320_20062801(string $version): void { if ($this->configData->isLdapEnabled()) { if ($this->configData->get('ldapType') === LdapTypeInterface::LDAP_AZURE) { @@ -358,7 +349,8 @@ final class UpgradeConfigService extends Service implements UpgradeInterface $this->config->saveConfig($this->configData, false); - $this->eventDispatcher->notifyEvent('upgrade.config.process', + $this->eventDispatcher->notifyEvent( + 'upgrade.config.process', new Event($this, EventMessage::factory() ->addDescription(__u('Update Configuration')) ->addDetail(__u('Version'), $version)) @@ -366,10 +358,7 @@ final class UpgradeConfigService extends Service implements UpgradeInterface } } - /** - * initialize - */ - protected function initialize() + protected function initialize(): void { $this->eventDispatcher->attach($this->dic->get(FileLogHandler::class)); } diff --git a/lib/SP/Services/Upgrade/UpgradeCustomFieldData.php b/lib/SP/Services/Upgrade/UpgradeCustomFieldData.php index 28458fb5..4cfbedca 100644 --- a/lib/SP/Services/Upgrade/UpgradeCustomFieldData.php +++ b/lib/SP/Services/Upgrade/UpgradeCustomFieldData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Upgrade; @@ -41,19 +41,17 @@ use SP\Storage\Database\QueryData; */ final class UpgradeCustomFieldData extends Service { - /** - * @var Database - */ - private $db; + private ?Database $db = null; /** * upgrade_300_18072902 * * @throws Exception */ - public function upgrade_300_18072902() + public function upgrade_300_18072902(): void { - $this->eventDispatcher->notifyEvent('upgrade.customField.start', + $this->eventDispatcher->notifyEvent( + 'upgrade.customField.start', new Event($this, EventMessage::factory() ->addDescription(__u('Custom fields update')) ->addDescription(__FUNCTION__)) @@ -70,7 +68,8 @@ final class UpgradeCustomFieldData extends Service $this->db->doQuery($queryData); - $this->eventDispatcher->notifyEvent('upgrade.customField.process', + $this->eventDispatcher->notifyEvent( + 'upgrade.customField.process', new Event($this, EventMessage::factory() ->addDescription(__u('Field updated'))) ); @@ -79,24 +78,23 @@ final class UpgradeCustomFieldData extends Service } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); throw $e; } - $this->eventDispatcher->notifyEvent('upgrade.customField.end', + $this->eventDispatcher->notifyEvent( + 'upgrade.customField.end', new Event($this, EventMessage::factory() ->addDescription(__u('Custom fields update')) ->addDescription(__FUNCTION__)) ); } - /** - * @param int $moduleId - * - * @return int - */ - private function moduleMapper(int $moduleId) + private function moduleMapper(int $moduleId): int { switch ($moduleId) { case 10: @@ -114,7 +112,7 @@ final class UpgradeCustomFieldData extends Service return $moduleId; } - protected function initialize() + protected function initialize(): void { $this->db = $this->dic->get(Database::class); } diff --git a/lib/SP/Services/Upgrade/UpgradeCustomFieldDefinition.php b/lib/SP/Services/Upgrade/UpgradeCustomFieldDefinition.php index aa0f8be3..cbb3ff25 100644 --- a/lib/SP/Services/Upgrade/UpgradeCustomFieldDefinition.php +++ b/lib/SP/Services/Upgrade/UpgradeCustomFieldDefinition.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Upgrade; @@ -44,19 +44,17 @@ use SP\Util\Util; */ final class UpgradeCustomFieldDefinition extends Service { - /** - * @var Database - */ - private $db; + private ?Database $db = null; /** * upgrade_300_18010101 * * @throws Exception */ - public function upgrade_300_18010101() + public function upgrade_300_18010101(): void { - $this->eventDispatcher->notifyEvent('upgrade.customField.start', + $this->eventDispatcher->notifyEvent( + 'upgrade.customField.start', new Event($this, EventMessage::factory() ->addDescription(__u('Custom fields update')) ->addDescription(__FUNCTION__)) @@ -71,43 +69,54 @@ final class UpgradeCustomFieldDefinition extends Service $customFieldType[$customFieldTypeData->getName()] = $customFieldTypeData->getId(); } - $this->transactionAware(function () use ($customFieldType) { - $customFieldDefService = $this->dic->get(CustomFieldDefService::class); + $this->transactionAware( + function () use ($customFieldType) { + $customFieldDefService = $this->dic->get(CustomFieldDefService::class); - $queryData = new QueryData(); - $queryData->setQuery('SELECT id, moduleId, field FROM CustomFieldDefinition WHERE field IS NOT NULL'); + $queryData = new QueryData(); + $queryData->setQuery('SELECT id, moduleId, field FROM CustomFieldDefinition WHERE field IS NOT NULL'); - foreach ($this->db->doSelect($queryData)->getDataAsArray() as $item) { - /** @var CustomFieldDefDataOld $data */ - $data = Util::unserialize(CustomFieldDefDataOld::class, $item->field, 'SP\DataModel\CustomFieldDefData'); + foreach ($this->db->doSelect($queryData)->getDataAsArray() as $item) { + /** @var CustomFieldDefDataOld $data */ + $data = Util::unserialize( + CustomFieldDefDataOld::class, + $item->field, + 'SP\DataModel\CustomFieldDefData' + ); - $itemData = new CustomFieldDefinitionData(); - $itemData->setId($item->id); - $itemData->setModuleId($this->moduleMapper((int)$item->moduleId)); - $itemData->setName($data->getName()); - $itemData->setHelp($data->getHelp()); - $itemData->setRequired($data->isRequired()); - $itemData->setShowInList($data->isShowInItemsList()); - $itemData->setTypeId($customFieldType[$this->typeMapper((int)$data->getType())]); + $itemData = new CustomFieldDefinitionData(); + $itemData->setId($item->id); + $itemData->setModuleId($this->moduleMapper((int)$item->moduleId)); + $itemData->setName($data->getName()); + $itemData->setHelp($data->getHelp()); + $itemData->setRequired($data->isRequired()); + $itemData->setShowInList($data->isShowInItemsList()); + $itemData->setTypeId($customFieldType[$this->typeMapper((int)$data->getType())]); - $customFieldDefService->updateRaw($itemData); + $customFieldDefService->updateRaw($itemData); - $this->eventDispatcher->notifyEvent('upgrade.customField.process', - new Event($this, EventMessage::factory() - ->addDescription(__u('Field updated')) - ->addDetail(__u('Field'), $data->getName())) - ); + $this->eventDispatcher->notifyEvent( + 'upgrade.customField.process', + new Event($this, EventMessage::factory() + ->addDescription(__u('Field updated')) + ->addDetail(__u('Field'), $data->getName())) + ); + } } - }); + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); throw $e; } - $this->eventDispatcher->notifyEvent('upgrade.customField.end', + $this->eventDispatcher->notifyEvent( + 'upgrade.customField.end', new Event($this, EventMessage::factory() ->addDescription(__u('Custom fields update')) ->addDescription(__FUNCTION__)) @@ -119,7 +128,7 @@ final class UpgradeCustomFieldDefinition extends Service * * @return int */ - private function moduleMapper(int $moduleId) + private function moduleMapper(int $moduleId): int { switch ($moduleId) { case 10: @@ -142,7 +151,7 @@ final class UpgradeCustomFieldDefinition extends Service * * @return string */ - private function typeMapper(int $typeId) + private function typeMapper(int $typeId): string { $types = [ 1 => 'text', @@ -157,7 +166,7 @@ final class UpgradeCustomFieldDefinition extends Service 10 => 'textarea' ]; - return isset($types[$typeId]) ? $types[$typeId] : $types[1]; + return $types[$typeId] ?? $types[1]; } /** @@ -165,41 +174,49 @@ final class UpgradeCustomFieldDefinition extends Service * * @throws Exception */ - public function upgrade_300_18072901() + public function upgrade_300_18072901(): void { - $this->eventDispatcher->notifyEvent('upgrade.customField.start', + $this->eventDispatcher->notifyEvent( + 'upgrade.customField.start', new Event($this, EventMessage::factory() ->addDescription(__u('Custom fields update')) ->addDescription(__FUNCTION__)) ); try { - $this->transactionAware(function () { - $customFieldDefService = $this->dic->get(CustomFieldDefService::class); + $this->transactionAware( + function () { + $customFieldDefService = $this->dic->get(CustomFieldDefService::class); - foreach ($customFieldDefService->getAllBasic() as $item) { + foreach ($customFieldDefService->getAllBasic() as $item) { - $itemData = clone $item; - $itemData->setModuleId($this->moduleMapper((int)$item->getModuleId())); + $itemData = clone $item; + $itemData->setModuleId($this->moduleMapper((int)$item->getModuleId())); - $customFieldDefService->updateRaw($itemData); + $customFieldDefService->updateRaw($itemData); - $this->eventDispatcher->notifyEvent('upgrade.customField.process', - new Event($this, EventMessage::factory() - ->addDescription(__u('Field updated')) - ->addDetail(__u('Field'), $item->getName())) - ); + $this->eventDispatcher->notifyEvent( + 'upgrade.customField.process', + new Event($this, EventMessage::factory() + ->addDescription(__u('Field updated')) + ->addDetail(__u('Field'), $item->getName())) + ); + } } - }); + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); throw $e; } - $this->eventDispatcher->notifyEvent('upgrade.customField.end', + $this->eventDispatcher->notifyEvent( + 'upgrade.customField.end', new Event($this, EventMessage::factory() ->addDescription(__u('Custom fields update')) ->addDescription(__FUNCTION__)) @@ -211,13 +228,14 @@ final class UpgradeCustomFieldDefinition extends Service * * @throws Exception */ - public function upgrade_310_19042701() + public function upgrade_310_19042701(): void { - if (!in_array('field', $this->db->getColumnsForTable('CustomFieldDefinition'))) { + if (!in_array('field', $this->db->getColumnsForTable('CustomFieldDefinition'), true)) { return; } - $this->eventDispatcher->notifyEvent('upgrade.customField.start', + $this->eventDispatcher->notifyEvent( + 'upgrade.customField.start', new Event($this, EventMessage::factory() ->addDescription(__u('Custom fields update')) ->addDescription(__FUNCTION__)) @@ -232,45 +250,56 @@ final class UpgradeCustomFieldDefinition extends Service $customFieldType[$customFieldTypeData->getName()] = $customFieldTypeData->getId(); } - $this->transactionAware(function () use ($customFieldType) { - $queryData = new QueryData(); - $queryData->setQuery('SELECT id, field FROM CustomFieldDefinition WHERE field IS NOT NULL'); - - foreach ($this->db->doSelect($queryData)->getDataAsArray() as $item) { - /** @var CustomFieldDefDataOld $data */ - $data = Util::unserialize(CustomFieldDefDataOld::class, $item->field, 'SP\DataModel\CustomFieldDefData'); - - $typeId = $customFieldType[$this->typeMapper((int)$data->getType())]; - + $this->transactionAware( + function () use ($customFieldType) { $queryData = new QueryData(); - $queryData->setQuery('UPDATE CustomFieldDefinition SET typeId = ? WHERE id = ? LIMIT 1'); - $queryData->setParams([$typeId, $item->id]); + $queryData->setQuery('SELECT id, field FROM CustomFieldDefinition WHERE field IS NOT NULL'); - $this->db->doQuery($queryData); + foreach ($this->db->doSelect($queryData)->getDataAsArray() as $item) { + /** @var CustomFieldDefDataOld $data */ + $data = Util::unserialize( + CustomFieldDefDataOld::class, + $item->field, + 'SP\DataModel\CustomFieldDefData' + ); - $this->eventDispatcher->notifyEvent('upgrade.customField.process', - new Event($this, EventMessage::factory() - ->addDescription(__u('Field updated')) - ->addDetail(__u('Field'), $data->getName())) - ); + $typeId = $customFieldType[$this->typeMapper((int)$data->getType())]; + + $queryData = new QueryData(); + $queryData->setQuery('UPDATE CustomFieldDefinition SET typeId = ? WHERE id = ? LIMIT 1'); + $queryData->setParams([$typeId, $item->id]); + + $this->db->doQuery($queryData); + + $this->eventDispatcher->notifyEvent( + 'upgrade.customField.process', + new Event($this, EventMessage::factory() + ->addDescription(__u('Field updated')) + ->addDetail(__u('Field'), $data->getName())) + ); + } } - }); + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); throw $e; } - $this->eventDispatcher->notifyEvent('upgrade.customField.end', + $this->eventDispatcher->notifyEvent( + 'upgrade.customField.end', new Event($this, EventMessage::factory() ->addDescription(__u('Custom fields update')) ->addDescription(__FUNCTION__)) ); } - protected function initialize() + protected function initialize(): void { $this->db = $this->dic->get(Database::class); } diff --git a/lib/SP/Services/Upgrade/UpgradeDatabaseService.php b/lib/SP/Services/Upgrade/UpgradeDatabaseService.php index a15c23bc..a19dd2de 100644 --- a/lib/SP/Services/Upgrade/UpgradeDatabaseService.php +++ b/lib/SP/Services/Upgrade/UpgradeDatabaseService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,15 +19,16 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Upgrade; use Exception; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; +use SP\Core\Exceptions\SPException; use SP\Providers\Log\FileLogHandler; use SP\Services\Service; use SP\Storage\Database\Database; @@ -46,7 +47,7 @@ final class UpgradeDatabaseService extends Service implements UpgradeInterface /** * @var array Versiones actualizables */ - const UPGRADES = [ + private const UPGRADES = [ '300.18010101', '300.18072302', '300.18072501', @@ -61,46 +62,37 @@ final class UpgradeDatabaseService extends Service implements UpgradeInterface '310.19042701' ]; - /** - * @var Database - */ - protected $db; + protected ?Database $db = null; /** * Check if it needs to be upgraded - * - * @param $version - * - * @return bool */ - public static function needsUpgrade($version) + public static function needsUpgrade(string $version): bool { - return empty($version) || VersionUtil::checkVersion($version, self::UPGRADES); + return empty($version) + || VersionUtil::checkVersion($version, self::UPGRADES); } /** * Inicia el proceso de actualización de la BBDD. * - * @param int $version con la versión de la BBDD actual - * @param ConfigData $configData - * - * @return bool * @throws FileException * @throws UpgradeException */ - public function upgrade($version, ConfigData $configData) + public function upgrade(string $version, ConfigDataInterface $configData): bool { - $this->eventDispatcher->notifyEvent('upgrade.db.start', + $this->eventDispatcher->notifyEvent( + 'upgrade.db.start', new Event($this, EventMessage::factory() ->addDescription(__u('Update DB'))) ); foreach (self::UPGRADES as $upgradeVersion) { if (VersionUtil::checkVersion($version, $upgradeVersion)) { - if ($this->applyPreUpgrade($upgradeVersion) === false) { + if ($this->applyPreUpgrade() === false) { throw new UpgradeException( __u('Error while applying an auxiliary update'), - UpgradeException::CRITICAL, + SPException::CRITICAL, __u('Please, check the event log for more details') ); } @@ -108,7 +100,7 @@ final class UpgradeDatabaseService extends Service implements UpgradeInterface if ($this->applyUpgrade($upgradeVersion) === false) { throw new UpgradeException( __u('Error while updating the database'), - UpgradeException::CRITICAL, + SPException::CRITICAL, __u('Please, check the event log for more details') ); } @@ -121,7 +113,8 @@ final class UpgradeDatabaseService extends Service implements UpgradeInterface } } - $this->eventDispatcher->notifyEvent('upgrade.db.end', + $this->eventDispatcher->notifyEvent( + 'upgrade.db.end', new Event($this, EventMessage::factory() ->addDescription(__u('Update DB'))) ); @@ -131,12 +124,8 @@ final class UpgradeDatabaseService extends Service implements UpgradeInterface /** * Aplicar actualizaciones auxiliares antes de actualizar la BBDD - * - * @param $version - * - * @return bool */ - private function applyPreUpgrade($version) + private function applyPreUpgrade(): bool { return true; } @@ -144,25 +133,26 @@ final class UpgradeDatabaseService extends Service implements UpgradeInterface /** * Actualiza la BBDD según la versión. * - * @param int $version con la versión a actualizar - * - * @returns bool - * @return bool - * @throws UpgradeException + * @throws \SP\Services\Upgrade\UpgradeException */ - private function applyUpgrade($version) + private function applyUpgrade(string $version): bool { $queries = $this->getQueriesFromFile($version); if (count($queries) === 0) { logger(__('Update file does not contain data'), 'ERROR'); - throw new UpgradeException(__u('Update file does not contain data'), UpgradeException::ERROR, $version); + throw new UpgradeException( + __u('Update file does not contain data'), + SPException::ERROR, + $version + ); } foreach ($queries as $query) { try { - $this->eventDispatcher->notifyEvent('upgrade.db.process', + $this->eventDispatcher->notifyEvent( + 'upgrade.db.process', new Event($this, EventMessage::factory() ->addDetail(__u('Version'), $version)) ); @@ -176,7 +166,8 @@ final class UpgradeDatabaseService extends Service implements UpgradeInterface logger('SQL: ' . $query); - $this->eventDispatcher->notifyEvent('exception', + $this->eventDispatcher->notifyEvent( + 'exception', new Event($this, EventMessage::factory() ->addDescription(__u('Error while updating the database')) ->addDetail('ERROR', sprintf('%s (%s)', $e->getMessage(), $e->getCode()))) @@ -186,7 +177,8 @@ final class UpgradeDatabaseService extends Service implements UpgradeInterface } } - $this->eventDispatcher->notifyEvent('upgrade.db.process', + $this->eventDispatcher->notifyEvent( + 'upgrade.db.process', new Event($this, EventMessage::factory() ->addDescription(__u('Database updating was completed successfully.'))) ); @@ -197,14 +189,14 @@ final class UpgradeDatabaseService extends Service implements UpgradeInterface /** * Obtener las consultas de actualización desde un archivo * - * @param $filename - * - * @return array|bool * @throws UpgradeException */ - private function getQueriesFromFile($filename) + private function getQueriesFromFile(string $filename): array { - $fileName = SQL_PATH . DIRECTORY_SEPARATOR . str_replace('.', '', $filename) . '.sql'; + $fileName = SQL_PATH . + DIRECTORY_SEPARATOR . + str_replace('.', '', $filename) . + '.sql'; try { $parser = new MySQLFileParser(new FileHandler($fileName)); @@ -217,10 +209,7 @@ final class UpgradeDatabaseService extends Service implements UpgradeInterface } } - /** - * initialize - */ - protected function initialize() + protected function initialize(): void { $this->eventDispatcher->attach($this->dic->get(FileLogHandler::class)); diff --git a/lib/SP/Services/Upgrade/UpgradeException.php b/lib/SP/Services/Upgrade/UpgradeException.php index 983fa7ec..90d3613f 100644 --- a/lib/SP/Services/Upgrade/UpgradeException.php +++ b/lib/SP/Services/Upgrade/UpgradeException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Upgrade; diff --git a/lib/SP/Services/Upgrade/UpgradeInterface.php b/lib/SP/Services/Upgrade/UpgradeInterface.php index 3a692ef5..b24072e2 100644 --- a/lib/SP/Services/Upgrade/UpgradeInterface.php +++ b/lib/SP/Services/Upgrade/UpgradeInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Upgrade; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; /** * Interface UpgradeInterface @@ -34,19 +34,12 @@ use SP\Config\ConfigData; interface UpgradeInterface { /** - * Performs the upgrading process - * - * @param $version - * @param ConfigData $configData + * Check if it needs to be upgraded */ - public function upgrade($version, ConfigData $configData); + public static function needsUpgrade(string $version): bool; /** - * Check if it needs to be upgraded - * - * @param $version - * - * @return bool + * Performs the upgrading process */ - public static function needsUpgrade($version); + public function upgrade(string $version, ConfigDataInterface $configData); } \ No newline at end of file diff --git a/lib/SP/Services/Upgrade/UpgradePlugin.php b/lib/SP/Services/Upgrade/UpgradePlugin.php index bddd38d6..65d8fe68 100644 --- a/lib/SP/Services/Upgrade/UpgradePlugin.php +++ b/lib/SP/Services/Upgrade/UpgradePlugin.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Upgrade; @@ -42,9 +42,10 @@ final class UpgradePlugin extends Service * * @throws Exception */ - public function upgrade_310_19012201() + public function upgrade_310_19012201(): void { - $this->eventDispatcher->notifyEvent('upgrade.plugin.start', + $this->eventDispatcher->notifyEvent( + 'upgrade.plugin.start', new Event($this, EventMessage::factory() ->addDescription(__u('Plugins upgrade')) ->addDescription(__FUNCTION__)) @@ -53,7 +54,8 @@ final class UpgradePlugin extends Service $this->dic->get(PluginManager::class) ->upgradePlugins('310.19012201'); - $this->eventDispatcher->notifyEvent('upgrade.plugin.end', + $this->eventDispatcher->notifyEvent( + 'upgrade.plugin.end', new Event($this, EventMessage::factory() ->addDescription(__u('Plugins upgrade')) ->addDescription(__FUNCTION__)) diff --git a/lib/SP/Services/Upgrade/UpgradePublicLink.php b/lib/SP/Services/Upgrade/UpgradePublicLink.php index b957c37c..9c693e03 100644 --- a/lib/SP/Services/Upgrade/UpgradePublicLink.php +++ b/lib/SP/Services/Upgrade/UpgradePublicLink.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Upgrade; @@ -42,70 +42,79 @@ use SP\Util\Util; */ final class UpgradePublicLink extends Service { - /** - * @var Database - */ - private $db; + private ?Database $db = null; /** * upgrade_300_18010101 */ - public function upgrade_300_18010101() + public function upgrade_300_18010101(): void { - $this->eventDispatcher->notifyEvent('upgrade.publicLink.start', + $this->eventDispatcher->notifyEvent( + 'upgrade.publicLink.start', new Event($this, EventMessage::factory() ->addDescription(__u('Public links update')) ->addDescription(__FUNCTION__)) ); try { - $this->transactionAware(function () { - $publicLinkService = $this->dic->get(PublicLinkService::class); + $this->transactionAware( + function () { + $publicLinkService = $this->dic->get(PublicLinkService::class); - $queryData = new QueryData(); - $queryData->setQuery('SELECT id, `data` FROM PublicLink'); + $queryData = new QueryData(); + $queryData->setQuery('SELECT id, `data` FROM PublicLink'); - foreach ($this->db->doSelect($queryData)->getDataAsArray() as $item) { - /** @var PublickLinkOldData $data */ - $data = Util::unserialize(PublickLinkOldData::class, $item->data, 'SP\DataModel\PublicLinkData'); + foreach ($this->db->doSelect($queryData)->getDataAsArray() as $item) { + /** @var PublickLinkOldData $data */ + $data = Util::unserialize( + PublickLinkOldData::class, + $item->data, + PublicLinkData::class + ); - $itemData = new PublicLinkData(); - $itemData->setId($item->id); - $itemData->setItemId($data->getItemId()); - $itemData->setHash($data->getLinkHash()); - $itemData->setUserId($data->getUserId()); - $itemData->setTypeId($data->getTypeId()); - $itemData->setNotify($data->isNotify()); - $itemData->setDateAdd($data->getDateAdd()); - $itemData->setDateExpire($data->getDateExpire()); - $itemData->setCountViews($data->getCountViews()); - $itemData->setMaxCountViews($data->getCountViews()); - $itemData->setUseInfo($data->getUseInfo()); - $itemData->setData($data->getData()); + $itemData = new PublicLinkData(); + $itemData->setId($item->id); + $itemData->setItemId($data->getItemId()); + $itemData->setHash($data->getLinkHash()); + $itemData->setUserId($data->getUserId()); + $itemData->setTypeId($data->getTypeId()); + $itemData->setNotify($data->isNotify()); + $itemData->setDateAdd($data->getDateAdd()); + $itemData->setDateExpire($data->getDateExpire()); + $itemData->setCountViews($data->getCountViews()); + $itemData->setMaxCountViews($data->getCountViews()); + $itemData->setUseInfo($data->getUseInfo()); + $itemData->setData($data->getData()); - $publicLinkService->update($itemData); + $publicLinkService->update($itemData); - $this->eventDispatcher->notifyEvent('upgrade.publicLink.process', - new Event($this, EventMessage::factory() - ->addDescription(__u('Link updated')) - ->addDetail(__u('Link'), $item->id)) - ); + $this->eventDispatcher->notifyEvent( + 'upgrade.publicLink.process', + new Event($this, EventMessage::factory() + ->addDescription(__u('Link updated')) + ->addDetail(__u('Link'), $item->id)) + ); + } } - }); + ); } catch (Exception $e) { processException($e); - $this->eventDispatcher->notifyEvent('exception', new Event($e)); + $this->eventDispatcher->notifyEvent( + 'exception', + new Event($e) + ); } - $this->eventDispatcher->notifyEvent('upgrade.publicLink.end', + $this->eventDispatcher->notifyEvent( + 'upgrade.publicLink.end', new Event($this, EventMessage::factory() ->addDescription(__u('Public links update')) ->addDescription(__FUNCTION__)) ); } - protected function initialize() + protected function initialize(): void { $this->db = $this->dic->get(Database::class); } diff --git a/lib/SP/Services/Upgrade/UpgradeUtil.php b/lib/SP/Services/Upgrade/UpgradeUtil.php index db827332..681ee8e7 100644 --- a/lib/SP/Services/Upgrade/UpgradeUtil.php +++ b/lib/SP/Services/Upgrade/UpgradeUtil.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,18 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\Upgrade; -use Defuse\Crypto\Exception\EnvironmentIsBrokenException; -use DI\DependencyException; -use DI\NotFoundException; use SP\Config\Config; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Storage\File\FileException; -use SP\Util\PasswordUtil; use SP\Util\VersionUtil; /** @@ -42,12 +38,8 @@ final class UpgradeUtil { /** * Normalizar un número de versión - * - * @param $version - * - * @return string */ - public static function fixVersionNumber($version) + public static function fixVersionNumber(string $version): string { if (strpos($version, '.') === false) { if (strlen($version) === 10) { @@ -61,35 +53,12 @@ final class UpgradeUtil } /** - * Establecer la key de actualización - * - * @param Config $config - * - * @throws DependencyException - * @throws NotFoundException - * @throws EnvironmentIsBrokenException * @throws FileException */ - public static function setUpgradeKey(Config $config) - { - $configData = $config->getConfigData(); - $upgradeKey = $configData->getUpgradeKey(); - - if (empty($upgradeKey)) { - $configData->setUpgradeKey(PasswordUtil::generateRandomBytes(32)); - } - - $configData->setMaintenance(true); - $config->saveConfig($configData, false); - } - - /** - * @param ConfigData $configData - * @param Config $config - * - * @throws FileException - */ - public static function fixAppUpgrade(ConfigData $configData, Config $config) + public static function fixAppUpgrade( + ConfigDataInterface $configData, + Config $config + ): void { // Fixes bug in 3.0.X version where some updates weren't applied // when upgrading from v2 diff --git a/lib/SP/Services/User/UpdatePassRequest.php b/lib/SP/Services/User/UpdatePassRequest.php index 7d8eb255..35e93bcf 100644 --- a/lib/SP/Services/User/UpdatePassRequest.php +++ b/lib/SP/Services/User/UpdatePassRequest.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\User; @@ -31,65 +31,36 @@ namespace SP\Services\User; */ final class UpdatePassRequest { - /** - * @var string - */ - private $pass; - /** - * @var int - */ - private $isChangePass = 0; - /** - * @var int - */ - private $isChangedPass = 0; + private string $pass; + private bool $isChangePass = false; + private bool $isChangedPass = false; - /** - * UpdatePassRequest constructor. - * - * @param string $pass - */ - public function __construct($pass) + public function __construct(string $pass) { $this->pass = $pass; } - /** - * @return string - */ - public function getPass() + public function getPass(): string { return $this->pass; } - /** - * @return int - */ - public function getisChangePass() + public function getisChangePass(): bool { return $this->isChangePass; } - /** - * @param int $isChangePass - */ - public function setIsChangePass($isChangePass) + public function setIsChangePass(bool $isChangePass): void { $this->isChangePass = $isChangePass; } - /** - * @return int - */ - public function getisChangedPass() + public function getisChangedPass(): bool { return $this->isChangedPass; } - /** - * @param int $isChangedPass - */ - public function setIsChangedPass($isChangedPass) + public function setIsChangedPass(bool $isChangedPass): void { $this->isChangedPass = $isChangedPass; } diff --git a/lib/SP/Services/User/UpdatedMasterPassException.php b/lib/SP/Services/User/UpdatedMasterPassException.php index 4c40e191..ec9177f3 100644 --- a/lib/SP/Services/User/UpdatedMasterPassException.php +++ b/lib/SP/Services/User/UpdatedMasterPassException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\User; @@ -37,13 +37,19 @@ final class UpdatedMasterPassException extends SPException /** * SPException constructor. * - * @param string $type - * @param int $code - * @param Exception $previous + * @param string $type + * @param int $code + * @param \Exception|null $previous */ - public function __construct($type, $code = 0, Exception $previous = null) + public function __construct(string $type, int $code = 0, Exception $previous = null) { - parent::__construct(__u('Master password updated'), $type, __u('Please, restart the session for update it'), $code, $previous); + parent::__construct( + __u('Master password updated'), + $type, + __u('Please, restart the session for update it'), + $code, + $previous + ); } } \ No newline at end of file diff --git a/lib/SP/Services/User/UserLoginRequest.php b/lib/SP/Services/User/UserLoginRequest.php index 87a44b01..5a1d456f 100644 --- a/lib/SP/Services/User/UserLoginRequest.php +++ b/lib/SP/Services/User/UserLoginRequest.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\User; @@ -31,103 +31,58 @@ namespace SP\Services\User; */ final class UserLoginRequest { - /** - * @var string - */ - private $login; - /** - * @var string - */ - private $name; - /** - * @var string - */ - private $password; - /** - * @var string - */ - private $email; - /** - * @var int - */ - private $isLdap; + private ?string $login = null; + private ?string $name = null; + private ?string $password = null; + private ?string $email = null; + private ?bool $isLdap = null; - /** - * @return string - */ - public function getLogin() + public function getLogin(): ?string { return $this->login; } - /** - * @param string $login - */ - public function setLogin($login) + public function setLogin(string $login): void { $this->login = $login; } - /** - * @return string - */ - public function getName() + public function getName(): ?string { return $this->name; } - /** - * @param string $name - */ - public function setName($name) + public function setName(string $name): void { $this->name = $name; } - /** - * @return string - */ - public function getPassword() + public function getPassword(): ?string { return $this->password; } - /** - * @param string $password - */ - public function setPassword($password) + public function setPassword(string $password): void { $this->password = $password; } - /** - * @return string - */ - public function getEmail() + public function getEmail(): ?string { return $this->email; } - /** - * @param string $email - */ - public function setEmail($email) + public function setEmail(string $email): void { $this->email = $email; } - /** - * @return int - */ - public function getisLdap() + public function getisLdap(): ?bool { return $this->isLdap; } - /** - * @param int $isLdap - */ - public function setIsLdap($isLdap) + public function setIsLdap(bool $isLdap): void { $this->isLdap = $isLdap; } diff --git a/lib/SP/Services/User/UserLoginResponse.php b/lib/SP/Services/User/UserLoginResponse.php index 4e2f6bd2..6acfa831 100644 --- a/lib/SP/Services/User/UserLoginResponse.php +++ b/lib/SP/Services/User/UserLoginResponse.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\User; @@ -33,531 +33,267 @@ use SP\DataModel\UserPreferencesData; */ final class UserLoginResponse { - /** - * @var int - */ - private $id; - /** - * @var string - */ - private $login; - /** - * @var string - */ - private $ssoLogin; - /** - * @var string - */ - private $name; - /** - * @var string - */ - private $email; - /** - * @var int - */ - private $userGroupId = 0; - /** - * @var string - */ - private $userGroupName; - /** - * @var int - */ - private $userProfileId = 0; - /** - * @var string - */ - private $userProfileName; - /** - * @var int - */ - private $isAdminApp = 0; - /** - * @var int - */ - private $isAdminAcc = 0; - /** - * @var int - */ - private $isDisabled = 0; - /** - * @var int - */ - private $isChangePass = 0; - /** - * @var int - */ - private $isChangedPass = 0; - /** - * @var int - */ - private $isLdap = 0; - /** - * @var int - */ - private $isMigrate = 0; - /** - * @var UserPreferencesData - */ - private $preferences; - /** - * @var string - */ - private $pass; - /** - * @var string - */ - private $hashSalt; - /** - * @var string - */ - private $mPass; - /** - * @var string - */ - private $mKey; - /** - * @var int - */ - private $lastUpdateMPass = 0; - /** - * @var int - */ - private $lastUpdate; + private ?int $id = null; + private ?string $login = null; + private ?string $ssoLogin = null; + private ?string $name = null; + private ?string $email = null; + private int $userGroupId = 0; + private ?string $userGroupName = null; + private int $userProfileId = 0; + private bool $isAdminApp = false; + private bool $isAdminAcc = false; + private bool $isDisabled = false; + private bool $isChangePass = false; + private bool $isChangedPass = false; + private bool $isLdap = false; + private bool $isMigrate = false; + private ?UserPreferencesData $preferences = null; + private ?string $pass = null; + private ?string $hashSalt = null; + private ?string $mPass = null; + private ?string $mKey = null; + private int $lastUpdateMPass = 0; + private ?int $lastUpdate = null; - /** - * @return string - */ - public function getLogin() + public function getLogin(): ?string { return $this->login; } - /** - * @param string $login - * - * @return UserLoginResponse - */ - public function setLogin($login) + public function setLogin(string $login): UserLoginResponse { $this->login = $login; return $this; } - /** - * @return string - */ - public function getSsoLogin() + public function getSsoLogin(): ?string { return $this->ssoLogin; } - /** - * @param string $ssoLogin - * - * @return UserLoginResponse - */ - public function setSsoLogin($ssoLogin) + public function setSsoLogin(?string $ssoLogin): UserLoginResponse { $this->ssoLogin = $ssoLogin; return $this; } - /** - * @return string - */ - public function getName() + public function getName(): ?string { return $this->name; } - /** - * @param string $name - * - * @return UserLoginResponse - */ - public function setName($name) + public function setName(string $name): UserLoginResponse { $this->name = $name; return $this; } - /** - * @return string - */ - public function getEmail() + public function getEmail(): ?string { return $this->email; } - /** - * @param string $email - * - * @return UserLoginResponse - */ - public function setEmail($email) + public function setEmail(?string $email): UserLoginResponse { $this->email = $email; return $this; } - /** - * @return int - */ - public function getUserGroupId() + public function getUserGroupId(): int { return $this->userGroupId; } - /** - * @param int $userGroupId - * - * @return UserLoginResponse - */ - public function setUserGroupId($userGroupId) + public function setUserGroupId(int $userGroupId): UserLoginResponse { - $this->userGroupId = (int)$userGroupId; + $this->userGroupId = $userGroupId; return $this; } - /** - * @return int - */ - public function getUserProfileId() + public function getUserProfileId(): int { return $this->userProfileId; } - /** - * @param int $userProfileId - * - * @return UserLoginResponse - */ - public function setUserProfileId($userProfileId) + public function setUserProfileId(int $userProfileId): UserLoginResponse { - $this->userProfileId = (int)$userProfileId; + $this->userProfileId = $userProfileId; return $this; } - /** - * @return int - */ - public function getIsAdminApp() + public function getIsAdminApp(): bool { return $this->isAdminApp; } - /** - * @param int $isAdminApp - * - * @return UserLoginResponse - */ - public function setIsAdminApp($isAdminApp) + public function setIsAdminApp(bool $isAdminApp): UserLoginResponse { - $this->isAdminApp = (int)$isAdminApp; + $this->isAdminApp = $isAdminApp; return $this; } - /** - * @return int - */ - public function getIsAdminAcc() + public function getIsAdminAcc(): bool { return $this->isAdminAcc; } - /** - * @param int $isAdminAcc - * - * @return UserLoginResponse - */ - public function setIsAdminAcc($isAdminAcc) + public function setIsAdminAcc(bool $isAdminAcc): UserLoginResponse { - $this->isAdminAcc = (int)$isAdminAcc; + $this->isAdminAcc = $isAdminAcc; return $this; } - /** - * @return int - */ - public function getIsDisabled() + public function getIsDisabled(): bool { return $this->isDisabled; } - /** - * @param int $isDisabled - * - * @return UserLoginResponse - */ - public function setIsDisabled($isDisabled) + public function setIsDisabled(bool $isDisabled): UserLoginResponse { - $this->isDisabled = (int)$isDisabled; + $this->isDisabled = $isDisabled; return $this; } - /** - * @return int - */ - public function getIsChangePass() + public function getIsChangePass(): bool { return $this->isChangePass; } - /** - * @param int $isChangePass - * - * @return UserLoginResponse - */ - public function setIsChangePass($isChangePass) + public function setIsChangePass(bool $isChangePass): UserLoginResponse { - $this->isChangePass = (int)$isChangePass; + $this->isChangePass = $isChangePass; return $this; } - /** - * @return int - */ - public function getIsChangedPass() + public function getIsChangedPass(): bool { return $this->isChangedPass; } - /** - * @param int $isChangedPass - * - * @return UserLoginResponse - */ - public function setIsChangedPass($isChangedPass) + public function setIsChangedPass(bool $isChangedPass): UserLoginResponse { - $this->isChangedPass = (int)$isChangedPass; + $this->isChangedPass = $isChangedPass; return $this; } - /** - * @return int - */ - public function getIsLdap() + public function getIsLdap(): bool { return $this->isLdap; } - /** - * @param int $isLdap - * - * @return UserLoginResponse - */ - public function setIsLdap($isLdap) + public function setIsLdap(bool $isLdap): UserLoginResponse { - $this->isLdap = (int)$isLdap; + $this->isLdap = $isLdap; return $this; } - /** - * @return int - */ - public function getIsMigrate() + public function getIsMigrate(): bool { return $this->isMigrate; } - /** - * @param int $isMigrate - * - * @return UserLoginResponse - */ - public function setIsMigrate($isMigrate) + public function setIsMigrate(bool $isMigrate): UserLoginResponse { - $this->isMigrate = (int)$isMigrate; + $this->isMigrate = $isMigrate; return $this; } - /** - * @return UserPreferencesData - */ - public function getPreferences() + public function getPreferences(): ?UserPreferencesData { return $this->preferences; } - /** - * @param mixed $preferences - * - * @return UserLoginResponse - */ - public function setPreferences(UserPreferencesData $preferences) + public function setPreferences(UserPreferencesData $preferences): UserLoginResponse { $this->preferences = $preferences; return $this; } - /** - * @return string - */ - public function getPass() + public function getPass(): ?string { return $this->pass; } - /** - * @param string $pass - * - * @return UserLoginResponse - */ - public function setPass($pass) + public function setPass(string $pass): UserLoginResponse { $this->pass = $pass; return $this; } - /** - * @return string - */ - public function getMPass() + public function getMPass(): ?string { return $this->mPass; } - /** - * @param string $mPass - * - * @return UserLoginResponse - */ - public function setMPass($mPass) + public function setMPass(string $mPass): UserLoginResponse { $this->mPass = $mPass; return $this; } - /** - * @return string - */ - public function getMKey() + public function getMKey(): ?string { return $this->mKey; } - /** - * @param string $mKey - * - * @return UserLoginResponse - */ - public function setMKey($mKey) + public function setMKey(string $mKey): UserLoginResponse { $this->mKey = $mKey; return $this; } - /** - * @return int - */ - public function getLastUpdateMPass() + public function getLastUpdateMPass(): int { return $this->lastUpdateMPass; } - /** - * @param int $lastUpdateMPass - * - * @return UserLoginResponse - */ - public function setLastUpdateMPass($lastUpdateMPass) + public function setLastUpdateMPass(int $lastUpdateMPass): UserLoginResponse { - $this->lastUpdateMPass = (int)$lastUpdateMPass; + $this->lastUpdateMPass = $lastUpdateMPass; return $this; } - /** - * @return string - */ - public function getHashSalt() + public function getHashSalt(): ?string { return $this->hashSalt; } - /** - * @param string $hashSalt - * - * @return UserLoginResponse - */ - public function setHashSalt($hashSalt) + public function setHashSalt(string $hashSalt): UserLoginResponse { $this->hashSalt = $hashSalt; return $this; } - /** - * @return int - */ - public function getId() + public function getId(): ?int { return $this->id; } - /** - * @param int $id - * - * @return UserLoginResponse - */ - public function setId($id) + public function setId(int $id): UserLoginResponse { - $this->id = (int)$id; + $this->id = $id; return $this; } - /** - * @return string - */ - public function getUserGroupName() + public function getUserGroupName(): ?string { return $this->userGroupName; } - /** - * @param string $userGroupName - * - * @return UserLoginResponse - */ - public function setUserGroupName($userGroupName) + public function setUserGroupName(string $userGroupName): UserLoginResponse { $this->userGroupName = $userGroupName; return $this; } - /** - * @return string - */ - public function getUserProfileName() - { - return $this->userProfileName; - } - /** - * @param string $userProfileName - * - * @return UserLoginResponse - */ - public function setUserProfileName($userProfileName) - { - $this->userProfileName = $userProfileName; - return $this; - } - - /** - * @return int - */ public function getLastUpdate(): int { return $this->lastUpdate; } - /** - * @param int $lastUpdate - * - * @return UserLoginResponse - */ - public function setLastUpdate(int $lastUpdate) + public function setLastUpdate(int $lastUpdate): UserLoginResponse { $this->lastUpdate = $lastUpdate; diff --git a/lib/SP/Services/User/UserPassResponse.php b/lib/SP/Services/User/UserPassResponse.php index 0f6ce843..1b77327d 100644 --- a/lib/SP/Services/User/UserPassResponse.php +++ b/lib/SP/Services/User/UserPassResponse.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\User; @@ -31,96 +31,52 @@ namespace SP\Services\User; */ final class UserPassResponse { - /** - * @var int - */ - private $status; - /** - * @var string - */ - private $cryptMasterPass; - /** - * @var string - */ - private $cryptSecuredKey; - /** - * @var string - */ - private $clearMasterPass; + private int $status; + private ?string $cryptMasterPass = null; + private ?string $cryptSecuredKey = null; + private ?string $clearMasterPass = null; /** * UserPassResponse constructor. - * - * @param int $status - * @param string $clearUserMPass */ - public function __construct($status, $clearUserMPass = null) + public function __construct(int $status, ?string $clearUserMPass = null) { $this->status = $status; $this->clearMasterPass = $clearUserMPass; } - /** - * @return int - */ - public function getStatus() + public function getStatus(): int { return $this->status; } - /** - * @param int $status - */ - public function setStatus($status) + public function setStatus(int $status): void { $this->status = $status; } - /** - * @return string - */ - public function getCryptMasterPass() + public function getCryptMasterPass(): ?string { return $this->cryptMasterPass; } - /** - * @param string $cryptMasterPass - */ - public function setCryptMasterPass($cryptMasterPass) + public function setCryptMasterPass(string $cryptMasterPass): void { $this->cryptMasterPass = $cryptMasterPass; } - /** - * @return string - */ - public function getCryptSecuredKey() + public function getCryptSecuredKey(): ?string { return $this->cryptSecuredKey; } - /** - * @param string $cryptSecuredKey - */ - public function setCryptSecuredKey($cryptSecuredKey) + public function setCryptSecuredKey(string $cryptSecuredKey): void { $this->cryptSecuredKey = $cryptSecuredKey; } - /** - * @return string - */ - public function getClearMasterPass() + public function getClearMasterPass(): ?string { return $this->clearMasterPass; } - - /** - * @param string $clearMasterPass - */ - public function setClearMasterPass($clearMasterPass) - { - $this->clearMasterPass = $clearMasterPass; - } } \ No newline at end of file diff --git a/lib/SP/Services/User/UserPassService.php b/lib/SP/Services/User/UserPassService.php index 6fd33172..2ec92c13 100644 --- a/lib/SP/Services/User/UserPassService.php +++ b/lib/SP/Services/User/UserPassService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\User; @@ -28,7 +28,7 @@ use Defuse\Crypto\Exception\CryptoException; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Config\Config; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Crypt\Crypt; use SP\Core\Crypt\Hash; use SP\Core\Exceptions\ConstraintException; @@ -48,47 +48,40 @@ use SP\Services\Service; final class UserPassService extends Service { // La clave maestra incorrecta - const MPASS_WRONG = 0; + public const MPASS_WRONG = 0; // La clave maestra correcta - const MPASS_OK = 1; + public const MPASS_OK = 1; // La clave maestra no está guardada - const MPASS_NOTSET = 2; + public const MPASS_NOTSET = 2; // La clave maestra ha cambiado - const MPASS_CHANGED = 3; + public const MPASS_CHANGED = 3; // Comprobar la clave maestra con la clave del usuario anterior - const MPASS_CHECKOLD = 4; + public const MPASS_CHECKOLD = 4; - /** - * @var ConfigData - */ - protected $configData; - /** - * @var UserRepository - */ - protected $userRepository; - /** - * @var ConfigService - */ - protected $configService; + protected ?ConfigDataInterface $configData = null; + protected ?UserRepository $userRepository = null; + protected ?ConfigService $configService = null; /** * Actualizar la clave maestra con la clave anterior del usuario * - * @param string $oldUserPass - * @param UserLoginData $userLoginData $UserData - * - * @return UserPassResponse * @throws SPException * @throws CryptoException * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - public function updateMasterPassFromOldPass($oldUserPass, UserLoginData $userLoginData) + public function updateMasterPassFromOldPass( + string $oldUserPass, + UserLoginData $userLoginData + ): UserPassResponse { $response = $this->loadUserMPass($userLoginData, $oldUserPass); if ($response->getStatus() === self::MPASS_OK) { - return $this->updateMasterPassOnLogin($response->getClearMasterPass(), $userLoginData); + return $this->updateMasterPassOnLogin( + $response->getClearMasterPass(), + $userLoginData + ); } return new UserPassResponse(self::MPASS_WRONG); @@ -97,14 +90,13 @@ final class UserPassService extends Service /** * Comprueba la clave maestra del usuario. * - * @param UserLoginData $userLoginData - * @param string $userPass Clave de cifrado - * - * @return UserPassResponse * @throws SPException * @throws ContainerExceptionInterface */ - public function loadUserMPass(UserLoginData $userLoginData, $userPass = null) + public function loadUserMPass( + UserLoginData $userLoginData, + ?string $userPass = null + ): UserPassResponse { $userLoginResponse = $userLoginData->getUserLoginResponse(); @@ -122,24 +114,30 @@ final class UserPassService extends Service return new UserPassResponse(self::MPASS_CHANGED); } -// if ($userLoginResponse->getIsMigrate() === 1) { -// $key = $this->makeKeyForUserOld($userLoginData->getLoginUser(), $userPass ?: $userLoginData->getLoginPass()); -// } - - if ($userPass === null && $userLoginResponse->getIsChangedPass() === 1) { + if ($userPass === null && $userLoginResponse->getIsChangedPass()) { return new UserPassResponse(self::MPASS_CHECKOLD); } try { - $key = $this->makeKeyForUser($userLoginData->getLoginUser(), $userPass ?: $userLoginData->getLoginPass()); + $key = $this->makeKeyForUser( + $userLoginData->getLoginUser(), + $userPass ?: $userLoginData->getLoginPass() + ); - $clearMPass = Crypt::decrypt($userLoginResponse->getMPass(), $userLoginResponse->getMKey(), $key); + $clearMPass = Crypt::decrypt( + $userLoginResponse->getMPass(), + $userLoginResponse->getMKey(), + $key + ); // Comprobamos el hash de la clave del usuario con la guardada if (Hash::checkHashKey($clearMPass, $configHashMPass)) { $this->setMasterKeyInContext($clearMPass); - $response = new UserPassResponse(self::MPASS_OK, $clearMPass); + $response = new UserPassResponse( + self::MPASS_OK, + $clearMPass + ); $response->setCryptMasterPass($userLoginResponse->getMPass()); $response->setCryptSecuredKey($userLoginResponse->getMKey()); @@ -155,35 +153,39 @@ final class UserPassService extends Service /** * Obtener una clave de cifrado basada en la clave del usuario y un salt. * - * @param string $userLogin - * @param string $userPass - * * @return string con la clave de cifrado */ - public function makeKeyForUser($userLogin, $userPass) + public function makeKeyForUser(string $userLogin, string $userPass): string { // Use always the most recent config data if (Config::getTimeUpdated() > $this->configData->getConfigDate()) { - return trim($userPass . $userLogin . $this->config->getConfigData()->getPasswordSalt()); - } else { - return trim($userPass . $userLogin . $this->configData->getPasswordSalt()); + return trim( + $userPass . + $userLogin . + $this->config->getConfigData()->getPasswordSalt() + ); } + + return trim( + $userPass . + $userLogin . + $this->configData->getPasswordSalt() + ); } /** * Actualizar la clave maestra del usuario al realizar login * - * @param string $userMPass con la clave maestra - * @param UserLoginData $userLoginData $userLoginData - * - * @return UserPassResponse * @throws SPException * @throws CryptoException * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface * @throws SPException */ - public function updateMasterPassOnLogin($userMPass, UserLoginData $userLoginData) + public function updateMasterPassOnLogin( + string $userMPass, + UserLoginData $userLoginData + ): UserPassResponse { $userData = $userLoginData->getUserLoginResponse(); $configHashMPass = $this->configService->getByParam('masterPwd'); @@ -199,9 +201,17 @@ final class UserPassService extends Service } if (Hash::checkHashKey($userMPass, $configHashMPass)) { - $response = $this->createMasterPass($userMPass, $userLoginData->getLoginUser(), $userLoginData->getLoginPass()); + $response = $this->createMasterPass( + $userMPass, + $userLoginData->getLoginUser(), + $userLoginData->getLoginPass() + ); - $this->userRepository->updateMasterPassById($userData->getId(), $response->getCryptMasterPass(), $response->getCryptSecuredKey()); + $this->userRepository->updateMasterPassById( + $userData->getId(), + $response->getCryptMasterPass(), + $response->getCryptSecuredKey() + ); // Tells that the master password has been updated $this->context->setTrasientKey('mpass_updated', true); @@ -217,15 +227,14 @@ final class UserPassService extends Service /** * Actualizar la clave maestra del usuario en la BBDD. * - * @param string $masterPass - * @param string $userLogin - * @param string $userPass - * - * @return UserPassResponse * @throws CryptoException * @throws SPException */ - public function createMasterPass($masterPass, $userLogin, $userPass) + public function createMasterPass( + string $masterPass, + string $userLogin, + string $userPass + ): UserPassResponse { $key = $this->makeKeyForUser($userLogin, $userPass); @@ -248,16 +257,18 @@ final class UserPassService extends Service } /** - * @param int $id - * @param string $userPass - * * @throws ConstraintException * @throws QueryException * @throws NoSuchItemException */ - public function migrateUserPassById($id, string $userPass) + public function migrateUserPassById(int $id, string $userPass): void { - if ($this->userRepository->updatePassById($id, new UpdatePassRequest(Hash::hashKey($userPass))) === 0) { + $updatePassById = $this->userRepository->updatePassById( + $id, + new UpdatePassRequest(Hash::hashKey($userPass)) + ); + + if ($updatePassById === 0) { throw new NoSuchItemException(__u('User does not exist')); } } @@ -266,10 +277,10 @@ final class UserPassService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->configData = $this->config->getConfigData(); $this->userRepository = $this->dic->get(UserRepository::class); - $this->configService = $this->dic->get(ConfigService::class);; + $this->configService = $this->dic->get(ConfigService::class); } } \ No newline at end of file diff --git a/lib/SP/Services/User/UserService.php b/lib/SP/Services/User/UserService.php index 998e05d9..c2b8bfab 100644 --- a/lib/SP/Services/User/UserService.php +++ b/lib/SP/Services/User/UserService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\User; @@ -52,21 +52,12 @@ final class UserService extends Service { use ServiceItemTrait; - /** - * @var UserRepository - */ - protected $userRepository; - /** - * @var UserPassService - */ - protected $userPassService; + protected ?UserRepository $userRepository = null; + protected ?UserPassService $userPassService = null; - /** - * @param UserData $userData - * - * @return UserLoginResponse - */ - public static function mapUserLoginResponse(UserData $userData) + public static function mapUserLoginResponse( + UserData $userData + ): UserLoginResponse { return (new UserLoginResponse())->setId($userData->getId()) ->setName($userData->getName()) @@ -94,15 +85,17 @@ final class UserService extends Service /** * Returns user's preferences object - * - * @param string $preferences - * - * @return UserPreferencesData */ - public static function getUserPreferences($preferences) + public static function getUserPreferences( + ?string $preferences + ): UserPreferencesData { if (!empty($preferences)) { - return Util::unserialize(UserPreferencesData::class, $preferences, 'SP\UserPreferences'); + return Util::unserialize( + UserPreferencesData::class, + $preferences, + 'SP\UserPreferences' + ); } return new UserPreferencesData(); @@ -111,14 +104,11 @@ final class UserService extends Service /** * Actualiza el último inicio de sesión del usuario en la BBDD. * - * @param $id int El id del usuario - * - * @return int * @throws ConstraintException * @throws NoSuchItemException * @throws QueryException */ - public function updateLastLoginById($id) + public function updateLastLoginById(int $id): int { $result = $this->userRepository->updateLastLoginById($id); @@ -130,13 +120,10 @@ final class UserService extends Service } /** - * @param $login - * - * @return bool - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function checkExistsByLogin($login) + public function checkExistsByLogin(string $login): bool { return $this->userRepository->checkExistsByLogin($login); } @@ -144,12 +131,9 @@ final class UserService extends Service /** * Returns the item for given id * - * @param int $id - * - * @return UserData * @throws SPException */ - public function getById($id) + public function getById(int $id): UserData { $result = $this->userRepository->getById($id); @@ -163,12 +147,11 @@ final class UserService extends Service /** * Returns the item for given id * - * @param $login - * - * @return UserData - * @throws SPException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function getByLogin($login) + public function getByLogin(string $login): UserData { $result = $this->userRepository->getByLogin($login); @@ -182,34 +165,38 @@ final class UserService extends Service /** * Deletes an item * - * @param $id - * - * @return UserService - * @throws ConstraintException - * @throws QueryException - * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function delete($id) + public function delete(int $id): UserService { if ($this->userRepository->delete($id) === 0) { - throw new NoSuchItemException(__u('User not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('User not found'), + SPException::INFO + ); } return $this; } /** - * @param array $ids + * @param int[] $ids * - * @return int * @throws ServiceException * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (($count = $this->userRepository->deleteByIdBatch($ids)) !== count($ids)) { - throw new ServiceException(__u('Error while deleting the users'), ServiceException::WARNING); + $count = $this->userRepository->deleteByIdBatch($ids); + + if ($count !== count($ids)) { + throw new ServiceException( + __u('Error while deleting the users'), + SPException::WARNING + ); } return $count; @@ -218,23 +205,20 @@ final class UserService extends Service /** * Creates an item * - * @param UserLoginRequest $userLoginRequest - * - * @return int * @throws SPException */ - public function createOnLogin(UserLoginRequest $userLoginRequest) + public function createOnLogin(UserLoginRequest $userLoginRequest): int { $userData = new UserData(); $userData->setLogin($userLoginRequest->getLogin()); $userData->setName($userLoginRequest->getName()); $userData->setEmail($userLoginRequest->getEmail()); - $userData->setIsLdap($userLoginRequest->getisLdap()); + $userData->setIsLdap($userLoginRequest->getisLdap() ?? false); $userData->setPass($userLoginRequest->getPassword()); $configData = $this->config->getConfigData(); - if ($userLoginRequest->getisLdap() === 1) { + if ($userLoginRequest->getisLdap() === true) { $userData->setUserGroupId($configData->getLdapDefaultGroup()); $userData->setUserProfileId($configData->getLdapDefaultProfile()); } else { @@ -248,12 +232,9 @@ final class UserService extends Service /** * Creates an item * - * @param UserData $itemData - * - * @return int * @throws SPException */ - public function create(UserData $itemData) + public function create(UserData $itemData): int { $itemData->setPass(Hash::hashKey($itemData->getPass())); @@ -263,17 +244,20 @@ final class UserService extends Service /** * Creates an item * - * @param UserData $itemData - * @param string $userPass - * @param string $masterPass - * - * @return int * @throws SPException * @throws CryptoException */ - public function createWithMasterPass(UserData $itemData, $userPass, $masterPass) + public function createWithMasterPass( + UserData $itemData, + string $userPass, + string $masterPass + ): int { - $response = $this->userPassService->createMasterPass($masterPass, $itemData->getLogin(), $userPass); + $response = $this->userPassService->createMasterPass( + $masterPass, + $itemData->getLogin(), + $userPass + ); $itemData->setMPass($response->getCryptMasterPass()); $itemData->setMKey($response->getCryptSecuredKey()); @@ -286,76 +270,74 @@ final class UserService extends Service /** * Searches for items by a given filter * - * @param ItemSearchData $SearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $SearchData) + public function search(ItemSearchData $searchData): QueryResult { - return $this->userRepository->search($SearchData); + return $this->userRepository->search($searchData); } /** * Updates an item * - * @param UserData $itemData - * * @throws ConstraintException * @throws QueryException * @throws DuplicatedItemException * @throws ServiceException */ - public function update($itemData) + public function update(UserData $userData): void { - if ($this->userRepository->update($itemData) === 0) { + $update = $this->userRepository->update($userData); + + if ($update === 0) { throw new ServiceException(__u('Error while updating the user')); } } /** - * Updates an user's pass - * - * @param int $userId - * @param string $pass + * Updates a user's pass * * @throws ConstraintException * @throws QueryException * @throws ServiceException */ - public function updatePass($userId, $pass) + public function updatePass(int $userId, string $pass): void { $passRequest = new UpdatePassRequest(Hash::hashKey($pass)); - $passRequest->setIsChangePass(0); - $passRequest->setIsChangedPass(1); + $passRequest->setIsChangePass(false); + $passRequest->setIsChangedPass(true); - if ($this->userRepository->updatePassById($userId, $passRequest) === 0) { + $updatePassById = $this->userRepository->updatePassById( + $userId, + $passRequest + ); + + if ($updatePassById === 0) { throw new ServiceException(__u('Error while updating the password')); } } /** - * @param $userId - * @param UserPreferencesData $userPreferencesData - * - * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function updatePreferencesById($userId, UserPreferencesData $userPreferencesData) + public function updatePreferencesById( + int $userId, + UserPreferencesData $userPreferencesData + ): int { - return $this->userRepository->updatePreferencesById($userId, $userPreferencesData); + return $this->userRepository->updatePreferencesById( + $userId, + $userPreferencesData + ); } /** - * @param UserLoginRequest $userLoginRequest - * - * @return int * @throws ConstraintException * @throws QueryException */ - public function updateOnLogin(UserLoginRequest $userLoginRequest) + public function updateOnLogin(UserLoginRequest $userLoginRequest): int { $userData = new UserData(); $userData->setLogin($userLoginRequest->getLogin()); @@ -374,74 +356,76 @@ final class UserService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAllBasic() + public function getAllBasic(): array { - return $this->userRepository->getBasicInfo()->getDataAsArray(); + return $this->userRepository + ->getBasicInfo() + ->getDataAsArray(); } /** * Obtener el email de los usuarios de un grupo * - * @param $groupId - * - * @return array - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getUserEmailForGroup($groupId) + public function getUserEmailForGroup(int $groupId): array { - return $this->userRepository->getUserEmailForGroup($groupId)->getDataAsArray(); + return $this->userRepository + ->getUserEmailForGroup($groupId) + ->getDataAsArray(); } /** * Obtener el email de los usuarios de un grupo * - * @return array * @throws ConstraintException * @throws QueryException * * @TODO create unit test */ - public function getUserEmailForAll() + public function getUserEmailForAll(): array { - return $this->userRepository->getUserEmail()->getDataAsArray(); + return $this->userRepository + ->getUserEmail() + ->getDataAsArray(); } /** * Return the email of the given user's id * - * @param array $ids + * @param int[] $ids * - * @return array * @throws ConstraintException * @throws QueryException * @TODO create unit test */ - public function getUserEmailById(array $ids) + public function getUserEmailById(array $ids): array { - return $this->userRepository->getUserEmailById($ids)->getDataAsArray(); + return $this->userRepository + ->getUserEmailById($ids) + ->getDataAsArray(); } /** * Returns the usage of the given user's id * - * @param int $id - * - * @return array * @throws ConstraintException * @throws QueryException */ - public function getUsageForUser($id) + public function getUsageForUser(int $id): array { - return $this->userRepository->getUsageForUser($id)->getDataAsArray(); + return $this->userRepository + ->getUsageForUser($id) + ->getDataAsArray(); } /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->userRepository = $this->dic->get(UserRepository::class); $this->userPassService = $this->dic->get(UserPassService::class); diff --git a/lib/SP/Services/UserGroup/UserGroupService.php b/lib/SP/Services/UserGroup/UserGroupService.php index 50406147..fd5ee20a 100644 --- a/lib/SP/Services/UserGroup/UserGroupService.php +++ b/lib/SP/Services/UserGroup/UserGroupService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\UserGroup; @@ -48,118 +48,119 @@ final class UserGroupService extends Service { use ServiceItemTrait; - /** - * @var UserGroupRepository - */ - protected $userGroupRepository; - /** - * @var UserToUserGroupService - */ - protected $userToUserGroupService; + protected ?UserGroupRepository $userGroupRepository = null; + protected ?UserToUserGroupService $userToUserGroupService = null; /** - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->userGroupRepository->search($itemSearchData); } /** - * @param $id - * - * @return UserGroupData * @throws ConstraintException * @throws QueryException * @throws NoSuchItemException */ - public function getById($id) + public function getById(int $id): UserGroupData { $result = $this->userGroupRepository->getById($id); if ($result->getNumRows() === 0) { - throw new NoSuchItemException(__u('Group not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Group not found'), + SPException::INFO + ); } - $data = $result->getData(UserGroupData::class); + $data = $result->getData(); $data->setUsers($this->userToUserGroupService->getUsersByGroupId($id)); return $data; } /** - * @param $id - * - * @return $this - * @throws SPException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function delete($id) + public function delete(int $id): UserGroupService { - if ($this->userGroupRepository->delete($id) === 0) { - throw new NoSuchItemException(__u('Group not found'), NoSuchItemException::INFO); + $delete = $this->userGroupRepository->delete($id); + + if ($delete === 0) { + throw new NoSuchItemException( + __u('Group not found'), + SPException::INFO + ); } return $this; } /** - * @param array $ids + * @param int[] $ids * - * @return int * @throws ServiceException * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (($count = $this->userGroupRepository->deleteByIdBatch($ids)) !== count($ids)) { - throw new ServiceException(__u('Error while deleting the groups'), ServiceException::WARNING); + $count = $this->userGroupRepository->deleteByIdBatch($ids); + + if ($count !== count($ids)) { + throw new ServiceException( + __u('Error while deleting the groups'), + SPException::WARNING + ); } return $count; } /** - * @param UserGroupData $itemData - * - * @return int * @throws ServiceException */ - public function create($itemData) + public function create(UserGroupData $itemData): int { - return $this->transactionAware(function () use ($itemData) { - $id = $this->userGroupRepository->create($itemData); + return $this->transactionAware( + function () use ($itemData) { + $id = $this->userGroupRepository->create($itemData); - $users = $itemData->getUsers(); + $users = $itemData->getUsers(); - if ($users !== null) { - $this->userToUserGroupService->add($id, $users); + if ($users !== null) { + $this->userToUserGroupService->add($id, $users); + } + + return $id; } - - return $id; - }); + ); } /** - * @param UserGroupData $itemData - * * @throws ServiceException */ - public function update($itemData) + public function update(UserGroupData $itemData): void { - $this->transactionAware(function () use ($itemData) { - $this->userGroupRepository->update($itemData); + $this->transactionAware( + function () use ($itemData) { + $this->userGroupRepository->update($itemData); - $users = $itemData->getUsers(); + $users = $itemData->getUsers(); - if ($users !== null) { - $this->userToUserGroupService->update($itemData->getId(), $users); + if ($users !== null) { + $this->userToUserGroupService->update( + $itemData->getId(), + $users + ); + } } - }); + ); } /** @@ -169,27 +170,29 @@ final class UserGroupService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAllBasic() + public function getAllBasic(): array { - return $this->userGroupRepository->getAll()->getDataAsArray(); + return $this->userGroupRepository + ->getAll() + ->getDataAsArray(); } /** * Returns the item for given name * - * @param string $name - * - * @return UserGroupData * @throws NoSuchItemException * @throws ConstraintException * @throws QueryException */ - public function getByName($name) + public function getByName(string $name): UserGroupData { $result = $this->userGroupRepository->getByName($name); if ($result->getNumRows() === 0) { - throw new NoSuchItemException(__u('Group not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Group not found'), + SPException::INFO + ); } return $result->getData(); @@ -198,36 +201,34 @@ final class UserGroupService extends Service /** * Returns the users that are using the given group id * - * @param $id int - * - * @return array * @throws ConstraintException * @throws QueryException */ - public function getUsage($id) + public function getUsage(int $id): array { - return $this->userGroupRepository->getUsage($id)->getDataAsArray(); + return $this->userGroupRepository + ->getUsage($id) + ->getDataAsArray(); } /** * Returns the items that are using the given group id * - * @param $id int - * - * @return array * @throws ConstraintException * @throws QueryException */ - public function getUsageByUsers($id) + public function getUsageByUsers(int $id): array { - return $this->userGroupRepository->getUsageByUsers($id)->getDataAsArray(); + return $this->userGroupRepository + ->getUsageByUsers($id) + ->getDataAsArray(); } /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->userGroupRepository = $this->dic->get(UserGroupRepository::class); $this->userToUserGroupService = $this->dic->get(UserToUserGroupService::class); diff --git a/lib/SP/Services/UserGroup/UserToUserGroupService.php b/lib/SP/Services/UserGroup/UserToUserGroupService.php index 2fe56599..386d7af1 100644 --- a/lib/SP/Services/UserGroup/UserToUserGroupService.php +++ b/lib/SP/Services/UserGroup/UserToUserGroupService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\UserGroup; @@ -28,6 +28,7 @@ use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; +use SP\Core\Exceptions\SPException; use SP\DataModel\UserToUserGroupData; use SP\Repositories\NoSuchItemException; use SP\Repositories\UserGroup\UserToUserGroupRepository; @@ -40,52 +41,41 @@ use SP\Services\Service; */ final class UserToUserGroupService extends Service { - /** - * @var UserToUserGroupRepository - */ - protected $userToUserGroupRepository; + protected ?UserToUserGroupRepository $userToUserGroupRepository = null; /** - * @param $id - * - * @return UserToUserGroupData[] - * @throws NoSuchItemException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function getById($id) + public function getById(int $id): array { $result = $this->userToUserGroupRepository->getById($id); if ($result->getNumRows() === 0) { - throw new NoSuchItemException(__u('Group not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Group not found'), + SPException::INFO + ); } return $result->getDataAsArray(); } /** - * @param $id - * @param array $users - * - * @return int - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function add($id, array $users) + public function add(int $id, array $users): int { return $this->userToUserGroupRepository->add($id, $users); } /** - * @param int $id - * @param array $users - * - * @return int * @throws ConstraintException * @throws QueryException */ - public function update($id, array $users) + public function update(int $id, array $users): int { if (count($users) === 0) { return $this->userToUserGroupRepository->delete($id); @@ -95,18 +85,19 @@ final class UserToUserGroupService extends Service } /** - * @param $id - * - * @return array * @throws ConstraintException * @throws QueryException */ - public function getUsersByGroupId($id) + public function getUsersByGroupId(int $id): array { $usersId = []; /** @var UserToUserGroupData $userToUserGroupData */ - foreach ($this->userToUserGroupRepository->getById($id)->getDataAsArray() as $userToUserGroupData) { + $userByGroup = $this->userToUserGroupRepository + ->getById($id) + ->getDataAsArray(); + + foreach ($userByGroup as $userToUserGroupData) { $usersId[] = $userToUserGroupData->getUserId(); } @@ -116,37 +107,33 @@ final class UserToUserGroupService extends Service /** * Checks whether the user is included in the group * - * @param $groupId - * @param $userId - * - * @return bool - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function checkUserInGroup($groupId, $userId) + public function checkUserInGroup(int $groupId, int $userId): bool { - return $this->userToUserGroupRepository->checkUserInGroup($groupId, $userId); + return $this->userToUserGroupRepository + ->checkUserInGroup($groupId, $userId); } /** * Returns the groups which the user belongs to * - * @param $userId - * - * @return array - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getGroupsForUser($userId) + public function getGroupsForUser(int $userId): array { - return $this->userToUserGroupRepository->getGroupsForUser($userId)->getDataAsArray(); + return $this->userToUserGroupRepository + ->getGroupsForUser($userId) + ->getDataAsArray(); } /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->userToUserGroupRepository = $this->dic->get(UserToUserGroupRepository::class); } diff --git a/lib/SP/Services/UserPassRecover/UserPassRecoverService.php b/lib/SP/Services/UserPassRecover/UserPassRecoverService.php index e2c66d83..9513aae0 100644 --- a/lib/SP/Services/UserPassRecover/UserPassRecoverService.php +++ b/lib/SP/Services/UserPassRecover/UserPassRecoverService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\UserPassRecover; @@ -48,25 +48,15 @@ final class UserPassRecoverService extends Service /** * Tiempo máximo para recuperar la clave */ - const MAX_PASS_RECOVER_TIME = 3600; + private const MAX_PASS_RECOVER_TIME = 3600; /** * Número de intentos máximos para recuperar la clave */ - const MAX_PASS_RECOVER_LIMIT = 3; - const USER_LOGIN_EXIST = 1; - const USER_MAIL_EXIST = 2; + public const MAX_PASS_RECOVER_LIMIT = 3; - /** - * @var UserPassRecoverRepository - */ - protected $userPassRecoverRepository; + protected ?UserPassRecoverRepository $userPassRecoverRepository = null; - /** - * @param $hash - * - * @return MailMessage - */ - public static function getMailMessage($hash) + public static function getMailMessage(string $hash): MailMessage { $mailMessage = new MailMessage(); $mailMessage->setTitle(__('Password Change')); @@ -82,32 +72,35 @@ final class UserPassRecoverService extends Service } /** - * @param $hash - * - * @return void - * @throws ServiceException - * @throws SPException + * @throws \SP\Core\Exceptions\SPException + * @throws \SP\Services\ServiceException */ - public function toggleUsedByHash($hash) + public function toggleUsedByHash(string $hash): void { - if ($this->userPassRecoverRepository->toggleUsedByHash($hash, time() - self::MAX_PASS_RECOVER_TIME) === 0) { - throw new ServiceException(__u('Wrong hash or expired'), ServiceException::INFO); + if ($this->userPassRecoverRepository->toggleUsedByHash( + $hash, + time() - self::MAX_PASS_RECOVER_TIME) === 0 + ) { + throw new ServiceException( + __u('Wrong hash or expired'), + SPException::INFO + ); } } /** - * @param int $id - * - * @return string * @throws ConstraintException * @throws QueryException * @throws ServiceException * @throws EnvironmentIsBrokenException */ - public function requestForUserId($id) + public function requestForUserId(int $id): string { if ($this->checkAttemptsByUserId($id)) { - throw new ServiceException(__u('Attempts exceeded'), ServiceException::WARNING); + throw new ServiceException( + __u('Attempts exceeded'), + SPException::WARNING + ); } $hash = PasswordUtil::generateRandomBytes(16); @@ -120,26 +113,22 @@ final class UserPassRecoverService extends Service /** * Comprobar el límite de recuperaciones de clave. * - * @param int $userId - * - * @return bool * @throws ConstraintException * @throws QueryException */ - public function checkAttemptsByUserId($userId) + public function checkAttemptsByUserId(int $userId): bool { - return $this->userPassRecoverRepository->getAttemptsByUserId($userId, time() - self::MAX_PASS_RECOVER_TIME) >= self::MAX_PASS_RECOVER_LIMIT; + return $this->userPassRecoverRepository->getAttemptsByUserId( + $userId, + time() - self::MAX_PASS_RECOVER_TIME + ) >= self::MAX_PASS_RECOVER_LIMIT; } /** - * @param $userId - * @param $hash - * - * @return bool - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function add($userId, $hash) + public function add(int $userId, string $hash): bool { return $this->userPassRecoverRepository->add($userId, $hash); } @@ -147,19 +136,22 @@ final class UserPassRecoverService extends Service /** * Comprobar el hash de recuperación de clave. * - * @param string $hash - * - * @return int * @throws ServiceException * @throws ConstraintException * @throws QueryException */ - public function getUserIdForHash($hash) + public function getUserIdForHash(string $hash): int { - $result = $this->userPassRecoverRepository->getUserIdForHash($hash, time() - self::MAX_PASS_RECOVER_TIME); + $result = $this->userPassRecoverRepository->getUserIdForHash( + $hash, + time() - self::MAX_PASS_RECOVER_TIME + ); if ($result->getNumRows() === 0) { - throw new ServiceException(__u('Wrong hash or expired'), ServiceException::INFO); + throw new ServiceException( + __u('Wrong hash or expired'), + SPException::INFO + ); } return (int)$result->getData()->userId; @@ -169,7 +161,7 @@ final class UserPassRecoverService extends Service * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->userPassRecoverRepository = $this->dic->get(UserPassRecoverRepository::class); } diff --git a/lib/SP/Services/UserProfile/UserProfileService.php b/lib/SP/Services/UserProfile/UserProfileService.php index 6c51ef98..36fb4d25 100644 --- a/lib/SP/Services/UserProfile/UserProfileService.php +++ b/lib/SP/Services/UserProfile/UserProfileService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Services\UserProfile; @@ -49,20 +49,14 @@ final class UserProfileService extends Service { use ServiceItemTrait; - /** - * @var UserProfileRepository - */ - protected $userProfileRepository; + protected ?UserProfileRepository $userProfileRepository = null; /** - * @param $id - * - * @return UserProfileData - * @throws ConstraintException - * @throws QueryException - * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function getById($id) + public function getById(int $id): UserProfileData { $result = $this->userProfileRepository->getById($id); @@ -71,92 +65,97 @@ final class UserProfileService extends Service } $userProfileData = $result->getData(); - $userProfileData->setProfile(Util::unserialize(ProfileData::class, $userProfileData->getProfile())); + $userProfileData->setProfile( + Util::unserialize( + ProfileData::class, + $userProfileData->getProfile() + ) + ); return $userProfileData; } /** - * @param ItemSearchData $itemSearchData - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function search(ItemSearchData $itemSearchData) + public function search(ItemSearchData $itemSearchData): QueryResult { return $this->userProfileRepository->search($itemSearchData); } /** - * @param $id - * - * @return $this - * @throws NoSuchItemException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ - public function delete($id) + public function delete(int $id): UserProfileService { if ($this->userProfileRepository->delete($id) === 0) { - throw new NoSuchItemException(__u('Profile not found'), NoSuchItemException::INFO); + throw new NoSuchItemException( + __u('Profile not found'), + SPException::INFO + ); } return $this; } /** - * @param array $ids + * @param int[] $ids * - * @return int * @throws ServiceException * @throws ConstraintException * @throws QueryException */ - public function deleteByIdBatch(array $ids) + public function deleteByIdBatch(array $ids): int { - if (($count = $this->userProfileRepository->deleteByIdBatch($ids)) !== count($ids)) { - throw new ServiceException(__u('Error while removing the profiles'), ServiceException::WARNING); + $count = $this->userProfileRepository->deleteByIdBatch($ids); + + if ($count !== count($ids)) { + throw new ServiceException( + __u('Error while removing the profiles'), + SPException::WARNING + ); } return $count; } /** - * @param $itemData - * - * @return int - * @throws SPException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\DuplicatedItemException */ - public function create($itemData) + public function create(UserProfileData $itemData): int { return $this->userProfileRepository->create($itemData); } /** - * @param $itemData - * - * @throws SPException - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\DuplicatedItemException + * @throws \SP\Services\ServiceException */ - public function update($itemData) + public function update(UserProfileData $itemData): void { - if ($this->userProfileRepository->update($itemData) === 0) { + $update = $this->userProfileRepository->update($itemData); + + if ($update === 0) { throw new ServiceException(__u('Error while updating the profile')); } } /** - * @param $id - * - * @return array - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getUsersForProfile($id) + public function getUsersForProfile(int $id): array { - return $this->userProfileRepository->getUsersForProfile($id)->getDataAsArray(); + return $this->userProfileRepository + ->getUsersForProfile($id) + ->getDataAsArray(); } /** @@ -166,16 +165,18 @@ final class UserProfileService extends Service * @throws ConstraintException * @throws QueryException */ - public function getAllBasic() + public function getAllBasic(): array { - return $this->userProfileRepository->getAll()->getDataAsArray(); + return $this->userProfileRepository + ->getAll() + ->getDataAsArray(); } /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ - protected function initialize() + protected function initialize(): void { $this->userProfileRepository = $this->dic->get(UserProfileRepository::class); } diff --git a/lib/SP/Services/Wiki/DokuWikiApi.php b/lib/SP/Services/Wiki/DokuWikiApi.php deleted file mode 100644 index 552e0354..00000000 --- a/lib/SP/Services/Wiki/DokuWikiApi.php +++ /dev/null @@ -1,280 +0,0 @@ -. - */ - -namespace SP\Services\Wiki; - -use InvalidArgumentException; -use SP\Core\Exceptions\SPException; - -defined('APP_ROOT') || die(); - -/** - * Class DokuWikiApi para realizar consultas a la API de DokuWiki - * - * @package SP\Services\Wiki - * @deprecated - */ -class DokuWikiApi extends DokuWikiApiBase -{ - /** - * @var string - */ - private $namespace; - - /** - * Constructor - * - * @param string $url La URL de conexión - * @param string $user El usuario de conexión - * @param string $pass La clave de conexión - * - * @throws SPException - */ - public function __construct($url = null, $user = null, $pass = null) - { - parent::__construct(); - - try { - $this->setConnectionData($url, $user, $pass); - - if (!empty($this->apiUser) && SessionFactory::getDokuWikiSession() === false) { - $Res = new DokuWikiApiParse($this->doLogin()); - $this->catchError($Res); - $resLogin = $Res->parseParams(); - - SessionFactory::setDokuWikiSession($resLogin[0]); - - if ($resLogin[0] === false) { - throw new SPException(__u('Authentication error'), SPException::WARNING); - } - } - - $this->namespace = $this->ConfigData->getDokuwikiNamespace(); - } catch (SPException $e) { - $this->logException($e); - throw $e; - } catch (InvalidArgumentException $e) { - throw new SPException($e->getMessage(), SPException::WARNING); - } - } - - /** - * Comprobar la conexión a DokuWiki - * - * @param string $url La URL de conexión - * @param string $user El usuario de conexión - * @param string $pass La clave de conexión - * - * @return DokuWikiApi - * @throws SPException - */ - public static function checkConnection($url = null, $user = null, $pass = null) - { - try { - // Reinicializar la cookie de DokuWiki - SessionFactory::setDokuWikiSession(false); - - return new DokuWikiApi($url, $user, $pass); - } catch (SPException $e) { - throw $e; - } - } - - /** - * Obtener el listado de páginas de la Wiki - * - * @return bool - */ - public function getPageList() - { - try { - $this->createMsg('dokuwiki.getPagelist'); - $this->addParam($this->namespace); - $this->addParam(['depth' => 0]); - $Res = new DokuWikiApiParse($this->callWiki()); - $this->catchError($Res); - - return $Res->parseParams(); - } catch (SPException $e) { - $this->logException($e, __FUNCTION__); - return false; - } - } - - /** - * Realizar una búsqueda en la Wiki - * - * @param string $search El texto a buscar - * - * @return array|bool - */ - public function getSearch($search) - { - try { - $this->createMsg('dokuwiki.search'); - $this->addParam($search); - $Res = new DokuWikiApiParse($this->callWiki()); - $this->catchError($Res); - - return $Res->parseParams(); - } catch (SPException $e) { - $this->logException($e, __FUNCTION__); - return false; - } - } - - /** - * Obtener una página de la Wiki - * - * @param string $page El nombre de la página a obtener - * - * @return array|bool - */ - public function getPage($page) - { - if (!empty($this->namespace)) { - $page = $this->namespace . ':' . $page; - } - - try { - $this->createMsg('wiki.getPageHTML'); - $this->addParam($page); - $Res = new DokuWikiApiParse($this->callWiki()); - $this->catchError($Res); - - return $Res->parseParams(); - } catch (SPException $e) { - $this->logException($e, __FUNCTION__); - return false; - } - } - - /** - * Obtener una página de la Wiki en formato original - * - * @param string $page El nombre de la página a obtener - * - * @return array|bool - */ - public function getRawPage($page) - { - try { - $this->createMsg('wiki.getPage'); - $this->addParam($page); - $Res = new DokuWikiApiParse($this->callWiki()); - $this->catchError($Res); - - return $Res->parseParams(); - } catch (SPException $e) { - $this->logException($e, __FUNCTION__); - return false; - } - } - - /** - * Obtener la información de una página de la Wiki - * - * @param string $page El nombre de la página a obtener - * - * @return array|bool - */ - public function getPageInfo($page) - { - if (!empty($this->namespace)) { - $page = $this->namespace . ':' . $page; - } - - try { - $this->createMsg('wiki.getPageInfo'); - $this->addParam($page); - $Res = new DokuWikiApiParse($this->callWiki()); - $this->catchError($Res); - - return $Res->parseParams(); - } catch (SPException $e) { - $this->logException($e, __FUNCTION__); - return false; - } - } - - /** - * Obtener la versión de DokuWiki - * - * @return array|bool - */ - public function getVersion() - { - try { - $this->createMsg('dokuwiki.getVersion'); - $Res = new DokuWikiApiParse($this->callWiki()); - $this->catchError($Res); - - return $Res->parseParams(); - } catch (SPException $e) { - $this->logException($e, __FUNCTION__); - return false; - } - } - - /** - * Obtener el nombre de la Wiki - * - * @return array|bool - */ - public function getTitle() - { - try { - $this->createMsg('dokuwiki.getTitle'); - $Res = new DokuWikiApiParse($this->callWiki()); - $this->catchError($Res); - - return $Res->parseParams(); - } catch (SPException $e) { - $this->logException($e, __FUNCTION__); - return false; - } - } - - /** - * Obtener los permisos de la página - * - * @param $page - * - * @return array|bool - */ - public function getAcl($page) - { - try { - $this->createMsg('wiki.aclCheck'); - $this->addParam($page); - $Res = new DokuWikiApiParse($this->callWiki()); - $this->catchError($Res); - - return $Res->parseParams(); - } catch (SPException $e) { - $this->logException($e, __FUNCTION__); - return false; - } - } -} \ No newline at end of file diff --git a/lib/SP/Services/Wiki/DokuWikiApiBase.php b/lib/SP/Services/Wiki/DokuWikiApiBase.php deleted file mode 100644 index 8e1b6203..00000000 --- a/lib/SP/Services/Wiki/DokuWikiApiBase.php +++ /dev/null @@ -1,233 +0,0 @@ -. - */ - -namespace SP\Services\Wiki; - -use DOMDocument; -use DOMElement; -use Exception; -use SP\Config\Config; -use SP\Config\ConfigData; -use SP\Core\Exceptions\SPException; -use SP\Http\XMLRPCResponseParse; -use SP\Util\Util; - -/** - * Class DokuWikiApiBase - * - * @package SP\Services\Wiki - * @deprecated - */ -abstract class DokuWikiApiBase -{ - /** - * @var string - */ - protected $apiUser = ''; - /** - * @var string - */ - protected $apiPassword = ''; - /** - * @var string - */ - protected $apiUrl = ''; - /** - * @var ConfigData - */ - protected $ConfigData; - /** - * @var DOMDocument - */ - private $xml; - /** - * @var DOMElement - */ - private $root; - /** - * @var DOMElement - */ - private $params; - - /** - * DokuWikiApiBase constructor. - */ - public function __construct() - { - $this->injectDependencies(); - } - - /** - * @return string - */ - public function getXml() - { - return $this->xml->saveXML(); - } - - /** - * @param Config $config - */ - public function inject(Config $config) - { - $this->ConfigData = $config->getConfigData(); - } - - /** - * Establecer la autorización - * - * @return bool|string - * @throws SPException - */ - protected function doLogin() - { - try { - $this->createMsg('dokuwiki.login'); - $this->addParam($this->apiUser); - $this->addParam($this->apiPassword); - return $this->callWiki(); - } catch (SPException $e) { - throw $e; - } - } - - /** - * Crear la llamada al método de DokuWiki - * - * @param $function - * - * @throws SPException - */ - protected function createMsg($function) - { - try { - $this->xml = new DOMDocument('1.0', 'UTF-8'); - - $xmlMethodCall = $this->xml->createElement('methodCall'); - $this->root = $this->xml->appendChild($xmlMethodCall); - - $xmlMethodName = $this->xml->createElement('methodName', $function); - $this->root->appendChild($xmlMethodName); - - $this->params = $this->xml->createElement('params'); - $this->root->appendChild($this->params); - } catch (Exception $e) { - throw new SPException($e->getMessage(), SPException::WARNING, __FUNCTION__); - } - } - - /** - * Añadir un parámetro - * - * @param $value - * - * @throws SPException - */ - protected function addParam($value) - { - try { - $xmlParam = $this->xml->createElement('param'); - $xmlValue = $this->xml->createElement('value'); - - if (is_numeric($value)) { - $xmlValue->appendChild($this->xml->createElement('int', (int)$value)); - } elseif (is_string($value)) { - $xmlValue->appendChild($this->xml->createElement('string', $value)); - } elseif (is_bool($value)) { - $xmlValue->appendChild($this->xml->createElement('boolean', (int)$value)); - } - - $xmlParam->appendChild($xmlValue); - $this->params->appendChild($xmlParam); - } catch (Exception $e) { - throw new SPException($e->getMessage(), SPException::WARNING, __FUNCTION__); - } - } - - /** - * Enviar el XML a la wiki y devolver la respuesta - * - * @throws SPException - */ - protected function callWiki() - { - try { - $data['type'] = ['Content-Type: text/xml']; - $data['data'] = $this->xml->saveXML(); - - return Util::getDataFromUrl($this->apiUrl, $data, true, true); - } catch (SPException $e) { - throw $e; - } - } - - /** - * Capturar si han habido errores en la consulta XML - * - * @param XMLRPCResponseParse $Res - * - * @throws SPException - */ - protected function catchError(XMLRPCResponseParse $Res) - { - $error = $Res->getError(); - - if (count($error) > 0) { - throw new SPException( - __u('Error while doing the query'), SPException::WARNING, $error['faultString'] - ); - } - } - - /** - * Escribir el error en el registro de eventos - * - * @param SPException $e - * @param string $source Origen del error - */ - protected function logException(SPException $e, $source = null) - { - processException($e); - } - - /** - * Establecer los datos de conexión a la API de DokuWiki - * - * @param string $url La URL de conexión - * @param string $user El usuario de conexión - * @param string $pass La clave de conexión - * - * @throws SPException - */ - protected function setConnectionData($url, $user, $pass) - { - $this->apiUrl = empty($url) ? $this->ConfigData->getDokuwikiUrl() : $url; - $this->apiUser = empty($user) ? $this->ConfigData->getDokuwikiUser() : $user; - $this->apiPassword = empty($pass) ? $this->ConfigData->getDokuwikiPass() : $pass; - - if (empty($this->apiUrl)) { - throw new SPException(__u('Connection URL not set'), SPException::WARNING); - } - } -} \ No newline at end of file diff --git a/lib/SP/Services/Wiki/DokuWikiApiParse.php b/lib/SP/Services/Wiki/DokuWikiApiParse.php deleted file mode 100644 index 9e8c417f..00000000 --- a/lib/SP/Services/Wiki/DokuWikiApiParse.php +++ /dev/null @@ -1,38 +0,0 @@ -. - */ - -namespace SP\Services\Wiki; - -use SP\Http\XMLRPCResponseParse; - -/** - * Class DokuWikiApiParse para el parseo de las respuestas de DokuWiki - * - * @package SP\Services\Wiki - * @deprecated - */ -class DokuWikiApiParse extends XMLRPCResponseParse -{ - -} \ No newline at end of file diff --git a/lib/SP/Storage/Database/DBStorageInterface.php b/lib/SP/Storage/Database/DBStorageInterface.php index f0a202b8..b05c64af 100644 --- a/lib/SP/Storage/Database/DBStorageInterface.php +++ b/lib/SP/Storage/Database/DBStorageInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\Database; diff --git a/lib/SP/Storage/Database/Database.php b/lib/SP/Storage/Database/Database.php index b26d152e..0a3e38cc 100644 --- a/lib/SP/Storage/Database/Database.php +++ b/lib/SP/Storage/Database/Database.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\Database; @@ -41,30 +41,12 @@ use SP\Core\Exceptions\SPException; */ final class Database implements DatabaseInterface { - /** - * @var int Número de registros obtenidos - */ - protected $numRows = 0; - /** - * @var int Número de campos de la consulta - */ - protected $numFields = 0; - /** - * @var array Resultados de la consulta - */ - protected $lastResult; - /** - * @var DBStorageInterface - */ - protected $dbHandler; - /** - * @var int Último Id de elemento insertado/actualizado - */ - private $lastId; - /** - * @var EventDispatcher - */ - private $eventDispatcher; + protected int $numRows = 0; + protected int $numFields = 0; + protected ?array $lastResult = null; + protected DBStorageInterface $dbHandler; + private ?int $lastId = null; + private EventDispatcher $eventDispatcher; /** * DB constructor. @@ -72,64 +54,55 @@ final class Database implements DatabaseInterface * @param DBStorageInterface $dbHandler * @param EventDispatcher $eventDispatcher */ - public function __construct(DBStorageInterface $dbHandler, EventDispatcher $eventDispatcher) + public function __construct( + DBStorageInterface $dbHandler, + EventDispatcher $eventDispatcher + ) { $this->dbHandler = $dbHandler; $this->eventDispatcher = $eventDispatcher; } - /** - * @return int - */ public function getNumRows(): int { return $this->numRows; } - /** - * @return int - */ public function getNumFields(): int { return $this->numFields; } - /** - * @return array|null - */ public function getLastResult(): ?array { return $this->lastResult; } - /** - * @return int|null - */ public function getLastId(): ?int { return $this->lastId; } - /** - * @return DBStorageInterface - */ public function getDbHandler(): DBStorageInterface { return $this->dbHandler; } /** - * @param QueryData $queryData - * @param bool $fullCount - * - * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function doSelect(QueryData $queryData, $fullCount = false): QueryResult + public function doSelect( + QueryData $queryData, + bool $fullCount = false + ): QueryResult { if ($queryData->getQuery() === '') { - throw new QueryException($queryData->getOnErrorMessage(), QueryException::ERROR, __u('Blank query')); + throw new QueryException( + $queryData->getOnErrorMessage(), + SPException::ERROR, + __u('Blank query') + ); } try { @@ -140,11 +113,7 @@ final class Database implements DatabaseInterface } return $queryResult; - } catch (ConstraintException $e) { - processException($e); - - throw $e; - } catch (QueryException $e) { + } catch (ConstraintException | QueryException $e) { processException($e); throw $e; @@ -164,9 +133,6 @@ final class Database implements DatabaseInterface /** * Realizar una consulta a la BBDD. * - * @param $queryData QueryData Los datos de la consulta - * - * @return QueryResult * @throws QueryException * @throws ConstraintException */ @@ -174,7 +140,8 @@ final class Database implements DatabaseInterface { $stmt = $this->prepareQueryData($queryData); - $this->eventDispatcher->notifyEvent('database.query', + $this->eventDispatcher->notifyEvent( + 'database.query', new Event($this, EventMessage::factory() ->addDescription($queryData->getQuery()) ) @@ -198,14 +165,14 @@ final class Database implements DatabaseInterface * @param bool $isCount Indica si es una consulta de contador de registros * @param array $options * - * @return PDOStatement - * @throws ConstraintException - * @throws QueryException + * @return \PDOStatement + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ private function prepareQueryData( QueryData $queryData, - bool $isCount = false, - array $options = [] + bool $isCount = false, + array $options = [] ): PDOStatement { $query = $queryData->getQuery(); @@ -219,7 +186,7 @@ final class Database implements DatabaseInterface try { $connection = $this->dbHandler->getConnection(); - if (!empty($params)) { + if (count($params) !== 0) { $stmt = $connection->prepare($query, $options); foreach ($params as $param => $value) { @@ -247,27 +214,28 @@ final class Database implements DatabaseInterface } catch (Exception $e) { processException($e); - switch ((int)$e->getCode()) { - case 23000: - throw new ConstraintException( - __u('Integrity constraint'), - ConstraintException::ERROR, - $e->getMessage(), - $e->getCode(), - $e - ); + if ((int)$e->getCode() === 23000) { + throw new ConstraintException( + __u('Integrity constraint'), + SPException::ERROR, + $e->getMessage(), + $e->getCode(), + $e + ); } - throw new QueryException($e->getMessage(), QueryException::CRITICAL, $e->getCode(), 0, $e); + throw new QueryException( + $e->getMessage(), + SPException::CRITICAL, + $e->getCode(), + 0, + $e + ); } } /** * Strips out the unused params from the query count - * - * @param QueryData $queryData - * - * @return array */ private function getParamsForCount(QueryData $queryData): array { @@ -275,21 +243,24 @@ final class Database implements DatabaseInterface $countFrom = substr_count($queryData->getFrom(), '?'); $countWhere = substr_count($queryData->getWhere(), '?'); - return array_slice($queryData->getParams(), $countSelect, $countFrom + $countWhere); + return array_slice( + $queryData->getParams(), + $countSelect, + $countFrom + $countWhere + ); } - /** - * @param QueryData $queryData - * @param PDOStatement $stmt - * - * @return array - */ private function fetch(QueryData $queryData, PDOStatement $stmt): array { if ($queryData->isUseKeyPair()) { return $stmt->fetchAll(PDO::FETCH_KEY_PAIR); - } elseif ($queryData->getMapClassName()) { - return $stmt->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, $queryData->getMapClassName()); + } + + if ($queryData->getMapClassName()) { + return $stmt->fetchAll( + PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, + $queryData->getMapClassName() + ); } return $stmt->fetchAll(); @@ -298,9 +269,7 @@ final class Database implements DatabaseInterface /** * Obtener el número de filas de una consulta realizada * - * @param QueryData $queryData Los datos de la consulta - * - * @return int Número de files de la consulta + * @return int Número de filas de la consulta * @throws SPException */ public function getFullRowCount(QueryData $queryData): int @@ -329,15 +298,19 @@ final class Database implements DatabaseInterface */ public function doQueryRaw( QueryData $queryData, - array $options = [], - ?bool $buffered = null): PDOStatement + array $options = [], + ?bool $buffered = null + ): PDOStatement { if ($buffered === false && $this->dbHandler instanceof MySQLHandler ) { $this->dbHandler ->getConnection() - ->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); + ->setAttribute( + PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, + false + ); } return $this->prepareQueryData($queryData, false, $options); @@ -345,8 +318,6 @@ final class Database implements DatabaseInterface /** * Iniciar una transacción - * - * @return bool */ public function beginTransaction(): bool { @@ -355,21 +326,25 @@ final class Database implements DatabaseInterface if (!$conn->inTransaction()) { $result = $conn->beginTransaction(); - $this->eventDispatcher->notifyEvent('database.transaction.begin', - new Event($this, EventMessage::factory()->addExtra('result', $result))); + $this->eventDispatcher->notifyEvent( + 'database.transaction.begin', + new Event( + $this, + EventMessage::factory() + ->addExtra('result', $result) + ) + ); return $result; - } else { - logger('beginTransaction: already in transaction'); - - return true; } + + logger('beginTransaction: already in transaction'); + + return true; } /** * Finalizar una transacción - * - * @return bool */ public function endTransaction(): bool { @@ -377,16 +352,20 @@ final class Database implements DatabaseInterface $result = $conn->inTransaction() && $conn->commit(); - $this->eventDispatcher->notifyEvent('database.transaction.end', - new Event($this, EventMessage::factory()->addExtra('result', $result))); + $this->eventDispatcher->notifyEvent( + 'database.transaction.end', + new Event( + $this, + EventMessage::factory() + ->addExtra('result', $result) + ) + ); return $result; } /** * Rollback de una transacción - * - * @return bool */ public function rollbackTransaction(): bool { @@ -394,17 +373,18 @@ final class Database implements DatabaseInterface $result = $conn->inTransaction() && $conn->rollBack(); - $this->eventDispatcher->notifyEvent('database.transaction.rollback', - new Event($this, EventMessage::factory()->addExtra('result', $result))); + $this->eventDispatcher->notifyEvent( + 'database.transaction.rollback', + new Event( + $this, + EventMessage::factory() + ->addExtra('result', $result) + ) + ); return $result; } - /** - * @param string $table - * - * @return array - */ public function getColumnsForTable(string $table): array { $conn = $this->dbHandler->getConnection() diff --git a/lib/SP/Storage/Database/DatabaseConnectionData.php b/lib/SP/Storage/Database/DatabaseConnectionData.php index 11176c40..2e8c26da 100644 --- a/lib/SP/Storage/Database/DatabaseConnectionData.php +++ b/lib/SP/Storage/Database/DatabaseConnectionData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,53 +19,32 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\Database; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; /** * Class DatabaseConnectionData * - * @package SP\Storage + * @package SP\Storage\Database */ final class DatabaseConnectionData { - /** - * @var string - */ - private $dbHost; - /** - * @var string - */ - private $dbSocket; - /** - * @var int - */ - private $dbPort; - /** - * @var string - */ - private $dbName; - /** - * @var string - */ - private $dbUser; - /** - * @var string - */ - private $dbPass; + private ?string $dbHost = null; + private ?string $dbSocket = null; + private ?int $dbPort = null; + private ?string $dbName = null; + private ?string $dbUser = null; + private ?string $dbPass = null; - /** - * @param ConfigData $configData - * - * @return mixed - */ - public static function getFromConfig(ConfigData $configData) + public static function getFromConfig( + ConfigDataInterface $configData + ): DatabaseConnectionData { - return (new DatabaseConnectionData()) + return (new self()) ->setDbHost($configData->getDbHost()) ->setDbName($configData->getDbName()) ->setDbUser($configData->getDbUser()) @@ -74,12 +53,9 @@ final class DatabaseConnectionData ->setDbSocket($configData->getDbSocket()); } - /** - * @param ConfigData $configData - * - * @return DatabaseConnectionData - */ - public function refreshFromConfig(ConfigData $configData) + public function refreshFromConfig( + ConfigDataInterface $configData + ): DatabaseConnectionData { logger('Refresh DB connection data'); @@ -91,114 +67,66 @@ final class DatabaseConnectionData ->setDbSocket($configData->getDbSocket()); } - /** - * @return string|null - */ public function getDbHost(): ?string { return $this->dbHost; } - /** - * @param string $dbHost - * - * @return DatabaseConnectionData - */ public function setDbHost(string $dbHost): DatabaseConnectionData { $this->dbHost = $dbHost; return $this; } - /** - * @return string|null - */ public function getDbSocket(): ?string { return $this->dbSocket; } - /** - * @param string|null $dbSocket - * - * @return DatabaseConnectionData - */ public function setDbSocket(?string $dbSocket): DatabaseConnectionData { $this->dbSocket = $dbSocket; return $this; } - /** - * @return int|null - */ public function getDbPort(): ?int { return $this->dbPort; } - /** - * @param int $dbPort - * - * @return DatabaseConnectionData - */ public function setDbPort(int $dbPort): DatabaseConnectionData { $this->dbPort = $dbPort; return $this; } - /** - * @return string|null - */ public function getDbName(): ?string { return $this->dbName; } - /** - * @param string $dbName - * - * @return DatabaseConnectionData - */ public function setDbName(string $dbName): DatabaseConnectionData { $this->dbName = $dbName; return $this; } - /** - * @return string|null - */ public function getDbUser(): ?string { return $this->dbUser; } - /** - * @param string $dbUser - * - * @return DatabaseConnectionData - */ public function setDbUser(string $dbUser): DatabaseConnectionData { $this->dbUser = $dbUser; return $this; } - /** - * @return string|null - */ public function getDbPass(): ?string { return $this->dbPass; } - /** - * @param string $dbPass - * - * @return DatabaseConnectionData - */ public function setDbPass(string $dbPass): DatabaseConnectionData { $this->dbPass = $dbPass; diff --git a/lib/SP/Storage/Database/DatabaseException.php b/lib/SP/Storage/Database/DatabaseException.php index dd942a40..4d382b1b 100644 --- a/lib/SP/Storage/Database/DatabaseException.php +++ b/lib/SP/Storage/Database/DatabaseException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\Database; diff --git a/lib/SP/Storage/Database/DatabaseFileInterface.php b/lib/SP/Storage/Database/DatabaseFileInterface.php index 7901b1df..5653e6c0 100644 --- a/lib/SP/Storage/Database/DatabaseFileInterface.php +++ b/lib/SP/Storage/Database/DatabaseFileInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\Database; @@ -33,10 +33,6 @@ interface DatabaseFileInterface { /** * Parses a database script file and returns an array of lines parsed - * - * @param string $delimiter - * - * @return array */ - public function parse($delimiter = ';'): array; + public function parse(string $delimiter = ';'): array; } \ No newline at end of file diff --git a/lib/SP/Storage/Database/DatabaseInterface.php b/lib/SP/Storage/Database/DatabaseInterface.php index 1db0c843..d7247eef 100644 --- a/lib/SP/Storage/Database/DatabaseInterface.php +++ b/lib/SP/Storage/Database/DatabaseInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\Database; @@ -38,9 +38,6 @@ interface DatabaseInterface /** * Performs a DB query * - * @param QueryData $queryData Query data - * - * @return QueryResult * @throws QueryException * @throws ConstraintException */ @@ -48,72 +45,29 @@ interface DatabaseInterface /** * Don't fetch records and return prepared statement - * - * @param QueryData $queryData - * - * @return PDOStatement */ public function doQueryRaw(QueryData $queryData): PDOStatement; /** * Returns the total number of records - * - * @param QueryData $queryData Query data - * - * @return int Records count */ public function getFullRowCount(QueryData $queryData): int; - /** - * @return DBStorageInterface - */ public function getDbHandler(): DBStorageInterface; - /** - * @return int - */ public function getNumRows(): int; - /** - * @return int - */ public function getNumFields(): int; - /** - * @return array|null - */ public function getLastResult(): ?array; - /** - * @return int|null - */ public function getLastId(): ?int; - /** - * Iniciar una transacción - * - * @return bool - */ public function beginTransaction(): bool; - /** - * Finalizar una transacción - * - * @return bool - */ public function endTransaction(): bool; - /** - * Rollback de una transacción - * - * @return bool - */ public function rollbackTransaction(): bool; - /** - * @param string $table - * - * @return array - */ public function getColumnsForTable(string $table): array; } \ No newline at end of file diff --git a/lib/SP/Storage/Database/DatabaseUtil.php b/lib/SP/Storage/Database/DatabaseUtil.php index f690d465..f02a659a 100644 --- a/lib/SP/Storage/Database/DatabaseUtil.php +++ b/lib/SP/Storage/Database/DatabaseUtil.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\Database; @@ -36,7 +36,7 @@ final class DatabaseUtil /** * @var array Tablas de la BBDD */ - public static $tables = [ + public const TABLES = [ 'Client', 'Category', 'Tag', @@ -60,49 +60,46 @@ final class DatabaseUtil 'UserPassRecover', 'UserToUserGroup', 'Plugin', + 'Track', 'Notification', 'account_data_v', 'account_search_v' ]; - /** - * @var DBStorageInterface - */ - private $DBStorage; + private DBStorageInterface $DBStorage; /** * DatabaseUtil constructor. - * - * @param DBStorageInterface $DBStorage */ public function __construct(DBStorageInterface $DBStorage) { - $this->DBStorage = $DBStorage; } /** * Comprobar que la base de datos existe. - * - * @param string $dbName - * - * @return bool */ public function checkDatabaseTables(string $dbName): bool { try { - $tables = implode(',', array_map(function ($value) { - return '\'' . $value . '\''; - }, self::$tables)); + $tables = implode(',', array_map( + static function ($value) { + return '\'' . $value . '\''; + }, + self::TABLES + )); $query = /** @lang SQL */ - 'SELECT COUNT(*) + sprintf('SELECT COUNT(*) FROM information_schema.tables - WHERE table_schema = \'' . $dbName . '\' - AND `table_name` IN (' . $tables . ')'; + WHERE table_schema = \'%s\' + AND `table_name` IN (%s)', $dbName, $tables); - $numTables = (int)$this->DBStorage->getConnection()->query($query)->fetchColumn(); + $numTables = $this->DBStorage + ->getConnection() + ->query($query) + ->fetchColumn(); - return $numTables === count(self::$tables); + return (int)$numTables === count(self::TABLES); } catch (Exception $e) { processException($e); } @@ -110,9 +107,6 @@ final class DatabaseUtil return false; } - /** - * @return bool - */ public function checkDatabaseConnection(): bool { try { @@ -128,8 +122,6 @@ final class DatabaseUtil /** * Obtener la información del servidor de base de datos - * - * @return array */ public function getDBinfo(): array { @@ -159,10 +151,6 @@ final class DatabaseUtil /** * Escapar una cadena de texto con funciones de mysqli. - * - * @param string $str string con la cadena a escapar - * - * @return string con la cadena escapada */ public function escape(string $str): string { diff --git a/lib/SP/Storage/Database/MySQLFileParser.php b/lib/SP/Storage/Database/MySQLFileParser.php index d172e4fe..1aa6a7dc 100644 --- a/lib/SP/Storage/Database/MySQLFileParser.php +++ b/lib/SP/Storage/Database/MySQLFileParser.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\Database; @@ -34,16 +34,8 @@ use SP\Storage\File\FileHandler; */ final class MySQLFileParser implements DatabaseFileInterface { - /** - * @var FileHandler - */ - private $fileHandler; + private FileHandler $fileHandler; - /** - * MySQLFileParser constructor. - * - * @param FileHandler $fileHandler - */ public function __construct(FileHandler $fileHandler) { $this->fileHandler = $fileHandler; @@ -52,12 +44,9 @@ final class MySQLFileParser implements DatabaseFileInterface /** * Parses a database script file and returns an array of lines parsed * - * @param string $delimiter - * - * @return array * @throws FileException */ - public function parse($delimiter = ';'): array + public function parse(string $delimiter = ';'): array { $queries = []; $query = ''; @@ -86,14 +75,18 @@ final class MySQLFileParser implements DatabaseFileInterface $query = ''; } - } else { - if (!$end) { - $query .= $buffer . PHP_EOL; - } elseif ($end && strpos($buffer, 'DELIMITER') === false) { - $queries[] = $query . trim(substr_replace($buffer, '', $length - $delimiterLength), $delimiterLength); + } else if (!$end) { + $query .= $buffer . PHP_EOL; + } else if (strpos($buffer, 'DELIMITER') === false) { + $queries[] = $query . + trim(substr_replace( + $buffer, + '', + $length - $delimiterLength), + $delimiterLength + ); - $query = ''; - } + $query = ''; } } } diff --git a/lib/SP/Storage/Database/MySQLHandler.php b/lib/SP/Storage/Database/MySQLHandler.php index fc5db618..d9e66c85 100644 --- a/lib/SP/Storage/Database/MySQLHandler.php +++ b/lib/SP/Storage/Database/MySQLHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\Database; @@ -45,24 +45,11 @@ final class MySQLHandler implements DBStorageInterface PDO::MYSQL_ATTR_FOUND_ROWS => true, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ ]; - /** - * @var PDO - */ - private $db; - /** - * @var int - */ - private $dbStatus = self::STATUS_KO; - /** - * @var DatabaseConnectionData - */ - private $connectionData; - /** - * MySQLHandler constructor. - * - * @param DatabaseConnectionData $connectionData - */ + private ?PDO $db = null; + private int $dbStatus = self::STATUS_KO; + private DatabaseConnectionData $connectionData; + public function __construct(DatabaseConnectionData $connectionData) { $this->connectionData = $connectionData; @@ -73,8 +60,6 @@ final class MySQLHandler implements DBStorageInterface * * OK -> 0 * KO -> 1 - * - * @return int */ public function getDbStatus(): int { @@ -85,7 +70,6 @@ final class MySQLHandler implements DBStorageInterface * Realizar la conexión con la BBDD. * Esta función utiliza PDO para conectar con la base de datos. * - * @return PDO * @throws DatabaseException */ public function getConnection(): PDO @@ -94,7 +78,8 @@ final class MySQLHandler implements DBStorageInterface if (null === $this->connectionData->getDbUser() || null === $this->connectionData->getDbPass() || null === $this->connectionData->getDbName() - || (null === $this->connectionData->getDbHost() && null === $this->connectionData->getDbSocket()) + || (null === $this->connectionData->getDbHost() + && null === $this->connectionData->getDbSocket()) ) { throw new DatabaseException( __u('Unable to connect to DB'), @@ -112,7 +97,10 @@ final class MySQLHandler implements DBStorageInterface // Set prepared statement emulation depending on server version $serverVersion = $this->db->getAttribute(PDO::ATTR_SERVER_VERSION); - $this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, version_compare($serverVersion, '5.1.17', '<')); + $this->db->setAttribute( + PDO::ATTR_EMULATE_PREPARES, + version_compare($serverVersion, '5.1.17', '<') + ); $this->dbStatus = self::STATUS_OK; } catch (Exception $e) { @@ -129,9 +117,6 @@ final class MySQLHandler implements DBStorageInterface return $this->db; } - /** - * @return string - */ public function getConnectionUri(): string { $dsn = ['charset=utf8']; @@ -156,7 +141,6 @@ final class MySQLHandler implements DBStorageInterface /** * Obtener una conexión PDO sin seleccionar la BD * - * @return PDO * @throws DatabaseException */ public function getConnectionSimple(): PDO @@ -172,7 +156,10 @@ final class MySQLHandler implements DBStorageInterface } try { - $opts = [PDO::ATTR_EMULATE_PREPARES => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]; + $opts = [ + PDO::ATTR_EMULATE_PREPARES => true, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION + ]; $this->db = new PDO( $this->getConnectionUri(), @@ -195,9 +182,6 @@ final class MySQLHandler implements DBStorageInterface return $this->db; } - /** - * @return string|null - */ public function getDatabaseName(): ?string { return $this->connectionData->getDbName(); diff --git a/lib/SP/Storage/Database/QueryData.php b/lib/SP/Storage/Database/QueryData.php index 686545e7..edf0f4d8 100644 --- a/lib/SP/Storage/Database/QueryData.php +++ b/lib/SP/Storage/Database/QueryData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,13 +19,11 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\Database; -use SP\DataModel\DataModelBase; - /** * Class QueryData * @@ -33,58 +31,19 @@ use SP\DataModel\DataModelBase; */ final class QueryData { - /** - * @var array - */ - protected $params = []; - /** - * @var string - */ - protected $query; - /** - * @var string - */ - protected $mapClassName; - /** - * @var bool - */ - protected $useKeyPair = false; - /** - * @var string - */ - protected $select; - /** - * @var string - */ - protected $from; - /** - * @var string - */ - protected $where; - /** - * @var string - */ - protected $groupBy; - /** - * @var string|null - */ - protected $order; - /** - * @var string - */ - protected $limit; - /** - * @var string - */ - protected $queryCount; - /** - * @var int Código de estado tras realizar la consulta - */ - protected $queryStatus = 0; - /** - * @var string - */ - protected $onErrorMessage; + protected array $params = []; + protected ?string $query = null; + protected ?string $mapClassName = null; + protected bool $useKeyPair = false; + protected ?string $select = null; + protected ?string $from = null; + protected ?string $where = null; + protected ?string $groupBy = null; + protected ?string $order = null; + protected ?string $limit = null; + protected ?string $queryCount = null; + protected int $queryStatus = 0; + protected ?string $onErrorMessage = null; /** * Añadir un parámetro a la consulta @@ -92,7 +51,7 @@ final class QueryData * @param $value * @param $name */ - public function addParam($value, $name = null) + public function addParam($value, $name = null): void { if (null !== $name) { $this->params[$name] = $value; @@ -101,123 +60,88 @@ final class QueryData } } - /** - * @return array - */ public function getParams(): array { return $this->params; } - /** - * Establecer los parámetros de la consulta - * - * @param array $data - */ - public function setParams(array $data) + public function setParams(array $data): void { $this->params = $data; } - /** - * @return string - */ public function getQuery(): string { if (empty($this->query)) { - return $this->select . ' ' . $this->from . ' ' . $this->where . ' ' . $this->groupBy . ' ' . $this->order . ' ' . $this->limit; + return $this->select . + ' ' . + $this->from . + ' ' . + $this->where . + ' ' . + $this->groupBy . + ' ' . + $this->order . + ' ' . + $this->limit; } return $this->query; } - /** - * @param $query - */ - public function setQuery($query) + public function setQuery(string $query): void { $this->query = $query; } - /** - * @return string|null - */ public function getMapClassName(): ?string { return $this->mapClassName; } - /** - * @param string $mapClassName - */ - public function setMapClassName(string $mapClassName) + public function setMapClassName(string $mapClassName): void { $this->mapClassName = $mapClassName; } - /** - * @return bool - */ public function isUseKeyPair(): bool { return $this->useKeyPair; } - /** - * @param boolean $useKeyPair - */ - public function setUseKeyPair(bool $useKeyPair) + public function setUseKeyPair(bool $useKeyPair): void { $this->useKeyPair = $useKeyPair; } - /** - * @return string|null - */ public function getSelect(): ?string { return $this->select; } - /** - * @param string $select - */ - public function setSelect(string $select) + public function setSelect(string $select): void { $this->select = 'SELECT ' . $select; } - /** - * @return string|null - */ public function getOrder(): ?string { return $this->order; } - /** - * @param string $order - */ - public function setOrder(string $order) + public function setOrder(string $order): void { if (!empty($order)) { $this->order = 'ORDER BY ' . $order; } } - /** - * @return string|null - */ public function getLimit(): ?string { return $this->limit; } - /** - * @param string $limit - * @param array|null $params - */ - public function setLimit(string $limit, ?array $params = null) + public function setLimit(string $limit, ?array $params = null): void { if (!empty($limit)) { $this->limit = 'LIMIT ' . $limit; @@ -228,19 +152,11 @@ final class QueryData } } - /** - * Añadir parámetros a la consulta - * - * @param array $params - */ - public function addParams(array $params) + public function addParams(array $params): void { $this->params = array_merge($this->params, $params); } - /** - * @return string - */ public function getQueryCount(): string { if (empty($this->queryCount)) { @@ -250,36 +166,27 @@ final class QueryData return $this->queryCount; } - /** - * @return string|null - */ public function getFrom(): ?string { return $this->from; } - /** - * @param string $from - */ - public function setFrom(string $from) + public function setFrom(string $from): void { if (!empty($from)) { $this->from = 'FROM ' . $from; } } - /** - * @return string|null - */ public function getWhere(): ?string { return $this->where; } /** - * @param array|string $where + * @param string[]|string $where */ - public function setWhere($where) + public function setWhere($where): void { if (!empty($where)) { if (is_array($where)) { @@ -290,34 +197,22 @@ final class QueryData } } - /** - * @return string - */ public function getOnErrorMessage(): string { return $this->onErrorMessage ?: __u('Error while querying'); } - /** - * @param string $onErrorMessage - */ - public function setOnErrorMessage(string $onErrorMessage) + public function setOnErrorMessage(string $onErrorMessage): void { $this->onErrorMessage = $onErrorMessage; } - /** - * @return string|null - */ - public function getGroupBy() + public function getGroupBy(): ?string { return $this->groupBy; } - /** - * @param string $groupBy - */ - public function setGroupBy(string $groupBy) + public function setGroupBy(string $groupBy): void { if (!empty($groupBy)) { $this->groupBy = 'GROUP BY ' . $groupBy; diff --git a/lib/SP/Storage/Database/QueryResult.php b/lib/SP/Storage/Database/QueryResult.php index 35f69091..66010b67 100644 --- a/lib/SP/Storage/Database/QueryResult.php +++ b/lib/SP/Storage/Database/QueryResult.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\Database; @@ -31,30 +31,12 @@ namespace SP\Storage\Database; */ final class QueryResult { - /** - * @var array - */ - private $data; - /** - * @var int - */ - private $numRows = 0; - /** - * @var int - */ - private $totalNumRows; - /** - * @var int - */ - private $affectedNumRows; - /** - * @var int - */ - private $statusCode; - /** - * @var int - */ - private $lastId = 0; + private ?array $data = null; + private int $numRows = 0; + private int $totalNumRows = 0; + private int $affectedNumRows = 0; + private int $statusCode = 0; + private int $lastId = 0; /** * QueryResult constructor. @@ -63,23 +45,20 @@ final class QueryResult */ public function __construct(?array $data = null) { - if ($data !== null) { + if (null !== $data) { $this->data = $data; $this->numRows = count($data); } } - /** - * @param array $data - * @param null $totalNumRows - * - * @return QueryResult - */ - public static function fromResults(array $data, $totalNumRows = null): QueryResult + public static function fromResults( + array $data, + ?int $totalNumRows = null + ): QueryResult { $result = new self($data); - if ($totalNumRows !== null) { + if (null !== $totalNumRows) { $result->totalNumRows = $totalNumRows; } @@ -91,44 +70,25 @@ final class QueryResult */ public function getData() { - if ($this->numRows === 1) { - return $this->data[0]; - } + return $this->numRows === 1 ? $this->data[0] : null; - return null; } - /** - * Always returns an array - * - * @return array - */ public function getDataAsArray(): array { - return (array)$this->data; + return $this->data ?? []; } - /** - * @return int - */ public function getNumRows(): int { return $this->numRows; } - /** - * @return int - */ public function getTotalNumRows(): int { return $this->totalNumRows; } - /** - * @param int $totalNumRows - * - * @return QueryResult - */ public function setTotalNumRows(int $totalNumRows): QueryResult { $this->totalNumRows = $totalNumRows; @@ -136,19 +96,11 @@ final class QueryResult return $this; } - /** - * @return int - */ public function getStatusCode(): int { return $this->statusCode; } - /** - * @param int $statusCode - * - * @return QueryResult - */ public function setStatusCode(int $statusCode): QueryResult { $this->statusCode = $statusCode; @@ -156,19 +108,11 @@ final class QueryResult return $this; } - /** - * @return int - */ public function getAffectedNumRows(): int { return $this->affectedNumRows; } - /** - * @param int $affectedNumRows - * - * @return QueryResult - */ public function setAffectedNumRows(int $affectedNumRows): QueryResult { $this->affectedNumRows = $affectedNumRows; @@ -176,19 +120,11 @@ final class QueryResult return $this; } - /** - * @return int - */ public function getLastId(): int { return $this->lastId; } - /** - * @param int $lastId - * - * @return QueryResult - */ public function setLastId(int $lastId): QueryResult { $this->lastId = $lastId; diff --git a/lib/SP/Storage/File/ArchiveHandler.php b/lib/SP/Storage/File/ArchiveHandler.php index 83392410..b29bbaec 100644 --- a/lib/SP/Storage/File/ArchiveHandler.php +++ b/lib/SP/Storage/File/ArchiveHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\File; @@ -37,40 +37,34 @@ use SP\Core\PhpExtensionChecker; */ final class ArchiveHandler { - const COMPRESS_EXTENSION = '.tar.gz'; + public const COMPRESS_EXTENSION = '.tar.gz'; - /** - * @var PhpExtensionChecker - */ - private $extensionChecker; - /** - * @var FileHandler - */ - private $archive; + private PhpExtensionChecker $extensionChecker; + private FileHandler $archive; - /** - * ArchiveHandler constructor. - * - * @param string $archive - * @param PhpExtensionChecker $extensionChecker - */ - public function __construct(string $archive, PhpExtensionChecker $extensionChecker) + public function __construct( + string $archive, + PhpExtensionChecker $extensionChecker + ) { $this->extensionChecker = $extensionChecker; $this->archive = new FileHandler(self::makeArchiveName($archive)); } - /** - * @param string $archive - * - * @return bool|string - */ - private static function makeArchiveName(string $archive) + private static function makeArchiveName(string $archive): string { - $archiveExtension = substr(self::COMPRESS_EXTENSION, 0, strrpos(self::COMPRESS_EXTENSION, '.')); + $archiveExtension = substr( + self::COMPRESS_EXTENSION, + 0, + strrpos(self::COMPRESS_EXTENSION, '.') + ); if (is_file($archive)) { - return substr($archive, 0, strrpos($archive, '.')) . $archiveExtension; + return substr( + $archive, + 0, + strrpos($archive, '.') + ) . $archiveExtension; } return $archive . $archiveExtension; @@ -79,13 +73,13 @@ final class ArchiveHandler /** * Realizar un backup de la aplicación y comprimirlo. * - * @param string $directory - * @param string|null $regex - * * @throws CheckException * @throws FileException */ - public function compressDirectory(string $directory, ?string $regex = null) + public function compressDirectory( + string $directory, + ?string $regex = null + ): void { $this->extensionChecker->checkPharAvailable(true); @@ -100,12 +94,10 @@ final class ArchiveHandler /** * Realizar un backup de la aplicación y comprimirlo. * - * @param string $file - * * @throws CheckException * @throws FileException */ - public function compressFile(string $file) + public function compressFile(string $file): void { $this->extensionChecker->checkPharAvailable(true); diff --git a/lib/SP/Storage/File/FileCache.php b/lib/SP/Storage/File/FileCache.php index 49f847bc..4d57ea6f 100644 --- a/lib/SP/Storage/File/FileCache.php +++ b/lib/SP/Storage/File/FileCache.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\File; @@ -32,7 +32,6 @@ namespace SP\Storage\File; final class FileCache extends FileCacheBase { /** - * @return mixed * @throws FileException */ public function load() @@ -41,9 +40,6 @@ final class FileCache extends FileCacheBase } /** - * @param mixed $data - * - * @return FileCacheInterface * @throws FileException */ public function save($data): FileCacheInterface diff --git a/lib/SP/Storage/File/FileCacheBase.php b/lib/SP/Storage/File/FileCacheBase.php index 523a1e51..e6afb266 100644 --- a/lib/SP/Storage/File/FileCacheBase.php +++ b/lib/SP/Storage/File/FileCacheBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\File; @@ -32,27 +32,14 @@ namespace SP\Storage\File; */ abstract class FileCacheBase implements FileCacheInterface { - /** - * @var FileHandler - */ - protected $path; + protected FileHandler $path; - /** - * FileCacheBase constructor. - * - * @param string $path - */ public function __construct(string $path) { $this->path = new FileHandler($path); } - /** - * @param $path - * - * @return FileCacheBase - */ - public static function factory($path): FileCacheBase + public static function factory(string $path): FileCacheBase { return new static($path); } @@ -60,12 +47,9 @@ abstract class FileCacheBase implements FileCacheInterface /** * Returns if the file is expired adding time to modification date * - * @param int $time - * - * @return bool * @throws FileException */ - public function isExpired($time = 86400): bool + public function isExpired(int $time = 86400): bool { $this->path->checkFileExists(); @@ -75,32 +59,32 @@ abstract class FileCacheBase implements FileCacheInterface /** * Returns if the file is expired adding time to modification date * - * @param int $date - * - * @return bool * @throws FileException */ public function isExpiredDate(int $date): bool { $this->path->checkFileExists(); - return (int)$date > $this->path->getFileTime(); + return $date > $this->path->getFileTime(); } /** * @throws FileException */ - public function createPath() + public function createPath(): void { $path = dirname($this->path->getFile()); - if (!is_dir($path) && mkdir($path, 0700, true) === false) { - throw new FileException(sprintf(__('Unable to create the directory (%s)'), $path)); + if (!is_dir($path) + && !mkdir($path, 0700, true) + && !is_dir($path)) { + throw new FileException( + sprintf(__('Unable to create the directory (%s)'), $path) + ); } } /** - * @return FileCacheInterface * @throws FileException */ public function delete(): FileCacheInterface @@ -110,9 +94,6 @@ abstract class FileCacheBase implements FileCacheInterface return $this; } - /** - * @return bool - */ public function exists(): bool { return file_exists($this->path->getFile()); diff --git a/lib/SP/Storage/File/FileCacheInterface.php b/lib/SP/Storage/File/FileCacheInterface.php index 273fdb0b..6ccc0791 100644 --- a/lib/SP/Storage/File/FileCacheInterface.php +++ b/lib/SP/Storage/File/FileCacheInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\File; @@ -38,39 +38,23 @@ interface FileCacheInterface public function load(); /** - * @param mixed $data - * - * @return FileCacheInterface * @throws FileException */ public function save($data): FileCacheInterface; - /** - * @return FileCacheInterface - */ public function delete(): FileCacheInterface; /** * Returns whether the file is expired - * - * @param int $time - * - * @return bool */ - public function isExpired($time = 86400): bool; + public function isExpired(int $time = 86400): bool; /** * Returns if the file is expired comparing against a reference date * - * @param int $date - * - * @return bool * @throws FileException */ public function isExpiredDate(int $date): bool; - /** - * @return bool - */ public function exists(): bool; } \ No newline at end of file diff --git a/lib/SP/Storage/File/FileCachePacked.php b/lib/SP/Storage/File/FileCachePacked.php index a7c51aa6..f9edda4a 100644 --- a/lib/SP/Storage/File/FileCachePacked.php +++ b/lib/SP/Storage/File/FileCachePacked.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\File; @@ -34,7 +34,6 @@ use RuntimeException; final class FileCachePacked extends FileCacheBase { /** - * @return mixed * @throws RuntimeException * @throws FileException */ @@ -44,7 +43,10 @@ final class FileCachePacked extends FileCacheBase $dataUnpacked = gzuncompress($this->path->readToString()); if ($dataUnpacked === false) { - throw new FileException(sprintf(__('Error while decompressing the file data (%s)'), $this->path->getFile())); + throw new FileException(sprintf( + __('Error while decompressing the file data (%s)'), + $this->path->getFile() + )); } $data = unserialize($dataUnpacked); @@ -57,9 +59,6 @@ final class FileCachePacked extends FileCacheBase } /** - * @param mixed $data - * - * @return FileCacheInterface * @throws FileException */ public function save($data): FileCacheInterface @@ -69,7 +68,10 @@ final class FileCachePacked extends FileCacheBase $data = gzcompress(serialize($data)); if ($data === false) { - throw new FileException(sprintf(__('Error while compressing the file data (%s)'), $this->path->getFile())); + throw new FileException(sprintf( + __('Error while compressing the file data (%s)'), + $this->path->getFile() + )); } $this->path->checkIsWritable() diff --git a/lib/SP/Storage/File/FileException.php b/lib/SP/Storage/File/FileException.php index eb80e3ee..a2a566cb 100644 --- a/lib/SP/Storage/File/FileException.php +++ b/lib/SP/Storage/File/FileException.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\File; diff --git a/lib/SP/Storage/File/FileHandler.php b/lib/SP/Storage/File/FileHandler.php index 05142f63..a7f223ba 100644 --- a/lib/SP/Storage/File/FileHandler.php +++ b/lib/SP/Storage/File/FileHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\File; @@ -33,25 +33,17 @@ use SP\Util\Util; */ final class FileHandler { - const CHUNK_LENGTH = 8192; - const CHUNK_FACTOR = 3; - /** - * @var string - */ - protected $file; + private const CHUNK_LENGTH = 8192; + public const CHUNK_FACTOR = 3; + protected string $file; /** * @var resource */ protected $handle; - /** - * @var bool - */ - private $locked = false; + private bool $locked = false; /** * FileHandler constructor. - * - * @param string $file */ public function __construct(string $file) { @@ -61,9 +53,6 @@ final class FileHandler /** * Writes data into file * - * @param mixed $data - * - * @return FileHandler * @throws FileException */ public function write($data): FileHandler @@ -73,7 +62,10 @@ final class FileHandler } if (@fwrite($this->handle, $data) === false) { - throw new FileException(sprintf(__('Unable to read/write the file (%s)'), $this->file)); + throw new FileException(sprintf( + __('Unable to read/write the file (%s)'), + $this->file) + ); } return $this; @@ -82,14 +74,10 @@ final class FileHandler /** * Opens the file * - * @param string $mode - * - * @param bool|null $lock - * * @return resource * @throws FileException */ - public function open(string $mode = 'r', ?bool $lock = false) + public function open(string $mode = 'rb', ?bool $lock = false) { $this->handle = @fopen($this->file, $mode); @@ -98,7 +86,10 @@ final class FileHandler } if ($this->handle === false) { - throw new FileException(sprintf(__('Unable to open the file (%s)'), $this->file)); + throw new FileException(sprintf( + __('Unable to open the file (%s)'), + $this->file) + ); } return $this->handle; @@ -107,16 +98,17 @@ final class FileHandler /** * Lock the file * - * @param int $mode - * * @throws FileException */ - private function lock(int $mode = LOCK_EX) + private function lock(int $mode = LOCK_EX): void { $this->locked = flock($this->handle, $mode); if (!$this->locked) { - throw new FileException(sprintf(__('Unable to obtain a lock (%s)'), $this->file)); + throw new FileException(sprintf( + __('Unable to obtain a lock (%s)'), + $this->file + )); } logger(sprintf('File locked: %s', $this->file)); @@ -125,13 +117,17 @@ final class FileHandler /** * Reads data from file into a string * - * @return string Data read from file * @throws FileException */ public function readToString(): string { - if (($data = file_get_contents($this->file)) === false) { - throw new FileException(sprintf(__('Unable to read from file (%s)'), $this->file)); + $data = file_get_contents($this->file); + + if ($data === false) { + throw new FileException(sprintf( + __('Unable to read from file (%s)'), + $this->file + )); } return $data; @@ -144,25 +140,30 @@ final class FileHandler */ public function readToArray(): array { - if (($data = @file($this->file, FILE_SKIP_EMPTY_LINES)) === false) { - throw new FileException(sprintf(__('Unable to read from file (%s)'), $this->file)); + $data = @file($this->file, FILE_SKIP_EMPTY_LINES); + + if ($data === false) { + throw new FileException(sprintf( + __('Unable to read from file (%s)'), + $this->file + )); } return $data; } /** - * Reads data from file into a string + * Saves a string into a file * - * @param string $data Data to write into file - * - * @return FileHandler * @throws FileException */ public function save(string $data): FileHandler { if (file_put_contents($this->file, $data, LOCK_EX) === false) { - throw new FileException(sprintf(__('Unable to read/write the file (%s)'), $this->file)); + throw new FileException(sprintf( + __('Unable to read/write the file (%s)'), + $this->file + )); } return $this; @@ -171,13 +172,12 @@ final class FileHandler /** * Reads data from file * - * @return string Data read from file * @throws FileException */ public function read(): string { if (!is_resource($this->handle)) { - $this->open('rb'); + $this->open(); } $data = ''; @@ -194,7 +194,6 @@ final class FileHandler /** * Closes the file * - * @return FileHandler * @throws FileException */ public function close(): FileHandler @@ -204,7 +203,10 @@ final class FileHandler } if (!is_resource($this->handle) || @fclose($this->handle) === false) { - throw new FileException(sprintf(__('Unable to close the file (%s)'), $this->file)); + throw new FileException(sprintf( + __('Unable to close the file (%s)'), + $this->file + )); } return $this; @@ -213,7 +215,7 @@ final class FileHandler /** * Unlock the file */ - private function unlock() + private function unlock(): void { $this->locked = !flock($this->handle, LOCK_UN); } @@ -224,16 +226,19 @@ final class FileHandler * * @throws FileException */ - public function readChunked(callable $chunker = null, ?float $rate = null) + public function readChunked( + callable $chunker = null, + ?float $rate = null + ): void { $maxRate = Util::getMaxDownloadChunk() / self::CHUNK_FACTOR; if ($rate === null || $rate > $maxRate) { - $rate = $maxRate; + $rate = (float)$maxRate; } if (!is_resource($this->handle)) { - $this->open('rb'); + $this->open(); } while (!feof($this->handle)) { @@ -252,13 +257,15 @@ final class FileHandler /** * Checks if the file is writable * - * @return FileHandler * @throws FileException */ public function checkIsWritable(): FileHandler { if (!is_writable($this->file) && @touch($this->file) === false) { - throw new FileException(sprintf(__('Unable to write in file (%s)'), $this->file)); + throw new FileException(sprintf( + __('Unable to write in file (%s)'), + $this->file + )); } return $this; @@ -267,38 +274,38 @@ final class FileHandler /** * Checks if the file exists * - * @return FileHandler * @throws FileException */ public function checkFileExists(): FileHandler { if (!file_exists($this->file)) { - throw new FileException(sprintf(__('File not found (%s)'), $this->file)); + throw new FileException(sprintf( + __('File not found (%s)'), + $this->file + )); } return $this; } - /** - * @return string - */ public function getFile(): string { return $this->file; } /** - * @param bool $isExceptionOnZero - * - * @return int * @throws FileException */ - public function getFileSize($isExceptionOnZero = false): int + public function getFileSize(bool $isExceptionOnZero = false): int { $size = filesize($this->file); - if ($size === false || ($isExceptionOnZero === true && $size === 0)) { - throw new FileException(sprintf(__('Unable to read/write file (%s)'), $this->file)); + if ($size === false + || ($isExceptionOnZero === true && $size === 0)) { + throw new FileException(sprintf( + __('Unable to read/write file (%s)'), + $this->file + )); } return $size; @@ -306,8 +313,6 @@ final class FileHandler /** * Clears the stat cache for the given file - * - * @return FileHandler */ public function clearCache(): FileHandler { @@ -319,13 +324,15 @@ final class FileHandler /** * Deletes a file * - * @return FileHandler * @throws FileException */ public function delete(): FileHandler { if (@unlink($this->file) === false) { - throw new FileException(sprintf(__('Unable to delete file (%s)'), $this->file)); + throw new FileException(sprintf( + __('Unable to delete file (%s)'), + $this->file + )); } return $this; @@ -334,7 +341,6 @@ final class FileHandler /** * Returns the content type in MIME format * - * @return string * @throws FileException */ public function getFileType(): string @@ -347,20 +353,21 @@ final class FileHandler /** * Checks if the file is readable * - * @return FileHandler * @throws FileException */ public function checkIsReadable(): FileHandler { if (!is_readable($this->file)) { - throw new FileException(sprintf(__('Unable to read/write file (%s)'), $this->file)); + throw new FileException(sprintf( + __('Unable to read/write file (%s)'), + $this->file + )); } return $this; } /** - * @return int * @throws FileException */ public function getFileTime(): int diff --git a/lib/SP/Storage/File/XmlFileStorageInterface.php b/lib/SP/Storage/File/XmlFileStorageInterface.php index 4dcf0712..69137637 100644 --- a/lib/SP/Storage/File/XmlFileStorageInterface.php +++ b/lib/SP/Storage/File/XmlFileStorageInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\File; @@ -32,9 +32,6 @@ namespace SP\Storage\File; interface XmlFileStorageInterface { /** - * @param string $node - * - * @return XmlFileStorageInterface * @throws FileException */ public function load(string $node = ''): XmlFileStorageInterface; @@ -43,28 +40,18 @@ interface XmlFileStorageInterface * @param mixed $data Data to be saved * @param string $node * - * @return XmlFileStorageInterface * @throws FileException */ public function save($data, string $node = ''): XmlFileStorageInterface; - /** - * @return mixed - */ public function getItems(); /** * Returns the given path node value * - * @param $path - * - * @return string - * @throws FileException + * @throws \SP\Storage\File\FileException */ public function getPathValue(string $path): string; - /** - * @return FileHandler - */ public function getFileHandler(): FileHandler; } \ No newline at end of file diff --git a/lib/SP/Storage/File/XmlHandler.php b/lib/SP/Storage/File/XmlHandler.php index e9c269d4..287f0868 100644 --- a/lib/SP/Storage/File/XmlHandler.php +++ b/lib/SP/Storage/File/XmlHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Storage\File; @@ -43,23 +43,11 @@ final class XmlHandler implements XmlFileStorageInterface * @var mixed */ protected $items; - /** - * @var DOMDocument - */ - private $Dom; - /** - * @var DOMElement - */ - private $root; - /** - * @var FileHandler - */ - private $fileHandler; + private ?DOMDocument $document = null; + private FileHandler $fileHandler; /** * XmlHandler constructor. - * - * @param FileHandler $fileHandler */ public function __construct(FileHandler $fileHandler) { @@ -69,9 +57,6 @@ final class XmlHandler implements XmlFileStorageInterface /** * Cargar un archivo XML * - * @param string $node - * - * @return XmlFileStorageInterface * @throws FileException * @throws RuntimeException */ @@ -82,9 +67,9 @@ final class XmlHandler implements XmlFileStorageInterface $this->items = []; $this->setDOM(); - $this->Dom->load($this->fileHandler->getFile()); + $this->document->load($this->fileHandler->getFile()); - $nodes = $this->Dom->getElementsByTagName($node); + $nodes = $this->document->getElementsByTagName($node); if ($nodes->length === 0) { throw new RuntimeException(__u('XML node does not exist')); @@ -98,17 +83,13 @@ final class XmlHandler implements XmlFileStorageInterface /** * Crear un nuevo documento XML */ - private function setDOM() + private function setDOM(): void { - $this->Dom = new DOMDocument('1.0', 'utf-8'); + $this->document = new DOMDocument('1.0', 'utf-8'); } /** * Leer de forma recursiva los nodos hijos y devolver un array multidimensional - * - * @param DOMNodeList $nodeList - * - * @return array */ protected function readChildNodes(DOMNodeList $nodeList): array { @@ -127,7 +108,7 @@ final class XmlHandler implements XmlFileStorageInterface } elseif ($node->hasAttribute('class')) { $nodes[$node->nodeName] = $this->readChildNodes($node->childNodes); - $nodes[$node->nodeName]['__class__'] = (string)$node->getAttribute('class');; + $nodes[$node->nodeName]['__class__'] = (string)$node->getAttribute('class'); } else { $nodes[$node->nodeName] = $this->readChildNodes($node->childNodes); } @@ -155,10 +136,6 @@ final class XmlHandler implements XmlFileStorageInterface /** * Obtener un elemento del array - * - * @param $id - * - * @return mixed */ public function __get($id) { @@ -168,10 +145,6 @@ final class XmlHandler implements XmlFileStorageInterface /** * Guardar el archivo XML * - * @param mixed $data Data to be saved - * @param string $node - * - * @return XmlFileStorageInterface * @throws FileException * @throws RuntimeException */ @@ -184,32 +157,32 @@ final class XmlHandler implements XmlFileStorageInterface } $this->setDOM(); - $this->Dom->formatOutput = true; + $this->document->formatOutput = true; - $this->root = $this->Dom->createElement($node); - $this->Dom->appendChild($this->root); - $this->writeChildNodes($data, $this->root); + $root = $this->document->createElement($node); + $this->document->appendChild($root); + $this->writeChildNodes($data, $root); - $this->fileHandler->save($this->Dom->saveXML()); + $this->fileHandler->save($this->document->saveXML()); return $this; } /** * Crear los nodos hijos recursivamente a partir de un array multidimensional - * - * @param mixed $items - * @param DOMNode $node - * @param null $type */ - protected function writeChildNodes($items, DOMNode $node, $type = null) + protected function writeChildNodes( + $items, + DOMNode $node, + $type = null + ): void { foreach ($this->analyzeItems($items) as $key => $value) { if (is_int($key)) { - $newNode = $this->Dom->createElement('item'); + $newNode = $this->document->createElement('item'); $newNode->setAttribute('type', $type); } else { - $newNode = $this->Dom->createElement($key); + $newNode = $this->document->createElement($key); } if (is_array($value)) { @@ -217,9 +190,9 @@ final class XmlHandler implements XmlFileStorageInterface } else if (is_object($value)) { $newNode->setAttribute('class', get_class($value)); $this->writeChildNodes($value, $newNode, $key); -// $newNode->appendChild($this->Dom->createTextNode(base64_encode(serialize($value)))); +// $newNode->appendChild($this->document->createTextNode(base64_encode(serialize($value)))); } else { - $newNode->appendChild($this->Dom->createTextNode(trim($value))); + $newNode->appendChild($this->document->createTextNode(trim($value))); } $node->appendChild($newNode); @@ -229,12 +202,9 @@ final class XmlHandler implements XmlFileStorageInterface /** * Analizar el tipo de elementos * - * @param mixed $items - * @param bool $serialize - * * @return array|string */ - protected function analyzeItems($items, $serialize = false) + protected function analyzeItems($items, bool $serialize = false) { if (is_array($items)) { ksort($items); @@ -252,12 +222,8 @@ final class XmlHandler implements XmlFileStorageInterface /** * Analizar un elemento del tipo objeto - * - * @param $object - * - * @return array */ - protected function analyzeObject($object) + protected function analyzeObject(object $object): array { $items = []; $reflection = new ReflectionObject($object); @@ -286,8 +252,6 @@ final class XmlHandler implements XmlFileStorageInterface /** * Devolver los elementos cargados - * - * @return mixed */ public function getItems() { @@ -296,12 +260,8 @@ final class XmlHandler implements XmlFileStorageInterface /** * Establecer los elementos - * - * @param $items - * - * @return XmlHandler */ - public function setItems($items) + public function setItems($items): XmlHandler { $this->items = $items; @@ -309,12 +269,9 @@ final class XmlHandler implements XmlFileStorageInterface } /** - * @param $path - * - * @return string - * @throws FileException + * @throws \SP\Storage\File\FileException */ - public function getPathValue(string $path):string + public function getPathValue(string $path): string { $this->fileHandler->checkIsReadable(); $this->fileHandler->getFileSize(true); @@ -331,9 +288,6 @@ final class XmlHandler implements XmlFileStorageInterface return $query->item(0)->nodeValue; } - /** - * @return FileHandler - */ public function getFileHandler(): FileHandler { return $this->fileHandler; diff --git a/lib/SP/Util/ArrayUtil.php b/lib/SP/Util/ArrayUtil.php index 02c37509..0df7de89 100644 --- a/lib/SP/Util/ArrayUtil.php +++ b/lib/SP/Util/ArrayUtil.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; @@ -42,10 +42,10 @@ final class ArrayUtil * @return false|object */ public static function searchInObject( - array $array, + array $array, string $property, string $value, - $default = null + $default = null ) { foreach ($array as $object) { @@ -57,7 +57,7 @@ final class ArrayUtil } } - return null !== $default ? $default : false; + return $default ?? false; } /** @@ -69,7 +69,11 @@ final class ArrayUtil * * @return bool */ - public static function checkInObjectArrayMethod(array $objectArray, string $method, $value) + public static function checkInObjectArrayMethod( + array $objectArray, + string $method, + $value + ): bool { foreach ($objectArray as $object) { if (is_callable([$object, $method]) && $object->$method() === $value) { @@ -82,16 +86,14 @@ final class ArrayUtil /** * Comprobar si un valor existe en un array de objetos - * - * @param array $objectArray - * @param string $property - * @param mixed $value - * - * @return bool */ - public static function checkInObjectArray(array $objectArray, string $property, $value) + public static function checkInObjectArray( + array $objectArray, + string $property, + $value + ): bool { - if (empty($objectArray)) { + if (count($objectArray) === 0) { return false; } diff --git a/lib/SP/Util/Checks.php b/lib/SP/Util/Checks.php index e512be0b..846a6c4b 100644 --- a/lib/SP/Util/Checks.php +++ b/lib/SP/Util/Checks.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; @@ -33,8 +33,6 @@ final class Checks { /** * Comprobar si sysPass se ejecuta en W$indows. - * - * @return bool */ public static function checkIsWindows(): bool { @@ -43,8 +41,6 @@ final class Checks /** * Comprobar la versión de PHP. - * - * @return bool */ public static function checkPhpVersion(): bool { diff --git a/lib/SP/Util/Connection.php b/lib/SP/Util/Connection.php index fdccfad7..8021e6c3 100644 --- a/lib/SP/Util/Connection.php +++ b/lib/SP/Util/Connection.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; @@ -38,27 +38,10 @@ final class Connection implements ConnectionInterface */ protected $socket; - /** - * @var string - */ - protected $host = ''; - - /** - * @var int - */ - protected $port = 0; - /** - * Código de error del socket - * - * @var int - */ - protected $errorno = 0; - /** - * Mensaje de error del socket - * - * @var string - */ - protected $errorstr = ''; + protected string $host; + protected int $port; + protected int $errorno = 0; + protected string $errorstr = ''; /** * @param $host string El host a conectar @@ -80,17 +63,17 @@ final class Connection implements ConnectionInterface */ public function getSocket(int $type) { - switch ($type) { - case self::TYPE_UDP: - $this->socket = $this->getUDPSocket(); - break; - default: - $this->socket = $this->getTCPSocket(); - break; + if ($type === self::TYPE_UDP) { + $this->socket = $this->getUDPSocket(); + } else { + $this->socket = $this->getTCPSocket(); } if ($this->socket === false) { - throw new SPException($this->getSocketError(), SPException::WARNING); + throw new SPException( + $this->getSocketError(), + SPException::WARNING + ); } stream_set_timeout($this->socket, self::SOCKET_TIMEOUT); @@ -105,8 +88,12 @@ final class Connection implements ConnectionInterface */ private function getUDPSocket() { - return stream_socket_client('udp://' . $this->host . ':' . $this->port, $this->errorno, $this->errorstr, self::SOCKET_TIMEOUT); -// return @socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); + return stream_socket_client( + 'udp://' . $this->host . ':' . $this->port, + $this->errorno, + $this->errorstr, + self::SOCKET_TIMEOUT + ); } /** @@ -116,19 +103,20 @@ final class Connection implements ConnectionInterface */ private function getTCPSocket() { - return stream_socket_client('tcp://' . $this->host . ':' . $this->port, $this->errorno, $this->errorstr, self::SOCKET_TIMEOUT); -// return @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + return stream_socket_client( + 'tcp://' . $this->host . ':' . $this->port, + $this->errorno, + $this->errorstr, + self::SOCKET_TIMEOUT + ); } /** * Obtener el último error del socket - * - * @return string */ public function getSocketError(): string { return sprintf('%s (%d)', $this->errorstr, $this->errorno); -// return socket_strerror(socket_last_error($this->_socket)); } /** @@ -137,28 +125,30 @@ final class Connection implements ConnectionInterface public function closeSocket() { fclose($this->socket); -// @socket_close($this->_socket); } /** * Enviar un mensaje al socket * - * @param $message string El mensaje a enviar - * - * @return int|bool * @throws SPException */ - public function send(string $message) + public function send(string $message): int { if (!is_resource($this->socket)) { - throw new SPException(__u('Socket not initialized'), SPException::WARNING); + throw new SPException( + __u('Socket not initialized'), + SPException::WARNING + ); } $nBytes = @fwrite($this->socket, $message); -// $nBytes = @socket_sendto($this->_socket, $message, strlen($message), 0, $this->_host, $this->port); if ($nBytes === false) { - throw new SPException(__u('Error while sending the data'), SPException::WARNING, $this->getSocketError()); + throw new SPException( + __u('Error while sending the data'), + SPException::WARNING, + $this->getSocketError() + ); } return $nBytes; diff --git a/lib/SP/Util/ConnectionInterface.php b/lib/SP/Util/ConnectionInterface.php index ae73de5e..21b442c5 100644 --- a/lib/SP/Util/ConnectionInterface.php +++ b/lib/SP/Util/ConnectionInterface.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; @@ -31,39 +31,29 @@ namespace SP\Util; */ interface ConnectionInterface { - const TYPE_TCP = 1; - const TYPE_UDP = 2; - const SOCKET_TIMEOUT = 10; + public const TYPE_TCP = 1; + public const TYPE_UDP = 2; + public const SOCKET_TIMEOUT = 10; /** * Obtener un socket * - * @param $type - * * @return resource */ public function getSocket(int $type); /** * Cerrar un socket - * - * @return mixed */ public function closeSocket(); /** * Obtener el último error del socket - * - * @return string */ public function getSocketError(): string; /** * Enviar un mensaje al socket - * - * @param $message string El mensaje a enviar - * - * @return mixed */ public function send(string $message); } \ No newline at end of file diff --git a/lib/SP/Util/DateUtil.php b/lib/SP/Util/DateUtil.php index ba97dd91..eae77309 100644 --- a/lib/SP/Util/DateUtil.php +++ b/lib/SP/Util/DateUtil.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; @@ -34,8 +34,8 @@ final class DateUtil /** * Returns date string from UNIX timestamp * - * @param mixed $date - * @param string $format + * @param int|string $date + * @param string $format * * @return false|string */ diff --git a/lib/SP/Util/ErrorUtil.php b/lib/SP/Util/ErrorUtil.php index 07225788..8dc3ed41 100644 --- a/lib/SP/Util/ErrorUtil.php +++ b/lib/SP/Util/ErrorUtil.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; @@ -42,25 +42,27 @@ final class ErrorUtil /** * Constantes de errores */ - const ERR_UNAVAILABLE = 0; - const ERR_ACCOUNT_NO_PERMISSION = 1; - const ERR_PAGE_NO_PERMISSION = 2; - const ERR_UPDATE_MPASS = 3; - const ERR_OPERATION_NO_PERMISSION = 4; - const ERR_EXCEPTION = 5; + public const ERR_UNAVAILABLE = 0; + public const ERR_ACCOUNT_NO_PERMISSION = 1; + public const ERR_PAGE_NO_PERMISSION = 2; + public const ERR_UPDATE_MPASS = 3; + public const ERR_OPERATION_NO_PERMISSION = 4; + public const ERR_EXCEPTION = 5; /** * Establecer la plantilla de error con el código indicado. * - * @param Template $view - * @param Exception $e - * @param string $replace Template replacement - * @param bool $render + * @param Template $view + * @param Exception $e + * @param string|null $replace Template replacement + * @param bool $render */ - public static function showExceptionInView(Template $view, - Exception $e, - $replace = null, - $render = true) + public static function showExceptionInView( + Template $view, + Exception $e, + ?string $replace = null, + bool $render = true + ): void { switch (get_class($e)) { case UpdatedMasterPassException::class: @@ -87,10 +89,10 @@ final class ErrorUtil */ public static function showErrorInView( Template $view, - int $type, - bool $render = true, - ?string $replace = null - ) + int $type, + bool $render = true, + ?string $replace = null + ): void { self::addErrorTemplate($view, $replace); @@ -114,11 +116,10 @@ final class ErrorUtil } } - /** - * @param Template $view - * @param string|null $replace - */ - private static function addErrorTemplate(Template $view, string $replace = null) + private static function addErrorTemplate( + Template $view, + string $replace = null + ): void { if ($replace === null) { $view->resetTemplates(); @@ -142,12 +143,8 @@ final class ErrorUtil /** * Return error message by type - * - * @param $type - * - * @return mixed */ - protected static function getErrorTypes($type): array + protected static function getErrorTypes(int $type): array { $errorTypes = [ self::ERR_UNAVAILABLE => [ @@ -176,13 +173,9 @@ final class ErrorUtil ] ]; - if (!isset($errorTypes[$type])) { - return [ + return $errorTypes[$type] ?? [ 'txt' => __('An exception occured'), 'hint' => __('Please contact to the administrator') ]; - } - - return $errorTypes[$type]; } } \ No newline at end of file diff --git a/lib/SP/Util/FileUtil.php b/lib/SP/Util/FileUtil.php index 8c41044d..720b41e1 100644 --- a/lib/SP/Util/FileUtil.php +++ b/lib/SP/Util/FileUtil.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; @@ -37,18 +37,20 @@ use SP\DataModel\FileData; */ final class FileUtil { - const IMAGE_MIME = ['image/jpeg', 'image/png', 'image/bmp', 'image/gif']; + private const IMAGE_MIME = [ + 'image/jpeg', + 'image/png', + 'image/bmp', + 'image/gif' + ]; /** * Removes a directory in a recursive way * - * @param $dir - * - * @return bool - * @throws FileNotFoundException + * @throws \SP\Core\Exceptions\FileNotFoundException * @see https://stackoverflow.com/a/7288067 */ - public static function rmdir_recursive($dir): bool + public static function rmdir_recursive(string $dir): bool { if (!is_dir($dir)) { throw new FileNotFoundException('Directory does not exist'); @@ -72,13 +74,12 @@ final class FileUtil return rmdir($dir); } - /** - * @param FileData $fileData - * - * @return bool - */ public static function isImage(FileData $fileData): bool { - return in_array(strtolower($fileData->getType()), self::IMAGE_MIME, true); + return in_array( + strtolower($fileData->getType()), + self::IMAGE_MIME, + true + ); } } \ No newline at end of file diff --git a/lib/SP/Util/Filter.php b/lib/SP/Util/Filter.php index bd3757ce..9976573b 100644 --- a/lib/SP/Util/Filter.php +++ b/lib/SP/Util/Filter.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; @@ -33,72 +33,55 @@ defined('APP_ROOT') || die(); */ final class Filter { - /** - * Limpiar una cadena de búsqueda de carácteres utilizados en expresiones regulares - * - * @param $string - * - * @return mixed - */ - public static function safeSearchString(string $string) - { - return str_replace(['/', '[', '\\', ']', '%', '{', '}', '*', '$'], '', (string)$string); - } + private const UNSAFE_CHARS = ['/', '[', '\\', ']', '%', '{', '}', '*', '$']; /** - * @param $value - * - * @return string + * Limpiar una cadena de búsqueda de carácteres utilizados en expresiones regulares */ + public static function safeSearchString(string $string): string + { + return str_replace(self::UNSAFE_CHARS, '', $string); + } + public static function getEmail(string $value): string { return filter_var(trim($value), FILTER_SANITIZE_EMAIL); } - /** - * @param array $array - * - * @return array - */ public static function getArray(array $array): array { - return array_map(static function ($value) { - if ($value !== null) { - return is_numeric($value) - ? Filter::getInt($value) - : Filter::getString($value); - } + return array_map( + static function ($value) { + if ($value !== null) { + return is_numeric($value) + ? Filter::getInt($value) + : Filter::getString($value); + } - return null; - }, $array); + return null; + }, + $array + ); } /** * @param string|int $value - * - * @return int */ public static function getInt($value): int { return (int)filter_var($value, FILTER_SANITIZE_NUMBER_INT); } - /** - * @param string|null $value - * - * @return string - */ public static function getString(?string $value): string { - return filter_var(trim($value), FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES); + return filter_var( + trim($value), + FILTER_SANITIZE_STRING, + FILTER_FLAG_NO_ENCODE_QUOTES + ); } - /** - * @param $value - * - * @return string - */ - public static function getRaw($value): string + public static function getRaw(string $value): string { return filter_var(trim($value), FILTER_UNSAFE_RAW); } diff --git a/lib/SP/Util/HttpUtil.php b/lib/SP/Util/HttpUtil.php index 1d75703d..5f6b4e91 100644 --- a/lib/SP/Util/HttpUtil.php +++ b/lib/SP/Util/HttpUtil.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,12 +19,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Html\Html; use SP\Http\Request; @@ -37,26 +37,35 @@ final class HttpUtil { /** * Comprobar y forzar (si es necesario) la conexión HTTPS - * - * @param ConfigData $configData - * @param Request $request */ - public static function checkHttps(ConfigData $configData, Request $request) + public static function checkHttps( + ConfigDataInterface $configData, + Request $request + ): void { if ($configData->isHttpsEnabled() && !$request->isHttps()) { $serverPort = $request->getServerPort(); $port = $serverPort !== 443 ? ':' . $serverPort : ''; - $host = str_replace('http', 'https', $request->getHttpHost()); + $host = str_replace( + 'http', + 'https', + $request->getHttpHost() + ); - header('Location: ' . $host . $port . $_SERVER['REQUEST_URI']); + header(sprintf( + 'Location: %s%s%s', + $host, + $port, + $_SERVER['REQUEST_URI'] + )); } } /** * Comprobar si existen parámetros pasados por POST para enviarlos por GET */ - public static function importUrlParamsToGet() + public static function importUrlParamsToGet(): string { $params = []; diff --git a/lib/SP/Util/ImageUtil.php b/lib/SP/Util/ImageUtil.php index 9d5d2451..7573e9df 100644 --- a/lib/SP/Util/ImageUtil.php +++ b/lib/SP/Util/ImageUtil.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; @@ -38,10 +38,6 @@ defined('APP_ROOT') || die(); final class ImageUtil { /** - * ImageUtil constructor. - * - * @param PhpExtensionChecker $checker - * * @throws CheckException */ public function __construct(PhpExtensionChecker $checker) @@ -52,12 +48,9 @@ final class ImageUtil /** * Crear miniatura de una imagen * - * @param $image string La imagen a redimensionar - * - * @return bool|string * @throws InvalidImageException */ - public function createThumbnail(string $image) + public function createThumbnail(string $image): string { $im = @imagecreatefromstring($image); @@ -76,13 +69,24 @@ final class ImageUtil $imTmp = imagecreatetruecolor($new_width, $new_height); // Redimensionar la imagen - imagecopyresized($imTmp, $im, 0, 0, 0, 0, $new_width, $new_height, $width, $height); + imagecopyresized( + $imTmp, + $im, + 0, + 0, + 0, + 0, + $new_width, + $new_height, + $width, + $height + ); // Devolver la imagen ob_start(); imagepng($imTmp); - $thumbnail = ob_get_contents(); - ob_end_clean(); + + $thumbnail = ob_get_clean(); imagedestroy($imTmp); imagedestroy($im); @@ -93,8 +97,6 @@ final class ImageUtil /** * Convertir un texto a imagen * - * @param $text string El texto a convertir - * * @return bool|string */ public function convertText(string $text) @@ -126,8 +128,7 @@ final class ImageUtil // Devolver la imagen ob_start(); imagepng($im); - $image = ob_get_contents(); - ob_end_clean(); + $image = ob_get_clean(); imagedestroy($im); diff --git a/lib/SP/Util/Link.php b/lib/SP/Util/Link.php index 0268e6fe..fea8d659 100644 --- a/lib/SP/Util/Link.php +++ b/lib/SP/Util/Link.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,14 +19,14 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; use SP\Bootstrap; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Acl\Acl; use SP\Http\Uri; @@ -37,20 +37,11 @@ use SP\Http\Uri; */ final class Link { - /** - * @param int $itemId - * @param int $actionId - * @param ConfigData $configData - * - * @param bool $useUI - * - * @return string - */ public static function getDeepLink( - int $itemId, - int $actionId, - ConfigData $configData, - bool $useUI = false + int $itemId, + int $actionId, + ConfigDataInterface $configData, + bool $useUI = false ): string { $route = Acl::getActionRoute($actionId) . '/' . $itemId; diff --git a/lib/SP/Util/PasswordUtil.php b/lib/SP/Util/PasswordUtil.php index 2ec41041..0fa6357c 100644 --- a/lib/SP/Util/PasswordUtil.php +++ b/lib/SP/Util/PasswordUtil.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; @@ -36,12 +36,12 @@ use Defuse\Crypto\Exception\EnvironmentIsBrokenException; */ final class PasswordUtil { - const CHARS = 'abcdefghijklmnopqrstuwxyz'; - const CHARS_SPECIAL = '@$%&/()!_:.;{}^-'; - const CHARS_NUMBER = '0123456789'; - const FLAG_PASSWORD_NUMBER = 2; - const FLAG_PASSWORD_SPECIAL = 4; - const FLAG_PASSWORD_STRENGTH = 8; + private const CHARS = 'abcdefghijklmnopqrstuwxyz'; + private const CHARS_SPECIAL = '@$%&/()!_:.;{}^-'; + private const CHARS_NUMBER = '0123456789'; + public const FLAG_PASSWORD_NUMBER = 2; + public const FLAG_PASSWORD_SPECIAL = 4; + public const FLAG_PASSWORD_STRENGTH = 8; /** * Generate a ramdom password @@ -50,11 +50,17 @@ final class PasswordUtil * @param int|null $flags Password chars included and checking strength flags * * @return string + * @throws \Exception */ - public static function randomPassword(int $length = 16, int $flags = null): string + public static function randomPassword( + int $length = 16, + int $flags = null + ): string { if ($flags === null) { - $flags = self::FLAG_PASSWORD_SPECIAL | self::FLAG_PASSWORD_NUMBER | self::FLAG_PASSWORD_STRENGTH; + $flags = self::FLAG_PASSWORD_SPECIAL + | self::FLAG_PASSWORD_NUMBER + | self::FLAG_PASSWORD_STRENGTH; } $useSpecial = ($flags & self::FLAG_PASSWORD_SPECIAL) > 0; @@ -72,13 +78,14 @@ final class PasswordUtil /** * @return array + * @throws \Exception */ - $passGen = function () use ($alphabet, $length) { + $passGen = static function () use ($alphabet, $length) { $pass = []; $alphaLength = strlen($alphabet) - 1; //put the length -1 in cache for ($i = 0; $i < $length; $i++) { - $n = mt_rand(0, $alphaLength); + $n = random_int(0, $alphaLength); $pass[] = $alphabet[$n]; } @@ -107,11 +114,6 @@ final class PasswordUtil return implode($passGen()); } - /** - * @param array $pass - * - * @return array - */ public static function checkStrength(array $pass): array { $charsUpper = strtoupper(self::CHARS); @@ -132,7 +134,6 @@ final class PasswordUtil * * @param int $length opcional, con la longitud de la cadena * - * @return string * @throws EnvironmentIsBrokenException */ public static function generateRandomBytes(int $length = 30): string diff --git a/lib/SP/Util/Util.php b/lib/SP/Util/Util.php index 2c2980e9..233f2504 100644 --- a/lib/SP/Util/Util.php +++ b/lib/SP/Util/Util.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; @@ -34,7 +34,6 @@ defined('APP_ROOT') || die(); */ final class Util { - /** * Comprueba y devuelve un directorio temporal válido * @@ -45,12 +44,12 @@ final class Util $sysTmp = sys_get_temp_dir(); $file = 'syspass.test'; - $checkDir = function ($dir) use ($file) { + $checkDir = static function ($dir) use ($file) { if (file_exists($dir . DIRECTORY_SEPARATOR . $file)) { return $dir; } - if (is_dir($dir) || @mkdir($dir)) { + if (is_dir($dir) || mkdir($dir) || is_dir($dir)) { if (touch($dir . DIRECTORY_SEPARATOR . $file)) { return $dir; } @@ -71,7 +70,7 @@ final class Util * * FIXME */ - public static function logout() + public static function logout(): void { exit(''); } @@ -86,21 +85,16 @@ final class Util self::convertShortUnit(ini_get('memory_limit'))); } - /** - * @param $value - * - * @return int - */ - public static function convertShortUnit($value): int + public static function convertShortUnit(string $value): int { if (preg_match('/(\d+)(\w+)/', $value, $match)) { switch (strtoupper($match[2])) { case 'K': return (int)$match[1] * 1024; case 'M': - return (int)$match[1] * pow(1024, 2); + return (int)$match[1] * (1024 ** 2); case 'G': - return (int)$match[1] * pow(1024, 3); + return (int)$match[1] * (1024 ** 3); } } @@ -120,13 +114,13 @@ final class Util * @author Samuel Levy * */ - public static function boolval($in, $strict = false): bool + public static function boolval($in, bool $strict = false): bool { $in = is_string($in) ? strtolower($in) : $in; // if not strict, we only have to check if something is false - if (in_array($in, ['false', 'no', 'n', '0', 'off', false, 0], true) - || !$in + if (!$in + || in_array($in, ['false', 'no', 'n', '0', 'off', false, 0], true) ) { return false; } @@ -160,9 +154,7 @@ final class Util if ($match) { foreach ($matches['class'] as $class) { - if (!class_exists($class) - || $class !== $dstClass - ) { + if ($class !== $dstClass || !class_exists($class)) { $process = true; } } @@ -178,7 +170,7 @@ final class Util if ($srcClass !== null) { $serialized = preg_replace_callback( '/:\d+:"\x00' . preg_quote($srcClass, '/') . '\x00(\w+)"/', - function ($matches) { + static function ($matches) { return ':' . strlen($matches[1]) . ':"' . $matches[1] . '"'; }, $serialized); @@ -197,11 +189,6 @@ final class Util /** * Cast an object to another class - * - * @param $cast - * @param $class - * - * @return mixed */ public static function castToClass($cast, $class) { @@ -209,31 +196,33 @@ final class Util $cast = is_object($cast) ? serialize($cast) : $cast; - return unserialize(preg_replace('/O:\d+:"[^"]++"/', 'O:' . strlen($class) . ':"' . $class . '"', $cast)); + return unserialize( + preg_replace( + '/O:\d+:"[^"]++"/', + 'O:' . strlen($class) . ':"' . $class . '"', + $cast + ) + ); } /** * Bloquear la aplicación * - * @param int $userId - * @param string $subject - * - * @throws FileException + * @throws \JsonException + * @throws \SP\Storage\File\FileException */ - public static function lockApp($userId, string $subject) + public static function lockApp(int $userId, string $subject): void { - $data = ['time' => time(), 'userId' => (int)$userId, 'subject' => $subject]; + $data = ['time' => time(), 'userId' => $userId, 'subject' => $subject]; $file = new FileHandler(LOCK_FILE); - $file->save(json_encode($data)); + $file->save(json_encode($data, JSON_THROW_ON_ERROR)); logger('Application locked out'); } /** * Desbloquear la aplicación - * - * @return bool */ public static function unlockApp(): bool { @@ -246,13 +235,19 @@ final class Util * Comprueba si la aplicación está bloqueada * * @return bool|string + * @throws \JsonException */ public static function getAppLock() { try { $file = new FileHandler(LOCK_FILE); - return json_decode($file->readToString()); + return json_decode( + $file->readToString(), + false, + 512, + JSON_THROW_ON_ERROR + ); } catch (FileException $e) { return false; } @@ -261,13 +256,13 @@ final class Util /** * Devolver el tiempo aproximado en segundos de una operación * - * @param $startTime - * @param $numItems - * @param $totalItems - * * @return array Con el tiempo estimado y los elementos por segundo */ - public static function getETA($startTime, $numItems, $totalItems): array + public static function getETA( + int $startTime, + int $numItems, + int $totalItems + ): array { if ($numItems > 0 && $totalItems > 0) { $runtime = time() - $startTime; @@ -281,22 +276,20 @@ final class Util /** * Adaptador para convertir una cadena de IDs a un array - * - * @param string $itemsId - * @param string $delimiter - * - * @return array */ - public static function itemsIdAdapter(string $itemsId, string $delimiter = ','): array + public static function itemsIdAdapter( + string $itemsId, + string $delimiter = ',' + ): array { - return array_map(function ($value) { - return intval($value); - }, explode($delimiter, $itemsId)); + return array_map( + static function ($value) { + return (int)$value; + }, + explode($delimiter, $itemsId) + ); } - /** - * @return int - */ public static function getMaxDownloadChunk(): int { return self::convertShortUnit(ini_get('memory_limit')) / FileHandler::CHUNK_FACTOR; diff --git a/lib/SP/Util/VersionUtil.php b/lib/SP/Util/VersionUtil.php index 0271034b..d10d18f7 100644 --- a/lib/SP/Util/VersionUtil.php +++ b/lib/SP/Util/VersionUtil.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with sysPass. If not, see . + * along with sysPass. If not, see . */ namespace SP\Util; @@ -35,8 +35,6 @@ final class VersionUtil { /** * Devolver versión normalizada en cadena - * - * @return string */ public static function getVersionStringNormalized(): string { @@ -68,8 +66,8 @@ final class VersionUtil return version_compare($currentVersion, $upgradeableVersion) === -1; } - list($currentVersion, $build) = explode('.', $currentVersion, 2); - list($upgradeVersion, $upgradeBuild) = explode('.', $upgradeableVersion, 2); + [$currentVersion, $build] = explode('.', $currentVersion, 2); + [$upgradeVersion, $upgradeBuild] = explode('.', $upgradeableVersion, 2); $versionRes = (int)$currentVersion < (int)$upgradeVersion; @@ -81,14 +79,12 @@ final class VersionUtil * Return a normalized version string to be compared * * @param string|array $versionIn - * - * @return string */ public static function normalizeVersionForCompare($versionIn): string { if (!empty($versionIn)) { if (is_string($versionIn)) { - list($version, $build) = explode('.', $versionIn); + [$version, $build] = explode('.', $versionIn); } elseif (is_array($versionIn) && count($versionIn) === 4) { $version = implode('', array_slice($versionIn, 0, 3)); $build = $versionIn[3]; @@ -109,15 +105,15 @@ final class VersionUtil } /** - * @param string $version - * * @return float|int */ public static function versionToInteger(string $version) { $intVersion = 0; - foreach (str_split(str_replace('.', '', $version)) as $key => $value) { + $strSplit = str_split(str_replace('.', '', $version)); + + foreach ($strSplit as $key => $value) { $intVersion += (int)$value * (10 ** (3 - $key)); } @@ -131,7 +127,7 @@ final class VersionUtil * * @return array con el número de versión */ - public static function getVersionArray($retBuild = false): array + public static function getVersionArray(bool $retBuild = false): array { $version = array_values(Installer::VERSION); @@ -146,8 +142,6 @@ final class VersionUtil /** * Devolver versión normalizada en array - * - * @return array */ public static function getVersionArrayNormalized(): array { diff --git a/tests/SP/Core/Crypt/CryptPKITest.php b/tests/SP/Core/Crypt/CryptPKITest.php index c75fa38e..7745faa0 100644 --- a/tests/SP/Core/Crypt/CryptPKITest.php +++ b/tests/SP/Core/Crypt/CryptPKITest.php @@ -60,7 +60,7 @@ class CryptPKITest extends TestCase $this->assertEquals($random, $this->cryptPki->decryptRSA($data)); - $this->assertFalse($this->cryptPki->decryptRSA('test123')); + $this->assertNull($this->cryptPki->decryptRSA('test123')); } /** diff --git a/tests/SP/DatabaseTrait.php b/tests/SP/DatabaseTrait.php index dd87bb61..22e0131d 100644 --- a/tests/SP/DatabaseTrait.php +++ b/tests/SP/DatabaseTrait.php @@ -32,20 +32,9 @@ use SP\Storage\Database\DatabaseException; */ trait DatabaseTrait { - /** - * @var bool - */ protected static bool $loadFixtures = false; - /** - * @var PDO|null - */ private static ?PDO $conn = null; - /** - * @param string $table - * - * @return int - */ protected static function getRowCount(string $table): int { if (!self::$conn) { diff --git a/tests/SP/Modules/Cli/CliTestCase.php b/tests/SP/Modules/Cli/CliTestCase.php index 35d10d9e..ba3cb61a 100644 --- a/tests/SP/Modules/Cli/CliTestCase.php +++ b/tests/SP/Modules/Cli/CliTestCase.php @@ -37,15 +37,10 @@ use function SP\Tests\getDbHandler; /** * Class CliTestCase - * - * @package SP\Tests\Modules\Cli */ abstract class CliTestCase extends TestCase { - /** - * @var ContainerInterface - */ - protected static $dic; + protected static ContainerInterface $dic; /** * @var string[] */ @@ -73,11 +68,6 @@ abstract class CliTestCase extends TestCase } /** - * @param string $commandClass - * @param array|null $inputData - * @param bool $useInputData - * - * @return CommandTester * @throws DependencyException * @throws NotFoundException */ diff --git a/tests/SP/Repositories/AccountRepositoryTest.php b/tests/SP/Repositories/AccountRepositoryTest.php index e67f8691..cc4f7556 100644 --- a/tests/SP/Repositories/AccountRepositoryTest.php +++ b/tests/SP/Repositories/AccountRepositoryTest.php @@ -438,9 +438,9 @@ class AccountRepositoryTest extends DatabaseTestCase * @throws ConstraintException * @throws QueryException */ - public function testGetAccountsPassData() + public function testGetAccountsPassData(): void { - $this->assertCount(4, self::$repository->getAccountsPassData()); + $this->assertCount(4, self::$repository->getAccountsPassData()->getDataAsArray()); } /** diff --git a/tests/SP/Repositories/ClientRepositoryTest.php b/tests/SP/Repositories/ClientRepositoryTest.php index 2764b31b..71d80bba 100644 --- a/tests/SP/Repositories/ClientRepositoryTest.php +++ b/tests/SP/Repositories/ClientRepositoryTest.php @@ -290,11 +290,11 @@ class ClientRepositoryTest extends DatabaseTestCase * @throws ConstraintException * @throws QueryException */ - public function testGetByIdBatch() + public function testGetByIdBatch(): void { - $this->assertCount(3, self::$repository->getByIdBatch([1, 2, 3])); - $this->assertCount(4, self::$repository->getByIdBatch([1, 2, 3, 4, 5])); - $this->assertCount(0, self::$repository->getByIdBatch([])); + $this->assertCount(3, self::$repository->getByIdBatch([1, 2, 3])->getDataAsArray()); + $this->assertCount(4, self::$repository->getByIdBatch([1, 2, 3, 4, 5])->getDataAsArray()); + $this->assertCount(0, self::$repository->getByIdBatch([])->getDataAsArray()); } /** diff --git a/tests/SP/Repositories/TagRepositoryTest.php b/tests/SP/Repositories/TagRepositoryTest.php index 6b2be3ab..e7f51049 100644 --- a/tests/SP/Repositories/TagRepositoryTest.php +++ b/tests/SP/Repositories/TagRepositoryTest.php @@ -239,9 +239,9 @@ class TagRepositoryTest extends DatabaseTestCase */ public function testGetByIdBatch() { - $this->assertCount(3, self::$repository->getByIdBatch([1, 2, 3])); - $this->assertCount(3, self::$repository->getByIdBatch([1, 2, 3, 4, 5])); - $this->assertCount(0, self::$repository->getByIdBatch([])); + $this->assertCount(3, self::$repository->getByIdBatch([1, 2, 3])->getDataAsArray()); + $this->assertCount(3, self::$repository->getByIdBatch([1, 2, 3, 4, 5])->getDataAsArray()); + $this->assertCount(0, self::$repository->getByIdBatch([])->getDataAsArray()); } /** diff --git a/tests/SP/Repositories/TrackRepositoryTest.php b/tests/SP/Repositories/TrackRepositoryTest.php index 1bff79ed..a85b229c 100644 --- a/tests/SP/Repositories/TrackRepositoryTest.php +++ b/tests/SP/Repositories/TrackRepositoryTest.php @@ -105,11 +105,8 @@ class TrackRepositoryTest extends DatabaseTestCase */ public function testAdd() { - $data = new TrackRequest(); + $data = new TrackRequest(time(), __METHOD__, 1); $data->setTrackIp('192.168.0.1'); - $data->userId = 1; - $data->time = time(); - $data->source = __METHOD__; $this->assertEquals(7, self::$repository->add($data)); @@ -153,10 +150,8 @@ class TrackRepositoryTest extends DatabaseTestCase */ public function testGetTracksForClientFromTime() { - $data = new TrackRequest(); + $data = new TrackRequest(1529272367, 'login'); $data->setTrackIp('172.22.0.1'); - $data->time = 1529272367; - $data->source = 'login'; $result = self::$repository->getTracksForClientFromTime($data); /** @var TrackData[] $resultData */ diff --git a/tests/SP/Repositories/UserGroupRepositoryTest.php b/tests/SP/Repositories/UserGroupRepositoryTest.php index 20b7bf11..bd793376 100644 --- a/tests/SP/Repositories/UserGroupRepositoryTest.php +++ b/tests/SP/Repositories/UserGroupRepositoryTest.php @@ -306,9 +306,9 @@ class UserGroupRepositoryTest extends DatabaseTestCase * @throws ConstraintException * @throws QueryException */ - public function testGetByIdBatch() + public function testGetByIdBatch(): void { - $data = self::$repository->getByIdBatch([1, 2, 10]); + $data = self::$repository->getByIdBatch([1, 2, 10])->getDataAsArray(); $this->assertCount(2, $data); $this->assertInstanceOf(UserGroupData::class, $data[0]); diff --git a/tests/SP/Repositories/UserProfileRepositoryTest.php b/tests/SP/Repositories/UserProfileRepositoryTest.php index 9bc7b232..ccc480cd 100644 --- a/tests/SP/Repositories/UserProfileRepositoryTest.php +++ b/tests/SP/Repositories/UserProfileRepositoryTest.php @@ -264,7 +264,7 @@ class UserProfileRepositoryTest extends DatabaseTestCase */ public function testGetByIdBatch() { - $profiles = self::$repository->getByIdBatch([1, 2, 5]); + $profiles = self::$repository->getByIdBatch([1, 2, 5])->getDataAsArray(); $this->assertCount(2, $profiles); $this->assertInstanceOf(UserProfileData::class, $profiles[0]); diff --git a/tests/SP/Repositories/UserRepositoryTest.php b/tests/SP/Repositories/UserRepositoryTest.php index d479694d..2b0c3118 100644 --- a/tests/SP/Repositories/UserRepositoryTest.php +++ b/tests/SP/Repositories/UserRepositoryTest.php @@ -208,7 +208,7 @@ class UserRepositoryTest extends DatabaseTestCase */ public function testGetByIdBatch() { - $users = self::$repository->getByIdBatch([1, 2, 10]); + $users = self::$repository->getByIdBatch([1, 2, 10])->getDataAsArray(); $this->assertCount(2, $users); $this->assertInstanceOf(UserData::class, $users[0]); diff --git a/tests/SP/Services/Account/AccountAclServiceTest.php b/tests/SP/Services/Account/AccountAclServiceTest.php index 7a7fe3c3..ef2caf3f 100644 --- a/tests/SP/Services/Account/AccountAclServiceTest.php +++ b/tests/SP/Services/Account/AccountAclServiceTest.php @@ -363,7 +363,7 @@ class AccountAclServiceTest extends DatabaseTestCase * @throws QueryException * @throws NoSuchItemException */ - private function setUpAccountEnvironment($accountId, $userId, $groupId, $isAdminApp = 0, $isAdminAcc = 0) + private function setUpAccountEnvironment($accountId, $userId, $groupId, $isAdminApp = false, $isAdminAcc = false) { AccountAclService::$useCache = false; diff --git a/tests/SP/Services/Account/AccountSearchServiceTest.php b/tests/SP/Services/Account/AccountSearchServiceTest.php index 5c7518c1..56194d8c 100644 --- a/tests/SP/Services/Account/AccountSearchServiceTest.php +++ b/tests/SP/Services/Account/AccountSearchServiceTest.php @@ -91,7 +91,7 @@ class AccountSearchServiceTest extends DatabaseTestCase $userData = new UserLoginResponse(); $userData->setId(1); $userData->setUserGroupId(1); - $userData->setIsAdminApp(1); + $userData->setIsAdminApp(false); $userData->setPreferences(new UserPreferencesData()); self::$setupUser->call($this, $userData); diff --git a/tests/SP/Services/Config/ConfigBackupServiceTest.php b/tests/SP/Services/Config/ConfigBackupServiceTest.php index 5d751b86..bc09b5d6 100644 --- a/tests/SP/Services/Config/ConfigBackupServiceTest.php +++ b/tests/SP/Services/Config/ConfigBackupServiceTest.php @@ -29,6 +29,7 @@ use DI\NotFoundException; use PHPUnit\Framework\TestCase; use SP\Config\Config; use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Context\ContextException; use SP\Services\Config\ConfigBackupService; use SP\Services\ServiceException; @@ -84,7 +85,7 @@ class ConfigBackupServiceTest extends TestCase /** * @depends testBackup * - * @param ConfigData $configData + * @param ConfigDataInterface $configData * * @throws DependencyException * @throws NotFoundException @@ -92,7 +93,7 @@ class ConfigBackupServiceTest extends TestCase * @throws ServiceException * @throws FileException */ - public function testRestore(ConfigData $configData) + public function testRestore(ConfigDataInterface $configData) { $dic = setupContext(); diff --git a/tests/SP/Services/Plugin/PluginServiceTest.php b/tests/SP/Services/Plugin/PluginServiceTest.php index 6e43a31b..b2c48009 100644 --- a/tests/SP/Services/Plugin/PluginServiceTest.php +++ b/tests/SP/Services/Plugin/PluginServiceTest.php @@ -122,7 +122,7 @@ class PluginServiceTest extends DatabaseTestCase */ public function testToggleAvailable() { - self::$service->toggleAvailable(1, 0); + self::$service->toggleAvailable(1, false); $data = self::$service->getById(1); @@ -130,7 +130,7 @@ class PluginServiceTest extends DatabaseTestCase $this->expectException(NoSuchItemException::class); - self::$service->toggleAvailable(4, 1); + self::$service->toggleAvailable(4, true); } /** @@ -320,7 +320,7 @@ class PluginServiceTest extends DatabaseTestCase */ public function testToggleEnabledByName() { - self::$service->toggleEnabledByName('Authenticator', 1); + self::$service->toggleEnabledByName('Authenticator', true); $data = self::$service->getByName('Authenticator'); @@ -328,7 +328,7 @@ class PluginServiceTest extends DatabaseTestCase $this->expectException(NoSuchItemException::class); - self::$service->toggleEnabledByName('Test', 0); + self::$service->toggleEnabledByName('Test', false); } /** @@ -338,7 +338,7 @@ class PluginServiceTest extends DatabaseTestCase */ public function testToggleAvailableByName() { - self::$service->toggleAvailableByName('Authenticator', 0); + self::$service->toggleAvailableByName('Authenticator', false); $data = self::$service->getByName('Authenticator'); @@ -346,7 +346,7 @@ class PluginServiceTest extends DatabaseTestCase $this->expectException(NoSuchItemException::class); - self::$service->toggleAvailableByName('Authenticator 2', 1); + self::$service->toggleAvailableByName('Authenticator 2', true); } /** @@ -372,7 +372,7 @@ class PluginServiceTest extends DatabaseTestCase */ public function testToggleEnabled() { - self::$service->toggleEnabled(1, 1); + self::$service->toggleEnabled(1, true); $data = self::$service->getById(1); @@ -380,6 +380,6 @@ class PluginServiceTest extends DatabaseTestCase $this->expectException(NoSuchItemException::class); - self::$service->toggleEnabled(4, 0); + self::$service->toggleEnabled(4, false); } } diff --git a/tests/SP/Services/PublicLink/PublicLinkServiceTest.php b/tests/SP/Services/PublicLink/PublicLinkServiceTest.php index e2c6cc6b..44c7fc3b 100644 --- a/tests/SP/Services/PublicLink/PublicLinkServiceTest.php +++ b/tests/SP/Services/PublicLink/PublicLinkServiceTest.php @@ -28,7 +28,7 @@ use Defuse\Crypto\Exception\CryptoException; use Defuse\Crypto\Exception\EnvironmentIsBrokenException; use DI\DependencyException; use DI\NotFoundException; -use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Context\ContextException; use SP\Core\Crypt\Vault; use SP\Core\Exceptions\ConstraintException; @@ -77,7 +77,7 @@ class PublicLinkServiceTest extends DatabaseTestCase // Inicializar el servicio self::$service = $dic->get(PublicLinkService::class); - self::$salt = $dic->get(ConfigData::class)->getPasswordSalt(); + self::$salt = $dic->get(ConfigDataInterface::class)->getPasswordSalt(); } /** diff --git a/tests/SP/Services/Track/TrackServiceTest.php b/tests/SP/Services/Track/TrackServiceTest.php index f8976f77..f3624eb5 100644 --- a/tests/SP/Services/Track/TrackServiceTest.php +++ b/tests/SP/Services/Track/TrackServiceTest.php @@ -91,11 +91,8 @@ class TrackServiceTest extends DatabaseTestCase */ public function testAdd() { - $data = new TrackRequest(); + $data = new TrackRequest(time(), __METHOD__, 1); $data->setTrackIp('192.168.0.1'); - $data->userId = 1; - $data->time = time(); - $data->source = __METHOD__; $this->assertEquals(7, self::$service->add($data)); @@ -116,10 +113,7 @@ class TrackServiceTest extends DatabaseTestCase */ public function testAddNoAddress() { - $data = new TrackRequest(); - $data->userId = 1; - $data->time = time(); - $data->source = __METHOD__; + $data = new TrackRequest(time(), __METHOD__, 1); $this->expectException(ServiceException::class); @@ -189,10 +183,8 @@ class TrackServiceTest extends DatabaseTestCase */ public function testGetTracksForClientFromTime() { - $data = new TrackRequest(); + $data = new TrackRequest(1529272367, 'login'); $data->setTrackIp('172.22.0.1'); - $data->time = 1529272367; - $data->source = 'login'; $this->assertEquals(3, self::$service->getTracksForClientFromTime($data)); diff --git a/tests/SP/Services/User/UserServiceTest.php b/tests/SP/Services/User/UserServiceTest.php index 6f0898b3..19086954 100644 --- a/tests/SP/Services/User/UserServiceTest.php +++ b/tests/SP/Services/User/UserServiceTest.php @@ -28,6 +28,7 @@ use Defuse\Crypto\Exception\CryptoException; use DI\DependencyException; use DI\NotFoundException; use SP\Config\ConfigData; +use SP\Config\ConfigDataInterface; use SP\Core\Context\ContextException; use SP\Core\Crypt\Hash; use SP\Core\Exceptions\ConstraintException; @@ -52,10 +53,10 @@ use function SP\Tests\setupContext; */ class UserServiceTest extends DatabaseTestCase { - const CURRENT_MASTERPASS = '12345678900'; + private const CURRENT_MASTERPASS = '12345678900'; /** - * @var ConfigData + * @var ConfigDataInterface */ private static $configData; @@ -79,7 +80,7 @@ class UserServiceTest extends DatabaseTestCase // Inicializar el servicio self::$service = $dic->get(UserService::class); - self::$configData = $dic->get(ConfigData::class); + self::$configData = $dic->get(ConfigDataInterface::class); } /** @@ -135,7 +136,7 @@ class UserServiceTest extends DatabaseTestCase $data->setLogin('test_ldap'); $data->setEmail('test_ldap@email.com'); $data->setPassword('test123ldap'); - $data->setIsLdap(1); + $data->setIsLdap(true); $result = self::$service->createOnLogin($data); @@ -690,7 +691,7 @@ class UserServiceTest extends DatabaseTestCase $data = new UserLoginRequest(); $data->setName('prueba'); $data->setEmail('prueba@syspass.org'); - $data->setIsLdap(1); + $data->setIsLdap(true); $data->setLogin('demo'); $data->setPassword('test123'); diff --git a/tests/SP/WebTestCase.php b/tests/SP/WebTestCase.php index 5d37f462..f07a51ef 100644 --- a/tests/SP/WebTestCase.php +++ b/tests/SP/WebTestCase.php @@ -37,37 +37,32 @@ use Symfony\Component\BrowserKit\Response; abstract class WebTestCase extends TestCase { /** - * @param string $url - * @param mixed $content Unencoded JSON data - * - * @return Client + * @throws \JsonException */ - protected static function postJson(string $url, $content = '') + protected static function postJson(string $url, $content = ''): Client { $client = self::createClient(); - $client->request('POST', $url, [], [], ['HTTP_CONTENT_TYPE' => 'application/json'], json_encode($content)); + $client->request( + 'POST', + $url, + [], + [], + ['HTTP_CONTENT_TYPE' => 'application/json'], + json_encode($content, JSON_THROW_ON_ERROR) + ); return $client; } - /** - * @param array $server - * - * @return Client - */ - protected static function createClient(array $server = []) + protected static function createClient(array $server = []): Client { return new Client($server); } - /** - * @param Client $client - * - * @param int $httpCode - * - * @return stdClass - */ - protected static function checkAndProcessJsonResponse(Client $client, $httpCode = 200) + protected static function checkAndProcessJsonResponse( + Client $client, + int $httpCode = 200 + ): stdClass { /** @var Response $response */ $response = $client->getResponse(); @@ -75,6 +70,11 @@ abstract class WebTestCase extends TestCase self::assertEquals($httpCode, $response->getStatus()); self::assertEquals('application/json; charset=utf-8', $response->getHeader('Content-Type')); - return json_decode($response->getContent()); + return json_decode( + $response->getContent(), + false, + 512, + JSON_THROW_ON_ERROR + ); } } \ No newline at end of file diff --git a/tests/SP/bootstrap.php b/tests/SP/bootstrap.php index 756ccac4..78cc1626 100644 --- a/tests/SP/bootstrap.php +++ b/tests/SP/bootstrap.php @@ -135,7 +135,7 @@ function setupContext(): Container $userData->setLogin('Admin'); $userData->setUserGroupName('Admins'); $userData->setUserGroupId(1); - $userData->setIsAdminApp(1); + $userData->setIsAdminApp(true); $userData->setLastUpdate(time()); $context->setUserData($userData); diff --git a/tests/phpunit.xml b/tests/phpunit.xml index b4061106..083df282 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -9,12 +9,12 @@ processIsolation="false" stopOnFailure="false"> - + ./SP ./SP/Modules - - ./SP/Modules + + ./SP/Modules/Api ./SP/Modules/Cli diff --git a/tests/res/config/config.xml b/tests/res/config/config.xml index b3693d96..de19e265 100644 --- a/tests/res/config/config.xml +++ b/tests/res/config/config.xml @@ -11,11 +11,12 @@ 1 1 + 32a3a2b9645e1161f9fc200be312555a80779689 - 1608465113 - 6075dd007ba509336b4861de65598f8a6247a1ab - Admin + 1634060870 + e3e496a5e8cc4eca9aaa98213da783b05dc83b4b + sysPass @@ -33,8 +34,7 @@ - dd2e9ad4d908b2d3ae913298530ae7030ca09a4b - + 1024 1 1 @@ -51,14 +51,14 @@ 0 0 1 - + - + 25 - + @@ -86,7 +86,7 @@ - +