foldershare-8.x-1.2/foldershare.install
foldershare.install
<?php
/**
* @file
* Handles module installation, uninstallation, and version updates.
*/
use Drupal\foldershare\ManageFileSystem;
use Drupal\foldershare\Settings;
use Drupal\foldershare\Utilities\FileUtilities;
use Drupal\foldershare\Entity\FolderShare;
use Drupal\foldershare\ManageUsageStatistics;
/**
* @defgroup foldershare FolderShare
*
* @{
* This module manages a hierarchy of files, folders, and subfolders,
* along with access controls that govern how content may be shared
* among users. The module provides a user interface, web services,
* hooks, access controls, administration pages, and a data model API
* for operating on the file system.
*
* Folders may nest within other folders to create a folder tree like
* that found in file systems for a Windows, Mac, and Linux system.
* Each file and folder has a name, creation and modification dates,
* a size (in bytes), an optional description, and any other fields
* added by the site admin or extension modules.
*
* Files and folders existing within a folder tree that starts with a
* "root" in a "root list". Each user has their own root list. That
* user may share a root file or folder by granting viewing or authoring
* access to specific users. If they grant access to the site's anonymous
* user, the root file or folder, and any nested items within a root
* folder, become accessible by anonymous visitors to the site.
* @}
*/
/**
* Defines the schema for the custom tables used by this module.
*
* This module defines an entity, whose primary and support tables are
* created automatically by Drupal core's entity type management.
*
* This module creates a support table to track overall usage by counting
* the number of files, folders, and bytes of storage per user.
*
* @return array
* An array of tables to create at module installation time to
* support per-folder access controls.
*
* @see foldershare_get_user_usage_schema()
*/
function foldershare_schema() {
//
// The installation process automatically creates tables required for
// custom entity types. Here we need to define any non-entity tables.
//
// The user usage table records a list of users and how they are using
// files, folders, and local disk space.
return ManageUsageStatistics::getSchema();
}
/**
* Helps to uninstall this module.
*
* Drupal's module uninstall handles deletion of most things automatically.
* It will:
* - Delete search plugins using the module's entity.
* - Delete views using the module's entity.
* - Delete view modes for the module's entity.
* - Delete entity form display configurations for the module's entity.
* - Delete entity view display configurations for the module's entity.
* - Delete all entities.
* - Delete fields for the module's entity.
* - Delete field storage for the module's entity.
* - Delete all files referenced by the module's entities.
* - Delete all database tables defined by foldershare_schema()
*
* However, it misses a few things that are handled here:
* - Delete comment types associated with this module's entity.
* - Delete the local directory tree for this module's files.
*/
function foldershare_uninstall() {
//
// Drupal has several uninstall hooks and callbacks, including:
// - hook_module_preuninstall()
// - hook_uninstall()
// - entity type delete listener
// - hook_modules_uninstalled()
//
// hook_module_preuninstall() is called for all modules to give them a
// chance to respond when a specific module is about to be uninstalled.
// This is called after the uninstall process has identified the full
// set of modules to uninstall, but before it has done anything.
//
// hook_uninstall() is called on the specific module about to be
// uninstalled. The above hook has executed, but nothing else has
// been done.
//
// All entity type delete listeners are called after an entity type's
// definitions and storage have been removed.
//
// hook_modules_uninstalled() is called on all modules, except the
// newly uninstalled module, to notify them that the uninstalled
// module is entirely gone. The entity type, database tables,
// and configurations are all gone and all caches rebuilt to reflect
// the loss of the module's routes, themes, etc.
//
// Remove the directory tree
// -------------------------
// This deletes all files associated with File entities referenced
// by FolderShare entities. Later deletion of those entities by the
// File module will recognize that the underlying file is already
// gone.
$scheme = Settings::getFileScheme();
$dir = ManageFileSystem::FILE_DIRECTORY;
$uri = $scheme . '://' . $dir;
FileUtilities::rrmdir($uri);
$entityTypeManager = \Drupal::service('entity_type.manager');
$entityType = FolderShare::ENTITY_TYPE_ID;
//
// Remove comment types
// --------------------
// The comment module *should* catch hook_modules_uninstalled() so that
// it can delete comment types associated with deleted entity types.
// But it doesn't. Instead, we need to:
// - Find all comment fields on FolderShare entities.
// - Delete those comment fields.
// - Find all comment types for FolderShare entities.
// - Delete those comment types.
//
// And this should only be done if the comment module is installed
// (which provides the 'comment.manager' service).
if (\Drupal::hasService('comment.manager') === TRUE) {
// Comment manager is available. Comment module is installed.
//
// Get several managers.
$commentManager = \Drupal::service('comment.manager');
$entityFieldManager = \Drupal::service('entity_field.manager');
// Get the names of all comment fields for the FolderShare entity type.
// There could be none.
$commentFields = $commentManager->getFields($entityType);
$commentFieldNames = array_keys($commentFields);
// Get field storage definitions for all of fields for the
// FolderShare entity type.
$fieldStorageDefinitions = $entityFieldManager->getFieldStorageDefinitions(
$entityType);
// Find each comment field, get it's storage definition and delete
// the field.
foreach ($commentFieldNames as $fieldName) {
if (isset($fieldStorageDefinitions[$fieldName]) === TRUE) {
$fieldStorageDefinitions[$fieldName]->delete();
}
}
// Find all comment type entities who's target entity type is
// the FolderShare entity type, and delete them.
$commentTypeStorage = $entityTypeManager->getStorage('comment_type');
foreach (\Drupal::entityQuery('comment_type')->execute() as $id) {
$commentType = $commentTypeStorage->load($id);
if ($commentType->getTargetEntityTypeId() === $entityType) {
$commentType->delete();
}
}
}
//
// Remove orphaned permissions
// ---------------------------
// The user module *should* catch hook_modules_uninstalled() so that
// it can delete permissions associated with deleted entity types.
// But it doesn't. Instead, these permissions remain in role configurations,
// even though they aren't displayed and apply to an uninstalled module.
//
// We need to:
// - Get a list of permissions defined for FolderShare entities.
// - Get a list of user roles.
// - Loop through the roles and revoke the permissions.
if (\Drupal::hasService('user.permissions') === TRUE) {
// User permissions are available. User module is installed (it is
// a core module, so it is always installed, but let's be safe).
//
// Get all user permissions for our entity type.
$names = [];
$permissionsHandler = \Drupal::service('user.permissions');
foreach ($permissionsHandler->getPermissions() as $name => $permission) {
if ($permission['provider'] === $entityType) {
$names[] = $name;
}
}
// Get a list of user roles.
$roleStorage = $entityTypeManager->getStorage('user_role');
$roles = $roleStorage->loadMultiple();
// Go through each role and revoke the FolderShare entity permissions.
foreach ($roles as $role) {
foreach ($names as $name) {
$role->revokePermission($name);
$role->save();
}
}
}
}
require 'foldershare.update.inc';
