class MenuDevelGenerate in Devel 8.3
Same name and namespace in other branches
- 8 devel_generate/src/Plugin/DevelGenerate/MenuDevelGenerate.php \Drupal\devel_generate\Plugin\DevelGenerate\MenuDevelGenerate
- 8.2 devel_generate/src/Plugin/DevelGenerate/MenuDevelGenerate.php \Drupal\devel_generate\Plugin\DevelGenerate\MenuDevelGenerate
- 4.x devel_generate/src/Plugin/DevelGenerate/MenuDevelGenerate.php \Drupal\devel_generate\Plugin\DevelGenerate\MenuDevelGenerate
Provides a MenuDevelGenerate plugin.
Plugin annotation
@DevelGenerate(
id = "menu",
label = @Translation("menus"),
description = @Translation("Generate a given number of menus and menu links. Optionally delete current menus."),
url = "menu",
permission = "administer devel_generate",
settings = {
"num_menus" = 2,
"num_links" = 50,
"title_length" = 12,
"max_width" = 6,
"kill" = FALSE,
}
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\devel_generate\DevelGenerateBase implements DevelGenerateBaseInterface
- class \Drupal\devel_generate\Plugin\DevelGenerate\MenuDevelGenerate implements ContainerFactoryPluginInterface
- class \Drupal\devel_generate\DevelGenerateBase implements DevelGenerateBaseInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of MenuDevelGenerate
File
- devel_generate/
src/ Plugin/ DevelGenerate/ MenuDevelGenerate.php, line 33
Namespace
Drupal\devel_generate\Plugin\DevelGenerateView source
class MenuDevelGenerate extends DevelGenerateBase implements ContainerFactoryPluginInterface {
/**
* The menu tree service.
*
* @var \Drupal\Core\Menu\MenuLinkTreeInterface
*/
protected $menuLinkTree;
/**
* The menu storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $menuStorage;
/**
* The menu link storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $menuLinkContentStorage;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* Database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* Constructs a MenuDevelGenerate object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Menu\MenuLinkTreeInterface $menu_tree
* The menu tree service.
* @param \Drupal\Core\Entity\EntityStorageInterface $menu_storage
* The menu storage.
* @param \Drupal\Core\Entity\EntityStorageInterface $menu_link_storage
* The menu storage.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Drupal\Core\Database\Connection $database
* Database connection.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MenuLinkTreeInterface $menu_tree, EntityStorageInterface $menu_storage, EntityStorageInterface $menu_link_storage, ModuleHandlerInterface $module_handler, Connection $database) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->menuLinkTree = $menu_tree;
$this->menuStorage = $menu_storage;
$this->menuLinkContentStorage = $menu_link_storage;
$this->moduleHandler = $module_handler;
$this->database = $database;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$entity_type_manager = $container
->get('entity_type.manager');
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('menu.link_tree'), $entity_type_manager
->getStorage('menu'), $entity_type_manager
->getStorage('menu_link_content'), $container
->get('module_handler'), $container
->get('database'));
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$menu_enabled = $this->moduleHandler
->moduleExists('menu_ui');
if ($menu_enabled) {
$menus = [
'__new-menu__' => $this
->t('Create new menu(s)'),
] + menu_ui_get_menus();
}
else {
$menus = menu_list_system_menus();
}
$form['existing_menus'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('Generate links for these menus'),
'#options' => $menus,
'#default_value' => [
'__new-menu__',
],
'#required' => TRUE,
];
if ($menu_enabled) {
$form['num_menus'] = [
'#type' => 'number',
'#title' => $this
->t('Number of new menus to create'),
'#default_value' => $this
->getSetting('num_menus'),
'#min' => 0,
'#states' => [
'visible' => [
':input[name="existing_menus[__new-menu__]"]' => [
'checked' => TRUE,
],
],
],
];
}
$form['num_links'] = [
'#type' => 'number',
'#title' => $this
->t('Number of links to generate'),
'#default_value' => $this
->getSetting('num_links'),
'#required' => TRUE,
'#min' => 0,
];
$form['title_length'] = [
'#type' => 'number',
'#title' => $this
->t('Maximum length for menu titles and menu links'),
'#description' => $this
->t('Text will be generated at random lengths up to this value. Enter a number between 2 and 128.'),
'#default_value' => $this
->getSetting('title_length'),
'#required' => TRUE,
'#min' => 2,
'#max' => 128,
];
$form['link_types'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('Types of links to generate'),
'#options' => [
'node' => $this
->t('Nodes'),
'front' => $this
->t('Front page'),
'external' => $this
->t('External'),
],
'#default_value' => [
'node',
'front',
'external',
],
'#required' => TRUE,
];
$form['max_depth'] = [
'#type' => 'select',
'#title' => $this
->t('Maximum link depth'),
'#options' => range(0, $this->menuLinkTree
->maxDepth()),
'#default_value' => floor($this->menuLinkTree
->maxDepth() / 2),
'#required' => TRUE,
];
unset($form['max_depth']['#options'][0]);
$form['max_width'] = [
'#type' => 'number',
'#title' => $this
->t('Maximum menu width'),
'#default_value' => $this
->getSetting('max_width'),
'#description' => $this
->t("Limit the width of the generated menu's first level of links to a certain number of items."),
'#required' => TRUE,
'#min' => 0,
];
$form['kill'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Delete existing custom generated menus and menu links before generating new ones.'),
'#default_value' => $this
->getSetting('kill'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function generateElements(array $values) {
// If the create new menus checkbox is off, set the number of menus to 0.
if (!isset($values['existing_menus']['__new-menu__']) || !$values['existing_menus']['__new-menu__']) {
$values['num_menus'] = 0;
}
else {
// Unset the aux menu to avoid attach menu new items.
unset($values['existing_menus']['__new-menu__']);
}
// Delete custom menus.
if ($values['kill']) {
list($menus_deleted, $links_deleted) = $this
->deleteMenus();
$this
->setMessage($this
->t('Deleted @menus_deleted menu(s) and @links_deleted other link(s).', [
'@menus_deleted' => $menus_deleted,
'@links_deleted' => $links_deleted,
]));
}
// Generate new menus.
$new_menus = $this
->generateMenus($values['num_menus'], $values['title_length']);
if (!empty($new_menus)) {
$this
->setMessage($this
->formatPlural(count($new_menus), 'Created the following 1 new menu: @menus', 'Created the following @count new menus: @menus', [
'@menus' => implode(', ', $new_menus),
]));
}
// Generate new menu links.
$menus = $new_menus;
if (isset($values['existing_menus'])) {
$menus = $menus + $values['existing_menus'];
}
$new_links = $this
->generateLinks($values['num_links'], $menus, $values['title_length'], $values['link_types'], $values['max_depth'], $values['max_width']);
$this
->setMessage($this
->formatPlural(count($new_links), 'Created 1 new menu link.', 'Created @count new menu links.'));
}
/**
* {@inheritdoc}
*/
public function validateDrushParams(array $args, array $options = []) {
$link_types = [
'node',
'front',
'external',
];
$values = [
'num_menus' => array_shift($args),
'num_links' => array_shift($args),
'kill' => $this
->isDrush8() ? drush_get_option('kill') : $options['kill'],
'pipe' => $this
->isDrush8() ? drush_get_option('pipe') : $options['pipe'],
'link_types' => array_combine($link_types, $link_types),
];
$max_depth = array_shift($args);
$max_width = array_shift($args);
$values['max_depth'] = $max_depth ? $max_depth : 3;
$values['max_width'] = $max_width ? $max_width : 8;
$values['title_length'] = $this
->getSetting('title_length');
$values['existing_menus']['__new-menu__'] = TRUE;
if ($this
->isNumber($values['num_menus']) == FALSE) {
throw new \Exception(dt('Invalid number of menus'));
}
if ($this
->isNumber($values['num_links']) == FALSE) {
throw new \Exception(dt('Invalid number of links'));
}
if ($this
->isNumber($values['max_depth']) == FALSE || $values['max_depth'] > 9 || $values['max_depth'] < 1) {
throw new \Exception(dt('Invalid maximum link depth. Use a value between 1 and 9'));
}
if ($this
->isNumber($values['max_width']) == FALSE || $values['max_width'] < 1) {
throw new \Exception(dt('Invalid maximum menu width. Use a positive numeric value.'));
}
return $values;
}
/**
* Deletes custom generated menus.
*/
protected function deleteMenus() {
if ($this->moduleHandler
->moduleExists('menu_ui')) {
$menu_ids = [];
foreach (menu_ui_get_menus(FALSE) as $menu => $menu_title) {
if (strpos($menu, 'devel-') === 0) {
$menu_ids[] = $menu;
}
}
if ($menu_ids) {
$menus = $this->menuStorage
->loadMultiple($menu_ids);
$this->menuStorage
->delete($menus);
}
}
// Delete menu links in other menus, but generated by devel.
$link_ids = $this->menuLinkContentStorage
->getQuery()
->condition('menu_name', 'devel', '<>')
->condition('link__options', '%' . $this->database
->escapeLike('s:5:"devel";b:1') . '%', 'LIKE')
->execute();
if ($link_ids) {
$links = $this->menuLinkContentStorage
->loadMultiple($link_ids);
$this->menuLinkContentStorage
->delete($links);
}
return [
count($menu_ids),
count($link_ids),
];
}
/**
* Generates new menus.
*
* @param int $num_menus
* Number of menus to create.
* @param int $title_length
* (optional) Maximum length of menu name.
*
* @return array
* Array containing the generated menus.
*/
protected function generateMenus($num_menus, $title_length = 12) {
$menus = [];
for ($i = 1; $i <= $num_menus; $i++) {
$name = $this
->randomSentenceOfLength(mt_rand(2, $title_length));
// Create a random string of random length for the menu id. The maximum
// machine-name length is 32, so allowing for prefix 'devel-' we can have
// up to 26 here. For safety avoid accidentally reusing the same id.
do {
$id = 'devel-' . $this
->getRandom()
->name(mt_rand(2, 26));
} while (array_key_exists($id, $menus));
$menu = $this->menuStorage
->create([
'label' => $name,
'id' => $id,
'description' => $this
->t('Description of @name', [
'@name' => $name,
]),
]);
$menu
->save();
$menus[$menu
->id()] = $menu
->label();
}
return $menus;
}
/**
* Generates menu links in a tree structure.
*/
protected function generateLinks($num_links, $menus, $title_length, $link_types, $max_depth, $max_width) {
$links = [];
$menus = array_keys(array_filter($menus));
$link_types = array_keys(array_filter($link_types));
$nids = [];
for ($i = 1; $i <= $num_links; $i++) {
// Pick a random menu.
$menu_name = $menus[array_rand($menus)];
// Build up our link.
$link_title = $this
->getRandom()
->word(mt_rand(2, max(2, $title_length)));
$link = $this->menuLinkContentStorage
->create([
'menu_name' => $menu_name,
'weight' => mt_rand(-50, 50),
'title' => $link_title,
'bundle' => 'menu_link_content',
'description' => $this
->t('Description of @title.', [
'@title' => $link_title,
]),
]);
$link->link->options = [
'devel' => TRUE,
];
// For the first $max_width items, make first level links.
if ($i <= $max_width) {
$depth = 0;
}
else {
// Otherwise, get a random parent menu depth.
$depth = mt_rand(1, max(1, $max_depth - 1));
}
// Get a random parent link from the proper depth.
do {
$parameters = new MenuTreeParameters();
$parameters
->setMinDepth($depth);
$parameters
->setMaxDepth($depth);
$tree = $this->menuLinkTree
->load($menu_name, $parameters);
if ($tree) {
$link->parent = array_rand($tree);
}
$depth--;
} while (!$link->parent && $depth > 0);
$link_type = array_rand($link_types);
switch ($link_types[$link_type]) {
case 'node':
// Grab a random node ID.
$select = $this->database
->select('node_field_data', 'n')
->fields('n', [
'nid',
'title',
])
->condition('n.status', 1)
->range(0, 1)
->orderRandom();
// Don't put a node into the menu twice.
if (!empty($nids[$menu_name])) {
$select
->condition('n.nid', $nids[$menu_name], 'NOT IN');
}
$node = $select
->execute()
->fetchAssoc();
if (isset($node['nid'])) {
$nids[$menu_name][] = $node['nid'];
$link->link->uri = 'entity:node/' . $node['nid'];
$link->title = $node['title'];
break;
}
case 'external':
$link->link->uri = 'http://www.example.com/';
break;
case 'front':
$link->link->uri = 'internal:/<front>';
break;
default:
$link->devel_link_type = $link_type;
break;
}
$link
->save();
$links[$link
->id()] = $link->link_title;
}
return $links;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
DevelGenerateBase:: |
protected | property | The entity type manager service. | |
DevelGenerateBase:: |
protected | property | The random data generator. | |
DevelGenerateBase:: |
protected | property | The plugin settings. | |
DevelGenerateBase:: |
public | function |
Execute the instructions in common for all DevelGenerate plugin. Overrides DevelGenerateBaseInterface:: |
|
DevelGenerateBase:: |
public | function |
Returns the default settings for the plugin. Overrides DevelGenerateBaseInterface:: |
|
DevelGenerateBase:: |
protected | function | Gets the entity type manager service. | |
DevelGenerateBase:: |
protected | function | Return a language code. | 1 |
DevelGenerateBase:: |
protected | function | Creates the language and translation section of the form. | |
DevelGenerateBase:: |
protected | function | Returns the random data generator. | |
DevelGenerateBase:: |
public | function |
Returns the array of settings, including defaults for missing settings. Overrides DevelGenerateBaseInterface:: |
|
DevelGenerateBase:: |
public | function |
Returns the current settings for the plugin. Overrides DevelGenerateBaseInterface:: |
|
DevelGenerateBase:: |
public | function | ||
DevelGenerateBase:: |
protected | function | Determines if Drush is version 8. | |
DevelGenerateBase:: |
public static | function | Check if a given param is a number. | |
DevelGenerateBase:: |
public static | function | Populate the fields on a given entity with sample values. | |
DevelGenerateBase:: |
protected | function | Generates a random sentence of specific length. | |
DevelGenerateBase:: |
protected | function | Set a message for either drush or the web interface. | |
DevelGenerateBase:: |
public | function |
Form validation handler. Overrides DevelGenerateBaseInterface:: |
2 |
MenuDevelGenerate:: |
protected | property | Database connection. | |
MenuDevelGenerate:: |
protected | property | The menu link storage. | |
MenuDevelGenerate:: |
protected | property | The menu tree service. | |
MenuDevelGenerate:: |
protected | property | The menu storage. | |
MenuDevelGenerate:: |
protected | property | The module handler. | |
MenuDevelGenerate:: |
public static | function |
Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface:: |
|
MenuDevelGenerate:: |
protected | function | Deletes custom generated menus. | |
MenuDevelGenerate:: |
public | function |
Business logic relating with each DevelGenerate plugin. Overrides DevelGenerateBase:: |
|
MenuDevelGenerate:: |
protected | function | Generates menu links in a tree structure. | |
MenuDevelGenerate:: |
protected | function | Generates new menus. | |
MenuDevelGenerate:: |
public | function |
Returns the form for the plugin. Overrides DevelGenerateBase:: |
|
MenuDevelGenerate:: |
public | function |
Responsible for validating Drush params. Overrides DevelGenerateBaseInterface:: |
|
MenuDevelGenerate:: |
public | function |
Constructs a MenuDevelGenerate object. Overrides PluginBase:: |
|
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |