hs_smallhierarchy.module 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. /**
  3. * @file
  4. * Implementation of the Hierarchical Select API that allows one to use a
  5. * hardcoded hierarchy. When it becomes to slow, you should move the hierarchy
  6. * into the database and write a proper implementation.
  7. */
  8. //----------------------------------------------------------------------------
  9. // Hierarchical Select hooks.
  10. /**
  11. * Implementation of hook_hierarchical_select_params().
  12. */
  13. function hs_smallhierarchy_hierarchical_select_params() {
  14. $params = array(
  15. 'hierarchy',
  16. 'id',
  17. 'separator',
  18. );
  19. return $params;
  20. }
  21. /**
  22. * Implementation of hook_hierarchical_select_root_level().
  23. */
  24. function hs_smallhierarchy_hierarchical_select_root_level($params) {
  25. $hierarchy = _hs_smallhierarchy_transform($params['hierarchy'], $params['id'], $params['separator']);
  26. $children = $hierarchy['root']['children'];
  27. $level = array();
  28. foreach ($children as $item) {
  29. $level[$item] = $hierarchy[$item]['label'];
  30. }
  31. return $level;
  32. }
  33. /**
  34. * Implementation of hook_hierarchical_select_children().
  35. */
  36. function hs_smallhierarchy_hierarchical_select_children($parent, $params) {
  37. $hierarchy = _hs_smallhierarchy_transform($params['hierarchy'], $params['id'], $params['separator']);
  38. $children = (isset($hierarchy[$parent]['children'])) ? $hierarchy[$parent]['children'] : array();
  39. $level = array();
  40. foreach ($children as $item) {
  41. $level[$item] = $hierarchy[$item]['label'];
  42. }
  43. return $level;
  44. }
  45. /**
  46. * Implementation of hook_hierarchical_select_lineage().
  47. */
  48. function hs_smallhierarchy_hierarchical_select_lineage($item, $params) {
  49. $parts = explode($params['separator'], $item);
  50. $lineage = array();
  51. for ($i = 0; $i < count($parts); $i++) {
  52. $lineage[$i] = implode($params['separator'], array_slice($parts, 0, $i + 1));
  53. }
  54. return $lineage;
  55. }
  56. /**
  57. * Implementation of hook_hierarchical_select_valid_item().
  58. */
  59. function hs_smallhierarchy_hierarchical_select_valid_item($item, $params) {
  60. $hierarchy = _hs_smallhierarchy_transform($params['hierarchy'], $params['id'], $params['separator']);
  61. // All valid items are in the keys of the $hierarchy array. Only the fake
  62. // "root" item is not a valid item.
  63. $items = array_keys($hierarchy);
  64. unset($items['root']);
  65. return (in_array($item, $items));
  66. }
  67. /**
  68. * Implementation of hook_hierarchical_select_item_get_label().
  69. */
  70. function hs_smallhierarchy_hierarchical_select_item_get_label($item, $params) {
  71. $hierarchy = _hs_smallhierarchy_transform($params['hierarchy'], $params['id'], $params['separator']);
  72. return $hierarchy[$item]['label'];
  73. }
  74. /**
  75. * Implementation of hook_hierarchical_select_implementation_info().
  76. */
  77. function hs_smallhierarchy_hierarchical_select_implementation_info() {
  78. return array(
  79. 'hierarchy type' => t('Custom'),
  80. 'entity type' => t('N/A'),
  81. );
  82. }
  83. //----------------------------------------------------------------------------
  84. // Private functions.
  85. /**
  86. * Automatically transform a given hierarchy with this format:
  87. * array(
  88. * 'win' => array(
  89. * 'label' => 'Windows',
  90. * 'children' => array(
  91. * 'xp' => array('label' => 'XP'),
  92. * 'vista' => array(
  93. * 'label' => 'Vista',
  94. * 'children' => array(
  95. * 'x86' => array('label' => '32-bits'),
  96. * 'x64' => array('label' => '64-bits'),
  97. * ),
  98. * ),
  99. * ),
  100. * ),
  101. * )
  102. *
  103. * to one with this format:
  104. * array(
  105. * 'root' => array(
  106. * 'children' => array(
  107. * 'xp',
  108. * 'vista',
  109. * ),
  110. * ),
  111. * 'win' => array(
  112. * 'label' => 'Windows',
  113. * 'children' => array(
  114. * 'win|xp',
  115. * 'win|vista',
  116. * ),
  117. * ),
  118. * 'win|xp' => array(
  119. * 'label' => 'XP',
  120. * ),
  121. * 'win|vista' => array(
  122. * 'label' => 'Vista',
  123. * 'children' => array(
  124. * 'win|vista|x86',
  125. * 'win|vista|x64',
  126. * ),
  127. * ),
  128. * 'win|vista|x86' => array(
  129. * 'label' => '32-bits',
  130. * ),
  131. * 'win|vista|x64' => array(
  132. * 'label' => '64-bits',
  133. * ),
  134. * )
  135. *
  136. * This new format:
  137. * - ensures unique identifiers for each item
  138. * - makes it very easy to find the parent of a given item.
  139. * - makes it very easy to find the label and children of a given item.
  140. *
  141. * @params $hierarchy
  142. * The hierarchy.
  143. * @params $id
  144. * A unique identifier for the hierarchy, for caching purposes.
  145. * @params $separator
  146. * The separator to use.
  147. */
  148. function _hs_smallhierarchy_transform($hierarchy, $id, $separator = '|') {
  149. // Make sure each hierarchy is only transformed once.
  150. if (!isset($hs_hierarchy[$id])) {
  151. $hs_hierarchy[$id] = array();
  152. // Build the root level.
  153. foreach ($hierarchy as $item => $children) {
  154. $hs_hierarchy[$id]['root']['children'][] = $item;
  155. $hs_hierarchy[$id][$item]['label'] = $children['label'];
  156. // Build the subsequent levels.
  157. if (isset($children['children'])) {
  158. _hs_smallhierarchy_transform_recurse($item, $hs_hierarchy[$id], $children['children'], $separator);
  159. }
  160. }
  161. }
  162. return $hs_hierarchy[$id];
  163. }
  164. /**
  165. * Helper function for _hs_smallhierarchy_transform().
  166. *
  167. * @params $parent
  168. * The parent item of the current level.
  169. * @params $hs_hierarchy
  170. * The HS hierarchy.
  171. * @params $relative_hierarchy
  172. * The hierarchy relative to the current level.
  173. * @params $separator
  174. * The separator to use.
  175. */
  176. function _hs_smallhierarchy_transform_recurse($parent, &$hs_hierarchy, $relative_hierarchy, $separator = '|') {
  177. foreach ($relative_hierarchy as $item => $children) {
  178. $generated_item = $parent . $separator . $item;
  179. $hs_hierarchy[$parent]['children'][] = $generated_item;
  180. $hs_hierarchy[$generated_item]['label'] = $children['label'];
  181. // Build the subsequent levels.
  182. if (isset($children['children'])) {
  183. _hs_smallhierarchy_transform_recurse($generated_item, $hs_hierarchy, $children['children'], $separator);
  184. }
  185. }
  186. }