fe_nodequeue.module 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <?php
  2. /**
  3. * @file
  4. * Main functions and hook implementations of the FE Nodequeue module.
  5. */
  6. /**
  7. * Implements hook_features_api().
  8. */
  9. function fe_nodequeue_features_api() {
  10. return array(
  11. 'fe_nodequeue' => array(
  12. 'name' => t('Nodequeues'),
  13. 'feature_source' => TRUE,
  14. 'default_hook' => 'fe_nodequeue_export_fields',
  15. 'default_file' => FEATURES_DEFAULTS_INCLUDED_COMMON,
  16. ),
  17. );
  18. }
  19. /**
  20. * Implements hook_features_export_options().
  21. */
  22. function fe_nodequeue_features_export_options() {
  23. $options = array();
  24. $fields = db_query('SELECT * FROM {nodequeue_queue}');
  25. while ($obj = $fields->fetchObject()) {
  26. $options[$obj->name] = t('@name [@machine_name]', array('@name' => $obj->title, '@machine_name' => $obj->name));
  27. }
  28. return $options;
  29. }
  30. /**
  31. * Implements hook_features_export().
  32. */
  33. function fe_nodequeue_features_export($data, &$export, $module_name = '') {
  34. $pipe = array();
  35. $map = features_get_default_map('fe_nodequeue');
  36. foreach ($data as $name) {
  37. $export['dependencies']['fe_nodequeue'] = 'fe_nodequeue';
  38. // If another module provides this style, add it as a dependency.
  39. if (isset($map[$name]) && $map[$name] != $module_name) {
  40. $module = $map[$name];
  41. $export['dependencies'][$module] = $module;
  42. }
  43. // Otherwise, export the nodequeue.
  44. elseif ($queue = _fe_nodequeue_load_queue_by_name($name, TRUE)) {
  45. // Add dependencies for the roles that are associated with these queues.
  46. if ($queue->roles) {
  47. // Filter out roles that have the 'manipulate all queues' permission.
  48. // @see http://drupal.org/node/213074
  49. $manipulate_all_queues = array_keys(user_roles(FALSE, 'manipulate all queues'));
  50. $queue->roles = array_diff($queue->roles, $manipulate_all_queues);
  51. $roles = user_roles();
  52. foreach ($queue->roles as $index => $rid) {
  53. $export['features']['user_role'][$roles[$rid]] = $roles[$rid];
  54. // Convert the role from a rid to a 'machine name' for saving. This
  55. // will be converted back to a rid when the feature is reverted.
  56. $queue->roles[$index] = $roles[$rid];
  57. }
  58. }
  59. $export['features']['fe_nodequeue'][$name] = $name;
  60. }
  61. }
  62. return $pipe;
  63. }
  64. /**
  65. * Implements hook_features_export_render().
  66. */
  67. function fe_nodequeue_features_export_render($module_name = '', $data) {
  68. $code = array();
  69. $code[] = ' $nodequeues = array();';
  70. $code[] = '';
  71. $roles = user_roles();
  72. foreach ($data as $name) {
  73. // Clone the nodequeue object so that our changes aren't statically cached.
  74. $nodequeue_static = _fe_nodequeue_load_queue_by_name($name, TRUE);
  75. if (!empty($nodequeue_static) && $nodequeue = clone $nodequeue_static) {
  76. // Sort roles and types arrays into ascending order so that we can check
  77. // for overridden db data without being affected by the order in which
  78. // this array gets stored/loaded.
  79. if (!empty($nodequeue->roles)) {
  80. // Roles that have the 'Manipulate all queues' permission will not get
  81. // saved and will throw override messages as a result.
  82. $manipulate_all_queues = array_keys(user_roles(FALSE, 'manipulate all queues'));
  83. $nodequeue->roles = array_diff($nodequeue->roles, $manipulate_all_queues);
  84. foreach ($nodequeue->roles as $index => $rid) {
  85. $nodequeue->roles[$index] = $roles[$rid];
  86. }
  87. sort($nodequeue->roles);
  88. }
  89. if (!empty($nodequeue->types)) {
  90. sort($nodequeue->types);
  91. }
  92. // Remove the nodequeue id. This is specific to the current site and
  93. // should not be exported.
  94. unset($nodequeue->qid);
  95. // We don't care how many subqueues are in here since they get created
  96. // automatically.
  97. if (module_exists('smartqueue')) {
  98. unset($nodequeue->subqueues);
  99. }
  100. $nodequeue_export = features_var_export($nodequeue, ' ');
  101. $code[] = " // Exported nodequeues: {$nodequeue->name}";
  102. $code[] = " \$nodequeues['{$name}'] = {$nodequeue_export};";
  103. $code[] = "";
  104. }
  105. }
  106. $code[] = ' return $nodequeues;';
  107. $code = implode("\n", $code);
  108. return array('fe_nodequeue_export_fields' => $code);
  109. }
  110. /**
  111. * Implements hook_features_revert().
  112. */
  113. function fe_nodequeue_features_revert($module) {
  114. $defaults = features_get_default('fe_nodequeue', $module);
  115. if (empty($defaults)) {
  116. return;
  117. }
  118. // Revert.
  119. foreach ($defaults as $object) {
  120. if (empty($object['name'])) {
  121. continue;
  122. }
  123. // Assign the existing qid if a nodequeue with the same name already exists.
  124. $map = _fe_nodequeue_get_qid_map();
  125. if (isset($map[$object['name']])) {
  126. $object['qid'] = $map[$object['name']];
  127. }
  128. // Clear the qid if it is a new nodequeue.
  129. else {
  130. unset($object['qid']);
  131. }
  132. $result = _fe_nodequeue_save_queue((array) $object);
  133. }
  134. return TRUE;
  135. }
  136. /**
  137. * Implements hook_features_revert().
  138. */
  139. function fe_nodequeue_features_rebuild($module) {
  140. fe_nodequeue_features_revert($module);
  141. }
  142. /**
  143. * Implements hook_features_enable_feature().
  144. */
  145. function fe_nodequeue_features_enable_feature($module) {
  146. fe_nodequeue_features_revert($module);
  147. }
  148. /**
  149. * Save a nodequeue queue.
  150. *
  151. * @param array $settings
  152. * A nodequeue settings array.
  153. *
  154. * @return array
  155. * The updated settings array.
  156. */
  157. function _fe_nodequeue_save_queue(array $settings) {
  158. // Convert roles from names to rids.
  159. $roles = array_flip(user_roles());
  160. foreach ((array) $settings['roles'] as $index => $role) {
  161. // In case we are dealing with an old export with rids, don't do anything.
  162. if (is_int($role)) {
  163. continue;
  164. }
  165. if (isset($roles[$role])) {
  166. $settings['roles'][$index] = $roles[$role];
  167. }
  168. else {
  169. // Do not attempt to assign a role which does not exist.
  170. unset($settings['roles'][$index]);
  171. }
  172. }
  173. // Simulate checkboxes.
  174. $settings['roles'] = drupal_map_assoc($settings['roles']);
  175. $settings['types'] = drupal_map_assoc($settings['types']);
  176. // Simulate submitting.
  177. $form_state = array();
  178. $form_state['values'] = $settings;
  179. module_load_include('inc', 'nodequeue', 'includes/nodequeue.admin');
  180. nodequeue_edit_queue_form_submit(NULL, $form_state);
  181. // Reset static caches.
  182. // Note: we are currently using a variant of nodequeue_get_qid_map() that uses
  183. // drupal_static() instead of a static variable to cache the results.
  184. // @see http://drupal.org/node/1666556
  185. drupal_static_reset('_fe_nodequeue_get_qid_map');
  186. return $settings;
  187. }
  188. /**
  189. * Return a map of queue name to qid values to aid in various lookups.
  190. *
  191. * This is based on nodequeue_get_qid_map() but uses drupal_static() instead of
  192. * a static variable to cache the results.
  193. *
  194. * @see nodequeue_get_qid_map()
  195. *
  196. * @todo Add a link to the issue that converts this to drupal_static().
  197. * @todo Create a followup issue to remove this once the above issue is fixed.
  198. * We will need to keep this in for a while to provide backwards compatibility
  199. * for people running old versions of Nodequeue.
  200. *
  201. * @return array
  202. * A array of qids, keyed by machine name.
  203. */
  204. function _fe_nodequeue_get_qid_map() {
  205. $map = &drupal_static(__FUNCTION__, array());
  206. if (!$map) {
  207. $result = db_query("SELECT qid, name FROM {nodequeue_queue}");
  208. while ($get = $result->fetchObject()) {
  209. $map[$get->name] = $get->qid;
  210. }
  211. }
  212. return $map;
  213. }
  214. /**
  215. * Return a queue by its machine name.
  216. *
  217. * This is obviously not ideal due to the extra queries, but probably preferable
  218. * to changing current API calls.
  219. *
  220. * This is based on nodequeue_load_queue_by_name() but passes through the
  221. * $bypass_cache flag.
  222. *
  223. * @see nodequeue_load_queue_by_name()
  224. * @see http://drupal.org/node/1964144
  225. *
  226. * @param string $name
  227. * The queue machine name.
  228. * @param bool $bypass_cache
  229. * Boolean value indicating whether to bypass the cache or not.
  230. *
  231. * @return array
  232. * The queue definition, or an empty array if no queue was found with the
  233. * given machine name.
  234. */
  235. function _fe_nodequeue_load_queue_by_name($name, $bypass_cache = FALSE) {
  236. $map = _fe_nodequeue_get_qid_map();
  237. if (isset($map[$name])) {
  238. $queues = nodequeue_load_queues(array($map[$name]), $bypass_cache);
  239. if ($queues) {
  240. return current($queues);
  241. }
  242. }
  243. return array();
  244. }