devel_generate.module 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. <?php
  2. /**
  3. * Implements hook_menu().
  4. */
  5. function devel_generate_menu() {
  6. $items = array();
  7. $items['admin/config/development/generate/user'] = array(
  8. 'title' => 'Generate users',
  9. 'description' => 'Generate a given number of users. Optionally delete current users.',
  10. 'page callback' => 'drupal_get_form',
  11. 'page arguments' => array('devel_generate_users_form'),
  12. 'access arguments' => array('administer users'),
  13. );
  14. $items['admin/config/development/generate/content'] = array(
  15. 'title' => 'Generate content',
  16. 'description' => 'Generate a given number of nodes and comments. Optionally delete current items.',
  17. 'page callback' => 'drupal_get_form',
  18. 'page arguments' => array('devel_generate_content_form'),
  19. 'access arguments' => array('administer nodes'),
  20. );
  21. if (module_exists('taxonomy')) {
  22. $items['admin/config/development/generate/taxonomy'] = array(
  23. 'title' => 'Generate terms',
  24. 'description' => 'Generate a given number of terms. Optionally delete current terms.',
  25. 'page callback' => 'drupal_get_form',
  26. 'page arguments' => array('devel_generate_term_form'),
  27. 'access arguments' => array('administer taxonomy'),
  28. );
  29. $items['admin/config/development/generate/vocabs'] = array(
  30. 'title' => 'Generate vocabularies',
  31. 'description' => 'Generate a given number of vocabularies. Optionally delete current vocabularies.',
  32. 'page callback' => 'drupal_get_form',
  33. 'page arguments' => array('devel_generate_vocab_form'),
  34. 'access arguments' => array('administer taxonomy'),
  35. );
  36. }
  37. $items['admin/config/development/generate/menu'] = array(
  38. 'title' => 'Generate menus',
  39. 'description' => 'Generate a given number of menus and menu links. Optionally delete current menus.',
  40. 'page callback' => 'drupal_get_form',
  41. 'page arguments' => array('devel_generate_menu_form'),
  42. 'access arguments' => array('administer menu'),
  43. );
  44. return $items;
  45. }
  46. /**
  47. * Generates users using FormAPI.
  48. */
  49. function devel_generate_users_form() {
  50. $form['num'] = array(
  51. '#type' => 'textfield',
  52. '#title' => t('How many users would you like to generate?'),
  53. '#default_value' => 50,
  54. '#size' => 10,
  55. );
  56. $form['kill_users'] = array(
  57. '#type' => 'checkbox',
  58. '#title' => t('Delete all users (except user id 1) before generating new users.'),
  59. '#default_value' => FALSE,
  60. );
  61. $options = user_roles(TRUE);
  62. unset($options[DRUPAL_AUTHENTICATED_RID]);
  63. $form['roles'] = array(
  64. '#type' => 'checkboxes',
  65. '#title' => t('Which roles should the users receive?'),
  66. '#description' => t('Users always receive the <em>authenticated user</em> role.'),
  67. '#options' => $options,
  68. );
  69. $form['pass'] = array(
  70. '#type' => 'textfield',
  71. '#title' => t('Password to be set'),
  72. '#default_value' => NULL,
  73. '#size' => 32,
  74. '#description' => t('Leave this field empty if you do not need to set a password.'),
  75. );
  76. $options = array(1 => t('Now'));
  77. foreach (array(3600, 86400, 604800, 2592000, 31536000) as $interval) {
  78. $options[$interval] = format_interval($interval, 1) . ' ' . t('ago');
  79. }
  80. $form['time_range'] = array(
  81. '#type' => 'select',
  82. '#title' => t('How old should user accounts be?'),
  83. '#description' => t('User ages will be distributed randomly from the current time, back to the selected time.'),
  84. '#options' => $options,
  85. '#default_value' => 604800,
  86. );
  87. $form['actions'] = array('#type' => 'actions');
  88. $form['actions']['submit'] = array(
  89. '#type' => 'submit',
  90. '#value' => t('Generate'),
  91. );
  92. return $form;
  93. }
  94. /**
  95. * FormAPI submission to generate users.
  96. */
  97. function devel_generate_users_form_submit($form, &$form_state) {
  98. module_load_include('inc', 'devel_generate');
  99. $values = $form_state['values'];
  100. devel_create_users($values['num'], $values['kill_users'], $values['time_range'], $values['roles'], $values['pass']);
  101. }
  102. /**
  103. * Generates nodes using FormAPI.
  104. */
  105. function devel_generate_content_form() {
  106. $options = array();
  107. if (module_exists('content')) {
  108. $types = content_types();
  109. foreach ($types as $type) {
  110. $warn = '';
  111. if (count($type['fields'])) {
  112. $warn = t('. This type contains CCK fields which will only be populated by fields that implement the content_generate hook.');
  113. }
  114. $options[$type['type']] = t($type['name']). $warn;
  115. }
  116. }
  117. else {
  118. $types = node_type_get_types();
  119. foreach ($types as $type) {
  120. $options[$type->type] = array(
  121. 'type' => t($type->name),
  122. );
  123. if (module_exists('comment')) {
  124. $default = variable_get('comment_' . $type->type, COMMENT_NODE_OPEN);
  125. $map = array(t('Hidden'), t('Closed'), t('Open'));
  126. $options[$type->type]['comments'] = '<small>'. $map[$default]. '</small>';
  127. }
  128. }
  129. }
  130. // we cannot currently generate valid polls.
  131. unset($options['poll']);
  132. if (empty($options)) {
  133. drupal_set_message(t('You do not have any content types that can be generated. <a href="@create-type">Go create a new content type</a> already!</a>', array('@create-type' => url('admin/structure/types/add'))), 'error', FALSE);
  134. return;
  135. }
  136. $header = array(
  137. 'type' => t('Content type'),
  138. );
  139. if (module_exists('comment')) {
  140. $header['comments'] = t('Comments');
  141. }
  142. $form['node_types'] = array(
  143. '#type' => 'tableselect',
  144. '#header' => $header,
  145. '#options' => $options,
  146. '#required' => TRUE,
  147. );
  148. if (module_exists('checkall')) $form['node_types']['#checkall'] = TRUE;
  149. $form['kill_content'] = array(
  150. '#type' => 'checkbox',
  151. '#title' => t('<strong>Delete all content</strong> in these content types before generating new content.'),
  152. '#default_value' => FALSE,
  153. );
  154. $form['num_nodes'] = array(
  155. '#type' => 'textfield',
  156. '#title' => t('How many nodes would you like to generate?'),
  157. '#default_value' => 50,
  158. '#size' => 10,
  159. );
  160. $options = array(1 => t('Now'));
  161. foreach (array(3600, 86400, 604800, 2592000, 31536000) as $interval) {
  162. $options[$interval] = format_interval($interval, 1) . ' ' . t('ago');
  163. }
  164. $form['time_range'] = array(
  165. '#type' => 'select',
  166. '#title' => t('How far back in time should the nodes be dated?'),
  167. '#description' => t('Node creation dates will be distributed randomly from the current time, back to the selected time.'),
  168. '#options' => $options,
  169. '#default_value' => 604800,
  170. );
  171. $form['max_comments'] = array(
  172. '#type' => module_exists('comment') ? 'textfield' : 'value',
  173. '#title' => t('Maximum number of comments per node.'),
  174. '#description' => t('You must also enable comments for the content types you are generating. Note that some nodes will randomly receive zero comments. Some will receive the max.'),
  175. '#default_value' => 0,
  176. '#size' => 3,
  177. '#access' => module_exists('comment'),
  178. );
  179. $form['title_length'] = array(
  180. '#type' => 'textfield',
  181. '#title' => t('Maximum number of words in titles'),
  182. '#default_value' => 4,
  183. '#size' => 10,
  184. );
  185. $form['add_alias'] = array(
  186. '#type' => 'checkbox',
  187. '#disabled' => !module_exists('path'),
  188. '#description' => t('Requires path.module'),
  189. '#title' => t('Add an url alias for each node.'),
  190. '#default_value' => FALSE,
  191. );
  192. $form['add_statistics'] = array(
  193. '#type' => 'checkbox',
  194. '#title' => t('Add statistics for each node (node_counter table).'),
  195. '#default_value' => TRUE,
  196. '#access' => module_exists('statistics'),
  197. );
  198. unset($options);
  199. $options[LANGUAGE_NONE] = t('Language neutral');
  200. if (module_exists('locale')) {
  201. $options += locale_language_list();
  202. }
  203. $form['add_language'] = array(
  204. '#type' => 'select',
  205. '#title' => t('Set language on nodes'),
  206. '#multiple' => TRUE,
  207. '#disabled' => !module_exists('locale'),
  208. '#description' => t('Requires locale.module'),
  209. '#options' => $options,
  210. '#default_value' => array(LANGUAGE_NONE),
  211. );
  212. $form['actions'] = array('#type' => 'actions');
  213. $form['actions']['submit'] = array(
  214. '#type' => 'submit',
  215. '#value' => t('Generate'),
  216. );
  217. $form['#redirect'] = FALSE;
  218. return $form;
  219. }
  220. /**
  221. * FormAPI validation before generate nodes.
  222. */
  223. function devel_generate_content_form_validate($form, &$form_state) {
  224. form_set_value($form['node_types'], array_filter($form_state['values']['node_types']) , $form_state);
  225. if (!empty($form_state['values']['kill_content']) && empty($form_state['values']['node_types'])) {
  226. form_set_error('', t('Please select at least one content type to delete the content.'));
  227. }
  228. }
  229. /**
  230. * FormAPI submission to generate nodes.
  231. */
  232. function devel_generate_content_form_submit($form, &$form_state) {
  233. module_load_include('inc', 'devel_generate', 'devel_generate');
  234. if ($form_state['values']['num_nodes'] <= 50 && $form_state['values']['max_comments'] <= 10) {
  235. module_load_include('inc', 'devel_generate');
  236. devel_generate_content($form_state);
  237. }
  238. else {
  239. module_load_include('inc', 'devel_generate', 'devel_generate_batch');
  240. devel_generate_batch_content($form_state);
  241. }
  242. }
  243. /**
  244. * Generates taxonomy terms using FormAPI.
  245. */
  246. function devel_generate_term_form() {
  247. $options = array();
  248. foreach (taxonomy_get_vocabularies() as $vid => $vocab) {
  249. $options[$vid] = $vocab->machine_name;
  250. }
  251. $form['vids'] = array(
  252. '#type' => 'select',
  253. '#multiple' => TRUE,
  254. '#title' => t('Vocabularies'),
  255. '#required' => TRUE,
  256. '#options' => $options,
  257. '#description' => t('Restrict terms to these vocabularies.'),
  258. );
  259. $form['num_terms'] = array(
  260. '#type' => 'textfield',
  261. '#title' => t('Number of terms?'),
  262. '#default_value' => 10,
  263. '#size' => 10,
  264. );
  265. $form['title_length'] = array(
  266. '#type' => 'textfield',
  267. '#title' => t('Maximum number of characters in term names'),
  268. '#default_value' => 12,
  269. '#size' => 10,
  270. );
  271. $form['kill_taxonomy'] = array(
  272. '#type' => 'checkbox',
  273. '#title' => t('Delete existing terms in specified vocabularies before generating new terms.'),
  274. '#default_value' => FALSE,
  275. );
  276. $form['actions'] = array('#type' => 'actions');
  277. $form['actions']['submit'] = array(
  278. '#type' => 'submit',
  279. '#value' => t('Generate'),
  280. );
  281. return $form;
  282. }
  283. /**
  284. * Generates taxonomy vocabularies using FormAPI.
  285. */
  286. function devel_generate_vocab_form() {
  287. $form['num_vocabs'] = array(
  288. '#type' => 'textfield',
  289. '#title' => t('Number of vocabularies?'),
  290. '#default_value' => 1,
  291. '#size' => 10,
  292. );
  293. $form['title_length'] = array(
  294. '#type' => 'textfield',
  295. '#title' => t('Maximum number of characters in vocabulary names'),
  296. '#default_value' => 12,
  297. '#size' => 10,
  298. );
  299. $form['kill_taxonomy'] = array(
  300. '#type' => 'checkbox',
  301. '#title' => t('Delete existing vocabularies before generating new ones.'),
  302. '#default_value' => FALSE,
  303. );
  304. $form['actions'] = array('#type' => 'actions');
  305. $form['actions']['submit'] = array(
  306. '#type' => 'submit',
  307. '#value' => t('Generate'),
  308. );
  309. return $form;
  310. }
  311. /**
  312. * FormAPI submission to generate taxonomy terms.
  313. */
  314. function devel_generate_term_form_submit($form, &$form_state) {
  315. $values = $form_state['values'];
  316. module_load_include('inc', 'devel_generate');
  317. if ($values['kill_taxonomy']) {
  318. foreach ($values['vids'] as $vid) {
  319. devel_generate_delete_vocabulary_terms($vid);
  320. }
  321. drupal_set_message(t('Deleted existing terms.'));
  322. }
  323. $vocabs = taxonomy_vocabulary_load_multiple($values['vids']);
  324. $new_terms = devel_generate_terms($values['num_terms'], $vocabs, $values['title_length']);
  325. if (!empty($new_terms)) {
  326. drupal_set_message(t('Created the following new terms: !terms', array('!terms' => implode(', ', $new_terms))));
  327. }
  328. }
  329. /**
  330. * FormAPI submission to generate taxonomy vocabularies.
  331. */
  332. function devel_generate_vocab_form_submit($form, &$form_state) {
  333. $values = $form_state['values'];
  334. module_load_include('inc', 'devel_generate');
  335. if ($values['kill_taxonomy']) {
  336. devel_generate_delete_vocabularies();
  337. drupal_set_message(t('Deleted existing vocabularies.'));
  338. }
  339. $new_vocs = devel_generate_vocabs($values['num_vocabs'], $values['title_length']);
  340. if (!empty($new_vocs)) {
  341. drupal_set_message(t('Created the following new vocabularies: !vocs', array('!vocs' => implode(', ', $new_vocs))));
  342. }
  343. }
  344. /**
  345. * Inserts nodes properly based on generation options.
  346. *
  347. * @param $node
  348. * The base node created on submit. Inspects $node->devel_generate.
  349. */
  350. function devel_generate_node_insert($node) {
  351. if (isset($node->devel_generate)) {
  352. $results = $node->devel_generate;
  353. if (!empty($results['max_comments']) && $node->comment >= COMMENT_NODE_OPEN) {
  354. devel_generate_add_comments($node, $results['users'], $results['max_comments'], $results['title_length']);
  355. }
  356. // Add an url alias. Cannot happen before save because we don't know the nid.
  357. if (!empty($results['add_alias'])) {
  358. $path = array(
  359. 'source' => 'node/' . $node->nid,
  360. 'alias' => 'node-' . $node->nid . '-' . $node->type,
  361. );
  362. path_save($path);
  363. }
  364. // Add node statistics.
  365. if (!empty($results['add_statistics']) && module_exists('statistics')) {
  366. devel_generate_add_statistics($node);
  367. }
  368. }
  369. }
  370. /**
  371. * Set a message for either drush or the web interface.
  372. *
  373. * @param $msg
  374. * The message to display.
  375. * @param $type
  376. * The message type, as defined by drupal_set_message().
  377. *
  378. * @return
  379. * Context-appropriate message output.
  380. */
  381. function devel_generate_set_message($msg, $type = 'status') {
  382. $function = function_exists('drush_log') ? 'drush_log' : 'drupal_set_message';
  383. $function($msg, $type);
  384. }
  385. /**
  386. * Generates menus using FormAPI.
  387. */
  388. function devel_generate_menu_form() {
  389. $menu_enabled = module_exists('menu');
  390. if ($menu_enabled) {
  391. $menus = array('__new-menu__' => t('Create new menu(s)')) + menu_get_menus();
  392. }
  393. else {
  394. $menus = menu_list_system_menus();
  395. }
  396. $form['existing_menus'] = array(
  397. '#type' => 'checkboxes',
  398. '#title' => t('Generate links for these menus'),
  399. '#options' => $menus,
  400. '#default_value' => array('__new-menu__'),
  401. '#required' => TRUE,
  402. );
  403. if ($menu_enabled) {
  404. $form['num_menus'] = array(
  405. '#type' => 'textfield',
  406. '#title' => t('Number of new menus to create'),
  407. '#default_value' => 2,
  408. '#size' => 10,
  409. '#states' => array(
  410. 'visible' => array(
  411. ':input[name="existing_menus[__new-menu__]"]' => array('checked' => TRUE),
  412. ),
  413. ),
  414. );
  415. }
  416. $form['num_links'] = array(
  417. '#type' => 'textfield',
  418. '#title' => t('Number of links to generate'),
  419. '#default_value' => 50,
  420. '#size' => 10,
  421. '#required' => TRUE,
  422. );
  423. $form['title_length'] = array(
  424. '#type' => 'textfield',
  425. '#title' => t('Maximum number of characters in menu and menu link names'),
  426. '#description' => t("The minimum length is 2."),
  427. '#default_value' => 12,
  428. '#size' => 10,
  429. '#required' => TRUE,
  430. );
  431. $form['link_types'] = array(
  432. '#type' => 'checkboxes',
  433. '#title' => t('Types of links to generate'),
  434. '#options' => array(
  435. 'node' => t('Nodes'),
  436. 'front' => t('Front page'),
  437. 'external' => t('External'),
  438. ),
  439. '#default_value' => array('node', 'front', 'external'),
  440. '#required' => TRUE,
  441. );
  442. $form['max_depth'] = array(
  443. '#type' => 'select',
  444. '#title' => t('Maximum link depth'),
  445. '#options' => range(0, MENU_MAX_DEPTH),
  446. '#default_value' => floor(MENU_MAX_DEPTH / 2),
  447. '#required' => TRUE,
  448. );
  449. unset($form['max_depth']['#options'][0]);
  450. $form['max_width'] = array(
  451. '#type' => 'textfield',
  452. '#title' => t('Maximum menu width'),
  453. '#default_value' => 6,
  454. '#size' => 10,
  455. '#description' => t("Limit the width of the generated menu's first level of links to a certain number of items."),
  456. '#required' => TRUE,
  457. );
  458. $form['kill'] = array(
  459. '#type' => 'checkbox',
  460. '#title' => t('Delete existing custom generated menus and menu links before generating new ones.'),
  461. '#default_value' => FALSE,
  462. );
  463. $form['actions'] = array('#type' => 'actions');
  464. $form['actions']['submit'] = array(
  465. '#type' => 'submit',
  466. '#value' => t('Generate'),
  467. );
  468. return $form;
  469. }
  470. /**
  471. * FormAPI submission to generate menus.
  472. */
  473. function devel_generate_menu_form_submit($form, &$form_state) {
  474. // If the create new menus checkbox is off, set the number of new menus to 0.
  475. if (!isset($form_state['values']['existing_menus']['__new-menu__']) || !$form_state['values']['existing_menus']['__new-menu__']) {
  476. $form_state['values']['num_menus'] = 0;
  477. }
  478. module_load_include('inc', 'devel_generate');
  479. // Delete custom menus.
  480. if ($form_state['values']['kill']) {
  481. devel_generate_delete_menus();
  482. drupal_set_message(t('Deleted existing menus and links.'));
  483. }
  484. // Generate new menus.
  485. $new_menus = devel_generate_menus($form_state['values']['num_menus'], $form_state['values']['title_length']);
  486. if (!empty($new_menus)) {
  487. drupal_set_message(t('Created the following new menus: !menus', array('!menus' => implode(', ', $new_menus))));
  488. }
  489. // Generate new menu links.
  490. $menus = $new_menus + $form_state['values']['existing_menus'];
  491. $new_links = devel_generate_links($form_state['values']['num_links'], $menus, $form_state['values']['title_length'], $form_state['values']['link_types'], $form_state['values']['max_depth'], $form_state['values']['max_width']);
  492. drupal_set_message(t('Created @count new menu links.', array('@count' => count($new_links))));
  493. }