foldershare-8.x-1.2/src/Form/AdminUsageReport.php

src/Form/AdminUsageReport.php
<?php

namespace Drupal\foldershare\Form;

use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;

use Drupal\foldershare\Constants;
use Drupal\foldershare\Utilities\FormatUtilities;
use Drupal\foldershare\Utilities\UserUtilities;
use Drupal\foldershare\ManageUsageStatistics;

/**
 * Creates a usage report showing per-user usage of files, folders, & storage.
 *
 * The usage report is intended for site administrators to help them find and
 * track heavy users. The report shows a table with one row per user and the
 * number of folders, files, and bytes used by that user.
 *
 * <B>Internal class</B>
 * This class is internal to the FolderShare module. The class's existance,
 * name, and content may change from release to release without any promise
 * of backwards compatability.
 *
 * <B>Access control</B>
 * The route to this form should restrict access to those with administration
 * permission.
 *
 * @ingroup foldershare
 *
 * @see \Drupal\foldershare\ManageUsageStatistics
 */
class AdminUsageReport extends FormBase {

  /*--------------------------------------------------------------------
   *
   * Fields - dependency injection.
   *
   *--------------------------------------------------------------------*/

  /**
   * The entity type manager, set at construction time.
   *
   * @var \Drupal\Core\Entity\EntityTypeManager
   */
  protected $entityTypeManager;

  /*--------------------------------------------------------------------
   *
   * Construction.
   *
   *--------------------------------------------------------------------*/

