Read from the package's own PHP files at the commit 74eceb1c44f1: its namespaces, classes, interfaces and enums, their public constants, properties and methods with their PHPDoc, and the options its factories take. Nothing of it is run.
DriveBundleclassThe drive application on top of omnibase: a site's own cloud of folders and files (FileShare), who each folder is for (the audiences), whom it is shared with by name, workspaces with their people and tasks, search, previews, zips and download counts - on the site's storage, or its Google Drive once connected from the back office.
3 methods
AudienceInterfaceinterfaceWho a folder or a file of the drive is for (SharedPath::$audience holds its key): the bundle's readers, users, members and staff, and whatever a site or another bundle adds - the associates of a company (omnibase/estate's), a studio's customers. A service implementing it is one more choice in « Pour qui », tagged drive.audience by autoconfiguration.
4 methods · 1 constant
AudiencesclassEvery audience of the drive (AudienceInterface, tagged drive.audience), by key, in the order of « Pour qui »: the bundle's (readers, users, members), the site's, then staff last. A key no audience answers to any more (a site that removed one) is read as the staff's: nobody else sees what was for it.
6 methods
MembersAudienceclassA path for the people of the workspace the path is in (the folder made one, and its people).
4 methods · 1 constant
ReadersAudienceclassA path for everyone, signed in or not.
4 methods · 1 constant
StaffAudienceclassA path for the staff only (who see everything anyway): nobody else.
4 methods · 1 constant
UsersAudienceclassA path for the signed-in accounts.
4 methods · 1 constant
CountCommandclassA path's downloads in the drive set at a number - the ones counted elsewhere before (an old download page's statistics); --add adds to what it has. A path no longer there may count too: a version gone, its downloads kept in its folder's total.
1 method
ImportCommandclassA folder of files into the drive (Base\Drive\Share\FileShare), as it is: its tree under `target` (the root by default). Hidden files (.git, .htaccess) stay behind; a file already there with the same size is left; one of another size is replaced, unless the retention lock keeps it (drive.retention: left as it is, and said). For what is too big or too many to upload from the page.
1 method
MoveCommandclassFiles and folders of the drive moved into another folder (a workspace, say): what was said of them and their downloads follow. --tags drops their own tags (their new folder's are theirs now). Nothing moves out of a folder the retention lock keeps (drive.retention).
1 method
WorkspaceCommandclassA workspace of the drive from the command line: a new folder at its root - or one already there, made a workspace -, who it is for, a few words on it, its tags.
1 method
ShareControllerclassThe drive's page (Base\Drive\Share\FileShare): files shared with the readers, the users, the people of a workspace and whoever the site's audiences let in, as an index of files - a folder lists what it holds (its README under it), a file opens, shows (?preview) or downloads, a folder downloads as a zip (?zip) - never the drive as a whole; a search through every folder (?q); someone the root is not for has a root of their own. Who sees what is ShareVoter's; the staff manage it on the page itself: upload (a dropped folder kept whole), a new folder, who a folder is for, whom it is shared with, a few words on it, move, rename, delete. Files added by the team may be shared at once with named people and groups (share_with[]): a copy in each one's space (Space\Spaces). With the retention lock on (drive.retention), nothing locked is deleted, renamed nor moved, and the superadmin lifts a folder's lock and puts it back from its access dialog, where the log is listed.
3 methods
DriveControllerclassThe drive's Google Drive, from the back office: connect the site's Google account, pick (or create) the folder the files live in, lay out the site's folders (TreeInterface, when it has one), disconnect. Until then the files stay on the site's storage, and move nowhere by themselves. Loaded with omnibase/admin and google/apiclient (config/services.php).
7 methods
Base\Drive\DependencyInjection
DriveConfigurationclass1 method
DriveExtensionclass2 methods
PersonalTagclassA tag someone put on a folder for themselves (Base\Drive\Share\PersonalTags, drive.personal_tags): theirs alone - nobody else sees it, the team neither -, to sort what they see as they like. Its colour is theirs too, the same on every folder they gave that tag.
8 methods
RetentionEventclassOne line of the retention log (drive.retention, Base\Drive\Share\Retention): a folder's lock lifted - until it is put back, or until a date -, or put back, by whom, when and why. The log is only ever added to: a folder's state is its latest line (a lift that is still running, or locked), a lift whose date has passed being a lock again by itself.
11 methods · 2 constants
ShareDownloadclassHow many times a file of the drive was downloaded (Base\Drive\Controller\ShareController) - or a folder, as a zip, or the old downloads of versions no longer there (drive:count). A number per path and when it last grew: nothing of who downloaded it.
6 methods
ShareGroupclassA group of people the team names - a flatshare's tenants, a couple, a family's heirs - to share folders with all of them at once (SharedPath::$groups): whoever is in it sees what is shared with it, as if shared with them by name; someone added later sees it too, someone taken out no longer does.
9 methods
ShareTaskclassA task of a workspace of the drive (SharedPath::$tasks): a few words, done or not - and when, and who wrote it.
12 methods
SharedPathclassWhat the team says of a folder or a file of the drive (Base\Drive\Share\FileShare): who it is for (an audience's key: Base\Drive\Audience), a few words shown above its list, its tags (what is under it has them too), whether it is listed. A folder may be a workspace: its people (members: they see it whoever else it is for, and what is "for its members" is for them) and its tasks. The files themselves are on the storage; a path without a row here is as its nearest parent with one - the root as drive.default_audience says.
26 methods
AccountPeopleclassThe drive's people by default: every account of drive.user_class, by its identifier and its e-mail, in one group ("accounts").
3 methods
PeopleInterfaceinterfaceWhom a folder of the drive may be shared with, by name and what they are to the site: groups of accounts (user id => label). The bundle's AccountPeople lists every account; a site says who its people are with its own implementation and #[AsAlias(PeopleInterface::class)] - omnibase/estate's tenants, associates, contractors and team for a property company. Each group's name is a translation key of the messages domain: share.people_group.<group>.
2 methods
RetentionEventRepositoryclass2 methods
ShareDownloadRepositoryclass4 methods
SharedPathRepositoryclass3 methods
ShareVoterclassWho sees a path of the drive (SHARE_VIEW, the path as subject), who manages it (SHARE_MANAGE: the staff, drive.staff_role), and who works in a workspace - its tasks, the files its people bring (SHARE_WORK, the path as subject: its members and the staff). A path is for its audience (FileShare::audience, answered by Base\Drive\Audience\Audiences: the readers, the signed-in users, the members of its workspace, the staff only, and the site's own); and, whatever its audience, for the people it was shared with (FileShare::isSharedWith: a workspace's people, in it or above it).
1 method · 5 constants
FileShareclassThe drive (« le Partage », « Cloud » on a site's pages): files a site shares with its readers, its users, the people of its workspaces and whoever its own audiences let in - an index of files, as a web server's "Index of /", with a little more: who each folder is for, whom it is shared with by name, a few words above it, its README under it, a search through the tree, each person's own root.
39 methods · 2 constants
LockedExceptionclassWhat the retention lock refuses (drive.retention): deleting, overwriting, renaming or moving something in a locked folder - whoever asks, the team included.
1 method · 1 property
PersonalTagsclassThe tags each one puts on folders for themselves (drive.personal_tags): a tenant sorting their papers, an owner theirs, nobody else seeing them. Like the team's tags, a folder's apply to what it holds (to filter by). Nothing when the option is off or nobody is signed in; their rows follow a folder moved and go with one deleted (FileShare).
10 methods
RetentionclassThe retention lock (drive.retention, off by default): with it on, every folder of the drive and what it holds is kept - nothing deleted, overwritten, renamed nor moved, by anyone, the team included (FileShare refuses it, ShareVoter's SHARE_ALTER says no). Adding files stays open.
12 methods
TagColorsclassA tag's colour, the same wherever the tag is shown: the one the team chose for it (kept in the site's settings, app.drive.tag_colors, by the tag's key), otherwise one of a few drawn from its name - so that a tag has a colour of its own before anyone chooses.
4 methods · 1 constant
SpaceProviderInterfaceinterfaceWhere a person's space is in the drive: the folder their role gives them - a tenant's, an owner's, a partner's. A bundle that knows its people implements it (omnibase/estate: Locataires/<tenant>, Propriétaires/<owner>, Indivisions/<ownership>), tagged drive.space by autoconfiguration; the providers are asked in their priority's order, the first to answer wins, and nobody answering leaves the drive's own place (Spaces: drive.spaces_root/<name>).
1 method · 1 constant
SpacesclassEach person's space in the drive, and files shared on upload with named people: a file added goes, besides the folder it was added to, into the space of each person named - and of each person of a group named (Entity\ShareGroup) -, the space made if missing, reused otherwise, shared with them read only unless the uploader lets them bring files too.
3 methods
DocumentsStorageclassWhere the drive's files are (the service drive.storage, alias documents.storage, read by Base\Drive\Share\FileShare): the site's Google Drive folder once connected from the back office (google/apiclient and masbug/flysystem-google-drive-ext installed), the site's own storage otherwise (drive.local_storage, local.share by default) - and always in the tests.
3 methods
DriveClientclassGoogle, for the documents: the consent screen (offline access, the whole Drive - so files dropped into the folder from Drive itself show up), and a Drive service on the stored refresh token. The OAuth client is the site's (GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET); its consent screen must be published, or Google drops the token after seven days.
6 methods
DriveSettingsclassWhat the site keeps of its Google Drive: the refresh token (encrypted with the app secret: it opens the whole Drive), the folder the documents live in, and who connected it. In omnibase's settings, under the names the sites stored them with (app.drive.*), sealed with the same key: a Drive connected before the bundle stays connected.
10 methods
DocumentsTreeclassA site's layout of folders (TreeInterface) created where the files are (its storage or its Google Drive): each folder missing made, who each is for set at the same time. Folders already there are left as they are, and so is what they hold.
2 methods
TreeInterfaceinterfaceA site's own layout of folders, laid out where the files are (its storage or its Google Drive) by DocumentsTree - from the back office's Google Drive page (« Créer les dossiers ») or the site's fixtures. A property company's: its statutes, general meetings, accounts, a folder per home. The page offers it only when the site has one: a service implementing this interface, aliased with #[AsAlias(TreeInterface::class)].
2 methods
DriveExtensionclassFor a site's templates: drive_tag_color(tag), a team's tag's colour (Share\TagColors); drive_my_tag_color(tag), the colour of a tag of one's own (Share\PersonalTags); path|drive_slug, a path as the drive's addresses read it (drive.slugs: its slugs, otherwise itself) - for path('app_share', {path: entry.path|drive_slug}).
3 methods
Base\Drive
DriveBundle class
class DriveBundle extends AbstractBaseBundle DriveBundle.php:15
The drive application on top of omnibase: a site's own cloud of folders and files (FileShare), who each folder is for (the audiences), whom it is shared with by name, workspaces with their people and tasks, search, previews, zips and download counts - on the site's storage, or its Google Drive once connected from the back office.
DriveBundle::__construct()
public function __construct()DriveBundle::getPath()
public function getPath(): stringThe bundle root is the package root: ./templates is @Drive, ./src/Entity is mapped.
DriveBundle::build()
public function build(ContainerBuilder $container): voidBase\Drive\Audience
AudienceInterface interface
interface AudienceInterface AudienceInterface.php:15
Who a folder or a file of the drive is for (SharedPath::$audience holds its key): the bundle's readers, users, members and staff, and whatever a site or another bundle adds - the associates of a company (omnibase/estate's), a studio's customers. A service implementing it is one more choice in « Pour qui », tagged drive.audience by autoconfiguration.
const TAG = 'drive.audience'
AudienceInterface::key()
public function key(): stringWhat sharedPath.audience holds: lower case, 16 characters at most ("readers", "associates").
AudienceInterface::label()
public function label(): stringIts name, a translation key of the messages domain ("share.audience.readers").
AudienceInterface::icon()
public function icon(): stringFont Awesome's icon for it ("fa-solid fa-earth-europe").
AudienceInterface::lets()
public function lets(?UserInterface $user, string $path, FileShare $share): boolWhether it lets someone see a path that is for it: $user is null when nobody is signed in.
The staff see everything anyway, and the people a path is shared with see it whatever its audience: neither is asked here.
Audiences class
final class Audiences Audiences.php:13
Every audience of the drive (AudienceInterface, tagged drive.audience), by key, in the order of « Pour qui »: the bundle's (readers, users, members), the site's, then staff last. A key no audience answers to any more (a site that removed one) is read as the staff's: nobody else sees what was for it.
Audiences::__construct()
public function __construct(readonly iterable $audiences)Audiences::all()
public function all(): arrayAudiences::has()
public function has(string $key): boolAudiences::get()
public function get(string $key): AudienceInterfaceThe audience of a key - the staff's for a key nobody answers to.
Audiences::find()
public function find(?string $key): ?AudienceInterfaceThe audience of a key typed or posted, or null when there is none of that key.
Audiences::keys()
public function keys(): arrayMembersAudience class
final class MembersAudience implements AudienceInterface MembersAudience.php:11
A path for the people of the workspace the path is in (the folder made one, and its people).
const KEY = 'members'
MembersAudience::key()
public function key(): stringMembersAudience::label()
public function label(): stringMembersAudience::icon()
public function icon(): stringMembersAudience::lets()
public function lets(?UserInterface $user, string $path, FileShare $share): boolReadersAudience class
final class ReadersAudience implements AudienceInterface ReadersAudience.php:10
A path for everyone, signed in or not.
const KEY = 'readers'
ReadersAudience::key()
public function key(): stringReadersAudience::label()
public function label(): stringReadersAudience::icon()
public function icon(): stringReadersAudience::lets()
public function lets(?UserInterface $user, string $path, FileShare $share): boolStaffAudience class
final class StaffAudience implements AudienceInterface StaffAudience.php:10
A path for the staff only (who see everything anyway): nobody else.
const KEY = 'staff'
StaffAudience::key()
public function key(): stringStaffAudience::label()
public function label(): stringStaffAudience::icon()
public function icon(): stringStaffAudience::lets()
public function lets(?UserInterface $user, string $path, FileShare $share): boolUsersAudience class
final class UsersAudience implements AudienceInterface UsersAudience.php:10
A path for the signed-in accounts.
const KEY = 'users'
UsersAudience::key()
public function key(): stringUsersAudience::label()
public function label(): stringUsersAudience::icon()
public function icon(): stringUsersAudience::lets()
public function lets(?UserInterface $user, string $path, FileShare $share): boolBase\Drive\Command
CountCommand class
final class CountCommand extends Command CountCommand.php:19
A path's downloads in the drive set at a number - the ones counted elsewhere before (an old download page's statistics); --add adds to what it has. A path no longer there may count too: a version gone, its downloads kept in its folder's total.
CountCommand::__construct()
public function __construct(readonly FileShare $share)ImportCommand class
final class ImportCommand extends Command ImportCommand.php:20
A folder of files into the drive (Base\Drive\Share\FileShare), as it is: its tree under target
(the root by default). Hidden files (.git, .htaccess) stay behind; a file already there with
the same size is left; one of another size is replaced, unless the retention lock keeps it
(drive.retention: left as it is, and said). For what is too big or too many to upload from the page.
ImportCommand::__construct()
public function __construct(readonly FileShare $share)MoveCommand class
final class MoveCommand extends Command MoveCommand.php:20
Files and folders of the drive moved into another folder (a workspace, say): what was said of them and their downloads follow. --tags drops their own tags (their new folder's are theirs now). Nothing moves out of a folder the retention lock keeps (drive.retention).
MoveCommand::__construct()
public function __construct(readonly FileShare $share)WorkspaceCommand class
final class WorkspaceCommand extends Command WorkspaceCommand.php:19
A workspace of the drive from the command line: a new folder at its root - or one already there, made a workspace -, who it is for, a few words on it, its tags.
WorkspaceCommand::__construct()
public function __construct(readonly FileShare $share, readonly Audiences $audiences)Base\Drive\Controller
ShareController class
class ShareController extends AbstractController ShareController.php:46
The drive's page (Base\Drive\Share\FileShare): files shared with the readers, the users, the people of a workspace and whoever the site's audiences let in, as an index of files - a folder lists what it holds (its README under it), a file opens, shows (?preview) or downloads, a folder downloads as a zip (?zip) - never the drive as a whole; a search through every folder (?q); someone the root is not for has a root of their own. Who sees what is ShareVoter's; the staff manage it on the page itself: upload (a dropped folder kept whole), a new folder, who a folder is for, whom it is shared with, a few words on it, move, rename, delete. Files added by the team may be shared at once with named people and groups (share_with[]): a copy in each one's space (Space\Spaces). With the retention lock on (drive.retention), nothing locked is deleted, renamed nor moved, and the superadmin lifts a folder's lock and puts it back from its access dialog, where the log is listed.
Its path is the site's: the key app.share of its config/routes_paths.yaml (fr: /cloud/{path}), its route names app_share and app_share_manage. Its page is @Drive/share/index.html.twig, which a site overrides with its own (templates/bundles/DriveBundle/share/index.html.twig).
ShareController::__construct()
public function __construct(readonly FileShare $share, readonly TranslatorInterface $translator, readonly EntityManagerInterface $entityManager, readonly PeopleInterface $people, readonly Audiences $audiences, readonly TagColors $tagColors, readonly PersonalTags $personalTags, readonly Retention $retention, readonly Spaces $spaces, readonly string $userClass = 'App\Entity\User', readonly string $zipName = 'drive', readonly bool $listedRoot = false, readonly string $teamTags = 'everyone', readonly bool $slugs = false)ShareController::show()
public function show(Request $request, string $path = ''): ResponseShareController::manage()
public function manage(Request $request, string $path = ''): ResponseThe staff's hand on a folder: upload, a new folder, who it is for and its words, delete.
Base\Drive\Controller\Admin
DriveController class
class DriveController extends AbstractController DriveController.php:25
The drive's Google Drive, from the back office: connect the site's Google account, pick (or create) the folder the files live in, lay out the site's folders (TreeInterface, when it has one), disconnect. Until then the files stay on the site's storage, and move nowhere by themselves. Loaded with omnibase/admin and google/apiclient (config/services.php).
DriveController::__construct()
public function __construct(readonly DriveSettings $settings, readonly DriveClient $client, readonly TranslatorInterface $translator, readonly ?TreeInterface $tree = null)DriveController::index()
public function index(DocumentsStorage $storage): ResponseDriveController::connect()
public function connect(Request $request): RedirectResponseDriveController::callback()
public function callback(Request $request): RedirectResponseDriveController::folder()
public function folder(Request $request): RedirectResponseDriveController::tree()
public function tree(Request $request, DocumentsTree $documents): RedirectResponseDriveController::disconnect()
public function disconnect(Request $request): RedirectResponseBase\Drive\DependencyInjection
DriveConfiguration class
class DriveConfiguration implements ConfigurationInterface DriveConfiguration.php:8
DriveConfiguration::getConfigTreeBuilder()
public function getConfigTreeBuilder(): TreeBuilderDriveExtension class
class DriveExtension extends AbstractBaseExtension DriveExtension.php:12
DriveExtension::getConfiguration()
public function getConfiguration(array $config, ContainerBuilder $container): DriveConfigurationDriveExtension::load()
public function load(array $configs, ContainerBuilder $container): voidBase\Drive\Entity
PersonalTag class
class PersonalTag PersonalTag.php:13
A tag someone put on a folder for themselves (Base\Drive\Share\PersonalTags, drive.personal_tags): theirs alone - nobody else sees it, the team neither -, to sort what they see as they like. Its colour is theirs too, the same on every folder they gave that tag.
PersonalTag::__construct()
public function __construct(User $user, string $path, string $name, string $tagKey)PersonalTag::getId()
public function getId(): ?intPersonalTag::getUser()
public function getUser(): UserPersonalTag::getPath()
public function getPath(): stringPersonalTag::getName()
public function getName(): stringPersonalTag::getTagKey()
public function getTagKey(): stringPersonalTag::getColor()
public function getColor(): ?stringPersonalTag::setColor()
public function setColor(?string $color): selfRetentionEvent class
class RetentionEvent RetentionEvent.php:15
One line of the retention log (drive.retention, Base\Drive\Share\Retention): a folder's lock lifted - until it is put back, or until a date -, or put back, by whom, when and why. The log is only ever added to: a folder's state is its latest line (a lift that is still running, or locked), a lift whose date has passed being a lock again by itself.
const LIFT = 'lift'const LOCK = 'lock'
RetentionEvent::__construct()
public function __construct(string $path, string $action, string $reason, ?User $user, \DateTimeImmutable $at, ?\DateTimeImmutable $until = null)RetentionEvent::getId()
public function getId(): ?intRetentionEvent::getPath()
public function getPath(): stringRetentionEvent::getAction()
public function getAction(): stringRetentionEvent::isLift()
public function isLift(): boolRetentionEvent::getUntil()
public function getUntil(): ?\DateTimeImmutableRetentionEvent::getReason()
public function getReason(): stringRetentionEvent::getUser()
public function getUser(): ?UserRetentionEvent::getUserName()
public function getUserName(): ?stringRetentionEvent::getAt()
public function getAt(): \DateTimeImmutableRetentionEvent::liftsOn()
public function liftsOn(\DateTimeImmutable $now): boolA lift still running at that moment: until it is put back, or until a date not reached yet.
ShareDownload class
class ShareDownload ShareDownload.php:13
How many times a file of the drive was downloaded (Base\Drive\Controller\ShareController) - or a folder, as a zip, or the old downloads of versions no longer there (drive:count). A number per path and when it last grew: nothing of who downloaded it.
ShareDownload::__construct()
public function __construct(string $path = '', int $count = 0)ShareDownload::getId()
public function getId(): ?intShareDownload::getPath()
public function getPath(): stringShareDownload::getCount()
public function getCount(): intShareDownload::setCount()
public function setCount(int $count): selfShareDownload::getLastAt()
public function getLastAt(): ?\DateTimeImmutableShareGroup class
class ShareGroup ShareGroup.php:16
A group of people the team names - a flatshare's tenants, a couple, a family's heirs - to share folders with all of them at once (SharedPath::$groups): whoever is in it sees what is shared with it, as if shared with them by name; someone added later sees it too, someone taken out no longer does.
ShareGroup::__construct()
public function __construct(string $name)ShareGroup::getId()
public function getId(): ?intShareGroup::getName()
public function getName(): stringShareGroup::setName()
public function setName(string $name): selfShareGroup::getMembers()
public function getMembers(): CollectionShareGroup::addMember()
public function addMember(User $user): selfShareGroup::removeMember()
public function removeMember(User $user): selfShareGroup::hasMember()
public function hasMember(User $user): boolShareGroup::__toString()
public function __toString(): stringShareTask class
class ShareTask ShareTask.php:12
A task of a workspace of the drive (SharedPath::$tasks): a few words, done or not - and when, and who wrote it.
ShareTask::__construct()
public function __construct(string $title = '', ?User $author = null)ShareTask::getId()
public function getId(): ?intShareTask::getWorkspace()
public function getWorkspace(): ?SharedPathShareTask::setWorkspace()
public function setWorkspace(?SharedPath $workspace): selfShareTask::getTitle()
public function getTitle(): stringShareTask::isDone()
public function isDone(): boolShareTask::getPosition()
public function getPosition(): intShareTask::setPosition()
public function setPosition(int $position): selfShareTask::getAuthor()
public function getAuthor(): ?UserShareTask::getCreatedAt()
public function getCreatedAt(): \DateTimeImmutableShareTask::getDoneAt()
public function getDoneAt(): ?\DateTimeImmutableShareTask::toggle()
public function toggle(): selfDone, or back to do.
SharedPath class
class SharedPath SharedPath.php:22
What the team says of a folder or a file of the drive (Base\Drive\Share\FileShare): who it is for (an audience's key: Base\Drive\Audience), a few words shown above its list, its tags (what is under it has them too), whether it is listed. A folder may be a workspace: its people (members: they see it whoever else it is for, and what is "for its members" is for them) and its tasks. The files themselves are on the storage; a path without a row here is as its nearest parent with one - the root as drive.default_audience says.
Its table keeps the name the sites created it under (sharedPath, sharedPathMember): no data moves. Its people are accounts of the application's App\Entity\User, as the core's own entities.
SharedPath::__construct()
public function __construct(string $path = '', string $audience = 'staff')SharedPath::getId()
public function getId(): ?intSharedPath::getPath()
public function getPath(): stringSharedPath::setPath()
public function setPath(string $path): selfSharedPath::getAudience()
public function getAudience(): stringSharedPath::setAudience()
public function setAudience(string $audience): selfSharedPath::getDescription()
public function getDescription(): ?stringSharedPath::setDescription()
public function setDescription(?string $description): selfSharedPath::getTags()
public function getTags(): arraySharedPath::setTags()
public function setTags(iterable $tags): self$tagseach trimmed, the same one once (whatever its case)
SharedPath::isListed()
public function isListed(): ?boolSharedPath::setListed()
public function setListed(?bool $listed): selfSharedPath::isWorkspace()
public function isWorkspace(): boolSharedPath::setWorkspace()
public function setWorkspace(bool $workspace): selfSharedPath::allowsDeposit()
public function allowsDeposit(): boolSharedPath::setDeposit()
public function setDeposit(bool $deposit): selfSharedPath::getMembers()
public function getMembers(): CollectionSharedPath::addMember()
public function addMember(User $user): selfSharedPath::removeMember()
public function removeMember(User $user): selfSharedPath::hasMember()
public function hasMember(User $user): boolOne of its people: by name, or through a group it is shared with.
SharedPath::getGroups()
public function getGroups(): CollectionSharedPath::addGroup()
public function addGroup(ShareGroup $group): selfSharedPath::removeGroup()
public function removeGroup(ShareGroup $group): selfSharedPath::getTasks()
public function getTasks(): CollectionSharedPath::addTask()
public function addTask(ShareTask $task): selfSharedPath::removeTask()
public function removeTask(ShareTask $task): selfBase\Drive\People
AccountPeople class
final class AccountPeople implements PeopleInterface AccountPeople.php:12
The drive's people by default: every account of drive.user_class, by its identifier and its e-mail, in one group ("accounts").
AccountPeople::__construct()
public function __construct(readonly EntityManagerInterface $entityManager, readonly string $userClass = 'App\Entity\User')AccountPeople::grouped()
public function grouped(): arrayAccountPeople::names()
public function names(): arrayPeopleInterface interface
interface PeopleInterface PeopleInterface.php:12
Whom a folder of the drive may be shared with, by name and what they are to the site: groups of accounts (user id => label). The bundle's AccountPeople lists every account; a site says who its people are with its own implementation and #[AsAlias(PeopleInterface::class)] - omnibase/estate's tenants, associates, contractors and team for a property company. Each group's name is a translation key of the messages domain: share.people_group.<group>.
PeopleInterface::grouped()
public function grouped(): array- Returns
each group's people, user id => name and what they are; empty groups left out
PeopleInterface::names()
public function names(): array- Returns
user id => their name and what they are, every group together
Base\Drive\Repository
RetentionEventRepository class
class RetentionEventRepository extends ServiceEntityRepository RetentionEventRepository.php:10
RetentionEventRepository::__construct()
public function __construct(ManagerRegistry $registry)RetentionEventRepository::log()
public function log(): array- Returns
the whole log, oldest first: a few lines a year
ShareDownloadRepository class
class ShareDownloadRepository extends ServiceEntityRepository ShareDownloadRepository.php:10
ShareDownloadRepository::__construct()
public function __construct(ManagerRegistry $registry)ShareDownloadRepository::increment()
public function increment(string $path): voidOne more download of a path: in one statement, whatever else is counting at the same time.
ShareDownloadRepository::counts()
public function counts(): array- Returns
every path's downloads
ShareDownloadRepository::deleteUnder()
public function deleteUnder(string $path): voidThe counts of a path and of everything under it: gone with it.
SharedPathRepository class
class SharedPathRepository extends ServiceEntityRepository SharedPathRepository.php:10
SharedPathRepository::__construct()
public function __construct(ManagerRegistry $registry)SharedPathRepository::byPath()
public function byPath(): array- Returns
every path the team said something of, by path
SharedPathRepository::findUnder()
public function findUnder(string $path): arrayThe rows of a path and of everything under it: renamed or deleted with it.
Base\Drive\Security\Voter
ShareVoter class
final class ShareVoter extends Voter ShareVoter.php:30
Who sees a path of the drive (SHARE_VIEW, the path as subject), who manages it (SHARE_MANAGE: the staff, drive.staff_role), and who works in a workspace - its tasks, the files its people bring (SHARE_WORK, the path as subject: its members and the staff). A path is for its audience (FileShare::audience, answered by Base\Drive\Audience\Audiences: the readers, the signed-in users, the members of its workspace, the staff only, and the site's own); and, whatever its audience, for the people it was shared with (FileShare::isSharedWith: a workspace's people, in it or above it).
The retention lock (drive.retention, Share\Retention): SHARE_ALTER - delete, overwrite, rename or move a path - is the staff's, and nobody's in a locked folder, the team included; SHARE_RETAIN - lift a folder's lock or put it back - is the superadmin's alone (drive.retention_role), with retention on.
ShareVoter::__construct()
public function __construct(readonly FileShare $share, readonly Audiences $audiences, readonly Security $security, readonly string $staffRole = 'ROLE_STAFF', readonly ?Retention $retention = null)Base\Drive\Share
FileShare class
class FileShare FileShare.php:39
The drive (« le Partage », « Cloud » on a site's pages): files a site shares with its readers, its users, the people of its workspaces and whoever its own audiences let in - an index of files, as a web server's "Index of /", with a little more: who each folder is for, whom it is shared with by name, a few words above it, its README under it, a search through the tree, each person's own root.
The files are on a storage of their own (drive.storage, alias documents.storage: the site's Google Drive folder once connected, its flysystem storage drive.local_storage otherwise - Base\Drive\Storage\DocumentsStorage), never public: they are read through ShareController, which asks ShareVoter. What the team says of a path (Base\Drive\Entity\SharedPath: its audience, its description, its tags, whether it is listed) is in the database; a path without a row is as its nearest parent with one - the root as drive.default_audience says; its tags are its own and all its folders'.
Paths are relative to the drive's root, "/"-separated, without slashes at their ends ("" is the root). Names beginning with a dot (.git, .htaccess) are never listed nor served.
With the retention lock on (drive.retention, Base\Drive\Share\Retention), what a locked folder holds is neither deleted, overwritten, renamed nor moved here (LockedException), whoever asks: the page, the commands and the bundles writing into the drive all come through these methods.
A folder's own words, shown under its list: the first of these found in it.
A folder larger than this is not offered as one zip: its files, one by one.
FileShare::__construct()
public function __construct(readonly FilesystemOperator $storage, readonly SharedPathRepository $paths, readonly EntityManagerInterface $entityManager, readonly ShareDownloadRepository $downloads, readonly string $defaultAudience = 'staff', readonly ?PersonalTags $personal = null, readonly ?Retention $retention = null)FileShare::normalize()
public static function normalize(string $path): stringA path as the drive keeps it: no slashes at its ends, no "." or ".." nor hidden part.
- Throws
InvalidArgumentException when it could lead out of the drive, or names something hidden
FileShare::name()
public static function name(string $name): stringA name fit for the drive, from what was typed or uploaded: its last part, without what a path cannot hold.
FileShare::slug()
public static function slug(string $path): stringA path as an address reads it (drive.slugs): each part in plain lower-case words joined by hyphens, a file keeping its extension - "Assemblées générales/2026/Procès-verbal.pdf" is "assemblees-generales/2026/proces-verbal.pdf". A part with nothing to slug stays as it is.
FileShare::resolve()
public function resolve(string $path): ?stringThe path an address leads to: each part the item of that name, or else the first of its folder whose slug it is - so that an address by names, as before, and one by slugs both lead there. Null when nothing does.
FileShare::isDirectory()
public function isDirectory(string $path): boolFileShare::isFile()
public function isFile(string $path): boolFileShare::entries()
public function entries(string $path): arrayWhat a folder holds, folders first, each by name.
FileShare::search()
public function search(string $query, callable $allowed, int $limit = 80, ?callable $tagsOf = null): arrayWhat may be found under the root by its name or its tags (accents and case aside), through the whole tree: only what $allowed lets through - what someone sees, and nothing above or beside it. Folders first, then files, each by path; at most $limit.
$tagsOfthe tags it is found by, when not its own and its folders' (the ones its reader sees)
- Returns
as entries(), each with its folder ("in")
FileShare::tops()
public function tops(callable $allowed): arrayThe highest folders someone sees when the root is not for them: each folder $allowed lets through whose own folder it does not - a tenant's, an owner's, a partner's space -, as entries of a root of their own.
FileShare::readme()
public function readme(string $path): ?array- Returns
a folder's README, as text
FileShare::audience()
public function audience(string $path): stringWho a path is for, an audience's key: its own, or its nearest parent's - drive.default_audience when none says.
FileShare::tags()
public function tags(string $path): array- Returns
a path's tags: its own, then its folders', each once
FileShare::listed()
public function listed(string $path): boolListed on the root and open to search engines: as itself or its nearest folder says - not listed when none does.
FileShare::downloads()
public function downloads(string $path): intHow many times a path was downloaded: a file's, or a folder's - its zips and everything under it.
FileShare::countDownload()
public function countDownload(string $path): voidOne more download of a path (a file, or a folder's zip).
FileShare::setDownloads()
public function setDownloads(string $path, int $count): voidA path's downloads set at a number - the old ones of a file restored (drive:count).
FileShare::tagKey()
public static function tagKey(string $tag): stringA tag as a filter key: "Raspberry Pi" is "raspberry-pi".
FileShare::row()
public function row(string $path): ?SharedPathWhat the team said of this very path, if anything.
FileShare::describe()
public function describe(string $path, ?string $audience, ?string $description, ?iterable $tags = null, bool|string|null $listed = 'keep'): voidIts audience (a key), its description, its tags and whether it is listed; an audience of null is its parent's again.
$tagsnull: the ones it has
$listedtrue/false, null as its folder; 'keep': as it is
FileShare::isLocked()
public function isLocked(string $path): boolKept by the retention lock (drive.retention): neither deleted, overwritten, renamed nor moved.
FileShare::createDirectory()
public function createDirectory(string $path): voidFileShare::upload()
public function upload(string $directory, UploadedFile $file): stringAn uploaded file into a folder, under its own name - beside the one already there, if any ("notes (2).pdf").
FileShare::copy()
public function copy(string $file, string $directory): stringA file of the drive copied into a folder, under its own name - beside one already there, never over it; its new path.
FileShare::workspace()
public function workspace(string $path): ?SharedPathThe workspace a path is in: itself, or its nearest folder made one - null when none.
FileShare::createWorkspace()
public function createWorkspace(string $name, string $audience, ?string $description = null): stringA new workspace: a folder of the drive's root, who it is for (an audience's key), a few words on it.
FileShare::isSharedWith()
public function isSharedWith(string $path, User $user): boolA path shared with someone: they are one of the people of a workspace it is in - its own or any folder above it. They see it whoever else it is for.
FileShare::shareWith()
public function shareWith(string $path, User $user, ?bool $deposit = null): voidA folder shared with someone: they see it and what it holds, from their own access, read only unless its people may bring files ($deposit). The folder becomes a workspace (its people, its tasks) if it was not one; whoever else it was for keeps it.
FileShare::shareWithGroup()
public function shareWithGroup(string $path, ShareGroup $group, ?bool $deposit = null): voidA folder shared with a group of people (Entity\ShareGroup), as shareWith() is with one person.
FileShare::setWorkspace()
public function setWorkspace(string $path, bool $workspace): voidA folder made a workspace, or a workspace made a plain folder again (its people, groups and tasks gone).
FileShare::move()
public function move(string $from, string $toDirectory, ?string $name = null): stringA file or a folder moved into another folder (and renamed, when $name is given): what it
holds, what was said of it and its downloads follow.
- Returns
its new path
- Throws
InvalidArgumentException into itself, or onto something already there
- Throws
LockedException out of a folder the retention lock keeps
FileShare::directories()
public function directories(): array- Returns
every folder of the drive, to move something into
FileShare::write()
public function write(string $path, $stream): voidA file from a stream (drive:import, the bundles filing into the drive), its folders made on the way; what is there already is replaced - unless the retention lock keeps it.
- Throws
LockedException over a file the retention lock keeps
FileShare::weight()
public function weight(string $path): intWhat a folder weighs, every file under it - hidden ones left out.
FileShare::delete()
public function delete(string $path): voidA file, or a folder and all it holds - and what was said of them.
- Throws
LockedException in a folder the retention lock keeps
FileShare::stream()
public function stream(string $path)FileShare::size()
public function size(string $path): intFileShare::modified()
public function modified(string $path): intFileShare::zip()
public function zip(string $path, callable $allowed): stringA folder as a zip, in a temporary file the caller deletes: every file under it that
$allowed lets through (the viewer's rights, folder by folder), hidden ones left out.
LockedException class
final class LockedException extends RuntimeException LockedException.php:9
What the retention lock refuses (drive.retention): deleting, overwriting, renaming or moving something in a locked folder - whoever asks, the team included.
LockedException::__construct()
public function __construct(public readonly string $path)PersonalTags class
final class PersonalTags PersonalTags.php:17
The tags each one puts on folders for themselves (drive.personal_tags): a tenant sorting their papers, an owner theirs, nobody else seeing them. Like the team's tags, a folder's apply to what it holds (to filter by). Nothing when the option is off or nobody is signed in; their rows follow a folder moved and go with one deleted (FileShare).
PersonalTags::__construct()
public function __construct(readonly EntityManagerInterface $entityManager, readonly Security $security, readonly bool $enabled = false)PersonalTags::enabled()
public function enabled(): boolWhether the one signed in has tags of their own here.
PersonalTags::own()
public function own(string $path): array- Returns
a path's own tags, as typed
PersonalTags::tags()
public function tags(string $path): array- Returns
a path's tags: its own, then its folders', each once
PersonalTags::add()
public function add(string $path, iterable $names): void$namesadded to a path, each once
PersonalTags::remove()
public function remove(string $path, iterable $names): void$namestaken off a path
PersonalTags::color()
public function color(string $tag): stringA tag's colour for the one signed in: the one they chose, otherwise one drawn from its name.
PersonalTags::choose()
public function choose(string $tag, ?string $color): voidThe colour they choose for a tag (#rrggbb) on every folder they gave it, or none to give it back its own.
PersonalTags::moved()
public function moved(string $from, string $to): voidEveryone's tags under a path moved, under its new path.
PersonalTags::deleted()
public function deleted(string $path): voidEveryone's tags under a path deleted, gone with it.
Retention class
class Retention Retention.php:24
The retention lock (drive.retention, off by default): with it on, every folder of the drive and what it holds is kept - nothing deleted, overwritten, renamed nor moved, by anyone, the team included (FileShare refuses it, ShareVoter's SHARE_ALTER says no). Adding files stays open.
Only the superadmin (drive.retention_role) lifts it, folder by folder - until it is put back, or for a while (a duration, an end date) -, and puts it back; each lift and each lock is a line of the log (Entity\RetentionEvent: who, when, which folder, until when, why - a reason is required), never changed nor removed. A folder is as the nearest of itself and its folders whose latest line says something: a lock, or a lift still running; a lift whose date has passed says nothing any more - the lock is back by itself, read so when asked, with no task to run.
Retention::__construct()
public function __construct(readonly RetentionEventRepository $repository, readonly EntityManagerInterface $entityManager, readonly bool $enabled = false, readonly string $role = 'ROLE_SUPERADMIN', readonly ?ClockInterface $clock = null)Retention::enabled()
public function enabled(): boolRetention::role()
public function role(): stringWho lifts and puts back the lock: the superadmin's role.
Retention::isLocked()
public function isLocked(string $path): boolKept as it is: retention on, and no lift running for it or the folder that decides for it.
Retention::guard()
public function guard(string $path): void- Throws
LockedException when the path is kept
Retention::isLockedTree()
public function isLockedTree(string $path): boolKept, or holding something locked again on its own: a folder goes (deleted, moved) only with all it holds.
Retention::guardTree()
public function guardTree(string $path): void- Throws
LockedException when isLockedTree()
Retention::lift()
public function lift(string $path): ?RetentionEventThe lift a path is open by - its own, or its nearest folder's -, null when it is locked (a lock said there, or nothing said up to the root).
Retention::liftFor()
public function liftFor(string $path, ?User $by, string $reason, ?\DateTimeImmutable $until = null): RetentionEventA folder's lock lifted, until it is put back ($until null) or until a moment to come.
- Throws
InvalidArgumentException without retention, without a reason, or with a moment gone
Retention::lock()
public function lock(string $path, ?User $by, string $reason): RetentionEventA folder's lock put back - also inside a folder lifted, for it and what it holds.
- Throws
InvalidArgumentException without retention, or without a reason
Retention::log()
public function log(string $path): arrayWhat the log says of a folder, newest first: its own lines, its folders' (which decide for it) and those of the folders under it - the root's is the whole log.
Retention::now()
public function now(): \DateTimeImmutableNow, by the application's clock when it has one (a test's, frozen).
TagColors class
final class TagColors TagColors.php:12
A tag's colour, the same wherever the tag is shown: the one the team chose for it (kept in the site's settings, app.drive.tag_colors, by the tag's key), otherwise one of a few drawn from its name - so that a tag has a colour of its own before anyone chooses.
TagColors::__construct()
public function __construct(readonly SettingBagInterface $settings)TagColors::of()
public function of(string $tag): stringTagColors::drawn()
public static function drawn(string $tag): stringThe colour a tag has before anyone chooses: one of the palette, drawn from its name.
TagColors::choose()
public function choose(string $tag, ?string $color): voidThe colour chosen for a tag (#rrggbb), or none to give it back its own.
Base\Drive\Space
SpaceProviderInterface interface
interface SpaceProviderInterface SpaceProviderInterface.php:18
Where a person's space is in the drive: the folder their role gives them - a tenant's, an owner's, a partner's. A bundle that knows its people implements it (omnibase/estate: Locataires/<tenant>, Propriétaires/<owner>, Indivisions/<ownership>), tagged drive.space by autoconfiguration; the providers are asked in their priority's order, the first to answer wins, and nobody answering leaves the drive's own place (Spaces: drive.spaces_root/<name>).
A provider makes the folder when it is missing and shares it with the person, read only, as its business does (the drive checks it is shared once more, whatever the provider did).
const TAG = 'drive.space'
SpaceProviderInterface::spaceOf()
public function spaceOf(User $user): ?stringThe person's space, made if missing, reused otherwise: its path from the drive's root - null when they are none of this provider's people.
Spaces class
class Spaces Spaces.php:22
Each person's space in the drive, and files shared on upload with named people: a file added goes, besides the folder it was added to, into the space of each person named - and of each person of a group named (Entity\ShareGroup) -, the space made if missing, reused otherwise, shared with them read only unless the uploader lets them bring files too.
Where a space is: the first provider to answer (SpaceProviderInterface, tagged drive.space - omnibase/estate's tenants, owners and partners), otherwise drive.spaces_root/<their name>, the team's (the staff audience) and theirs alone.
Spaces::__construct()
public function __construct(readonly FileShare $share, readonly iterable $providers = [], readonly string $root = 'Spaces')Spaces::of()
public function of(User $user, bool $deposit = false): stringA person's space: made if missing, reused otherwise, shared with them (read only, unless $deposit); its path.
Spaces::deliver()
public function deliver(string $file, iterable $recipients, bool $deposit = false): arrayA file of the drive shared with people: a copy in each one's space (a group: each of its people's), beside what is there, never over it - none where the file already is in their space. Each person once, however often named.
- Returns
each copy's path => the space it went to
Base\Drive\Storage
DocumentsStorage class
class DocumentsStorage DocumentsStorage.php:17
Where the drive's files are (the service drive.storage, alias documents.storage, read by Base\Drive\Share\FileShare): the site's Google Drive folder once connected from the back office (google/apiclient and masbug/flysystem-google-drive-ext installed), the site's own storage otherwise (drive.local_storage, local.share by default) - and always in the tests.
DocumentsStorage::__construct()
public function __construct(readonly DriveSettings $settings, readonly DriveClient $client, readonly FilesystemOperator $local, readonly string $environment, readonly ?LoggerInterface $logger = null)DocumentsStorage::create()
public function create(): FilesystemOperatorDocumentsStorage::isDrive()
public function isDrive(): boolDriveClient class
class DriveClient DriveClient.php:17
Google, for the documents: the consent screen (offline access, the whole Drive - so files dropped into the folder from Drive itself show up), and a Drive service on the stored refresh token. The OAuth client is the site's (GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET); its consent screen must be published, or Google drops the token after seven days.
DriveClient::__construct()
public function __construct(readonly DriveSettings $settings, readonly UrlGeneratorInterface $urls, readonly ?string $clientId = null, readonly ?string $clientSecret = null)DriveClient::isConfigured()
public function isConfigured(): boolDriveClient::client()
public function client(): ClientDriveClient::authorizationUrl()
public function authorizationUrl(string $state): stringDriveClient::exchange()
public function exchange(string $code): arrayDriveClient::drive()
public function drive(): DriveDriveSettings class
class DriveSettings DriveSettings.php:15
What the site keeps of its Google Drive: the refresh token (encrypted with the app secret: it opens the whole Drive), the folder the documents live in, and who connected it. In omnibase's settings, under the names the sites stored them with (app.drive.*), sealed with the same key: a Drive connected before the bundle stays connected.
DriveSettings::__construct()
public function __construct(readonly SettingBagInterface $settings, readonly string $secret)DriveSettings::isConnected()
public function isConnected(): boolDriveSettings::refreshToken()
public function refreshToken(): ?stringDriveSettings::connect()
public function connect(string $refreshToken, ?string $account): voidDriveSettings::disconnect()
public function disconnect(): voidDriveSettings::folderId()
public function folderId(): ?stringDriveSettings::folderName()
public function folderName(): ?stringDriveSettings::account()
public function account(): ?stringDriveSettings::sharedDriveId()
public function sharedDriveId(): ?stringDriveSettings::useFolder()
public function useFolder(string $id, string $name, ?string $sharedDriveId = null): voidBase\Drive\Tree
DocumentsTree class
class DocumentsTree DocumentsTree.php:12
A site's layout of folders (TreeInterface) created where the files are (its storage or its Google Drive): each folder missing made, who each is for set at the same time. Folders already there are left as they are, and so is what they hold.
DocumentsTree::__construct()
public function __construct(readonly FileShare $share)DocumentsTree::create()
public function create(TreeInterface $tree): int- Returns
the folders created
TreeInterface interface
interface TreeInterface TreeInterface.php:12
A site's own layout of folders, laid out where the files are (its storage or its Google Drive) by DocumentsTree - from the back office's Google Drive page (« Créer les dossiers ») or the site's fixtures. A property company's: its statutes, general meetings, accounts, a folder per home. The page offers it only when the site has one: a service implementing this interface, aliased with #[AsAlias(TreeInterface::class)].
TreeInterface::folders()
public function folders(): array- Returns
each folder's path (parents before their children; "" is the root) => the key of the audience it is for, or null: as its folder
TreeInterface::summary()
public function summary(): stringWhat it lays out, in a sentence for the back office.
Base\Drive\Twig
DriveExtension class
final class DriveExtension extends AbstractExtension DriveExtension.php:19
For a site's templates: drive_tag_color(tag), a team's tag's colour (Share\TagColors); drive_my_tag_color(tag), the colour of a tag of one's own (Share\PersonalTags); path|drive_slug, a path as the drive's addresses read it (drive.slugs: its slugs, otherwise itself) - for path('app_share', {path: entry.path|drive_slug}).
DriveExtension::__construct()
public function __construct(readonly TagColors $colors, readonly PersonalTags $personal, readonly bool $slugs = false)DriveExtension::getFilters()
public function getFilters(): arrayDriveExtension::getFunctions()
public function getFunctions(): array