layoutManager = $layout_manager; $this->updateManager = $update_manager; $this->alterInfo('bootstrap_layouts_handler_info'); $this->setCacheBackend($cache_backend, 'bootstrap_layouts_handler_info'); } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('container.namespaces'), $container->get('cache.discovery'), $container->get('module_handler'), $container->get('theme_handler'), $container->get('theme.manager'), $container->get('plugin.manager.layout_plugin'), $container->get('plugin.manager.bootstrap_layouts.update') ); } /** * {@inheritdoc} */ protected function findDefinitions() { $definitions = parent::findDefinitions(); // The handler plugin identifiers represent the module or theme that // implements said layouts. Remove any handler plugins that not installed. foreach (array_keys($definitions) as $provider) { if (!$this->providerExists($provider)) { unset($definitions[$provider]); } else { // Attempt to retrieve the theme human readable label first. try { $label = $this->themeHandler->getName($provider); } // Otherwise attempt to retrieve the module human readable label. catch (\Exception $e) { $label = $this->moduleHandler->getName($provider); } $definitions[$provider]['label'] = $label; } } return $definitions; } /** * Retrieves classes that can be used in Bootstrap layouts as select options. * * @return array * An associative array of grouped classes to be used in select options. */ public function getClassOptions() { static $classes; if (!isset($classes)) { $utility = []; $col = []; $hidden = []; $visible = []; $bg = []; $text_color = []; $text_alignment = [ 'text-left' => $this->t('Left'), 'text-right' => $this->t('Right'), 'text-center' => $this->t('Center'), 'text-justify' => $this->t('Justify'), 'text-nowrap' => $this->t('No Wrap'), ]; $text_transformation = [ 'text-lowercase' => $this->t('Lowercase'), 'text-uppercase' => $this->t('Uppercase'), 'text-capitalize' => $this->t('Capitalize'), ]; // Utility. $utility['clearfix'] = $this->t('Clear Fix'); $utility['row'] = $this->t('Row'); $sizes = [ 'xs' => $this->t('Extra Small'), 'sm' => $this->t('Small'), 'md' => $this->t('Medium'), 'lg' => $this->t('Large'), ]; foreach ($sizes as $size => $size_label) { $hidden["hidden-$size"] = $size_label; $visible["visible-$size"] = $size_label; foreach (range(1, 12) as $column) { $col["col-$size-$column"] = $this->t('@size: @column', [ '@size' => $size_label, '@column' => $column, ]); } } // Background/text color classes. foreach (['primary', 'danger', 'info', 'warning', 'success'] as $type) { $bg["bg-$type"] = $this->t('@type', ['@type' => Unicode::ucfirst($type)]); $text_color["text-$type"] = $this->t('@type', ['@type' => Unicode::ucfirst($type)]); } $text_color['text-muted'] = $this->t('Muted'); // Groups. $groups = [ 'utility' => $this->t('Utility'), 'columns' => $this->t('Columns'), 'hidden' => $this->t('Hidden'), 'visible' => $this->t('Visible'), 'background' => $this->t('Background'), 'text_alignment' => $this->t('Text alignment'), 'text_color' => $this->t('Text color'), 'text_transformation' => $this->t('Text transformation'), ]; // Classes, keyed by group. $classes = [ 'utility' => $utility, 'columns' => $col, 'hidden' => $hidden, 'visible' => $visible, 'background' => $bg, 'text_alignment' => $text_alignment, 'text_color' => $text_color, 'text_transformation' => $text_transformation, ]; // Invokes hook_bootstrap_layouts_class_options_alter(). $this->moduleHandler->alter('bootstrap_layouts_class_options', $classes, $groups); $this->themeManager->alter('bootstrap_layouts_class_options', $classes, $groups); // Render the group labels and use them for optgroup values. $grouped = []; foreach ($classes as $group => $data) { $group = (string) (isset($groups[$group]) ? $groups[$group] : $group); $grouped[$group] = $data; } $classes = $grouped; } return $classes; } /** * Indicates if provided layout identifier is a Bootstrap Layouts layout. * * @param string $id * The layout identifier to test. * * @return bool * TRUE or FALSE */ public function isBootstrapLayout($id) { static $layouts; if (!isset($layouts)) { $layouts = []; foreach (array_keys($this->layoutManager->getDefinitions()) as $layout_id) { $plugin = $this->layoutManager->createInstance($layout_id); if ($plugin instanceof BootstrapLayoutsBase) { $layouts[] = $layout_id; } } } return in_array($id, $layouts); } /** * Retrieves all available handler instances. * * @return \Drupal\bootstrap_layouts\Plugin\BootstrapLayouts\BootstrapLayoutsHandlerInterface[] */ public function getHandlers() { $instances = []; foreach (array_keys($this->getDefinitions()) as $plugin_id) { $instances[$plugin_id] = $this->createInstance($plugin_id); } return $instances; } /** * Runs update(s) for a specific schema version. * * @param int $schema * The schema version to update. * @param bool $display_messages * Flag determining whether a message will be displayed indicating whether * the layout was processed successfully or not. */ public function update($schema, $display_messages = TRUE) { $handlers = $this->getHandlers(); $data = []; foreach ($this->updateManager->getUpdates($schema) as $update) { // See if there's an adjoining YML file with the update plugin. $r = new \ReflectionClass($update); $data_paths = [dirname($r->getFileName()), $update->getPath()]; // Merge in any update data. foreach ($data_paths as $path) { $file = "$path/bootstrap_layouts.update.$schema.yml"; if (file_exists($file) && ($yaml = Yaml::decode(file_get_contents($file)))) { $data = NestedArray::mergeDeep($data, $yaml); } } // Perform the update. $update->update($this, $data, $display_messages); // Process any existing layouts after the update. foreach ($handlers as $handler_id => $handler) { foreach ($handler->loadInstances() as $storage_id => $layout) { $update->processExistingLayout($layout, $data, $display_messages); // Determine if the layout has changed and then save it. if ($layout->hasChanged()) { try { $handler->saveInstance($storage_id, $layout); if ($display_messages) { \drupal_set_message($this->t('Successfully updated the existing Bootstrap layout found in "@id".', ['@id' => $storage_id])); } } catch (\Exception $e) { \drupal_set_message($this->t('Unable to update the existing Bootstrap layout found in "@id":', ['@id' => $storage_id]), 'error'); \drupal_set_message($e->getMessage(), 'error'); } } } } } } }