publish_button.module 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. <?php
  2. /**
  3. * @file
  4. * Functions to create a publish button. Real simple, but could be needed.
  5. *
  6. * @todo
  7. * Add permissions, expose to Views, better ctools integration, add simple class
  8. * settings for css. Nice buttons should have colours.
  9. */
  10. /**
  11. * Implements hook_help().
  12. */
  13. function publish_button_help($path, $arg) {
  14. switch ($path) {
  15. case 'admin/help#publish_button':
  16. return '<h2>' . t('Usage of Publish button') . '</h2>
  17. <p>' . t('After installation, on each content type there are a
  18. new setting, Publish button, and to activate publish/unpublish button
  19. for that content type, you need to check "Use publish/unpublish button
  20. for this content type" and then click save.') . '</p>
  21. <p>' . t('Now you need to add permissions for which user roles which
  22. are allowed to publsih content.') . '</p>
  23. <p>' . t('Now, when you create a new node, there are a
  24. publish or unpublish button for all the content types that have the
  25. button settings.') . '</p>';
  26. }
  27. }
  28. /**
  29. * Implements hook_form_alter().
  30. *
  31. * Here we have both the settings for which content types that would have the
  32. * button and the button itself.
  33. */
  34. function publish_button_form_alter(&$form, &$form_state, $form_id) {
  35. // Add settings for using content type on types/manage/my_content_type
  36. if ($form_id == 'node_type_form') {
  37. // After that a checkbox for settings.
  38. $form['workflow']['publish_button_content_type'] = array(
  39. '#type' => 'checkbox',
  40. '#title' => t('Use publish/unpublish button for this content type'),
  41. // Getting/setting the variable that contains the setting for the content
  42. // type.
  43. '#default_value' => variable_get('publish_button_content_type_' . $form['#node_type']->type, FALSE),
  44. );
  45. }
  46. }
  47. /**
  48. * Implements hook_form_BASE_FORM_ID_alter().
  49. */
  50. function publish_button_form_node_form_alter(&$form, &$form_state, $form_id) {
  51. // Now for the button itself.
  52. // For best practice, make the user object global, because we are checking
  53. // permissions. Usually we have the object, but we should declare that we
  54. // need it. We want to be the good guys, don't we?
  55. global $user;
  56. if (variable_get('publish_button_content_type_' . $form['#node']->type) == TRUE) {
  57. // First we check if the node have the status TRUE. That could be TRUE
  58. // also for unpublished nodes. A little bit sci-fi, isn't it?
  59. if ($form['#node']->status == TRUE) {
  60. // So we check if nid have value, so we do not try to unpublish a node
  61. // that does not exists, that should destroy the universe. We do not
  62. // want that.
  63. if (isset($form['nid']['#value'])) {
  64. if ($form['nid']['#value'] !== NULL) {
  65. // Add the unpublish button to the actions array.
  66. if (_publish_button_unpublish_permissions($form['#node']->type) == TRUE) {
  67. // Check if we are on a delete confirm page.
  68. if ($form['#form_id'] != 'node_delete_confirm') {
  69. $form['actions']['unpublish'] = publish_button_render_unpublish_button();
  70. }
  71. }
  72. }
  73. }
  74. else {
  75. if (_publish_button_publish_permissions($form['#node']->type) == TRUE && (isset($form['actions']))) {
  76. // Check if we are on a delete confirm page.
  77. if ($form['#form_id'] != 'node_delete_confirm') {
  78. $form['actions']['publish'] = publish_button_render_publish_button();
  79. }
  80. }
  81. }
  82. }
  83. // Then we check if the node have status FALSE.
  84. if ($form['#node']->status == FALSE) {
  85. // Add the publish button to the action array.
  86. if (_publish_button_publish_permissions($form['#node']->type) == TRUE && (isset($form['actions']))) {
  87. // Check if we are on a delete confirm page.
  88. if ($form['#form_id'] != 'node_delete_confirm') {
  89. $form['actions']['publish'] = publish_button_render_publish_button();
  90. }
  91. }
  92. }
  93. }
  94. }
  95. /**
  96. * Render publish button.
  97. */
  98. function publish_button_render_publish_button() {
  99. $publish_button = array(
  100. '#type' => 'submit',
  101. '#access' => TRUE,
  102. '#value' => t('Publish'),
  103. '#weight' => '30',
  104. // Add the submit handler.
  105. '#submit' => array('_publish_button_publish_node'),
  106. );
  107. return $publish_button;
  108. }
  109. /**
  110. * Render unpublish button.
  111. */
  112. function publish_button_render_unpublish_button() {
  113. $unpublish_button = array(
  114. '#type' => 'submit',
  115. '#access' => TRUE,
  116. '#value' => t('Unpublish'),
  117. // Set a pretty high weight, so the button would come last, but
  118. // still make it possible for other modules to add buttons after
  119. // it.
  120. '#weight' => '30',
  121. // Add the submit handler.
  122. '#submit' => array('_publish_button_unpublish_node'),
  123. );
  124. return $unpublish_button;
  125. }
  126. /**
  127. * Submit handler to publish the node.
  128. */
  129. function _publish_button_publish_node($form, &$form_state) {
  130. // Set the node status as published. And that's it.
  131. $form_state['values']['status'] = 1;
  132. // Use the standard submit function. Do not go custom on me boy.
  133. node_form_submit($form, $form_state);
  134. }
  135. /**
  136. * Submit handler to unpublish the node.
  137. */
  138. function _publish_button_unpublish_node($form, &$form_state) {
  139. // Set the status as unpublished. And there is no more to that.
  140. $form_state['values']['status'] = 0;
  141. // Use the standard submit function.
  142. node_form_submit($form, $form_state);
  143. }
  144. /**
  145. * Implements hook_permission().
  146. */
  147. function publish_button_permission() {
  148. $perms = array(
  149. 'publish button publish any content types' => array(
  150. 'title' => t('Publish any content types'),
  151. ),
  152. 'publish button unpublish any content types' => array(
  153. 'title' => t('Unpublish any content types'),
  154. ),
  155. );
  156. foreach (node_type_get_types() as $type) {
  157. // First we need to check if there are a publish button for the content
  158. // type.
  159. if (variable_get('publish_button_content_type_' . $type->type, FALSE)) {
  160. // And if there is, go through the content types that have the button
  161. // and create permissions for them.
  162. if (isset($type->type)) {
  163. $perms['publish button publish any ' . $type->type] = array(
  164. 'title' => t('@type: Publish any', array('@type' => $type->name)));
  165. $perms['publish button publish own ' . $type->type] = array(
  166. 'title' => t('@type: Publish own', array('@type' => $type->name)));
  167. $perms['publish button publish editable ' . $type->type] = array(
  168. 'title' => t('@type: Publish editable', array('@type' => $type->name)));
  169. $perms['publish button unpublish any ' . $type->type] = array(
  170. 'title' => t('@type: Unpublish any', array('@type' => $type->name)));
  171. $perms['publish button unpublish own ' . $type->type] = array(
  172. 'title' => t('@type: Unpublish own', array('@type' => $type->name)));
  173. $perms['publish button unpublish editable ' . $type->type] = array(
  174. 'title' => t('@type: Unpublish editable', array('@type' => $type->name)));
  175. }
  176. }
  177. }
  178. return $perms;
  179. }
  180. /**
  181. * Checking publish permissions.
  182. */
  183. function _publish_button_publish_permissions($type) {
  184. global $user;
  185. if (user_access('publish button publish any ' . $type) ||
  186. user_access('publish button publish own ' . $type) ||
  187. user_access('publish button publish editable ' . $type) ||
  188. user_access('publish button publish any content types') == TRUE) {
  189. return TRUE;
  190. }
  191. else {
  192. return FALSE;
  193. }
  194. }
  195. /**
  196. * Checking unpublish permissions.
  197. */
  198. function _publish_button_unpublish_permissions($type) {
  199. global $user;
  200. if (user_access('publish button unpublish any ' . $type) ||
  201. user_access('publish button unpublish own ' . $type) ||
  202. user_access('publish button unpublish editable ' . $type) ||
  203. user_access('publish button unpublish any content types') == TRUE) {
  204. return TRUE;
  205. }
  206. else {
  207. return FALSE;
  208. }
  209. }
  210. // Start of views integration.
  211. /**
  212. * Implements hook_views_api().
  213. */
  214. function publish_button_views_api() {
  215. return array('api' => 3);
  216. }
  217. /**
  218. * Implements hook_views_data_alter().
  219. */
  220. function publish_button_views_data_alter(&$data) {
  221. $data['node']['publish_button'] = array(
  222. 'title' => t('Publish button'),
  223. 'help' => t('Display a publish button.'),
  224. 'field' => array(
  225. 'handler' => 'publish_button_views_handler_node_link',
  226. ),
  227. );
  228. }
  229. /**
  230. * Implements hook_menu().
  231. */
  232. function publish_button_menu() {
  233. $items['publish_button/%/publish'] = array(
  234. 'title' => 'Publish node',
  235. 'page callback' => 'publish_button_status',
  236. 'page arguments' => array(1),
  237. 'type' => MENU_CALLBACK,
  238. 'access callback' => '_publish_button_menu_access',
  239. 'access arguments' => array(1, 'publish'),
  240. );
  241. $items['publish_button/%/unpublish'] = array(
  242. 'title' => 'Unpublish node',
  243. 'page callback' => 'publish_button_status',
  244. 'page arguments' => array(1),
  245. 'type' => MENU_CALLBACK,
  246. 'access callback' => '_publish_button_menu_access',
  247. 'access arguments' => array(1, 'unpublish'),
  248. );
  249. return $items;
  250. }
  251. /**
  252. * Check permissions to hook_menu call.
  253. */
  254. function _publish_button_menu_access($nid, $status) {
  255. if ($status == 'publish') {
  256. $node = node_load($nid);
  257. if (isset($node->type)) {
  258. if (_publish_button_publish_permissions($node->type) == TRUE) {
  259. return TRUE;
  260. }
  261. }
  262. }
  263. if ($status == 'unpublish') {
  264. $node = node_load($nid);
  265. if (isset($node->type)) {
  266. if (_publish_button_unpublish_permissions($node->type) == TRUE) {
  267. return TRUE;
  268. }
  269. }
  270. }
  271. else {
  272. return FALSE;
  273. }
  274. }
  275. /**
  276. * Callback to publish/unpublish node, preferable used via Views.
  277. */
  278. function publish_button_status($nid) {
  279. if (!isset($_GET['csrf_token']) || !drupal_valid_token($_GET['csrf_token'], 'publish_button_' . $nid)) {
  280. drupal_access_denied();
  281. return;
  282. }
  283. // Load the node in a object so we could use it.
  284. $node = node_load($nid);
  285. // If the node is published.
  286. if ($node->status == 1) {
  287. $node->status = 0;
  288. node_save($node);
  289. }
  290. // If the node is unpublished.
  291. elseif ($node->status == 0) {
  292. $node->status = 1;
  293. node_save($node);
  294. }
  295. drupal_goto(drupal_get_destination());
  296. }