PHPackages                             fof/terms - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. fof/terms

ActiveFlarum-extension[Authentication &amp; Authorization](/categories/authentication)

fof/terms
=========

Ask users to accept terms of use before using the forum

1.5.0(5mo ago)1375.9k↓20.6%11[2 issues](https://github.com/FriendsOfFlarum/terms/issues)[3 PRs](https://github.com/FriendsOfFlarum/terms/pulls)1MITPHPCI failing

Since May 3Pushed 2mo agoCompare

[ Source](https://github.com/FriendsOfFlarum/terms)[ Packagist](https://packagist.org/packages/fof/terms)[ Docs](https://friendsofflarum.org)[ Fund](https://opencollective.com/fof/donate)[ RSS](/packages/fof-terms/feed)WikiDiscussions 2.x Synced 1w ago

READMEChangelog (10)Dependencies (3)Versions (45)Used By (1)

Terms by FriendsOfFlarum
========================

[](#terms-by-friendsofflarum)

[![MIT license](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](https://github.com/FriendsOfFlarum/terms/blob/master/LICENSE.md) [![Latest Stable Version](https://camo.githubusercontent.com/0b5a1e9b8a62233210796602ec85af1cdca7f289d17960d0e05c066541b06af5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f666f662f7465726d732e737667)](https://packagist.org/packages/fof/terms) [![Total Downloads](https://camo.githubusercontent.com/2b8fc63ca58a7a6c396507a11a24781799844bcbea381256f1abb6c9fdcf92ef/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f666f662f7465726d732e737667)](https://packagist.org/packages/fof/terms)

This extension allows you to define a list of terms the user must agree to before using the forum.

It was made with the new General Data Protection Regulation in mind but please consult with your legal team to see whether it fits your requirements.

Installation
------------

[](#installation)

```
composer require fof/terms
```

Updating
--------

[](#updating)

```
composer require fof/terms:"*"
php flarum migrate
php flarum cache:clear
```

### Updating from Flagrow

[](#updating-from-flagrow)

This extension replaces [Flagrow Terms](https://packagist.org/packages/flagrow/terms).

To upgrade from the old extension to the new one:

- **Backup your data!** You should backup the database. You can also download Terms' data as JSON, see documentation below.
- Disable the Terms extension in the admin panel.
- Run:

```
composer require fof/terms
```

Composer should let you know that `flagrow/terms` has been automatically removed.

- Enable the new extension in the admin panel.
- Your existing data will be migrated to FoF Terms automatically.

Configuration
-------------

[](#configuration)

You can define a list of "policies" the users must agree to. A policy has a name and url.

You can define an "update message" that will be shown to users who have not yet agreed to the latest version of the policy or not agreed to the policy at all (this includes users registered before the policy extension was enabled).

You can define an "updated at" time that will ask all users who accepted prior to that date to accept again.

If users don't accept the terms, they can't register. Additionally, if they already have an account, they can login but their account is locked until they accept the latest version of the terms (similar to how the suspend extension blocks users).

You can customize who can skip the modal without accepting the new terms immediately via the permissions tab (by default admins only). You might want to give this permission to bot accounts for example as they will also be blocked from the API if there's a terms update.

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
--------------

[](#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:

```
  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:

```
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 (

        {this.keyattr}
         {
            this.updateAttribute(val.target.value);
          }}
        />

    );
  }
}
```

This example shows a way to save data only as string format: `key: `, however if You want to use data in a more sophisticated format, there are some rules that should be followed. Let's say You want to save a JSON object instead of simple string, in a such form: `{"boolval": ,  "stringval": }`.

Here is an example how to obtain such behaviour:

```
import Component from 'flarum/common/Component';
import Switch from 'flarum/common/components/Switch';

export default class YourSophisticatedComponent extends Component {
  oninit(vnode) {
    super.oninit(vnode);
    this.keyattr = vnode.attrs.keyattr;
    this.policy = vnode.attrs.policy;
    this.updateAttribute = vnode.attrs.updateAttribute;
  }

  view() {
    return (

        {this.keyattr}
         {
            let objectAttributes = this.policy.additionalInfo()[this.keyattr];
            if (objectAttributes === undefined) {
              objectAttributes = {};
            }
            objectAttributes['boolval'] = val;
            this.updateAttribute(objectAttributes);
          }}
        >
          boolval

         {
            let objectAttributes = this.policy.additionalInfo()[this.keyattr];
            if (objectAttributes === undefined) {
              objectAttributes = {};
            }
            objectAttributes['stringval'] = val.target.value;
            this.updateAttribute(objectAttributes);
          }}
        />

    );
  }
}
```

Note that `oninput` handler is a bit more complicated - in order to save some subvalue, you need to fetch the whole JSON object, assign its subvalue, and then call `this.updateAttribute` method.

As mentioned above, it is possible to store every value imaginable, as long as it is a primitive, or valid JSON object.

Data Export
-----------

[](#data-export)

In case you want to export the data (for your GDPR logs for example), a JSON and CSV export is available.

The link can be found in the Policy edit form of the admin panel.

If you want to automate the export, the available options are [documented on the wiki](https://github.com/FriendsOfFlarum/terms/wiki/Export-url).

Links
-----

[](#links)

- [Flarum Discuss post](https://discuss.flarum.org/d/11714)
- [Source code on GitHub](https://github.com/FriendsOfFlarum/terms)
- [Report an issue](https://github.com/FriendsOfFlarum/terms/issues)
- [Download via Packagist](https://packagist.org/packages/fof/terms)

An extension by [FriendsOfFlarum](https://github.com/FriendsOfFlarum)

###  Health Score

58

—

FairBetter than 98% of packages

Maintenance76

Regular maintenance activity

Popularity41

Moderate usage in the ecosystem

Community26

Small or concentrated contributor base

Maturity76

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~78 days

Recently: every ~25 days

Total

38

Last Release

56d ago

Major Versions

0.6.2 → 1.0.02021-05-26

1.5.0 → 2.0.0-beta.12026-01-02

1.x-dev → 2.0.0-beta.62026-04-14

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/16573496?v=4)[IanM](/maintainers/imorland)[@imorland](https://github.com/imorland)

![](https://avatars.githubusercontent.com/u/1630413?v=4)[Gregor Hammerschmidt](/maintainers/GreXXL)[@GreXXL](https://github.com/GreXXL)

![](https://www.gravatar.com/avatar/0538135c1debcef5602dce7ece027909cc832b7a6284ab9189a19aa8de98d60d?d=identicon)[clarkwinkelmann](/maintainers/clarkwinkelmann)

![](https://www.gravatar.com/avatar/1298cdc0b2402a1aa34fb75a254947d655e090d62bd0531311331d369cac934e?d=identicon)[datitisev](/maintainers/datitisev)

---

Top Contributors

[![clarkwinkelmann](https://avatars.githubusercontent.com/u/5264300?v=4)](https://github.com/clarkwinkelmann "clarkwinkelmann (48 commits)")[![imorland](https://avatars.githubusercontent.com/u/16573496?v=4)](https://github.com/imorland "imorland (23 commits)")[![flarum-bot](https://avatars.githubusercontent.com/u/39334649?v=4)](https://github.com/flarum-bot "flarum-bot (22 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (17 commits)")[![iPurpl3x](https://avatars.githubusercontent.com/u/18526076?v=4)](https://github.com/iPurpl3x "iPurpl3x (4 commits)")[![rafaucau](https://avatars.githubusercontent.com/u/25438601?v=4)](https://github.com/rafaucau "rafaucau (3 commits)")[![dsevillamartin](https://avatars.githubusercontent.com/u/6401250?v=4)](https://github.com/dsevillamartin "dsevillamartin (2 commits)")[![StyleCIBot](https://avatars.githubusercontent.com/u/11048387?v=4)](https://github.com/StyleCIBot "StyleCIBot (1 commits)")[![AngryDragonite](https://avatars.githubusercontent.com/u/109293673?v=4)](https://github.com/AngryDragonite "AngryDragonite (1 commits)")[![SychO9](https://avatars.githubusercontent.com/u/20267363?v=4)](https://github.com/SychO9 "SychO9 (1 commits)")[![BHZoon](https://avatars.githubusercontent.com/u/114921772?v=4)](https://github.com/BHZoon "BHZoon (1 commits)")[![DavideIadeluca](https://avatars.githubusercontent.com/u/146922689?v=4)](https://github.com/DavideIadeluca "DavideIadeluca (1 commits)")[![j-a-pope](https://avatars.githubusercontent.com/u/64874788?v=4)](https://github.com/j-a-pope "j-a-pope (1 commits)")[![manurohr](https://avatars.githubusercontent.com/u/38522534?v=4)](https://github.com/manurohr "manurohr (1 commits)")[![rob006](https://avatars.githubusercontent.com/u/5972388?v=4)](https://github.com/rob006 "rob006 (1 commits)")[![spaeps](https://avatars.githubusercontent.com/u/1037160?v=4)](https://github.com/spaeps "spaeps (1 commits)")

---

Tags

extensionflarumtermsPolicytos

### Embed Badge

![Health badge](/badges/fof-terms/health.svg)

```
[![Health](https://phpackages.com/badges/fof-terms/health.svg)](https://phpackages.com/packages/fof-terms)
```

###  Alternatives

[flarum-lang/russian

Russian language pack for Flarum.

12127.5k](/packages/flarum-lang-russian)[flarum-lang/french

French language pack to localize the Flarum forum software plus its official and third-party extensions.

1936.5k](/packages/flarum-lang-french)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
