content_type_extras.module 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. <?php
  2. define('CONTENT_TYPE_EXTRAS_ADMIN_DEFAULTS', 'administer content type defaults');
  3. define('CONTENT_TYPE_EXTRAS_NODE_DISPLAY_PERM', 'override content type title display');
  4. /**
  5. * Implements hook_init().
  6. */
  7. function content_type_extras_init() {
  8. drupal_add_css(drupal_get_path('module', 'content_type_extras') . '/css/content_type_extras.css');
  9. }
  10. /**
  11. * Implements hook_permission().
  12. */
  13. function content_type_extras_permission() {
  14. return array(
  15. CONTENT_TYPE_EXTRAS_ADMIN_DEFAULTS => array(
  16. 'title' => t('Administer content type defaults'),
  17. 'description' => t('Set the default settings to use on content types that are not overridden.'),
  18. ),
  19. CONTENT_TYPE_EXTRAS_NODE_DISPLAY_PERM => array(
  20. 'title' => t('Override content type title display'),
  21. 'description' => t('Allow the default node title display setting to be overridden on a per-node basis.'),
  22. ),
  23. );
  24. }
  25. /**
  26. * Implements hook_preprocess_page().
  27. */
  28. function content_type_extras_preprocess_page(&$vars) {
  29. // We have to check for the front page first since it's setting take precedence
  30. // over the node type setting.
  31. if (drupal_is_front_page()) {
  32. $hide_title_front = content_type_extras_get_default('content_type_extras_title_hide_front');
  33. if ($hide_title_front) {
  34. $hide_title_css = content_type_extras_get_default('content_type_extras_title_hide_css');
  35. if ($hide_title_css) {
  36. $vars['title_prefix']['content_type_extras'] = array(
  37. '#prefix' => '<div class="element-invisible">',
  38. );
  39. $vars['title_suffix']['content_type_extras'] = array(
  40. '#suffix' => '</div>',
  41. );
  42. }
  43. else {
  44. $vars['title'] = '';
  45. }
  46. }
  47. }
  48. elseif (!empty($vars['node'])) {
  49. $hide_title = content_type_extras_get_setting('content_type_extras_title_hide', $vars['node']->type);
  50. if ($hide_title) {
  51. $hide_title_css = content_type_extras_get_default('content_type_extras_title_hide_css');
  52. if ($hide_title_css) {
  53. $vars['title_prefix']['content_type_extras'] = array(
  54. '#prefix' => '<div class="element-invisible">',
  55. );
  56. $vars['title_suffix']['content_type_extras'] = array(
  57. '#suffix' => '</div>',
  58. );
  59. }
  60. else {
  61. $vars['title'] = '';
  62. }
  63. }
  64. }
  65. }
  66. /**
  67. * Implements hook_menu().
  68. */
  69. function content_type_extras_menu() {
  70. $items['admin/structure/types/list'] = array(
  71. 'title' => 'List',
  72. 'type' => MENU_DEFAULT_LOCAL_TASK,
  73. 'weight' => 0,
  74. );
  75. $items['admin/structure/types/defaults'] = array(
  76. 'title' => 'Default Settings',
  77. 'page callback' => 'drupal_get_form',
  78. 'page arguments' => array('content_type_extras_settings'),
  79. 'access arguments' => array(CONTENT_TYPE_EXTRAS_ADMIN_DEFAULTS),
  80. 'type' => MENU_LOCAL_TASK,
  81. 'file' => 'content_type_extras.admin.inc',
  82. 'file path' => drupal_get_path('module', 'content_type_extras') . '/includes',
  83. 'weight' => 10,
  84. );
  85. return $items;
  86. }
  87. /**
  88. * Implements hook_form_alter()
  89. */
  90. function content_type_extras_form_alter(&$form, &$form_state, $form_id) {
  91. // This is a list of node form ids to omit from being processed, since they don't
  92. // play nice with content_type_extras.
  93. $exclude_node_form = array(
  94. 'subscriptions_ui_node_form',
  95. );
  96. // node_type_form = Content type edit forms.
  97. if ($form_id == 'node_type_form') {
  98. module_load_include('inc', 'content_type_extras', 'includes/content_type_extras.node_type_form');
  99. content_type_extras_node_type_form($form);
  100. }
  101. // Viewing a specific node edit form
  102. elseif (strpos($form_id, '_node_form') && !in_array($form_id, $exclude_node_form)) {
  103. $type = $form['type']['#value'];
  104. // We need to check to see if auto_nodetitle module is hiding the title field
  105. // Thus, we check for $form['title']['#value'] != 'ant'
  106. if (user_access(CONTENT_TYPE_EXTRAS_NODE_DISPLAY_PERM) && (isset($form['title']['#value']) && $form['title']['#value'] != 'ant')) {
  107. $hide = content_type_extras_get_setting('content_type_extras_title_hide', $type);
  108. if (!empty($form['nid']['#value'])) {
  109. $hide = _content_type_extras_get_node_display($form['nid']['#value']);
  110. }
  111. $form['title_hide'] = array(
  112. '#type' => 'checkbox',
  113. '#title' => t("Exclude this node's title from display"),
  114. '#default_value' => $hide,
  115. '#weight' => 0,
  116. );
  117. if (variable_get('site_frontpage', '') . '/edit' == current_path()) {
  118. // We need to get the default settings since that is the only place that
  119. // the hide_title_front setting is stored.
  120. $defaults = content_type_extras_get_default();
  121. if (!empty($defaults['extras']['title_hide_front'])) {
  122. $form['title_hide']['#disabled'] = TRUE;
  123. $form['title_hide']['#description'] = t('<em>You cannot edit this option as it is set as the front page and the front page title is set to be hidden by the administrator.</em>');
  124. }
  125. }
  126. }
  127. $title_label = content_type_extras_get_setting('title_label', $type);
  128. if (isset($title_label) && $title_label != t('Title')) {
  129. $form['title']['#title'] = $title_label;
  130. }
  131. $save_and_new = content_type_extras_get_setting('content_type_extras_save_and_new', $type);
  132. if (!empty($save_and_new)) {
  133. $form['actions']['save_and_new'] = array(
  134. '#type' => 'submit',
  135. '#value' => content_type_extras_get_setting('content_type_extras_save_and_new_button', $type),
  136. '#weight' => $form['actions']['submit']['#weight'] + 1,
  137. '#submit' => array(
  138. 'node_form_submit',
  139. 'content_type_extras_node_form_new_submit',
  140. ),
  141. );
  142. }
  143. $save_and_edit = content_type_extras_get_setting('content_type_extras_save_and_edit', $type);
  144. if (!empty($save_and_edit)) {
  145. $form['actions']['save_and_edit'] = array(
  146. '#type' => 'submit',
  147. '#value' => content_type_extras_get_setting('content_type_extras_save_and_edit_button', $type),
  148. '#weight' => $form['actions']['submit']['#weight'] + 2,
  149. '#submit' => array(
  150. 'node_form_submit',
  151. 'content_type_extras_node_form_edit_submit',
  152. ),
  153. );
  154. }
  155. $preview = content_type_extras_get_setting('node_preview', $type);
  156. if (!empty($preview)) {
  157. // Since the initial button is provided by Core, but the ability to change the
  158. // text is provided by Content Type: Extras, we need to search for the appropriate
  159. // setting below to set the value
  160. $form['actions']['preview'] = array(
  161. '#type' => 'submit',
  162. '#value' => content_type_extras_get_setting('content_type_extras_preview_button', $type),
  163. '#weight' => $form['actions']['submit']['#weight'] + 2,
  164. );
  165. // We need to add this one differently since Preview is a button provided
  166. // inititally by Core.
  167. $form['actions']['preview']['#submit'][] = 'content_type_extras_node_form_edit_submit';
  168. }
  169. $cancel = content_type_extras_get_setting('content_type_extras_cancel', $type);
  170. if (!empty($cancel)) {
  171. drupal_add_js(drupal_get_path('module', 'content_type_extras') . '/js/content_type_extras.cancel_button.js');
  172. $form['actions']['cancel'] = array(
  173. '#type' => 'button',
  174. '#value' => t('Cancel'),
  175. '#weight' => 100, // We want this at the end of whatever buttons are showing
  176. '#post_render' => array('content_type_extras_change_button_type'),
  177. );
  178. }
  179. // Add the form buttons to the top of the page
  180. // Based on: http://blog.urbaninsight.com/2011/09/20/editors-perspective-creating-content-drupal
  181. $top_buttons = content_type_extras_get_default('content_type_extras_top_buttons');
  182. if (!empty($top_buttons['node_edit'])) {
  183. $form['pre_actions'] = $form['actions'];
  184. $form['pre_actions']['#weight'] = -100;
  185. }
  186. $form['#submit'][] = 'content_type_extras_node_form_submit';
  187. }
  188. // Content type field machine names can only be a maximum of 32 characters (including 'field_')
  189. // but the user can enter a name any length, getting an error message if the name is too long
  190. // That drives me crazy!! This fixes that!
  191. elseif ($form_id == 'field_ui_field_overview_form') {
  192. drupal_add_js(drupal_get_path('module', 'content_type_extras') . '/js/content_type_extras.manage_fields.js');
  193. $top_buttons = content_type_extras_get_default('content_type_extras_top_buttons');
  194. if (!empty($top_buttons['manage_fields'])) {
  195. $form['pre_actions'] = $form['actions'];
  196. $form['pre_actions']['#weight'] = -100;
  197. }
  198. $form['fields']['_add_new_field']['field_name']['#maxlength'] = 26;
  199. $form['fields']['_add_new_field']['field_name']['#description'] .= t(' - <span class="characters">26</span> characters max.');
  200. // The field_group module does the same thing, so if that is enabled, handle it the same way
  201. if (module_exists('field_group')) {
  202. $form['fields']['_add_new_group']['group_name']['#maxlength'] = 26;
  203. $form['fields']['_add_new_group']['group_name']['#description'] .= t(' - <span class="characters">26</span> characters max.');
  204. }
  205. }
  206. }
  207. /**
  208. * Form submission handler for $form_id *_node_form
  209. */
  210. function content_type_extras_node_form_submit(&$form, &$form_state) {
  211. if (!empty($form_state['values']['title_hide'])) {
  212. _content_type_extras_set_node_display($form_state['values']['nid'], $form_state['values']['title_hide']);
  213. }
  214. }
  215. /**
  216. * Form submission for $form_id *_node_form
  217. */
  218. function content_type_extras_node_form_new_submit(&$form, &$form_state) {
  219. $form_state['redirect'] = 'node/add/' . str_replace('_', '-', $form_state['node']->type);
  220. }
  221. /**
  222. * Form submission for $form_id *_node_form
  223. */
  224. function content_type_extras_node_form_edit_submit(&$form, &$form_state) {
  225. $form_state['redirect'] = 'node/' . $form_state['values']['nid'] . '/edit';
  226. }
  227. /**
  228. * Implements hook_node_type_delete().
  229. */
  230. function content_type_extras_node_type_delete($info) {
  231. db_delete('variable')
  232. ->condition('name', 'content_type_extras_%_' . $info->type, 'LIKE')
  233. ->execute();
  234. }
  235. /**
  236. * Function to change the type of button from 'submit' to 'button.
  237. * -- From http://drupal.org/node/133861#comment-4002698
  238. */
  239. function content_type_extras_change_button_type($markup, $element) {
  240. $markup = str_replace('type="submit', 'type="button', $markup);
  241. return $markup;
  242. }
  243. /**
  244. * Function to set values for node title display
  245. */
  246. function _content_type_extras_set_node_display($nid, $hide) {
  247. $settings = variable_get('content_type_extras_node_display', array());
  248. $settings[$nid] = $hide;
  249. variable_set('content_type_extras_node_display', $settings);
  250. }
  251. /**
  252. * Function to get values for node title display
  253. */
  254. function _content_type_extras_get_node_display($nid) {
  255. $settings = variable_get('content_type_extras_node_display', array());
  256. if (isset($settings[$nid])) {
  257. return $settings[$nid];
  258. }
  259. return FALSE;
  260. }
  261. /**
  262. * Function to get values based on node type.
  263. *
  264. * @param $setting
  265. * Retrieve a specific setting from $type.
  266. * @param $type
  267. * The type of content to get $setting from.
  268. *
  269. * @return
  270. * Returns the requested setting for the given content type.
  271. */
  272. function content_type_extras_get_setting($setting, $type) {
  273. // We have to handle title_label differently because it is stored in the node_type
  274. // table, not in variables
  275. if ($setting == 'title_label') {
  276. $result = db_query("SELECT title_label
  277. FROM {node_type}
  278. WHERE module = 'node'
  279. AND type = :type", array(':type' => $type))->fetchField();
  280. if ($result) {
  281. return $result;
  282. }
  283. }
  284. return variable_get($setting . '_' . $type, content_type_extras_get_default($setting));
  285. }
  286. /**
  287. * Function to get default setting(s), when settings for content type do not exist.
  288. *
  289. * @param $setting
  290. * Retrieve a specific default setting.
  291. *
  292. * @return
  293. * Returns the requested setting or, if NULL, returns all default settings.
  294. */
  295. function content_type_extras_get_default($setting = NULL) {
  296. // This has to be unserialized as it will crash the default settings page.
  297. $defaults = variable_get('content_type_extras_default_settings');
  298. if ($setting == NULL) {
  299. if (!empty($defaults)) {
  300. return $defaults;
  301. }
  302. else {
  303. return content_type_extras_get_initial();
  304. }
  305. }
  306. else {
  307. if (isset($defaults[$setting])) {
  308. return $defaults[$setting];
  309. }
  310. else {
  311. return content_type_extras_get_initial($setting);
  312. }
  313. }
  314. }
  315. /**
  316. * Function to retrive intial (module default) settings when no other settings exist.
  317. * This will primarily be used when the module is first installed.
  318. *
  319. * @param $setting
  320. * Retrieve a specific initial setting.
  321. *
  322. * @return
  323. * Returns the requested setting or, if NULL, returns all initial settings.
  324. */
  325. function content_type_extras_get_initial($setting = NULL) {
  326. $initial_values = array(
  327. // Values set by Drupal Core (node.module)
  328. 'title_label' => t('Title'),
  329. 'node_preview' => 1,
  330. 'node_options' => array(
  331. 'status' => 'status',
  332. 'promote' => 'promote',
  333. 'sticky' => 0,
  334. 'revision' => 0,
  335. ),
  336. 'node_submitted' => 1,
  337. // Values set by content_type_extras.module
  338. 'content_type_extras_preview_button' => t('Preview'),
  339. 'content_type_extras_save_and_new' => 0,
  340. 'content_type_extras_save_and_new_button' => t('Save and New'),
  341. 'content_type_extras_save_and_edit' => 0,
  342. 'content_type_extras_save_and_edit_button' => t('Save and Edit'),
  343. 'content_type_extras_cancel' => 0,
  344. 'content_type_extras_title_hide' => 0,
  345. 'content_type_extras_title_hide_css' => 0,
  346. 'content_type_extras_title_hide_front' => 0,
  347. 'content_type_extras_top_buttons' => array(),
  348. 'content_type_extras_remove_body' => 0,
  349. 'content_type_extras_descriptions_required' => 0,
  350. 'content_type_extras_user_permissions_select' => 'cte',
  351. // Values set by comment.module
  352. 'comment' => array(
  353. 'comment' => 2,
  354. 'default_mode' => 1,
  355. 'default_per_page' => 50,
  356. 'anonymous' => 0,
  357. 'subject_field' => 1,
  358. 'form_location' => 1,
  359. 'preview' => 1,
  360. ),
  361. // Values set by xmlsitemap.module
  362. 'xmlsitemap_settings' => array(
  363. 'status' => 1,
  364. 'priority' => '0.5',
  365. ),
  366. );
  367. $admin_role = variable_get('user_admin_role', '');
  368. $initial_values['user_permissions'] = array(
  369. 'create_roles' => array($admin_role => $admin_role),
  370. 'edit_roles' => array($admin_role => $admin_role),
  371. 'delete_roles' => array($admin_role => $admin_role),
  372. );
  373. if ($setting == NULL) {
  374. return $initial_values;
  375. }
  376. return $initial_values[$setting];
  377. }
  378. /**
  379. * Redirect function to content_type_extras_node_type_form_submit().
  380. *
  381. * We use this method because when other modules are enabled, like Location,
  382. * that modify node_type_form an error is thrown saying that
  383. * content_type_extras_node_type_form_submit() is not declared. This is a
  384. * workaround to keep the actual function in
  385. * content_type_extras.node_type_form.inc for organization, but keep the
  386. * submission form from throwing an error.
  387. * @TODO: I'd like to find a better way to handle this, if one exists!
  388. */
  389. function content_type_extras_node_type_form_submit_redirect(&$form, &$form_state) {
  390. include_once(drupal_get_path('module', 'content_type_extras') . '/includes/content_type_extras.node_type_form.inc');
  391. content_type_extras_node_type_form_submit($form, $form_state);
  392. }