wing.module 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <?php
  2. /**
  3. * @file
  4. * Workflow - New Generation
  5. *
  6. * - States are entities
  7. * - Worfklows are the bundle entities of states
  8. * - Transitions are fields on states, storing a (rid, sid) pair per item
  9. * - Any entity type can be subject to a workflow: association is represented by
  10. * an entityreference field whose widget uses a specific view to list the
  11. * relevant states
  12. * - Workflow access is handled by field access using the permission associated
  13. * with a state, one "view" or "edit" permission per state entity
  14. *
  15. * URL structure admin/structure/wing/...
  16. * /: dashboard
  17. * /settings: module settings
  18. * /add: workflow creation form
  19. * /workflow[/list]: list of workflows
  20. * /workflow/add: state creation form
  21. * /workflow/<wname>[/info]: info on workflow with list of states
  22. * /workflow/<wname>/edit|clone|delete|export: workflow operations form
  23. * /workflow/<wname>/fields: field UI for workflow as state bundle
  24. * /workflow/<wname>/fields: view modes for workflow as state bundle
  25. * /state[/list]: list of states
  26. * /state/<sname>[/info]: info on state, with list of previous/next states
  27. * and list of entities in state
  28. * /state/<sname>/edit|clone|delete|export
  29. * state operations form. Main point of interest is the transitions subform
  30. */
  31. /**
  32. * Implements hook_entity_info().
  33. */
  34. function wing_entity_info() {
  35. $ret = array();
  36. $ret['wing_workflow'] = array(
  37. 'access callback' => 'wing_workflow_access',
  38. 'admin ui' => array(
  39. 'controller class' => 'WingWorkflowUIController',
  40. // 'file' => '',
  41. // 'file path' => '',
  42. 'menu wildcard' => '%entity_object',
  43. 'path' => 'admin/content/wing/workflow'
  44. ),
  45. 'base table' => 'wing_workflow',
  46. 'bundle of' => 'wing_state',
  47. 'controller class' => 'WingWorkflowController',
  48. 'entity class' => 'WingWorkflow',
  49. 'entity keys' => array(
  50. 'id' => 'wid',
  51. 'label' => 'title',
  52. 'module' => 'module',
  53. 'name' => 'name',
  54. 'status' => 'status',
  55. ),
  56. 'export' => array(
  57. 'default hook' => 'default_wing_workflows',
  58. ),
  59. 'exportable' => TRUE,
  60. 'features controller class' => 'WingWorkflowFeaturesController',
  61. 'fieldable' => FALSE,
  62. 'label' => t('Wing: Workflow'),
  63. 'label callback' => 'entity_class_label',
  64. 'load hook' => 'wing_workflow_load', // Enable hook_workflow_load().
  65. 'module' => 'wing',
  66. 'uri callback' => 'entity_class_uri',
  67. 'view modes' => array(
  68. 'full' => array(
  69. 'label' => t('Full'),
  70. 'custom settings' => FALSE,
  71. ),
  72. 'summary' => array(
  73. 'label' => t('Summary'),
  74. 'custom settings' => FALSE,
  75. ),
  76. 'simple' => array(
  77. 'label' => t('Simple'),
  78. 'custom settings' => FALSE,
  79. ),
  80. ),
  81. 'views controller class' => 'WingWorkflowViewsController',
  82. );
  83. $ret['wing_state'] = array(
  84. 'access callback' => 'wing_state_access',
  85. 'admin ui' => array(
  86. 'controller class' => 'WingStateUIController',
  87. // 'file' => '',
  88. // 'file path' => '',
  89. 'menu wildcard' => '%entity_object',
  90. 'path' => 'admin/content/wing/state/%entity_object'
  91. ),
  92. 'base table' => 'wing_state',
  93. 'bundle keys' => array('bundle' => 'workflow'),
  94. 'bundles' => array(),
  95. 'controller class' => 'WingStateController',
  96. 'entity class' => 'WingState',
  97. 'entity keys' => array(
  98. 'id' => 'sid',
  99. 'bundle' => 'workflow',
  100. 'label' => 'title',
  101. 'module' => 'module',
  102. 'name' => 'name',
  103. 'status' => 'status',
  104. ),
  105. 'export' => array(
  106. 'default_hook' => 'default_wing_states',
  107. ),
  108. 'exportable' => TRUE,
  109. 'features controller class' => 'WingStateFeaturesController',
  110. 'fieldable' => TRUE,
  111. 'label' => t('Wing: State'),
  112. 'label callback' => 'entity_class_label',
  113. 'load hook' => 'wing_state_load',
  114. 'module' => 'wing',
  115. 'uri callback' => 'entity_class_uri',
  116. 'view modes' => array(
  117. 'full' => array(
  118. 'label' => t('Full'),
  119. 'custom settings' => FALSE,
  120. ),
  121. 'summary' => array(
  122. 'label' => t('Summary'),
  123. 'custom settings' => FALSE,
  124. ),
  125. 'simple' => array(
  126. 'label' => t('Simple'),
  127. 'custom settings' => FALSE,
  128. ),
  129. ),
  130. 'views controller class' => 'WingStateViewsController',
  131. );
  132. // Add bundle info but bypass entity_load() as we cannot use it here.
  133. $workflows = db_select('wing_workflow', 'ww')
  134. ->fields('ww')
  135. ->execute()
  136. ->fetchAllAssoc('name');
  137. foreach ($workflows as $workflow_name => $workflow) {
  138. $ret['wing_state']['bundles'][$workflow_name] = array(
  139. 'label' => $workflow->title,
  140. 'admin' => array(
  141. 'path' => 'admin/content/wing/workflow/%entity_object',
  142. 'real path' => 'admin/content/wing/workflow/' . $workflow_name,
  143. 'bundle argument' => 4,
  144. 'access arguments' => array('administer wing'),
  145. ),
  146. );
  147. }
  148. return $ret;
  149. }
  150. /**
  151. * Implements hook_field_info().
  152. *
  153. * Define "wing_transition" as a UI-less field.
  154. */
  155. function wing_field_info() {
  156. $ret = array(
  157. 'wing_transition' => array(
  158. 'label' => t('Wing: Transition'),
  159. 'description' => t('Store access from one workflow state to another.'),
  160. 'settings' => array(),
  161. 'instance_settings' => array(),
  162. 'default_widget' => 'text_textfield',
  163. 'default_formatter' => 'text_default',
  164. // 'default_widget' => 'wing_transition_widget',
  165. // 'default_formatter' => 'wing_transition_default',
  166. // 'no_ui' => FALSE,
  167. ),
  168. );
  169. dsm($ret);
  170. return $ret;
  171. }
  172. /**
  173. * Implements hook_field_widget_info().
  174. */
  175. function wing_field_widget_info() {
  176. $ret = array(
  177. 'text_textfield' => array(
  178. 'label' => t('Text field'),
  179. 'field types' => array('text'),
  180. 'settings' => array('size' => 60),
  181. 'behaviors' => array(
  182. 'multiple values' => FIELD_BEHAVIOR_DEFAULT,
  183. 'default value' => FIELD_BEHAVIOR_DEFAULT,
  184. ),
  185. ),
  186. );
  187. return $ret;
  188. }
  189. /**
  190. * Implements hook_field_widget_info_alter().
  191. */
  192. function wing_field_widget_info_alter(&$info) {
  193. if (module_exists('text')) {
  194. $info['text_textfield']['field types'][] = 'wing_transition';
  195. }
  196. }
  197. /**
  198. * Implements hook_menu().
  199. */
  200. function wing_menu() {
  201. $items = array();
  202. $items['admin/content/wing'] = array(
  203. 'title' => 'Wing',
  204. 'access arguments' => array('administer wing'),
  205. 'page callback' => 'wing_overview',
  206. 'file' => 'wing.pages.inc',
  207. );
  208. $items['admin/content/wing/info'] = array(
  209. 'title' => 'Info',
  210. 'type' => MENU_DEFAULT_LOCAL_TASK,
  211. );
  212. $items['admin/content/wing/settings'] = array(
  213. 'title' => 'Settings',
  214. 'type' => MENU_LOCAL_TASK,
  215. 'page callback' => 'drupal_get_form',
  216. 'page arguments' => array('wing_settings_form'),
  217. 'file' => 'wing.admin.inc',
  218. 'access arguments' => array('administer wing'),
  219. );
  220. return $items;
  221. }
  222. /**
  223. * Implements hook_permission().
  224. */
  225. function wing_permission() {
  226. $ret = array(
  227. 'administer wing' => array(
  228. 'title' => t('Administer Wing'),
  229. 'description' => t('Perform administration tasks for Wing.'),
  230. ),
  231. );
  232. return $ret;
  233. }
  234. /**
  235. * Entity access callback for wing_state.
  236. *
  237. * @param string $op
  238. * 'create', 'update', 'delete' or 'view'
  239. * @param WingState $entity
  240. * @param stdClass $account
  241. * @param string $entity_type
  242. *
  243. * @return boolean
  244. */
  245. function wing_state_access($op, $entity, $account, $entity_type) {
  246. dsm(get_defined_vars(), __FUNCTION__);
  247. return TRUE;
  248. }
  249. /**
  250. * Entity access callback for wing_workflow.
  251. *
  252. * @param string $op
  253. * 'create', 'update', 'delete' or 'view'
  254. * @param WingWorkflow $entity
  255. * @param stdClass $account
  256. * @param string $entity_type
  257. *
  258. * @return boolean
  259. */
  260. function wing_workflow_access($op, $entity, $account, $entity_type) {
  261. dsm(get_defined_vars(), __FUNCTION__);
  262. return TRUE;
  263. }