For Developers 

fp-fileprotector can be extended with your own access types. An access type is a small PHP class that decides whether the current visitor may access a protected folder, plus the Fluid partials used to display and edit its settings in the backend module.

At runtime, all registered access types are collected and combined with an OR conjunction: access is granted as soon as one of them grants it. Adding your own access type therefore never restricts existing rules — it only adds a new way to grant access.

A custom access type consists of the following parts.

The access type class 

The heart of every access type is a class that implements \Fixpunkt\FpFileprotector\AccessType\AccessTypeInterface. Place it under Classes/AccessType/<Name>AccessType.php in your own extension.

Classes/AccessType/AccessTypeInterface.php
interface AccessTypeInterface
{
    /** @param array<string, mixed> $protection Raw protection database record */
    public function isGranted(array $protection): bool;
    public function getPartials(): string;
}
Copied!
isGranted()
Receives the raw protection database record as an associative array and returns whether the current visitor should be granted access. Return true to grant access, false to abstain. Because access types are combined with OR, returning false never blocks another access type from granting access.
getPartials()
Returns the partial path used to render this access type in the backend module, e.g. 'Access/MyType'. The module renders <path>/Show.html to display the rule and <path>/Edit.html to edit it (see the partials section).
Classes/AccessType/MyTypeAccessType.php
<?php

declare(strict_types=1);

namespace Vendor\MyExtension\AccessType;

use Fixpunkt\FpFileprotector\AccessType\AccessTypeInterface;

class MyTypeAccessType implements AccessTypeInterface
{
    /** @param array<string, mixed> $protection Raw protection database record */
    public function isGranted(array $protection): bool
    {
        // Your access decision, based on the protection record.
        return (bool)($protection['my_field'] ?? false);
    }

    public function getPartials(): string
    {
        return 'Access/MyType';
    }
}
Copied!

Registering the class 

fp-fileprotector discovers access types through the service container. Your class must be registered as a service and tagged with fp_fileprotector.access. Add the tag in your extension's Configuration/Services.yaml:

Configuration/Services.yaml
services:
  _defaults:
    autowire: true
    autoconfigure: true

  Vendor\MyExtension\:
    resource: '../Classes/*'

  Vendor\MyExtension\AccessType\MyTypeAccessType:
    tags:
      - { name: 'fp_fileprotector.access' }
Copied!

The partials 

Each access type provides two Fluid partials, ideally located under Access/<Name>/ so they match the path returned by getPartials():

Show.html
Renders the current settings of the rule read-only. It receives the protection record as the {protection} variable.
Edit.html
Renders the form fields used to create or edit the rule. It receives all available variables ({_all}), including the current record.
Resources/Private/Partials/Access/MyType/Show.html
<div class="col-xs-12 col-md-4">
  <div class="form-group">
    <label>My setting:</label><br>
    <f:if condition="{protection.my_field}">
      <f:then><span class="text-success">Yes</span></f:then>
      <f:else><span class="text-danger">No</span></f:else>
    </f:if>
  </div>
</div>
Copied!
Resources/Private/Partials/Access/MyType/Edit.html
<div class="checkbox">
  <label>
    <f:form.checkbox name="protection[my_field]" value="1" checked="{record.my_field}" />
    My setting
  </label>
</div>
Copied!

Making the partials available to the backend module 

Because the partials live in your own extension, you have to tell the backend module where to find them. fp-fileprotector ships no TypoScript for this; instead use the TSconfig-based backend template override introduced in TYPO3 v12 (see Feature #96812). It registers an additional, higher-priority root path for the templates of a given extension.

Add the following to your extension's Configuration/page.tsconfig (automatically loaded) using the pattern templates.<overridden-extension>.<unique> = <your-extension>:<entry-path>. The key names the extension whose templates you extend (fixpunkt/fp-fileprotector), the number only has to be unique, and the value is your own composer package name followed by the path that contains your Partials/ folder:

Configuration/page.tsconfig
templates.fixpunkt/fp-fileprotector.1643293191 = my_vendor/my_extension:Resources/Private
Copied!

TYPO3 automatically appends the Templates/, Partials/ and Layouts/ subdirectories. The partial path returned by getPartials() (e.g. Access/MyType) is therefore resolved to EXT:my_extension/Resources/Private/Partials/Access/MyType/ inside your extension.

The TCA override (optional) 

If your access type needs additional fields on the protection record — for example a checkbox or a relation — add them via a TCA override for the table tx_fpfileprotector_domain_model_protection.

This step is optional: if your access decision does not require any extra data stored on the rule, you can skip it entirely.

Configuration/TCA/Overrides/tx_fpfileprotector_domain_model_protection.php
<?php

declare(strict_types=1);

defined('TYPO3') or die();

$table = 'tx_fpfileprotector_domain_model_protection';

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns($table, [
    'my_field' => [
        'label' => 'My setting',
        'exclude' => 1,
        'config' => [
            'type' => 'check',
            'renderType' => 'checkboxToggle',
        ],
    ],
]);
Copied!