From aa2f624e26c33c16c86a7e30bdbe3a42834c4e24 Mon Sep 17 00:00:00 2001 From: AngryDragonite <109293673+AngryDragonite@users.noreply.github.com> Date: Sun, 29 Sep 2024 19:43:58 +0200 Subject: [PATCH] Feat/add optional policies (#51) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: added 'optional' field to fof-terms-policies table feat: added 'is_accepted' field to fof-terms-policy-user table feat: added settings to opt out of consents in user profile feat: added functionality that allows users to decline policies that were declared optional * feat: accept policies really accepted by user instead of all * feat: added 'additionalInfo' model attribute feat: added 'ExtensionData' component * feat: changes in policy consents in profile settings now save automatically feat: changed 'ExtensionData' component, so it allows other extensions to sync with fof/terms fix: synced new model field name to its DB column * refactor: minor changes in 'ExtensionData' and 'PolicyEdit' feat: started writing guide on how to integrate fof/terms with other extensions in README.md * refactor: simplified addManagePoliciesOption code feat: added translations feat: improved ExtensionData component feat: added recipe for integrating fof/terms with other extensions in README fix: additionalInfo is now properly saved into DB chore: removed redundant imports and comments * Apply fixes from StyleCI * refactor: changed additionalInfo column name into additional_info * fix: fixed bug that caused inappropriate behaviour when deleting policies. * style: formatted README.md * fix: optional policies that were not accepted during registration are now saved properly. * chore: added phpstan ignore to User::$fofTermsPoliciesState. * Update resources/locale/en.yml Co-authored-by: Davide Iadeluca <146922689+DavideIadeluca@users.noreply.github.com> * Update resources/locale/en.yml Co-authored-by: Davide Iadeluca <146922689+DavideIadeluca@users.noreply.github.com> * chore: minor changes in addManagePoliciesOption.js * chore: renamed migration files * chore: revert file permissions * chore: reverted file permissions chore: removed accidently added files * chore: fixed migration files' names * chore: reset js/dist folder changes * Delete js/dist/forum.js.map * Delete js/dist/admin.js * Delete js/dist/forum.js * Delete js/dist/admin.js.map * chore: sync fork and reset dist and package.json files * style: reformat addManagePoliciesOption.js * remove var_dump * style: one array access method * Apply fixes from StyleCI * style: use link component * fix: replace JSON column with longText for compatibility * refactor: simplify migrations * Apply fixes from StyleCI * fix: mark existing policies as accepted for all users, then set the default value to false for new users * Apply fixes from StyleCI * chore: resolve merge conflict --------- Co-authored-by: Rafał Całka Co-authored-by: rafaucau Co-authored-by: Davide Iadeluca <146922689+DavideIadeluca@users.noreply.github.com> Co-authored-by: flarum-bot --- README.md | 152 ++++++++++++++++++ extend.php | 20 +-- js/src/admin/components/ExtensionData.js | 32 ++++ js/src/admin/components/PolicyEdit.js | 32 +++- js/src/admin/components/index.js | 2 + js/src/common/models/Policy.js | 2 + .../forum/components/AcceptPoliciesModal.js | 4 +- .../components/addManagePoliciesOption.js | 55 +++++++ js/src/forum/index.js | 2 + ..._01_add_optional_policies_user_columns.php | 20 +++ ...04_24_01_add_optional_policies_columns.php | 19 +++ ...01_change_accepted_state_default_value.php | 26 +++ resources/less/admin.less | 16 ++ resources/less/forum.less | 5 + resources/locale/en.yml | 4 +- src/Controllers/PolicyDeclineController.php | 56 +++++++ src/Controllers/PolicyStoreController.php | 1 + src/Data/UserPolicyData.php | 2 + src/Middlewares/RegisterMiddleware.php | 59 +++++-- src/Policy.php | 21 +++ src/Repositories/PolicyRepository.php | 30 +++- src/Validators/RegisterPolicyValidator.php | 4 +- 22 files changed, 523 insertions(+), 41 deletions(-) create mode 100644 js/src/admin/components/ExtensionData.js create mode 100644 js/src/forum/components/addManagePoliciesOption.js create mode 100644 migrations/2024_04_11_01_add_optional_policies_user_columns.php create mode 100644 migrations/2024_04_24_01_add_optional_policies_columns.php create mode 100644 migrations/2024_06_17_01_change_accepted_state_default_value.php create mode 100644 resources/less/forum.less create mode 100644 src/Controllers/PolicyDeclineController.php diff --git a/README.md b/README.md index f47ae66..c1e3155 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,158 @@ You can customize who can skip the modal without accepting the new terms immedia Admins can see the date at which a user accepted the terms by going to their profile page and selecting the terms button in the dropdown menu. You can customize who can see those dates in the permissions. +## For developers + +You can easily add a custom field in PolicyEdit component to integrate fof/terms with other extensions. In +`fof-terms-policies`, there is a column, `additionalInfo` dedicated to save your custom data into `fof/terms` database. +Data is stored inside one, global JSON object, allowing multiple extensions to save their data. + +``` + additionalInfo JSON object example + + { + "fof/extension-1": "extension1 data", + "fof/extension-2": true, + "fof/extension-3": {"extension-3-boolval": false, "extension-3-stringval": "extension-3 data"} + } +``` + +You can save any value, as long as it is a primitive or a valid JSON object. + +To add your field to `additionalInfo`, you must follow these steps: +1) Choose a custom **key** value, it is recommended to select Your extension's name to avoid naming conflicts. +2) Prepare a component, which You would want to insert into `PolicyEdit` +3) Extend `PolicyEdit.prototype`'s `fields` method, and add Your component, wrapped inside `ExtensionData` component: +```js + import { extend } from 'flarum/common/extend'; + import PolicyEdit from 'fof/terms/components/PolicyEdit'; + import ExtensionData from 'fof/terms/components/ExtensionData'; + + export default function() { + extend(PolicyEdit.prototype, 'fields', function (items) { + const key = 'fof/extension-1'; + const priority = 81; + + items.add( + key, + { + this.dirty = true; + }} + > + {({ keyattr, policy, updateAttribute }) => + + } + , + priority + ) + }); + } +``` +As shown above, `ExtensionData` component takes three props: +1) `keyattr` - specified key, usually Your extension's name, +2) `policy` - reference to `policy` object, +3) `setDirty` - reference to function that allows saving the policy, if any change is made + +Your component should also take three props: +1) `keyattr` - same as in above +2) `policy` - same as above +3) `updateAttribute` - reference to `ExtensionData`'s method that manages saving Your data into database +( it is a bit different than `PolicyEdit`'s updateAttribute method ) + + +Your component could look something like this: +```js +import Component from 'flarum/common/Component'; + +export default class YourComponent extends Component { + oninit(vnode) { + super.oninit(vnode); + this.keyattr = vnode.attrs.keyattr; + this.policy = vnode.attrs.policy; + this.updateAttribute = vnode.attrs.updateAttribute; + } + + view() { + return ( + <> + +