  /**
   * Constructs a new page.
   *
   * @param \Drupal\Core\Entity\EntityTypeManager $entityTypeManager
   *   The entity type manager.
   */
  public function __construct(EntityTypeManager $entityTypeManager) {
    $this->entityTypeManager = $entityTypeManager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container->get('entity_type.manager'));
  }

  /*--------------------------------------------------------------------
   *
   * Form setup.
   *
   *--------------------------------------------------------------------*/

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return str_replace('\\', '_', get_class($this));
  }

  /*--------------------------------------------------------------------
   *
   * Form build.
   *
   *--------------------------------------------------------------------*/

  /**
   * {@inheritdoc}
   */
  public function buildForm(
    array $form,
    FormStateInterface $formState = NULL) {

    //
    // Create table column titles.
    // ---------------------------
    // These titles are used in the table description, but they also show
    // up in URLs as the value of the 'order' argument to select the column
    // to sort on.
    $userTitle    = $this->t('User');
    $foldersTitle = $this->t('Folders');
    $filesTitle   = $this->t('Files');
    $bytesTitle   = $this->t('Bytes');

    //
    // Get request arguments.
    // ----------------------
    // "sort" selects the sort direction, and "order" selects the column.
    $request       = \Drupal::request();
    $sortDirection = mb_strtoupper($request->get('sort', 'asc'));
    $sortOrder     = $request->get('order', (string) $userTitle);

    //
    // Assemble and sort usage information.
    // ------------------------------------
    // Get totals and per-user information (array keys are UIDs).
    $nFolders = ManageUsageStatistics::getNumberOfFolders();
    $nFiles   = ManageUsageStatistics::getNumberOfFiles();
    $nBytes   = ManageUsageStatistics::getNumberOfBytes();

    $userUsage = ManageUsageStatistics::getAllUsage();

    // The above usage array contains entries ONLY for users that
    // are using the module. Any user that has never created a file or
    // folder will have no usage entry.
    //
    // For the table on this page, we'd like to include ALL users. So,
    // for any user not in the above usage array, add an empty entry.
    $displayNames = UserUtilities::getAllDisplayNames();
    $data = [];
    foreach ($displayNames as $uid => $displayName) {
      if (isset($userUsage[$uid]) === TRUE) {
        $data[$uid] = [
          'displayName'     => $displayName,
          'sortDisplayName' => mb_strtolower($displayName),
          'nFolders'        => $userUsage[$uid]['nFolders'],
          'nFiles'          => $userUsage[$uid]['nFiles'],
          'nBytes'          => $userUsage[$uid]['nBytes'],
        ];
      }
      else {
        $data[$uid] = [
          'displayName'     => $displayName,
          'sortDisplayName' => mb_strtolower($displayName),
          'nFolders'        => 0,
          'nFiles'          => 0,
          'nBytes'          => 0,
        ];
      }
    }

    unset($userUsage);

    // Sort.
    switch ($sortOrder) {
      default:
      case (string) $userTitle:
        if ($sortDirection === 'ASC') {
          usort(
            $data,
            function ($a, $b) {
              return ($a['sortDisplayName'] <=> $b['sortDisplayName']);
            });
        }
        else {
          usort(
            $data,
            function ($a, $b) {
              return ($b['sortDisplayName'] <=> $a['sortDisplayName']);
            });
        }
        break;

      case (string) $foldersTitle:
        if ($sortDirection === 'ASC') {
          usort(
            $data,
            function ($a, $b) {
              return ($a['nFolders'] <=> $b['nFolders']);
            });
        }
        else {
          usort(
            $data,
            function ($a, $b) {
              return ($b['nFolders'] <=> $a['nFolders']);
            });
        }
        break;

      case (string) $filesTitle:
        if ($sortDirection === 'ASC') {
          usort(
            $data,
            function ($a, $b) {
              return ($a['nFiles'] <=> $b['nFiles']);
            });
        }
        else {
          usort(
            $data,
            function ($a, $b) {
              return ($b['nFiles'] <=> $a['nFiles']);
            });
        }
        break;

      case (string) $bytesTitle:
        if ($sortDirection === 'ASC') {
          usort(
            $data,
            function ($a, $b) {
              return ($a['nBytes'] <=> $b['nBytes']);
            });
        }
        else {
          usort(
            $data,
            function ($a, $b) {
              return ($b['nBytes'] <=> $a['nBytes']);
            });
        }
        break;
    }

    //
    // Setup form.
    // -----------
    // Create class names, attach libraries, and create the container body
    // that will hold the table.
    $baseClass          = Constants::MODULE . '-admin-usage-table';
    $tableClass         = $baseClass;
    $userColumnClass    = $baseClass . '-user';
    $foldersColumnClass = $baseClass . '-folders';
    $filesColumnClass   = $baseClass . '-files';
    $bytesColumnClass   = $baseClass . '-bytes';
    $totalsClass        = $baseClass . '-total';
    $updateBarClass     = $baseClass . '-update-bar';
    $updateTimeClass    = $baseClass . '-update-time';
    $updateButtonClass  = $baseClass . '-update-button';

    $tableName = Constants::MODULE . '-admin-usage-table';

    $form['#attached']['library'][] = Constants::LIBRARY_MODULE;
    $form['#attached']['library'][] = Constants::LIBRARY_ADMIN;

    $form['#tree'] = TRUE;

    $updateTime = ManageUsageStatistics::getLastUpdateTime();
    switch ($updateTime) {
      case '':
      case 'never':
        $updateTime = $this->t('Never updated');
        break;

      case 'pending':
        $updateTime = $this->t('Update in progress');
        break;

      default:
        try {
          // The stored update time is a timestamp string.
          // Compute how long ago the time was.
          $now = new \DateTime();
          $diff = (array) $now->diff(new \DateTime($updateTime));

          // Introduce a weeks count.
          $diff['w'] = (int) floor(($diff['d'] / 7));
          $diff['d'] -= ($diff['w'] * 7);

          // Get rid of the microsecond value, increasing seconds.
          if ((float) $diff['f'] !== 0) {
            $diff['s']++;
            unset($diff['f']);
          }

          // Get rid of the seconds value, increasing minutes.
          if ((int) $diff['s'] > 0) {
            $diff['i']++;
            unset($diff['s']);
          }

          // Watch for negatives. While it should not be possible for the
          // difference between NOW and a PAST event to ever be negative,
          // in practice it can happen. This may be differences in the
          // resolution returned by \DateTime() for NOW and \DateTime($time)
          // for PAST where $time was earlier set to time().
          if ($diff['y'] < 0 ||
              $diff['m'] < 0 ||
              $diff['w'] < 0 ||
              $diff['d'] < 0 ||
              $diff['h'] < 0 ||
              $diff['i'] < 0) {
            // Force everything to zero, except minutes.
            $diff['y'] = 0;
            $diff['m'] = 0;
            $diff['w'] = 0;
            $diff['d'] = 0;
            $diff['h'] = 0;
            $diff['i'] = 1;
          }

          // Use the rest of the time denominations and build up a string.
          $string = [
            'y' => [
              '@count year',
              '@count years',
            ],
            'm' => [
              '@count month',
              '@count months',
            ],
            'w' => [
              '@count week',
              '@count weeks',
            ],
            'd' => [
              '@count day',
              '@count days',
            ],
            'h' => [
              '@count hour',
              '@count hours',
            ],
            'i' => [
              '@count minute',
              '@count minutes',
            ],
          ];

          foreach ($string as $k => &$v) {
            if ($diff[$k] === 0) {
              unset($string[$k]);
              continue;
            }

            $v = (string) $this->formatPlural(
              $diff[$k],
              $v[0],
              $v[1]);
          }

          $updateTime = $this->t(
            'Updated @time ago',
            [
              '@time' => ((count($string) === 1) ?
                reset($string) : implode(', ', $string)),
            ]);
        }
        catch (\Exception $e) {
          // The stored time is invalid. Revert to 'never'.
          $updateTime = $this->t('Never updated');
        }
        break;
    }

    $form['update'] = [
      '#type'            => 'container',
      '#weight'          => 10,
      '#attributes'      => [
        'class'          => [$updateBarClass],
      ],
      'time'             => [
        '#type'          => 'html_tag',
        '#tag'           => 'span',
        '#value'         => $updateTime,
        '#weight'        => 0,
        '#attributes'    => [
          'class'        => [$updateTimeClass],
        ],
      ],
      'actions'          => [
        '#type'          => 'actions',
        '#weight'        => 1,
        'submit'         => [
          '#type'        => 'submit',
          '#button_type' => 'not-primary',
          '#value'       => '',
          '#attributes'  => [
            'title'      => $this->t('Update the usage table'),
            'class'      => [$updateButtonClass],
          ],
        ],
      ],
    ];

    //
    // Create table and headers.
    // -------------------------
    // The table's headers are:
    // - User name.
    // - Number of folders.
    // - Number of files.
    // - Number of bytes.
    $form['usage_table'] = [
      '#type'         => 'table',
      '#name'         => $tableName,
      '#responsive'   => FALSE,
      '#sticky'       => TRUE,
      '#weight'       => 10,
      '#attributes'   => [
        'class'       => [$tableClass],
      ],
      '#header'       => [
        'user'        => [
          'data'      => $userTitle,
          'class'     => [$userColumnClass],
          'field'     => 'user',
        ],
        'nfolders'    => [
          'data'      => $foldersTitle,
          'class'     => [$foldersColumnClass],
          'field'     => 'nfolders',
        ],
        'nfiles'      => [
          'data'      => $filesTitle,
          'class'     => [$filesColumnClass],
          'field'     => 'nfiles',
        ],
        'nbytes'      => [
          'data'      => $bytesTitle,
          'class'     => [$bytesColumnClass],
          'field'     => 'nbytes',
        ],
      ],
    ];

    // Note which column we sorted on.
    switch ($sortOrder) {
      default:
      case (string) $userTitle:
        $form['usage_table']['#header']['user']['sort'] = $sortDirection;
        break;

      case (string) $foldersTitle:
        $form['usage_table']['#header']['nfolders']['sort'] = $sortDirection;
        break;

      case (string) $filesTitle:
        $form['usage_table']['#header']['nfiles']['sort'] = $sortDirection;
        break;

      case (string) $bytesTitle:
        $form['usage_table']['#header']['nbytes']['sort'] = $sortDirection;
        break;
    }

    //
    // Create table rows.
    // ------------------
    // One row for each user, followed by a totals row.
    $rows = [];
    foreach ($data as $d) {
      // The user column has the user's display name and link to the user.
      $userColumn = [
        'data'      => [
          '#type'   => 'item',
          '#markup' => $d['displayName'],
        ],
        'class'     => [$userColumnClass],
      ];

      // The folders column has the number of folders used by the user.
      $foldersColumn = [
        'data'      => [
          '#type'   => 'item',
          '#markup' => $d['nFolders'],
        ],
        'class'     => [$foldersColumnClass],
      ];

      // The files column has the number of files used by the user.
      $filesColumn = [
        'data'      => [
          '#type'   => 'item',
          '#markup' => $d['nFiles'],
        ],
        'class'     => [$filesColumnClass],
      ];

      // The bytes column has the number of bytes used by the user.
      $bytesColumn = [
        'data'      => [
          '#type'   => 'item',
          '#markup' => FormatUtilities::formatBytes($d['nBytes']),
        ],
        'class'     => [$bytesColumnClass],
      ];

      $rows[] = [
        'data' => [
          'user'     => $userColumn,
          'nfolders' => $foldersColumn,
          'nfiles'   => $filesColumn,
          'nbytes'   => $bytesColumn,
        ],
      ];
    }

    // Add row for totals.
    //
    // The user column says "total" for the totals row.
    $userColumn = [
      'data'      => [
        '#type'   => 'item',
        '#markup' => $this->t('Total'),
      ],
      'class'     => [$userColumnClass],
    ];

    // The folders column has the total number of folders.
    $foldersColumn = [
      'data'      => [
        '#type'   => 'item',
        '#markup' => $nFolders,
      ],
      'class'     => [$foldersColumnClass],
    ];

    // The files column has the total number of files.
    $filesColumn = [
      'data'      => [
        '#type'   => 'item',
        '#markup' => $nFiles,
      ],
      'class'     => [$filesColumnClass],
    ];

    // The bytes column has the total number of bytes.
    $bytesColumn = [
      'data'      => [
        '#type'   => 'item',
        '#markup' => FormatUtilities::formatBytes($nBytes),
      ],
      'class'     => [$bytesColumnClass],
    ];

    $rows[] = [
      'data' => [
        'user'     => $userColumn,
        'nfolders' => $foldersColumn,
        'nfiles'   => $filesColumn,
        'nbytes'   => $bytesColumn,
      ],
      'class'      => [$totalsClass],
    ];

    // Add the rows to the table.
    $form['usage_table']['#rows'] = $rows;

    return $form;
  }

  /*--------------------------------------------------------------------
   *
   * Form validate.
   *
   *--------------------------------------------------------------------*/

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $formState) {
    // Nothing to do.
  }

  /*--------------------------------------------------------------------
   *
   * Form submit.
   *
   *--------------------------------------------------------------------*/

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $formState) {
    ManageUsageStatistics::updateUsage();
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc