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

src/Form/UIAncestorMenu.php
<?php

namespace Drupal\foldershare\Form;

use Drupal\Core\Url;
use Drupal\Component\Utility\Html;

use Symfony\Component\HttpFoundation\Request;

use Drupal\foldershare\Constants;
use Drupal\foldershare\Entity\FolderShare;
use Drupal\foldershare\FolderShareInterface;

/**
 * Provides support for the ancestor menu used on multiple pages.
 *
 * <B>Warning:</B> This class is strictly internal to the FolderShare
 * module. The class's existance, name, and content may change from
 * release to release without any promise of backwards compatability.
 *
 * @ingroup foldershare
 */
final class UIAncestorMenu {

  /*--------------------------------------------------------------------
   *
   * Functions.
   *
   *-------------------------------------------------------------------*/

  /**
   * Creates a render description for an ancestor menu.
   *
   * The last item in the ancestor menu is a list of available root lists
   * for the user:
   * - Personal files.
   * - Public files.
   * - All files.
   *
   * The anonoymous user always sees only the "public" list, regardless of
   * the value of the $allowPublicRootList argument.
   *
   * The "all" list is only included if the user has module admin permissions.
   *
   * The "public" list is only included if $allowPublicRootList is TRUE.
   *
   * @param int $currentId
   *   (optional, default = FolderShareInterface::USER_ROOT_LIST) The integer
   *   entity ID of the current FolderShare item. If the value is negative or
   *   FolderShareInterface::USER_ROOT_LIST, if the current item is
   *   the user's root list.
   * @param bool $allowPublicRootList
   *   (optional, default = TRUE) When TRUE, the public root list is available.
   *
   * @return array
   *   Returns an array of renderable elements for an ancestor menu's
   *   entries.
   */
  public static function build(
    int $currentId = FolderShareInterface::USER_ROOT_LIST,
    bool $allowPublicRootList = TRUE) {
    //
    // Setup.
    // ------
    // Get services and the current request.
    $routeProvider = \Drupal::service('router.route_provider');
    $titleResolver = \Drupal::service('title_resolver');
    $dummyRequest = new Request();

    //
    // Load entity.
    // ------------
    // Load the current entity, if any.
    $currentItem = NULL;
    if ($currentId >= 0) {
      $currentItem = FolderShare::load($currentId);
      if ($currentItem === NULL) {
        $currentId = FolderShareInterface::USER_ROOT_LIST;
      }
    }

    $uiClass         = 'foldershare-ancestormenu';
    $menuButtonClass = $uiClass . '-menu-button';
    $menuClass       = $uiClass . '-menu';

    //
    // Add ancestor list markup.
    // -------------------------
    // Build a list of ancestor folders for the ancestor menu. For each one,
    // include the ancestor's URL as an attribute. Javascript will use this
    // to load the appropriate page. The URL is not included in an <a> for
    // the menu item so that menu items aren't styled as links.
    //
    // File classes are added so that themes can style the item with
    // folder icons.
    $menuMarkup = "<ul class=\"hidden $menuClass\">";

    if ($currentItem !== NULL) {
      // The page is for entity. Get its ancestors.
      $folders = $currentItem->findAncestorFolders();

      // Reverse ancestors from root first to root last.
      $folders = array_reverse($folders);

      // Push the current entity onto the ancestor list so that it gets
      // included in the menu.
      array_unshift($folders, $currentItem);

      // Add ancestors to menu.
      foreach ($folders as $item) {
        // Get the URL to the folder.
        $url = rawurlencode($item->toUrl(
          'canonical',
          [
            'absolute' => TRUE,
          ])->toString());

        // Get the name for the folder.
        $name = Html::escape($item->getName());

        // Add the HTML. Include file classes that mark this as a folder
        // or file.
        if ($item->isFolder() === TRUE) {
          $fileClasses = 'file file--folder file--mime-folder-directory';
        }
        else {
          $mimes = explode('/', $item->getMimeType());
          $fileClasses = 'file file--' . $mimes[0] .
            ' file--mime-' . $mimes[0] . '-' . $mimes[1];
        }

        if ($item->isSystemDisabled() === TRUE) {
          $attr = '';
        }
        else {
          $attr = 'data-foldershare-id="' . $item->id() . '"';
        }

        $menuMarkup .= "<li $attr data-foldershare-url=\"$url\"><div><span class=\"$fileClasses\"></span>$name</div></li>";
      }
    }

    //
    // Add root list.
    // --------------
    // Show a list of available root lists in a submenu. If there is only
    // one available root list, then don't use a submenu.
    $currentUser = \Drupal::currentUser();

    // Start by assembling a list of available root lists for this user.
    $rootLists = [];
    if ($currentUser->isAnonymous() === TRUE) {
      // The anonymous user can only view the public list.
      $rootLists[] = [
        "public",
        Constants::ROUTE_ROOT_ITEMS_PUBLIC,
      ];
    }
    elseif ($currentUser->hasPermission(Constants::ADMINISTER_PERMISSION) === TRUE) {
      // An admin user can view all of the lists.
      $rootLists[] = [
        "personal",
        Constants::ROUTE_ROOT_ITEMS_PERSONAL,
      ];

      if ($allowPublicRootList === TRUE) {
        $rootLists[] = [
          "public",
          Constants::ROUTE_ROOT_ITEMS_PUBLIC,
        ];
      }

      $rootLists[] = [
        "all",
        Constants::ROUTE_ROOT_ITEMS_ALL,
      ];
    }
    else {
      // Authenticated non-admin users can view their personal list.
      $rootLists[] = [
        "personal",
        Constants::ROUTE_ROOT_ITEMS_PERSONAL,
      ];

      if ($allowPublicRootList === TRUE) {
        $rootLists[] = [
          "public",
          Constants::ROUTE_ROOT_ITEMS_PUBLIC,
        ];
      }
    }

    // Build markup for the available root lists.
    $fileClasses = 'file file--folder file--mime-rootfolder-group-directory';

    if (count($rootLists) === 1) {
      $rootListName = $rootLists[0][0];
      $rootListRoute = $rootLists[0][1];

      // Get the root list's route.
      $route = $routeProvider->getRouteByName($rootListRoute);

      // Create a route URL to the root list.
      $url = Url::fromRoute(
        $rootListRoute,
        [],
        ['absolute' => TRUE])->toString();

      // Get the route's title.
      $title = $titleResolver->getTitle($dummyRequest, $route);

      // Create markup for a menu entry to the root list.
      $attr = "data-foldershare-id=\"$rootListName\" data-foldershare-url=\"$url\"";

      $menuMarkup .= "<li $attr><div><span class=\"$fileClasses\"></span>$title</div></li>";
    }
    else {
      $title = (string) t('Lists');
      $menuMarkup .= "<li><div>$title</div><ul>";

      foreach ($rootLists as $rootList) {
        $rootListName = $rootList[0];
        $rootListRoute = $rootList[1];

        // Get the root list's route.
        $route = $routeProvider->getRouteByName($rootListRoute);

        // Create a route URL to the root list.
        $url = Url::fromRoute(
          $rootListRoute,
          [],
          ['absolute' => TRUE])->toString();

        // Get the route's title.
        $title = $titleResolver->getTitle($dummyRequest, $route);

        // Create markup for a menu entry to the root list.
        $attr = "data-foldershare-id=\"$rootListName\" data-foldershare-url=\"$url\"";
        $menuMarkup .= "<li $attr><div><span class=\"$fileClasses\"></span>$title</div></li>";
      }
      $menuMarkup .= "</ul></li>";
    }

    $menuMarkup .= '</ul>';

    //
    // Create menu button.
    // -------------------
    // Create HTML for a button. Include:
    //
    // - Class 'hidden' so that the button is initially hidden and only shown
    //   later by Javascript, if the browser supports scripting.
    $buttonText = (string) t('Ancestors');
    $buttonMarkup = "<button type=\"button\" class=\"hidden $menuButtonClass\"><span>$buttonText</span></button>";

    //
    // Create UI
    // ---------
    // Everything is hidden initially, and only exposed by Javascript, if
    // the browser supports Javascript.
    $renderable = [
      '#attributes' => [
        'class'     => [
          'foldershare-ancestormenu',
        ],
      ],
      $uiClass => [
        '#type'              => 'container',
        '#weight'            => -90,
        '#attributes'        => [
          'class'            => [
            $uiClass,
            'hidden',
          ],
        ],

        // Add a hierarchical menu of ancestors. Javascript uses jQuery.ui
        // to build a menu from this and presents it from a menu button.
        // The menu was built and marked as hidden.
        //
        // Implementation note: The field is built using an inline template
        // to avoid Drupal's HTML cleaning that can remove classes and
        // attributes on the menu items, which we need to retain to provide
        // the URLs of ancestor folders. Those URLs are used by Javascript
        // to load the appropriate page when a menu item is selected.
        $menuClass           => [
          '#type'            => 'inline_template',
          '#template'        => '{{ menu|raw }}',
          '#context'         => [
            'menu'           => $menuMarkup,
          ],
        ],

        // Add a button to go up a folder. Javascript binds a behavior
        // to the button to load the parent page. The button is hidden
        // initially and only shown if the browser supports Javascript.
        //
        // Implementation note: The field is built using an inline template
        // so that we get a <button>. If we used the '#type' 'button',
        // Drupal instead creates an <input>. Since we specifically want a
        // button so that jQuery.button() will button-ize it, we have to
        // bypass Drupal.
        $menuButtonClass       => [
          '#type'            => 'inline_template',
          '#template'        => '{{ button|raw }}',
          '#context'         => [
            'button'         => $buttonMarkup,
          ],
        ],
      ],
    ];

    return $renderable;
  }

}

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

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