foldershare-8.x-1.2/foldershare.drush.inc
foldershare.drush.inc
<?php
/**
* @file
* Implements drush commands specific to the module.
*/
use Drupal\Core\Cache\Cache;
use Drupal\user\Entity\User;
use Drupal\foldershare\Settings;
use Drupal\foldershare\Entity\FolderShare;
use Drupal\foldershare\ManageUsageStatistics;
use Drupal\foldershare\Entity\FolderShareScheduledTask;
/**
* Implements hook_drush_command().
*/
function foldershare_drush_command() {
$commands['foldershare'] = [
'description' => 'List FolderShare module commands.',
'aliases' => [
'fs',
],
'options' => [
'all' => [
'description' => 'List all commands, including those for debugging.',
'hidden' => TRUE,
],
],
'bootstrap' => DRUSH_BOOTSTRAP_NONE,
'category' => 'San Diego Supercomputer Center (SDSC)',
'topic' => TRUE,
'examples' => [
'drush foldershare' => 'List FolderShare commands',
],
];
$commands['foldershare-admin'] = [
'description' => 'Perform administrative functions.',
'hidden' => TRUE,
'aliases' => [
'fsadmin',
],
'arguments' => [
'uid' => [
'description' => 'The user ID owning affected content',
],
'newuid' => [
'description' => 'The user ID for a new owner of the content',
],
],
'options' => [
'deleteall' => [
'description' => 'Delete all content',
],
'deleteby' => [
'description' => 'Delete all content owned by a user',
],
'changeownerby' => [
'description' => 'Change ownership of all content owned by a user',
],
'unsharewith' => [
'description' => 'Remove the user from all sharing grants',
],
],
'examples' => [
'drush foldershare-admin --deleteall' => 'Delete everything',
'drush foldershare-admin --deleteby 123' => 'Delete all owned by 123',
'drush foldershare-admin --changeownerby 123 456' => 'Change ownership of all owned by 123 to be 456',
'drush foldershare-admin --unsharewith 123' => 'Remove sharing with 123',
],
'drupal dependencies' => [
'foldershare',
],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
'category' => 'San Diego Supercomputer Center (SDSC)',
];
$commands['foldershare-disabled'] = [
'description' => 'List, enable, and disable items marked as "disabled".',
'hidden' => TRUE,
'aliases' => [
'fsdisable',
'fsdisabled',
],
'arguments' => [
'id' => [
'description' => 'The entity ID to disable or enable',
],
],
'options' => [
'disable' => [
'description' => 'Disable the item',
],
'enable' => [
'description' => 'Enable an item',
],
'enableall' => [
'description' => 'Enable all disabled items',
],
'list' => [
'description' => 'List all disabled items',
],
],
'examples' => [
'drush foldershare-disabled' => 'List disabled items',
'drush foldershare-disabled --list' => 'List disabled items',
'drush foldershare-disabled --disable ID' => 'Disable item with entity ID',
'drush foldershare-disabled --enable ID' => 'Enable item with entity ID',
'drush foldershare-disabled --enableall' => 'Enable all items',
],
'drupal dependencies' => [
'foldershare',
],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
'category' => 'San Diego Supercomputer Center (SDSC)',
];
$commands['foldershare-fsck'] = [
'description' => 'Find and fix file system problems.',
'aliases' => [
'fsfsck',
],
'options' => [
'fix' => [
'description' => 'Automatically fix problems',
],
],
'examples' => [
'drush foldershare-fsck' => 'Find file system problems',
'drush foldershare-fsck --fix' => 'Find and fix file system problems',
],
'drupal dependencies' => [
'foldershare',
],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
'category' => 'San Diego Supercomputer Center (SDSC)',
];
$commands['foldershare-hidden'] = [
'description' => 'List, hide, or show items marked as "hidden".',
'hidden' => TRUE,
'aliases' => [
'fshide',
'fshidden',
],
'arguments' => [
'id' => [
'description' => 'The entity ID to hide or show',
],
],
'options' => [
'hide' => [
'description' => 'Hide an item',
],
'list' => [
'description' => 'List all hidden items',
],
'show' => [
'description' => 'show an item',
],
'showall' => [
'description' => 'show all hidden items',
],
],
'examples' => [
'drush foldershare-hidden' => 'List hidden items',
'drush foldershare-hidden --list' => 'List hidden items',
'drush foldershare-hidden --hide ID' => 'Hide item with entity ID',
'drush foldershare-hidden --show ID' => 'Show item with entity ID',
'drush foldershare-hidden --showall' => 'Show all items',
],
'drupal dependencies' => [
'foldershare',
],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
'category' => 'San Diego Supercomputer Center (SDSC)',
];
$commands['foldershare-lock'] = [
'description' => 'List, acquire, or release locks.',
'hidden' => TRUE,
'aliases' => [
'foldershare-locks',
'fslock',
'fslocks',
],
'arguments' => [
'id' => [
'description' => "The root entity ID to lock or unlock",
],
],
'options' => [
'list' => [
'description' => 'List root folder locks',
],
'lock' => [
'description' => 'Lock the root folder of an item',
],
'unlock' => [
'description' => 'Unlock the root folder of an item',
],
'unlockall' => [
'description' => 'Unlock all root folders',
],
],
'examples' => [
'drush foldershare-lock' => 'List locked root items',
'drush foldershare-lock --list' => 'List locked root items',
'drush foldershare-lock --lock ID' => 'Lock root item with entity ID',
'drush foldershare-lock --unlock ID' => 'Unlock root item with entity ID',
'drush foldershare-lock --unlockall' => 'Unlock all root items',
],
'drupal dependencies' => [
'foldershare',
],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
'category' => 'San Diego Supercomputer Center (SDSC)',
];
$commands['foldershare-config'] = [
'description' => 'List module config.',
'aliases' => [
'fsconfig',
],
'examples' => [
'drush foldershare-config' => 'List configuration',
],
'drupal dependencies' => [
'foldershare',
],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
'category' => 'San Diego Supercomputer Center (SDSC)',
];
$commands['foldershare-tasks'] = [
'description' => 'List, run, and delete module tasks.',
'hidden' => TRUE,
'aliases' => [
'fstasks',
],
'options' => [
'list' => [
'description' => 'List scheduled tasks',
],
'delete' => [
'description' => 'Delete a task by its ID',
],
'deleteall' => [
'description' => 'Delete all tasks',
],
'run' => [
'description' => 'Run tasks that are ready',
],
],
'arguments' => [
'id' => [
'description' => "The ID of a task",
],
],
'examples' => [
'drush foldershare-tasks' => 'List scheduled tasks',
'drush foldershare-tasks --list' => 'List scheduled tasks',
'drush foldershare-tasks --run' => 'Run ready scheduled tasks',
],
'drupal dependencies' => [
'foldershare',
],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
'category' => 'San Diego Supercomputer Center (SDSC)',
];
$commands['foldershare-usage'] = [
'description' => 'List module usage by user.',
'aliases' => [
'fsusage',
],
'options' => [
'list' => [
'description' => 'List usage per user',
],
'update' => [
'description' => 'Update the usage table',
],
],
'examples' => [
'drush foldershare-usage' => 'List usage per user',
'drush foldershare-usage --list' => 'List usage per user',
'drush foldershare-usage --update' => 'Update the usage table',
],
'drupal dependencies' => [
'foldershare',
],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
'category' => 'San Diego Supercomputer Center (SDSC)',
];
$commands['foldershare-version'] = [
'description' => 'Show module version number.',
'aliases' => [
'fsversion',
],
'examples' => [
'drush foldershare-version' => 'Show version number',
],
'drupal dependencies' => [
'foldershare',
],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
'category' => 'San Diego Supercomputer Center (SDSC)',
];
$commands['foldershare-benchmark'] = [
'description' => 'Benchmark selected module features.',
'hidden' => TRUE,
'aliases' => [
'fsbench',
'fsbenchmark',
],
'options' => [
'folder' => [
'description' => 'Benchmark folder create and delete',
],
'lock' => [
'description' => 'Benchmark process lock and release',
],
'config' => [
'description' => 'Benchmark get and set of configuration',
],
'system' => [
'description' => 'Benchmark misc system calls',
],
],
'drupal dependencies' => [
'foldershare',
],
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
'category' => 'San Diego Supercomputer Center (SDSC)',
];
return $commands;
}
/*---------------------------------------------------------------------
*
* Help.
*
*---------------------------------------------------------------------*/
/**
* Lists available commands.
*/
function drush_foldershare() {
FolderShareScheduledTask::setTaskExecutionEnabled(FALSE);
$showAll = (empty(drush_get_option('all')) === FALSE);
drush_print(
dt('FolderShare: Commands for the module:'));
drush_print(sprintf(
" %-22s %s",
"foldershare",
dt("List these commands.")));
if ($showAll === TRUE) {
drush_print(sprintf(
" %-22s %s",
"foldershare-admin",
dt("Perform administrative operations.")));
}
if ($showAll === TRUE) {
drush_print(sprintf(
" %-22s %s",
"foldershare-benchmark",
dt("Benchmark selected module features.")));
}
if ($showAll === TRUE) {
drush_print(sprintf(
" %-22s %s",
"foldershare-disabled",
dt('List, enable, and disable items marked as "disabled".')));
}
drush_print(sprintf(
" %-22s %s",
"foldershare-fsck",
dt("Find and fix filesystem problems.")));
if ($showAll === TRUE) {
drush_print(sprintf(
" %-22s %s",
"foldershare-hidden",
dt('List, enable, and disable items marked as "hidden".')));
}
if ($showAll === TRUE) {
drush_print(sprintf(
" %-22s %s",
"foldershare-locks",
dt('List, aquire, and release locks.')));
}
drush_print(sprintf(
" %-22s %s",
"foldershare-config",
dt("List module configuration.")));
if ($showAll === TRUE) {
drush_print(sprintf(
" %-22s %s",
"foldershare-tasks",
dt('List, run, and delete module tasks.')));
}
drush_print(sprintf(
" %-22s %s",
"foldershare-usage",
dt("List module usage by user.")));
drush_print(sprintf(
" %-22s %s",
"foldershare-version",
dt("Show module version number.")));
}
/*---------------------------------------------------------------------
*
* Admin - delete and change owner.
*
*---------------------------------------------------------------------*/
/**
* Performs administrative operations.
*
* --changeownerby Changes ownership of all content owned by a user.
* --deleteall Deletes all content.
* --deleteby Deletes all content owned by a user.
* --unsharewith Remove the user from all sharing grants.
*
* @param int $uid
* (optional, default = (-1)) The user entity ID of the affected user.
* @param int $newuid
* (optional, default = (-1)) The user entity ID of the new owner of
* content, for changeownerall.
*/
function drush_foldershare_admin($uid = (-1), $newuid = (-1)) {
FolderShareScheduledTask::setTaskExecutionEnabled(FALSE);
if (empty(drush_get_option('deleteall')) === FALSE &&
empty(drush_get_option('deleteby')) === FALSE &&
empty(drush_get_option('unsharewith')) === FALSE &&
empty(drush_get_option('changeownerby')) === FALSE) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(" Too many FolderShare admin options. Only one allowed."));
drush_print(dt(' Type "drush help foldershare-admin" for admin options.'));
return;
}
if (empty(drush_get_option('deleteall')) === FALSE) {
drush_foldershare_admin_deleteall($uid, $newuid);
return;
}
if (empty(drush_get_option('deleteby')) === FALSE) {
drush_foldershare_admin_deleteby($uid, $newuid);
return;
}
if (empty(drush_get_option('changeownerby')) === FALSE) {
drush_foldershare_admin_changeownerby($uid, $newuid);
return;
}
if (empty(drush_get_option('unsharewith')) === FALSE) {
drush_foldershare_admin_unsharewith($uid, $newuid);
return;
}
drush_print(dt("FolderShare: Error"));
drush_print(dt(" Missing or unrecognized admin option."));
drush_print(dt(' Type "drush help foldershare-admin" for admin options.'));
}
/**
* Performs an administrative "delete all".
*
* @param int $uid
* Should always be -1.
* @param int $newuid
* Should always be -1.
*/
function drush_foldershare_admin_deleteall($uid, $newuid) {
//
// Validate.
// ---------
// There should be no user IDs.
if ($uid !== (-1) || $newuid !== (-1)) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(" The --deleteall option does not require a user ID, but one was provided."));
drush_print(dt(" Did you mean to use --deleteby?"));
drush_print(dt(' Type "drush help foldershare-admin" for admin options.'));
return;
}
//
// Explain.
// --------
// Explain what will happen and to how much content.
drush_print(dt("FolderShare: Delete all"));
drush_print('------------------------------------------------------------------------');
drush_print(dt("All FolderShare files and folders will be deleted immediately!"));
drush_print("");
drush_print(dt("Checking the number of items to delete..."));
$nFiles = FolderShare::countNumberOfFiles(FolderShare::ANY_USER_ID);
$nFolders = FolderShare::countNumberOfFolders(FolderShare::ANY_USER_ID);
if (($nFiles + $nFolders) === 0) {
drush_print(dt("... none! There are no files or folders to delete."));
return;
}
drush_print(dt(
"... @nFiles files and @nFolders folders.",
[
'@nFiles' => $nFiles,
'@nFolders' => $nFolders,
]));
drush_print("");
// Prompt.
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Execute.
drush_print("");
drush_print(dt("Deleting all content."));
drush_print(dt("This may take a few minutes..."));
FolderShare::deleteAll(FolderShare::ANY_USER_ID);
drush_print(dt("Done."));
}
/**
* Performs an administrative "delete by".
*
* @param int $uid
* A valid user ID.
* @param int $newuid
* Should always be -1.
*/
function drush_foldershare_admin_deleteby($uid, $newuid) {
// Validate that there is a UID.
if ($uid < 0) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(' The --deleteby option requires a user ID.'));
drush_print(dt(' Type "drush help foldershare-admin" for admin options.'));
return;
}
$uidEntity = User::load($uid);
if ($uidEntity === NULL) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(
" The ID @uid does not match any known user.",
[
'@uid' => $uid,
]));
return;
}
// Validate that there is no second UID.
if ($newuid !== (-1)) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(" The --deleteby option does not require a second user ID, but one was provided."));
drush_print(dt(' Type "drush help foldershare-admin" for admin options.'));
return;
}
// Explain.
drush_print(dt(
"FolderShare: Delete all items owned by @uidName (@uid)",
[
'@uid' => $uid,
'@uidName' => $uidEntity->getDisplayName(),
]));
drush_print('------------------------------------------------------------------------');
drush_print(dt("All FolderShare files and folders owned by the user will be deleted."));
drush_print(dt("immediately."));
drush_print("");
drush_print(dt("This can delete content owned by other users! When a folder is"));
drush_print(dt("deleted, everything inside it is deleted too, even if it is owned by"));
drush_print(dt("another user."));
drush_print("");
drush_print(dt("This can delete content inside folders owned by other users! Files"));
drush_print(dt("and folders owned by the user but in another user's folders will be"));
drush_print(dt("deleted too."));
drush_print("");
drush_print(dt("Checking the number of items to delete..."));
// Validate that there is content.
$nFiles = FolderShare::countNumberOfFiles($uid);
$nFolders = FolderShare::countNumberOfFolders($uid);
if (($nFiles + $nFolders) === 0) {
drush_print(dt("... none! The user has no files or folders to delete."));
return;
}
drush_print(dt(
"... @nFiles files and @nFolders folders.",
[
'@nFiles' => $nFiles,
'@nFolders' => $nFolders,
]));
drush_print("");
// Prompt.
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Execute.
drush_print("");
drush_print(dt("Deleting all content owned by @uidName (@uid).",
[
'@uid' => $uid,
'@uidName' => $uidEntity->getDisplayName(),
]));
drush_print(dt("This may take a few minutes..."));
FolderShare::deleteAll($uid);
drush_print(dt("Done."));
}
/**
* Performs an administrative "change owner by".
*
* @param int $uid
* A valid user ID for the owner of content.
* @param int $newuid
* A valid user ID for the new owner of the content.
*/
function drush_foldershare_admin_changeownerby($uid, $newuid) {
// Validate that there are two user IDs.
if ($uid < 0) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(' The --changeownerall option requires a source user ID.'));
drush_print(dt(' Type "drush help foldershare-admin" for admin options.'));
return;
}
if ($newuid < 0) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(' The --changeownerall option requires a destination user ID.'));
drush_print(dt(' Type "drush help foldershare-admin" for admin options.'));
return;
}
$uidEntity = User::load($uid);
if ($uidEntity === NULL) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(
" The ID @uid does not match any known user.",
[
'@uid' => $uid,
]));
return;
}
$newuidEntity = User::load($newuid);
if ($newuidEntity === NULL) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(
" The ID @newuid does not match any known user.",
[
'@newuid' => $newuid,
]));
return;
}
// Explain.
drush_print("");
drush_print(dt(
"FolderShare: Change all items owned by @uidName (@uid)",
[
'@uid' => $uid,
'@uidName' => $uidEntity->getDisplayName(),
]));
drush_print(dt(" to be owned by @newuidName (@newuid)",
[
'@newuid' => $newuid,
'@newuidName' => $newuidEntity->getDisplayName(),
]));
drush_print('------------------------------------------------------------------------');
drush_print(dt("All FolderShare files and folders owned by the first user will be"));
drush_print(dt("changed immediately to be owned by the second user."));
drush_print("");
drush_print(dt("Checking the number of items to change..."));
// Validate that there is content.
$nFiles = FolderShare::countNumberOfFiles($uid);
$nFolders = FolderShare::countNumberOfFolders($uid);
if (($nFiles + $nFolders) === 0) {
drush_print(dt("... none! The user has no files or folders to change."));
return;
}
drush_print(dt(
"... @nFiles files and @nFolders folders.",
[
'@nFiles' => $nFiles,
'@nFolders' => $nFolders,
]));
drush_print("");
// Prompt.
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Execute.
drush_print("");
drush_print(dt(
"Changing all content owned by @uidName (@uid() to be owned by @newuidName (@newuid).",
[
'@uid' => $uid,
'@uidName' => $uidEntity->getDisplayName(),
'@newuid' => $newuid,
'@newuidName' => $newuidEntity->getDisplayName(),
]));
drush_print(dt("This may take a few minutes..."));
drush_print("");
FolderShare::changeAllOwnerIdByUser($uid, $newuid);
drush_print(dt("Done."));
}
/**
* Performs an administrative "unshare with".
*
* @param int $uid
* A valid user ID for the owner of content.
*/
function drush_foldershare_admin_unsharewith($uid) {
// Validate that there are two user IDs.
if ($uid < 0) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(' The --unsharewith option requires a user ID.'));
drush_print(dt(' Type "drush help foldershare-admin" for admin options.'));
return;
}
$uidEntity = User::load($uid);
if ($uidEntity === NULL) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(
" The ID @uid does not match any known user.",
[
'@uid' => $uid,
]));
return;
}
// Explain.
drush_print(dt(
"FolderShare: Remove @uidName (@uid) from all sharing grants",
[
'@uid' => $uid,
'@uidName' => $uidEntity->getDisplayName(),
]));
drush_print('------------------------------------------------------------------------');
drush_print(dt("The user will be removed from all items owned by others that grant the"));
drush_print(dt("user shared access."));
drush_print("");
// Prompt.
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Execute.
drush_print("");
drush_print(dt(
"Unsharing @uidName (@uid) from all shared content.",
[
'@uid' => $uid,
'@uidName' => $uidEntity->getDisplayName(),
]));
drush_print(dt("This may take a few minutes..."));
drush_print("");
FolderShare::unshareFromAll($uid);
drush_print(dt("Done."));
}
/*---------------------------------------------------------------------
*
* Fix - disabled flags.
*
*---------------------------------------------------------------------*/
/**
* Performs operations to list, enable, and disable items.
*
* --enable Enable an item.
* --enableall Enable all items.
* --disable Disable an item.
* --list (default) List all hidden items.
*
* @param int $id
* (optional, default = (-1)) The FolderShare entity ID to enable or
* disable. The $id is ignored if the 'list' option is used, and
* required for the 'enable' and 'disable' options.
*/
function drush_foldershare_disabled($id = (-1)) {
FolderShareScheduledTask::setTaskExecutionEnabled(FALSE);
if (empty(drush_get_option('enableall')) === FALSE) {
drush_foldershare_disabled_enableall();
return;
}
if (empty(drush_get_option('enable')) === FALSE) {
drush_foldershare_disabled_enable($id);
return;
}
if (empty(drush_get_option('disable')) === FALSE) {
drush_foldershare_disabled_disable($id);
return;
}
// Default to a list.
drush_foldershare_disabled_list();
}
/**
* Performs a disabled item list.
*/
function drush_foldershare_disabled_list() {
// Table heading.
drush_print(dt('FolderShare: Disabled files and folders'));
drush_print(sprintf(
"%-20s %10s %s",
'Owner',
'Entity ID',
'Path'));
drush_print(sprintf(
"%-20s %10s %s",
'--------------------',
'----------',
'---------------------------------------------'));
// Get a list of everything that is disabled. Typically this is a
// very short list, but it might not be.
$disabledIds = FolderShare::findAllDisabledIds();
if (count($disabledIds) === 0) {
drush_print(dt("None."));
return;
}
// List each item.
foreach ($disabledIds as $id) {
$item = FolderShare::load($id);
if ($item === NULL) {
// The item does not exist.
continue;
}
$ownerId = $item->getOwnerId();
$path = $item->getPath();
if ($item->isFolder() === TRUE) {
$path .= '/';
}
$u = User::load($ownerId);
if ($u === NULL) {
$ownerName = sprintf('%s (%d)', dt('unknown'), $ownerId);
}
else {
$ownerName = sprintf('%s (%d)', $u->getDisplayName(), $ownerId);
}
drush_print(sprintf(
"%-20s %10d %s",
$ownerName,
$id,
$path));
}
}
/**
* Performs an enable on all disabled items.
*/
function drush_foldershare_disabled_enableall() {
// Explain.
drush_print(dt("FolderShare: Enable all disabled items"));
drush_print('------------------------------------------------------------------------');
drush_print(dt("WARNING: Items marked disabled are being used by operations such as a"));
drush_print(dt("copy or move. The mark also is used by copy operations to keep track"));
drush_print(dt("of their progress. Manually enabling all disabled items will cause"));
drush_print(dt("them to become available for new operations and corrupt marks used"));
drush_print(dt("for copy operations already in progress. This can cause operations"));
drush_print(dt("to collide and make copy operations end prematurely."));
drush_print("");
drush_print(dt(" ** This can corrupt the file system **"));
drush_print("");
drush_print(dt("Enabling all items manually should only be done during debugging."));
drush_print("");
// Prompt.
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Execute.
drush_print("");
drush_print(dt("Enabling all disabled items."));
drush_print(dt(" This may take a few minutes..."));
$nChanged = FolderShare::clearAllSystemDisabled();
// Flush the entity cache so that it is not out of date compared to
// the now-marked entities in the database.
\Drupal::entityTypeManager()->getStorage(FolderShare::ENTITY_TYPE_ID)
->resetCache(NULL);
\Drupal::service('cache.render')->invalidateAll();
if ($nChanged === 0) {
drush_print(dt("Done. No items were changed."));
}
else {
drush_print(dt(
"Done. @count items were changed.",
[
'@count' => $nChanged,
]));
}
}
/**
* Performs an enable on a specified item.
*
* @param int $id
* The FolderShare entity ID to enable.
*/
function drush_foldershare_disabled_enable($id = (-1)) {
// Validate entity ID.
$id = (int) $id;
if ($id < 0) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(' Missing entity ID to enable.'));
return;
}
$item = FolderShare::load($id);
if ($item === NULL) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(
" The entity ID @id does not match any known content.",
[
'@id' => $id,
]));
return;
}
$path = $item->getPath();
if ($item->isFolder() === TRUE) {
$path .= '/';
}
// Explain.
drush_print(dt(
"FolderShare: Enable item ID @id at @path",
[
'@id' => $id,
'@path' => $path,
]));
drush_print('------------------------------------------------------------------------');
drush_print(dt("WARNING: Items marked disabled are being used by operations such as a"));
drush_print(dt("copy or move. The mark also is used by copy operations to keep track"));
drush_print(dt("of their progress. Manually enabling a disabled item will cause it"));
drush_print(dt("to become available for new operations that can collide if a prior"));
drush_print(dt("operation is still in progres. This also can cause copy operations"));
drush_print(dt("to end prematurely and leave some content uncopied. The premature end"));
drush_print(dt("will not alert the user that the copied item is invalid."));
drush_print("");
drush_print(dt(" ** This can corrupt the file system **"));
drush_print("");
drush_print(dt("Enabling an item manually should only be done during debugging."));
drush_print("");
// Prompt.
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Execute.
drush_print("");
drush_print(dt(
"Enabling ID @id at @path...",
[
'@id' => $id,
'@path' => $path,
]));
$item->setSystemDisabled(FALSE);
$item->save();
drush_print(dt("Done. One item was changed."));
}
/**
* Performs a disable on a specified item.
*
* @param int $id
* The FolderShare entity ID to disable.
*/
function drush_foldershare_disabled_disable($id = (-1)) {
// Validate entity ID.
$id = (int) $id;
if ($id < 0) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(' Missing entity ID to disable.'));
return;
}
$item = FolderShare::load($id);
if ($item === NULL) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(
" The entity ID @id does not match any known content.",
[
'@id' => $id,
]));
return;
}
$path = $item->getPath();
if ($item->isFolder() === TRUE) {
$path .= '/';
}
// Explain.
drush_print(dt(
"FolderShare: Disable item ID @id at @path",
[
'@id' => $id,
'@path' => $path,
]));
drush_print('------------------------------------------------------------------------');
drush_print(dt("WARNING: Disabling an item will prevent users, including administrators,"));
drush_print(dt("from starting new operations using it. This includes viewing,"));
drush_print(dt("downloading, moving, copying, and deleting. The item will remain"));
drush_print(dt("visible in lists and show a spinner. Normally the spinner goes away"));
drush_print(dt("when an operation enables the item after it completes. But with a"));
drush_print(dt("manually disabled item, there is no associated operation to enable"));
drush_print(dt("item again. The item will remain disabled and the spinner will run"));
drush_print(dt("indefinitely. This is like to cause user confusion."));
drush_print("");
drush_print(dt("Disabling an item manually should only be done during debugging."));
drush_print("");
// Prompt.
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Execute.
drush_print("");
drush_print(dt(
"Disabling ID @id at @path...",
[
'@id' => $id,
'@path' => $path,
]));
$item->setSystemDisabled(TRUE);
$item->save();
drush_print(dt("Done. One item was changed."));
}
/*---------------------------------------------------------------------
*
* Fix - hidden flags.
*
*---------------------------------------------------------------------*/
/**
* Performs operations to list, show, and hide items.
*
* --hide Hide a non-hidden item.
* --list (default) List all hidden items.
* --show Show a hidden item.
* --showall Show all hidden items.
*
* @param int $id
* (optional, default = (-1)) The FolderShare entity ID to show or
* hide. The $id is ignored if the 'list' option is used, and
* required for the 'show' and 'hide' options.
*/
function drush_foldershare_hidden($id = (-1)) {
FolderShareScheduledTask::setTaskExecutionEnabled(FALSE);
if (empty(drush_get_option('showall')) === FALSE) {
drush_foldershare_hidden_showall();
return;
}
if (empty(drush_get_option('show')) === FALSE) {
drush_foldershare_hidden_show($id);
return;
}
if (empty(drush_get_option('hide')) === FALSE) {
drush_foldershare_hidden_hide($id);
return;
}
// Default to a list.
drush_foldershare_hidden_list();
}
/**
* Performs a hidden item list.
*/
function drush_foldershare_hidden_list() {
// Table heading.
drush_print(dt('FolderShare: Hidden files and folders'));
drush_print(sprintf(
"%-20s %10s %s",
dt('Owner'),
dt('Entity ID'),
dt('Path')));
drush_print(sprintf(
"%-20s %10s %s",
'--------------------',
'----------',
'---------------------------------------------'));
// Get a list of everything that is hidden. Typically this is a
// very short list, but it might not be.
$hiddenIds = FolderShare::findAllHiddenIds();
if (count($hiddenIds) === 0) {
drush_print(dt("None."));
return;
}
// List each item.
foreach ($hiddenIds as $id) {
$item = FolderShare::load($id);
if ($item === NULL) {
// The item does not exist.
continue;
}
$ownerId = $item->getOwnerId();
$path = $item->getPath();
if ($item->isFolder() === TRUE) {
$path .= '/';
}
$u = User::load($ownerId);
if ($u === NULL) {
$ownerName = sprintf('%s (%d)', dt('unknown'), $ownerId);
}
else {
$ownerName = sprintf('%s (%d)', $u->getDisplayName(), $ownerId);
}
drush_print(sprintf(
"%-20s %10d %s",
$ownerName,
$id,
$path));
}
}
/**
* Performs a show on all hidden items.
*/
function drush_foldershare_hidden_showall() {
// Explain.
drush_print(dt("FolderShare: Show all items"));
drush_print('------------------------------------------------------------------------');
drush_print(dt("WARNING: Items marked hidden are in the process of being deleted."));
drush_print(dt("Manually marking all hidden items as visible will let users see the"));
drush_print(dt("items as they are being deleted, but it will not abort the delete."));
drush_print(dt("This can be confusing to users and it can cause problems if a user"));
drush_print(dt("tries to use an item just as it is being deleted."));
drush_print("");
drush_print(dt("Showing hidden items should only be done during debugging."));
drush_print("");
// Prompt.
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Execute.
drush_print("");
drush_print(dt("Showing all hidden items."));
drush_print(dt(" This may take a few minutes..."));
$nChanged = FolderShare::clearAllSystemHidden();
// Flush the entity cache so that it is not out of date compared to
// the now-marked entities in the database.
\Drupal::entityTypeManager()->getStorage(FolderShare::ENTITY_TYPE_ID)
->resetCache(NULL);
\Drupal::service('cache.render')->invalidateAll();
if ($nChanged === 0) {
drush_print(dt("Done. No items were changed."));
}
else {
drush_print(dt(
"Done. @count items were changed.",
[
'@count' => $nChanged,
]));
}
}
/**
* Performs a show on a selected item.
*
* @param int $id
* A valid FolderShare entity ID.
*/
function drush_foldershare_hidden_show($id) {
// Validate entity ID.
$id = (int) $id;
if ($id < 0) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(' Missing entity ID to show.'));
return;
}
$item = FolderShare::load($id);
if ($item === NULL) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(
" The entity ID @id does not match any known content.",
[
'@id' => $id,
]));
return;
}
$path = $item->getPath();
if ($item->isFolder() === TRUE) {
$path .= '/';
}
drush_print(dt(
"FolderShare: Show item ID @id at @path",
[
'@id' => $id,
'@path' => $path,
]));
drush_print('------------------------------------------------------------------------');
drush_print(dt("WARNING: Items marked hidden are in the process of being deleted."));
drush_print(dt("Manually marking a hidden item as visible will let users see the item"));
drush_print(dt("before it is deleted, but it will not abort the delete. This can be"));
drush_print(dt("confusing to users and it can cause problems if a user tries to use an"));
drush_print(dt("item just as it is being deleted."));
drush_print("");
drush_print(dt("Showing hidden items should only be done during debugging."));
drush_print("");
// Prompt.
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Execute.
drush_print("");
drush_print(dt(
'Showing ID @id at @path...',
[
'@id' => $id,
'@path' => $path,
]));
$item->setSystemHidden(FALSE);
$item->save();
// Flush the entity cache so that it is not out of date compared to
// the now-marked entities in the database.
\Drupal::entityTypeManager()->getStorage(FolderShare::ENTITY_TYPE_ID)
->resetCache(NULL);
\Drupal::service('cache.render')->invalidateAll();
drush_print(dt("Done. One item was changed."));
}
/**
* Performs a hide on a selected item.
*
* @param int $id
* A valid FolderShare entity ID.
*/
function drush_foldershare_hidden_hide($id) {
// Validate entity ID.
$id = (int) $id;
if ($id < 0) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(' Missing entity ID to hide.'));
return;
}
$item = FolderShare::load($id);
if ($item === NULL) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(
" The entity ID @id does not match any known content.",
[
'@id' => $id,
]));
return;
}
$path = $item->getPath();
if ($item->isFolder() === TRUE) {
$path .= '/';
}
// Explain.
drush_print(dt(
"FolderShare: Hide item ID @id at @path",
[
'@id' => $id,
'@path' => $path,
]));
drush_print('------------------------------------------------------------------------');
drush_print(dt("WARNING: Items marked hidden are in the process of being deleted."));
drush_print(dt("Manually marking an item hidden will make it invisible to users, but"));
drush_print(dt("will not delete it."));
drush_print("");
drush_print(dt("Hiding items should only be done during debugging."));
drush_print("");
// Prompt.
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Execute.
drush_print("");
drush_print(dt(
'Hiding ID @id at @path...',
[
'@id' => $id,
'@path' => $path,
]));
$item->setSystemHidden(TRUE);
$item->save();
// Flush the entity cache so that it is not out of date compared to
// the now-marked entities in the database.
\Drupal::entityTypeManager()->getStorage(FolderShare::ENTITY_TYPE_ID)
->resetCache(NULL);
\Drupal::service('cache.render')->invalidateAll();
drush_print(dt("Done. One item was changed."));
}
/*---------------------------------------------------------------------
*
* Fix - root locks.
*
*---------------------------------------------------------------------*/
/**
* Performs operations to list, lock, and unlock exclusive access locks.
*
* --list (default) List all root locks.
* --lock Lock a root.
* --unlock Unlock a root.
*/
function drush_foldershare_lock($id = (-1)) {
FolderShareScheduledTask::setTaskExecutionEnabled(FALSE);
if (empty(drush_get_option('lock')) === FALSE) {
drush_foldershare_lock_lock($id);
return;
}
if (empty(drush_get_option('unlock')) === FALSE) {
drush_foldershare_lock_unlock($id);
return;
}
// Default to a list.
drush_foldershare_lock_list();
}
/**
* Performs a lock list.
*/
function drush_foldershare_lock_list() {
// Table heading.
drush_print(dt('FolderShare: Locked root items'));
drush_print(sprintf(
"%-20s %10s %s",
dt('Owner'),
dt('Root ID'),
dt('Path')));
drush_print(sprintf(
"%-20s %10s %s",
'--------------------',
'----------',
'---------------------------------------------'));
// Get a list of everything that is disabled. Typically this is a
// very short list, but it might not be.
$rootIds = FolderShare::findAllRootItemIds();
$lockedRootIds = [];
foreach ($rootIds as $rootId) {
if (FolderShare::isRootOperationLockAvailable($rootId) === FALSE) {
$lockedRootIds[] = $rootId;
}
}
if (count($lockedRootIds) === 0) {
drush_print(dt("None."));
return;
}
// List each item.
foreach ($lockedRootIds as $rootId) {
$item = FolderShare::load($rootId);
if ($item === NULL) {
// The item does not exist.
continue;
}
$ownerId = $item->getOwnerId();
$path = $item->getPath();
if ($item->isFolder() === TRUE) {
$path .= '/';
}
$u = User::load($ownerId);
if ($u === NULL) {
$ownerName = sprintf('%s (%d)', dt('unknown'), $ownerId);
}
else {
$ownerName = sprintf('%s (%d)', $u->getDisplayName(), $ownerId);
}
drush_print(sprintf(
"%-20s %10d %s",
$ownerName,
$rootId,
$path));
}
}
/**
* Performs a lock on a selected item.
*
* @param int $id
* The FolderShare entity ID to lock.
*/
function drush_foldershare_lock_lock($id) {
// Validate entity ID.
$id = (int) $id;
if ($id < 0) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(' Missing entity ID to lock.'));
return;
}
$item = FolderShare::load($id);
if ($item === NULL) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(
" The entity ID @id does not match any known content.",
[
'@id' => $id,
]));
return;
}
if ($item->isRootItem() === FALSE) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(
' The entity ID @id is not a root item and therefore cannot be locked.',
[
'@id' => $id,
]));
return;
}
$path = $item->getPath();
if ($item->isFolder() === TRUE) {
$path .= '/';
}
// Explain.
drush_print(dt(
"FolderShare: Lock root ID @id at @path",
[
'@id' => $id,
'@path' => $path,
]));
drush_print('------------------------------------------------------------------------');
drush_print(dt("WARNING: Locking a root item will block all further operations on the"));
drush_print(dt("entire folder tree under the root. Create, copy, delete, move, and"));
drush_print(dt("other operations will fail for all users, including administrators."));
drush_print("");
drush_print(dt("Locking manually should only be done during debugging."));
drush_print("");
// Prompt.
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Execute.
drush_print("");
drush_print(dt(
"Locking root ID @id @path...",
[
'@id' => $id,
'@path' => $path,
]));
FolderShare::acquireRootOperationLock($id);
drush_print(dt("Done. One lock was changed."));
}
/**
* Performs an unlock on a selected item.
*
* @param int $id
* The FolderShare entity ID to unlock.
*/
function drush_foldershare_lock_unlock($id) {
// Validate entity ID.
$id = (int) $id;
if ($id < 0) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(' Missing entity ID to unlock.'));
return;
}
$item = FolderShare::load($id);
if ($item === NULL) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(
" The entity ID @id does not match any known content.",
[
'@id' => $id,
]));
return;
}
if ($item->isRootItem() === FALSE) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(
' The entity ID @id is not a root item and therefore cannot be unlocked.',
[
'@id' => $id,
]));
return;
}
$path = $item->getPath();
if ($item->isFolder() === TRUE) {
$path .= '/';
}
// Explain.
drush_print(dt(
"FolderShare: Unlock root ID @id at @path",
[
'@id' => $id,
'@path' => $path,
]));
drush_print(dt("Unlock item"));
drush_print('------------------------------------------------------------------------');
drush_print(dt("WARNING: Unlocking a root item will allow new operations to be started"));
drush_print(dt("anywhere within the folder tree under the root. If there is a pending"));
drush_print(dt("operations on anything in the folder tree, a new operation can collide"));
drush_print(dt("by attempting to change the same files and folders."));
drush_print("");
drush_print(dt(" ** This can corrupt the file system **"));
drush_print("");
drush_print(dt("Unlocking manually should only be done during debugging."));
drush_print("");
// Prompt.
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Unlock the item.
drush_print("");
drush_print(dt(
"Unlocking root ID @id @path...",
[
'@id' => $id,
'@path' => $path,
]));
FolderShare::releaseRootOperationLock($id);
drush_print(dt("Done. One lock was changed."));
}
/*---------------------------------------------------------------------
*
* Fix - file system check.
*
*---------------------------------------------------------------------*/
/**
* Checks the file system.
*
* --fix Run file system checks.
*/
function drush_foldershare_fsck() {
FolderShareScheduledTask::setTaskExecutionEnabled(FALSE);
$fix = (empty(drush_get_option('fix')) === FALSE);
// Scan and possibly fix the file system.
if ($fix === TRUE) {
drush_print(dt("FolderShare: File system check and repair"));
drush_print('------------------------------------------------------------------------');
drush_print(dt("This may take a few minutes..."));
drush_print("");
$originalMode = \Drupal::state()->get('system.maintenance_mode');
if ($originalMode !== 1) {
drush_print(dt('Entering maintenance mode.'));
\Drupal::state()->set('system.maintenance_mode', 1);
drush_print("");
}
$wereFixed = FolderShare::fsck(TRUE);
if ($originalMode !== 1) {
drush_print(dt('Exiting maintenance mode.'));
\Drupal::state()->set('system.maintenance_mode', $originalMode);
drush_print("");
}
if ($wereFixed === TRUE) {
drush_print(dt('Repairs were made.'));
}
else {
drush_print(dt('No repairs were needed or made.'));
}
}
else {
drush_print(dt('FolderShare: File system check only'));
drush_print('------------------------------------------------------------------------');
drush_print(dt('This may take a few minutes...'));
drush_print("");
$needToBeFixed = FolderShare::fsck(FALSE);
if ($needToBeFixed === TRUE) {
drush_print(dt('Repairs need to be made.'));
drush_print(dt('To make repairs, run "drush foldershare-fsck --fix".'));
}
else {
drush_print(dt('No repairs are needed.'));
}
}
}
/*---------------------------------------------------------------------
*
* Module configuration - configuration.
*
*---------------------------------------------------------------------*/
/**
* Lists module configuration.
*
* The module's configuration is listed, including that of plugins.
*/
function drush_foldershare_config() {
FolderShareScheduledTask::setTaskExecutionEnabled(FALSE);
$moduleHandler = \Drupal::moduleHandler();
$typeManager = \Drupal::entityTypeManager();
drush_print(dt("FolderShare configuration"));
drush_print('------------------------------------------------------------------------');
//
// Files.
drush_print(dt("Files:"));
drush_print('--------------------------------');
drush_print(sprintf("%-45s %s",
dt('File system:'),
Settings::getFileScheme()));
drush_print(sprintf("%-45s %s",
dt('New ZIP archive name:'),
Settings::getNewZipArchiveName()));
drush_print(sprintf("%-45s %s",
dt('New ZIP archive comment:'),
Settings::getNewZipArchiveComment()));
drush_print(sprintf("%-45s %s",
dt('ZIP unarchive to subfolder:'),
(Settings::getZipUnarchiveMultipleToSubfolder() === TRUE) ? 'true' : 'false'));
drush_print(sprintf("%-45s %s",
dt('File name extensions restricted:'),
(Settings::getFileRestrictExtensions() === TRUE) ? 'true' : 'false'));
drush_print(sprintf("%-45s\n%s",
dt('Allowed file name extensions (if restricted):'),
Settings::getAllowedNameExtensions()));
drush_print("");
//
// Interface.
drush_print(dt('User interface:'));
drush_print('--------------------------------');
drush_print(sprintf("%-45s %s",
dt('Command menu restricted:'),
(Settings::getCommandMenuRestrict() === TRUE) ? 'true' : 'false'));
drush_print(sprintf("%-45s\n%s",
dt('Allowed commands (if restricted):'),
implode(', ', Settings::getCommandMenuAllowed())));
drush_print(sprintf("%-45s %s",
dt('Commands report normal completion:'),
(Settings::getCommandNormalCompletionReportEnable() === TRUE) ? 'true' : 'false'));
drush_print(sprintf("%-45s %d sec",
dt('Interface refresh polling interval:'),
Settings::getStatusPollingInterval()));
drush_print("");
//
// Search.
drush_print(dt('Search:'));
drush_print('--------------------------------');
if ($moduleHandler->moduleExists('search') === FALSE) {
drush_print(dt('Drupal core "search" module is not installed.'));
}
else {
try {
$searchPage = $typeManager->getStorage('search_page')
->load('foldershare_search');
$searchPlugin = $searchPage->getPlugin();
drush_print(sprintf("%-45s %s",
dt('Include file text in search index:'),
($searchPlugin->getSearchFileContent() === TRUE) ? 'true' : 'false'));
drush_print(sprintf("%-45s %d bytes",
dt('Maximum file content to index for search:'),
$searchPlugin->getSearchFileSize()));
drush_print(sprintf("%-45s %s",
dt('File types to include in search index:'),
$searchPlugin->getSearchFileExtensions()));
}
catch (\Exception $e) {
// Ignore.
}
}
drush_print("");
//
// System.
drush_print(dt('System:'));
drush_print('--------------------------------');
drush_print(sprintf("%-45s %s",
dt('Activity logging:'),
(Settings::getActivityLogEnable() === TRUE) ? 'true' : 'false'));
drush_print(sprintf("%-45s %s",
dt('Usage update interval:'),
Settings::getUsageUpdateInterval()));
$t = ManageUsageStatistics::getLastUpdateTime();
if ($t !== 'never') {
if ($t[0] === '@') {
$t = date('Y-m-d H:i:s', intval(substr($t, 1)));
}
else {
$t = date('Y-m-d H:i:s', intval($t));
}
}
drush_print(sprintf("%-45s %s",
dt('Usage last updated:'),
$t));
drush_print(sprintf("%-45s %d sec",
dt('Content lock duration:'),
Settings::getContentLockDuration()));
drush_print(sprintf("%-45s %d sec",
dt('Operation lock duration:'),
Settings::getOperationLockDuration()));
drush_print(sprintf("%-45s %d sec",
dt('Task initial scheduling delay:'),
Settings::getScheduledTaskInitialDelay()));
drush_print(sprintf("%-45s %d sec",
dt('Task continuation scheduling delay:'),
Settings::getScheduledTaskContinuationDelay()));
drush_print(sprintf("%-45s %d sec",
dt('Task safety-net scheduling delay:'),
Settings::getScheduledTaskSafetyNetDelay()));
drush_print(sprintf("%-45s %4.1f %%",
dt('Memory use limit as % of PHP limit:'),
100.0 * Settings::getMemoryUseLimitPercentage()));
drush_print(sprintf("%-45s %4.1f %%",
dt('Execution time limit as % of PHP limit:'),
100.0 * Settings::getExecutionTimeLimitPercentage()));
drush_print("");
//
// Web services.
//
// REST services are provided by a separately installed FolderShare REST
// module, however the services are associated with FolderShare entities.
// If those services are installed, list them.
drush_print(dt('Web services:'));
drush_print('--------------------------------');
if (\Drupal::moduleHandler()->moduleExists('rest') === FALSE) {
drush_print(dt('Drupal core "rest" module not installed.'));
}
else {
try {
$restPlugin = $typeManager->getStorage('rest_resource_config')
->load('entity.foldershare');
if ($restPlugin !== NULL) {
foreach ($restPlugin->getMethods() as $method) {
$formats = $restPlugin->getFormats($method);
$auths = $restPlugin->getAuthenticationPRoviders($method);
drush_print($method);
drush_print(sprintf(" %-43s %s",
dt("Serialization formats:"),
implode(', ', $formats)));
drush_print(sprintf(" %-43s %s",
dt("Authentication providers:"),
implode(', ', $auths)));
}
}
}
catch (\Exception $e) {
// Ignore.
}
}
drush_print("");
//
// PHP directives.
drush_print(dt('Relevant PHP directives:'));
drush_print('--------------------------------');
drush_print(sprintf("%-45s %s",
dt('Max upload file size (upload_max_filesize):'),
ini_get('upload_max_filesize')));
drush_print(sprintf("%-45s %d",
dt('Max # of uploaded files (max_file_uploads):'),
ini_get('max_file_uploads')));
$t = ini_get('post_max_size');
if ($t === "0") {
drush_print(sprintf("%-45s %s",
dt('Max post message size (post_max_size):'),
dt('(unlimited)')));
}
else {
drush_print(sprintf("%-45s %s",
dt('Max post message size (post_max_size):'),
$t));
}
$t = (int) ini_get('max_input_time');
if ($t === (-1)) {
drush_print(sprintf("%-45s %s",
dt('Max post processing time (max_input_time):'),
dt('(uses max_execution_time)')));
}
else {
drush_print(sprintf("%-45s %d sec",
dt('Max post processing time (max_input_time):'),
$t));
}
$t = ini_get('memory_limit');
if ($t === "-1") {
drush_print(sprintf("%-45s %s",
dt('Max memory use (memory_limit):'),
dt('(unlimited)')));
}
else {
drush_print(sprintf("%-45s %s",
dt('Max memory use (memory_limit):'),
$t));
}
// Drush runs from the command line interpreter, and that always sets the
// execution time to 0. There is no way to get the value a web-invoked
// PHP would see.
drush_print(sprintf("%-45s %s",
dt('Max execution time (max_execution_time):'),
dt("(unavailable via drush)")));
}
/*---------------------------------------------------------------------
*
* Module configuration - tasks.
*
*---------------------------------------------------------------------*/
/**
* Performs operations to list, run, and delete tasks.
*
* --delete Delete the indicated task.
* --deleteall Delete all scheduled tasks.
* --list (default) List all scheduled task entities.
* --run Run the scheduled task executor.
*
* @param int $id
* (optional, default = (-1)) The task entity ID to delete.
*/
function drush_foldershare_tasks($id = -1) {
if (empty(drush_get_option('run')) === FALSE) {
drush_foldershare_tasks_run();
return;
}
FolderShareScheduledTask::setTaskExecutionEnabled(FALSE);
if (empty(drush_get_option('deleteall')) === FALSE) {
drush_foldershare_tasks_deleteall();
return;
}
if (empty(drush_get_option('delete')) === FALSE) {
drush_foldershare_tasks_delete($id);
return;
}
// Default to a list.
drush_foldershare_tasks_list();
}
/**
* Performs an execution of ready tasks.
*/
function drush_foldershare_tasks_run() {
drush_print(dt('FolderShare: Executing ready tasks...'));
FolderShareScheduledTask::setTaskExecutionEnabled(TRUE);
FolderShareScheduledTask::executeTasks(time());
}
/**
* Performs a deletion of all tasks.
*/
function drush_foldershare_tasks_deleteall() {
// Explain.
drush_print(dt("FolderShare: Delete all tasks"));
drush_print('------------------------------------------------------------------------');
drush_print(dt("WARNING: Deleting all tasks will leave pending operations incomplete."));
drush_print(dt("This can stop tasks that are in the middle of deleting, copying,"));
drush_print(dt("moving, and changing the ownership of content. This will leave locks"));
drush_print(dt("held, items hidden or disabled, and operations unfinished."));
drush_print("");
drush_print(dt(" ** This can corrupt the file system **"));
drush_print("");
drush_print(dt("This should be done only when there is something deeply wrong and you"));
drush_print(dt("are very sure that deleting all tasks is the best thing to do."));
drush_print("");
drush_print(dt("Checking the number of tasks to delete..."));
$n = FolderShareScheduledTask::findNumberOfTasks();
if ($n === 0) {
drush_print(dt("... none! There are no tasks to delete."));
return;
}
drush_print("");
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Execute.
drush_print("");
drush_print(dt("Deleting all tasks."));
drush_print(dt(" This may take a few minutes..."));
FolderShareScheduledTask::deleteAllTasks();
drush_print("");
drush_print(dt("Done. You should run 'drush foldershare-fsck' immediately to check for file"));
drush_print(dt("system corruption."));
}
/**
* Performs a deletion of a selected task.
*
* @param int $id
* The ID of a task to delete.
*/
function drush_foldershare_tasks_delete($id) {
// Validate entity ID.
$id = (int) $id;
if ($id < 0) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(' Missing task ID to delete.'));
return;
}
$task = FolderShareScheduledTask::load($id);
if ($task === NULL) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(
" The task ID @id does not match any known task.",
[
'@id' => $id,
]));
return;
}
// Explain.
drush_print(dt("FolderShare: Delete task"));
drush_print('------------------------------------------------------------------------');
drush_print(dt("WARNING: Deleting a task will leave a pending operation incomplete."));
drush_print(dt("This can stop task in the middle of deleting, copying, moving,, and"));
drush_print(dt("changing the ownership of content. This will leave locks held, items"));
drush_print(dt("hidden or disabled, and operations unfinished."));
drush_print("");
drush_print(dt(" ** This can corrupt the file system **"));
drush_print("");
// Prompt.
$answer = readline(dt("Are you sure [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
// Execute.
drush_print("");
drush_print(dt("Deleting task @id...", ['@id' => $id]));
$task->delete();
drush_print("");
drush_print(dt("Done. You should run 'drush foldershare-fsck' immediately to check for file"));
drush_print(dt("system corruption."));
}
/**
* Performs a task list.
*/
function drush_foldershare_tasks_list() {
// Table heading.
drush_print(dt('FolderShare Scheduled tasks'));
drush_print(sprintf(
'%10s %-15s %-80s',
dt('Task ID'),
dt('Requester'),
dt('Callback')));
drush_print('------------------------------------------------------------------------');
// Get a list of tasks.
$taskIds = FolderShareScheduledTask::findTaskIds();
if (count($taskIds) === 0) {
drush_print(dt("None."));
return;
}
// List each item.
foreach ($taskIds as $id) {
$task = FolderShareScheduledTask::load($id);
if ($task === NULL) {
// Task does not exist.
continue;
}
$callback = $task->getCallback();
$requester = $task->getRequester();
$parameters = $task->getParameters();
$comments = $task->getComments();
$executionTime = $task->getAccumulatedExecutionTime();
$createdTime = date('Y-m-d H:i:s', intval($task->getcreatedTime()));
$scheduledTime = date('Y-m-d H:i:s', intval($task->getScheduledTime()));
$startTime = date('Y-m-d H:i:s', intval($task->getStartedTime()));
$u = User::load($requester);
if ($u === NULL) {
$requesterName = sprintf('%s (%d)', dt('unknown'), $requester);
}
else {
$requesterName = sprintf('%s (%d)', $u->getDisplayName(), $requester);
}
drush_print(sprintf(
'%10d %-15s %-80s',
$id,
$requesterName,
$callback));
drush_print(sprintf(
'%26s First started %s',
"",
$startTime));
drush_print(sprintf(
'%26s Current created %s',
"",
$createdTime));
drush_print(sprintf(
'%26s Next scheduled %s',
"",
$scheduledTime));
drush_print(sprintf(
'%26s Total run time %d sec',
"",
$executionTime));
if (empty($comments) === FALSE) {
drush_print(sprintf("%26s %s", "", $comments));
}
if (empty($parameters) === FALSE) {
drush_print(sprintf("%26s %s = %s", "", dt('parameters'), $parameters));
}
drush_print("");
}
}
/*---------------------------------------------------------------------
*
* Module configuration - usage.
*
*---------------------------------------------------------------------*/
/**
* Operates on the usage table.
*
* --list (default) List the usage table.
* --update Update the usage table now.
*/
function drush_foldershare_usage() {
FolderShareScheduledTask::setTaskExecutionEnabled(FALSE);
//
// Update usage table.
// -------------------
// Immediately update the usage table.
if (empty(drush_get_option('update')) === FALSE) {
drush_print(dt("FolderShare usage statistics update"));
drush_print(dt(" This may take a few minutes..."));
ManageUsageStatistics::updateUsage();
drush_print(dt("Done."));
return;
}
//
// List usage table.
// -----------------
// Get and present the usage table.
$t = ManageUsageStatistics::getLastUpdateTime();
switch ($t) {
case '':
$t = 'never';
drush_print(dt('FolderShare usage: (never updated)'));
break;
case 'never':
case 'pending':
drush_print(dt('FolderShare usage: (never updated)'));
break;
default:
if ($t[0] === '@') {
$t = date('Y-m-d H:i:s', intval(substr($t, 1)));
}
else {
$t = date('Y-m-d H:i:s', intval($t));
}
drush_print(dt(
'FolderShare usage: (last updated @updated)',
[
'@updated' => $t,
]));
break;
}
// Table heading.
drush_print(sprintf(
'%-50s %10s %10s %10s',
dt('User'),
dt('Folders'),
dt('Files'),
dt('Bytes')));
drush_print(sprintf(
'%-50s %10s %10s %10s',
'--------------------------------------------------',
'----------',
'----------',
'----------'));
// Get all usage. This has one entry per user.
$allUsage = ManageUsageStatistics::getAllUsage();
// List each item.
foreach ($allUsage as $uid => $usage) {
// Load the user entity so we can get the display name.
$u = User::load($uid);
if ($u === NULL) {
$userName = sprintf('%s (%d)', dt('unknown'), $uid);
}
else {
$userName = sprintf('%s (%d)', $u->getDisplayName(), $uid);
}
drush_print(sprintf(
'%-50s %10d %10d %10d',
$userName,
$usage['nFolders'],
$usage['nFiles'],
$usage['nBytes']));
}
}
/*---------------------------------------------------------------------
*
* Module configuration - version.
*
*---------------------------------------------------------------------*/
/**
* Shows the version number.
*/
function drush_foldershare_version() {
FolderShareScheduledTask::setTaskExecutionEnabled(FALSE);
$modules = system_get_info('module');
if (isset($modules['foldershare']) === TRUE) {
$version = $modules['foldershare']['version'];
drush_print("FolderShare $version");
}
else {
drush_print(sprintf("FolderShare (%s)", dt('unknown')));
}
}
/*---------------------------------------------------------------------
*
* Benchmark.
*
*---------------------------------------------------------------------*/
/**
* Benchmark FolderShare.
*/
function drush_foldershare_benchmark() {
FolderShareScheduledTask::setTaskExecutionEnabled(FALSE);
if (empty(drush_get_option('config')) === TRUE &&
empty(drush_get_option('lock')) === TRUE &&
empty(drush_get_option('system')) === TRUE &&
empty(drush_get_option('folder')) === TRUE) {
drush_print(dt("FolderShare: Error"));
drush_print(dt(" No benchmark specified."));
drush_print(dt(' Type "drush help foldershare-benchmark" for a list.'));
return;
}
// Explain.
drush_print(dt("FolderShare: Benchmarks"));
drush_print('------------------------------------------------------------------------');
drush_print(dt("These benchmarks automatically enter and exit maintenance mode."));
drush_print(dt("If there are non-administrator users connected to the site, they will"));
drush_print(dt("be blocked from activity during benchmarking."));
drush_print("");
// Prompt.
$answer = readline(dt("Are you ready [y|n]? "));
if ($answer[0] !== 'y') {
drush_print(dt("Aborted."));
return;
}
drush_print("");
$warmUpCount = 2;
$benchmarkCount = 10;
// Put the site into maintenance mode.
$originalMode = \Drupal::state()->get('system.maintenance_mode');
\Drupal::state()->set('system.maintenance_mode', 1);
Cache::invalidateTags(['rendered']);
try {
if (empty(drush_get_option('config')) === FALSE) {
drush_foldershare_benchmark_config($warmUpCount, $benchmarkCount);
}
elseif (empty(drush_get_option('lock')) === FALSE) {
drush_foldershare_benchmark_lock($warmUpCount, $benchmarkCount);
}
elseif (empty(drush_get_option('folder')) === FALSE) {
drush_foldershare_benchmark_folder($warmUpCount, $benchmarkCount);
}
elseif (empty(drush_get_option('system')) === FALSE) {
drush_foldershare_benchmark_system($warmUpCount, $benchmarkCount);
}
}
catch (\Exception $e) {
drush_print($e);
}
// Restore the original mode.
\Drupal::state()->set('system.maintenance_mode', $originalMode);
}
/**
* Benchmarks get/set of FolderShare configuration.
*
* All module configuration are managed by the Settings class, which
* gets and sets values in a configuration saved to the database by Drupal
* core. Since all of them are treated the same, this method picks one and
* benchmarks get and set operations using it.
*
* @param int $warmUpCount
* The number of passes during a warm-up phase.
* @param int $benchmarkCount
* The number of passes during a benchmark phase.
*/
function drush_foldershare_benchmark_config(
int $warmUpCount,
int $benchmarkCount) {
drush_print("FolderShare: Benchmark configuration get/set");
drush_print("----------------------------------------------------------------");
drush_print("This benchmark measures the time to get and set configuration");
drush_print("values managed by FolderShare's Settings class.");
drush_print("");
// Save the original value.
$originalValue = Settings::getStatusPollingInterval();
//
// Get setting.
// -----------.
$bogusValue = 0;
for ($i = 0; $i < $warmUpCount; ++$i) {
$bogusValue += Settings::getStatusPollingInterval();
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$bogusValue += Settings::getStatusPollingInterval();
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Get configuration", $tdelta));
//
// Set setting.
// -----------.
$newValue = $originalValue + 0.1;
for ($i = 0; $i < $warmUpCount; ++$i) {
Settings::setStatusPollingInterval($newValue);
$newValue += 0.1;
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
Settings::setStatusPollingInterval($newValue);
$newValue += 0.1;
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Set configuration", $tdelta));
// Restore the original value.
Settings::setStatusPollingInterval($originalValue);
}
/**
* Benchmarks lock and release.
*
* All major FolderShare operations (e.g. copy, move, delete) lock a root
* folder and/or a root list, then release the lock.
*
* @param int $warmUpCount
* The number of passes during a warm-up phase.
* @param int $benchmarkCount
* The number of passes during a benchmark phase.
*/
function drush_foldershare_benchmark_lock(
int $warmUpCount,
int $benchmarkCount) {
drush_print("FolderShare: Benchmark lock and release");
drush_print("----------------------------------------------------------------");
drush_print("This benchmark measures the time to lock a root folder or a");
drush_print("root list, then release the lock. Since locks do not involve");
drush_print("entities, just entity IDs, these benchmarks use a bogus ID.");
drush_print("");
//
// Lock root.
// ---------.
for ($i = 0; $i < $warmUpCount; ++$i) {
FolderShare::acquireRootOperationLock(0);
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
FolderShare::acquireRootOperationLock(0);
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Root operation lock", $tdelta));
//
// Unlock root.
// -----------.
for ($i = 0; $i < $warmUpCount; ++$i) {
FolderShare::releaseRootOperationLock(0);
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
FolderShare::releaseRootOperationLock(0);
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Root operation release", $tdelta));
//
// Lock root list.
// --------------.
for ($i = 0; $i < $warmUpCount; ++$i) {
FolderShare::acquireUserRootListLock(0);
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
FolderShare::acquireUserRootListLock(0);
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Root list lock", $tdelta));
//
// Unlock root list.
// ----------------.
for ($i = 0; $i < $warmUpCount; ++$i) {
FolderShare::releaseUserRootListLock(0);
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
FolderShare::releaseUserRootListLock(0);
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Root list release", $tdelta));
}
/**
* Benchmarks folder operations.
*
* Folders exist solely within the database. This method benchmarks creating,
* deleting, loading, etc on folders. No file operations take place.
*
* @param int $warmUpCount
* The number of passes during a warm-up phase.
* @param int $benchmarkCount
* The number of passes during a benchmark phase.
*/
function drush_foldershare_benchmark_folder(
int $warmUpCount,
int $benchmarkCount) {
drush_print("FolderShare: Benchmark folder operations");
drush_print("----------------------------------------------------------------");
drush_print("This benchmark measures the time to create, delete, load,");
drush_print("copy, and move individual empty folders.");
drush_print("");
//
// Create root folders.
// -------------------.
$created = [];
for ($i = 0; $i < $warmUpCount; ++$i) {
$created[] = FolderShare::createRootFolder();
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$created[] = FolderShare::createRootFolder();
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Create root folder", $tdelta));
//
// Load root folders from memory cache.
// -----------------------------------.
// Evidentally, created items are NOT automatically added to the storage
// manager's memory and database caches. An entry is only added to those
// caches if an item is loaded. So, start with a redundant load of the
// same entities created above.
foreach ($created as $item) {
FolderShare::load($item->id());
}
$n = 0;
for ($i = 0; $i < $warmUpCount; ++$i) {
$item = FolderShare::load($created[$n++]->id());
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$item = FolderShare::load($created[$n++]->id());
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Load root folder (memory cached)", $tdelta));
//
// Load root folders from database cache.
// -------------------------------------.
// Clear the memory cache. This should leave the storage manager's database
// cache in place and subsequent loads will load from it.
\Drupal::service('entity.memory_cache')->deleteAll();
$n = 0;
for ($i = 0; $i < $warmUpCount; ++$i) {
$item = FolderShare::load($created[$n++]->id());
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$item = FolderShare::load($created[$n++]->id());
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Load root folder (DB cached)", $tdelta));
//
// Load root folders from database (uncached).
// ------------------------------------------.
// Reseting the storage manager's cache clears everything from memory and
// database caches. Further loads must assemble the entity from assorted
// database tables.
\Drupal::entityTypeManager()->getStorage('foldershare')->resetCache();
$n = 0;
for ($i = 0; $i < $warmUpCount; ++$i) {
$item = FolderShare::load($created[$n++]->id());
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$item = FolderShare::load($created[$n++]->id());
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Load root folder (uncached)", $tdelta));
//
// Duplicate root folders.
// ----------------------.
$n = 0;
for ($i = 0; $i < $warmUpCount; ++$i) {
$created[] = $created[$n++]->duplicate();
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$created[] = $created[$n++]->duplicate();
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Duplicate root folder", $tdelta));
//
// Change owner on root folders.
// ----------------------------.
for ($i = 0; $i < $warmUpCount; ++$i) {
$item = $created[$i];
$item->changeOwnerId(1, FALSE);
}
$nCreated = count($created);
$tStart = microtime(TRUE);
foreach ($created as $item) {
$item->changeOwnerId(1, FALSE);
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $nCreated;
drush_print(sprintf(" %-35s %10.6f sec", "Change owner on root folder", $tdelta));
//
// Delete root folders.
// -------------------.
for ($i = 0; $i < $warmUpCount; ++$i) {
$item = array_shift($created);
$item->delete();
}
$nCreated = count($created);
$tStart = microtime(TRUE);
foreach ($created as $item) {
$item->delete();
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $nCreated;
drush_print(sprintf(" %-35s %10.6f sec", "Delete root folder", $tdelta));
drush_print("");
//
// Create subfolders.
// -----------------.
$parent = FolderShare::createRootFolder();
$created = [];
for ($i = 0; $i < $warmUpCount; ++$i) {
$created[] = $parent->createFolder();
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$created[] = $parent->createFolder();
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Create subfolder", $tdelta));
//
// Load subfolders from memory cache.
// ----------------------------------.
// See comments above on the memory cache.
foreach ($created as $item) {
FolderShare::load($item->id());
}
$n = 0;
for ($i = 0; $i < $warmUpCount; ++$i) {
$item = FolderShare::load($created[$n++]->id());
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$item = FolderShare::load($created[$n++]->id());
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Load subfolder (memory cached)", $tdelta));
//
// Load sub folders from database cache.
// ------------------------------------.
// See comments above on the database cache.
\Drupal::service('entity.memory_cache')->deleteAll();
$n = 0;
for ($i = 0; $i < $warmUpCount; ++$i) {
$item = FolderShare::load($created[$n++]->id());
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$item = FolderShare::load($created[$n++]->id());
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Load subfolder (DB cached)", $tdelta));
//
// Load subfolders from database (uncached).
// ----------------------------------------.
// See comments above on reseting the cache.
\Drupal::entityTypeManager()->getStorage('foldershare')->resetCache();
$n = 0;
for ($i = 0; $i < $warmUpCount; ++$i) {
$item = FolderShare::load($created[$n++]->id());
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$item = FolderShare::load($created[$n++]->id());
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Load subfolder (uncached)", $tdelta));
//
// Duplicate subfolders.
// --------------------.
$n = 0;
for ($i = 0; $i < $warmUpCount; ++$i) {
$created[] = $created[$n++]->duplicate();
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$created[] = $created[$n++]->duplicate();
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Duplicate subfolder", $tdelta));
//
// Change owner on subfolders.
// --------------------------.
for ($i = 0; $i < $warmUpCount; ++$i) {
$item = $created[$i];
$item->changeOwnerId(1, FALSE);
}
$nCreated = count($created);
$tStart = microtime(TRUE);
foreach ($created as $item) {
$item->changeOwnerId(1, FALSE);
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $nCreated;
drush_print(sprintf(" %-35s %10.6f sec", "Change owner on subfolder", $tdelta));
//
// Delete subfolders.
// -----------------.
for ($i = 0; $i < $warmUpCount; ++$i) {
$item = array_shift($created);
$item->delete();
}
$nCreated = count($created);
$tStart = microtime(TRUE);
foreach ($created as $item) {
$item->delete();
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $nCreated;
drush_print(sprintf(" %-35s %10.6f sec", "Delete subfolder", $tdelta));
// Clean up.
$parent->delete();
$created = [];
}
/**
* Benchmarks getting system values.
*
* Getting PHP ini directive values, the current time, the current memory
* usage are all queries of system values.
*
* @param int $warmUpCount
* The number of passes during a warm-up phase.
* @param int $benchmarkCount
* The number of passes during a benchmark phase.
*/
function drush_foldershare_benchmark_system(
int $warmUpCount,
int $benchmarkCount) {
drush_print("FolderShare: Benchmark getting system values");
drush_print("----------------------------------------------------------------");
drush_print("This benchmark measures the time to get system values, such as");
drush_print("PHP ini directive values, the current time, the current memory");
drush_print("usage, and so on.");
drush_print("");
//
// Get ini value.
// -------------.
$bogusValue = 0;
for ($i = 0; $i < $warmUpCount; ++$i) {
$bogusValue += ini_get('max_execution_time');
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$bogusValue += ini_get('max_execution_time');
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Get ini value", $tdelta));
//
// Get time.
// --------.
for ($i = 0; $i < $warmUpCount; ++$i) {
$bogusValue += time();
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$bogusValue += time();
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Get time", $tdelta));
//
// Get memory usage.
// ----------------.
for ($i = 0; $i < $warmUpCount; ++$i) {
$bogusValue += memory_get_usage();
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$bogusValue += memory_get_usage();
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Get memory usage", $tdelta));
//
// Garbage collect (no garbage).
// ----------------------------.
for ($i = 0; $i < $warmUpCount; ++$i) {
gc_collect_cycles();
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
gc_collect_cycles();
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Garbage collect (no garbage)", $tdelta));
//
// Garbage collect (some garbage).
// ----------------------------.
for ($i = 0; $i < $warmUpCount; ++$i) {
$junk = [];
for ($j = 0; $j < 100; ++$j) {
$junk[] = new stdClass();
}
for ($j = 0; $j < 100; ++$j) {
unset($junk[$j]);
}
gc_collect_cycles();
}
$tStart = microtime(TRUE);
for ($i = 0; $i < $benchmarkCount; ++$i) {
$junk = [];
for ($j = 0; $j < 100; ++$j) {
$junk[] = new stdClass();
}
for ($j = 0; $j < 100; ++$j) {
unset($junk[$j]);
}
gc_collect_cycles();
}
$tEnd = microtime(TRUE);
$tdelta = ($tEnd - $tStart) / $benchmarkCount;
drush_print(sprintf(" %-35s %10.6f sec", "Garbage collect (with garbage)", $tdelta));
}
