diff --git a/multiversion.libraries.yml b/multiversion.libraries.yml new file mode 100644 index 0000000..8d6b7a2 --- /dev/null +++ b/multiversion.libraries.yml @@ -0,0 +1,5 @@ +multiversion.switcherform: + version: VERSION + css: + layout: + css/multiversion.switcherform.css: {} diff --git a/multiversion.services.yml b/multiversion.services.yml index a617103..be355d6 100644 --- a/multiversion.services.yml +++ b/multiversion.services.yml @@ -38,7 +38,7 @@ services: - { name: cache.context } multiversion.toolbar: class: Drupal\multiversion\Toolbar - arguments: ['@entity_type.manager', '@workspace.manager'] + arguments: ['@entity_type.manager', '@workspace.manager', '@form_builder'] # @todo: {@link https://www.drupal.org/node/2597414 Simplify the container diff --git a/multiversion_ui/css/multiversion.switcherform.css b/multiversion_ui/css/multiversion.switcherform.css new file mode 100644 index 0000000..3fb9e69 --- /dev/null +++ b/multiversion_ui/css/multiversion.switcherform.css @@ -0,0 +1,4 @@ +form.multiversion-switcher-form { + display: inline; + border: 2px solid red; +} diff --git a/src/Form/WorkspaceSwitcherForm.php b/src/Form/WorkspaceSwitcherForm.php new file mode 100644 index 0000000..55adf78 --- /dev/null +++ b/src/Form/WorkspaceSwitcherForm.php @@ -0,0 +1,107 @@ +get('workspace.manager'), + $container->get('entity_type.manager') + ); + } + + public function __construct(WorkspaceManagerInterface $workspace_manager, EntityTypeManagerInterface $entity_type_manager) { + $this->workspaceManager = $workspace_manager; + $this->entityTypeManager = $entity_type_manager; + } + + + /** + * @inheritDoc + */ + public function getFormId() { + return 'workspace_switcher_form_' . static::$formCounter++; + } + + /** + * @inheritDoc + */ + public function buildForm(array $form, FormStateInterface $form_state, WorkspaceInterface $workspace = NULL) { + $form['workspace_id'] = [ + '#type' => 'hidden', + '#value' => $workspace->id(), + ]; + + $form['submit'] = [ + '#type' => 'submit', + '#value' => $workspace->label(), + ]; + + // @todo This does not appear to have any effect. I am not sure yet why. + $form['#attached']['library'][] = 'multiversion/switcherform'; + + return $form; + } + + /** + * @inheritDoc + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $id = $form_state->getValue('workspace_id'); + + if (!$id) { + // @todo Error handling, as this shouldn't be possible. + } + + /** @var WorkspaceInterface $workspace */ + $workspace = $this->entityTypeManager->getStorage('workspace')->load($id); + // @todo Using the global $_SESSION is deprecated, I'm pretty sure. I + // need to check and see what the proper new way is. + $_SESSION['workspace'] = $id; + + drupal_set_message($this->t('Now viewing workspace %workspace', ['%workspace' => $workspace->label()])); + } + +} diff --git a/src/Plugin/Block/WorkspaceBlock.php b/src/Plugin/Block/WorkspaceBlock.php deleted file mode 100644 index 7f675bf..0000000 --- a/src/Plugin/Block/WorkspaceBlock.php +++ /dev/null @@ -1,80 +0,0 @@ -workspaceManager = $workspace_manager; - $this->entityTypeManager = $entity_type_manager; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $container->get('workspace.manager'), - $container->get('entity_type.manager') - ); - } - - /** - * {@inheritdoc} - */ - public function build() { - $build = array(); - $route_name = \Drupal::service('path.matcher')->isFrontPage() ? '' : ''; - $links = $this->workspaceManager->getWorkspaceSwitchLinks(Url::fromRoute($route_name)); - - if (isset($links)) { - $build = array( - '#theme' => 'links__workspace_block', - '#links' => $links, - '#attributes' => array( - 'class' => array( - 'workspace-switcher', - ), - ), - '#set_active_class' => TRUE, - // @todo: The caching need tests. - '#cache' => [ - 'contexts' => $this->entityTypeManager->getDefinition('workspace')->getListCacheContexts(), - 'tags' => $this->entityTypeManager->getDefinition('workspace')->getListCacheTags(), - ], - ); - } - return $build; - } - -} diff --git a/src/Toolbar.php b/src/Toolbar.php index d136f8b..1eb2d69 100644 --- a/src/Toolbar.php +++ b/src/Toolbar.php @@ -4,9 +4,12 @@ namespace Drupal\multiversion; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Form\FormBuilderInterface; +use Drupal\Core\Link; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; use Drupal\multiversion\Entity\WorkspaceInterface; +use Drupal\multiversion\Form\WorkspaceSwitcherForm; use Drupal\multiversion\Workspace\WorkspaceManagerInterface; @@ -27,16 +30,25 @@ class Toolbar { protected $workspaceManager; /** + * @var \Drupal\Core\Form\FormBuilderInterface + */ + protected $formBuilder; + + /** * Constructs a new Toolbar. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager service. * @param \Drupal\multiversion\Workspace\WorkspaceManagerInterface $workspace_manager * The workspace manager service. + * @param \Drupal\Core\Form\FormBuilderInterface $form_builder + * The form builder service. */ - public function __construct(EntityTypeManagerInterface $entity_type_manager, WorkspaceManagerInterface $workspace_manager) { + + public function __construct(EntityTypeManagerInterface $entity_type_manager, WorkspaceManagerInterface $workspace_manager, FormBuilderInterface $form_builder) { $this->entityTypeManager = $entity_type_manager; $this->workspaceManager = $workspace_manager; + $this->formBuilder = $form_builder; } /** @@ -68,20 +80,20 @@ class Toolbar { ], ]; + $create_link = Link::createFromRoute($this->t('Create new workspace'), 'entity.workspace.add'); + $items['workspace_switcher']['tray'] = [ '#heading' => $this->t('Switch to workspace'), - 'workspace_links' => [ - '#pre_render' => ['multiversion.toolbar:preRenderWorkspaceLinks'], - '#cache' => [ - 'contexts' => $this->entityTypeManager->getDefinition('workspace')->getListCacheContexts(), - 'tags' => $this->entityTypeManager->getDefinition('workspace')->getListCacheTags(), - ], - '#theme' => 'links__toolbar_workspaces', - // This will be filled in during pre-render. - '#links' => [], - '#attributes' => [ - 'class' => ['toolbar-menu'], - ], + '#pre_render' => ['multiversion.toolbar:preRenderWorkspaceSwitcherForms'], + 'create_link' => $create_link->toRenderable(), + // This wil get filled in via pre-render. + 'workspace_forms' => [], + '#cache' => [ + 'contexts' => $this->entityTypeManager->getDefinition('workspace')->getListCacheContexts(), + 'tags' => $this->entityTypeManager->getDefinition('workspace')->getListCacheTags(), + ], + '#attributes' => [ + 'class' => ['toolbar-menu'], ], ]; @@ -89,48 +101,19 @@ class Toolbar { } /** - * Prerender callback; Adds the workspace links to the render array. + * Prerender callback; Adds the workspace switcher forms to the render array. * * @param array $element * * @return array * The modified $element. */ - public function preRenderWorkspaceLinks(array $element) { - $element['#links'] = $this->workspaceLinks(); - - return $element; - } - - /** - * Builds a render array of links to switch to all workspaces. - * - * Note: This is an expensive call so should only be made from within a - * pre-render callback, so it gets cached. - * - * @return array - * A render array of links to switch to each workspace. - */ - protected function workspaceLinks() { - $links = []; - - $links['add'] = [ - 'title' => $this->t('Create new workspace'), - 'url' => Url::fromRoute('entity.workspace.add'), - ]; - - /** @var WorkspaceInterface $workspace */ + public function preRenderWorkspaceSwitcherForms(array $element) { foreach ($this->allWorkspaces() as $workspace) { - $links['workspace_' . $workspace->getMachineName()] = [ - 'title' => $workspace->label(), - 'url' => Url::fromRoute('', ['workspace' => $workspace->id()]), - 'attributes' => [ - 'title' => t('Switch to %workspace workspace', ['%workspace' => $workspace->label()]) - ], - ]; + $element['workspace_forms']['workspace_' . $workspace->getMachineName()] = $this->formBuilder->getForm(WorkspaceSwitcherForm::class, $workspace); } - return $links; + return $element; } /** diff --git a/src/Workspace/SessionWorkspaceNegotiator.php b/src/Workspace/SessionWorkspaceNegotiator.php index e336438..3503ca5 100644 --- a/src/Workspace/SessionWorkspaceNegotiator.php +++ b/src/Workspace/SessionWorkspaceNegotiator.php @@ -24,10 +24,10 @@ class SessionWorkspaceNegotiator extends WorkspaceNegotiatorBase implements Work * {@inheritdoc} */ public function getWorkspaceId(Request $request) { - $workspace_id = $request->query->get('workspace') ?: NULL; - if (!$workspace_id && isset($_SESSION['workspace'])) { + if (isset($_SESSION['workspace'])) { // @todo: {@link https://www.drupal.org/node/2597464 Review from a // security perspective.} + // @todo Switch this to not use a superglobal. $workspace_id = $_SESSION['workspace']; } return $workspace_id ?: $this->container->getParameter('workspace.default');