[/info]: info on workflow with list of states * /workflow//edit|clone|delete|export: workflow operations form * /workflow//fields: field UI for workflow as state bundle * /workflow//fields: view modes for workflow as state bundle * /state[/list]: list of states * /state/[/info]: info on state, with list of previous/next states * and list of entities in state * /state//edit|clone|delete|export * state operations form. Main point of interest is the transitions subform */ /** * Implements hook_entity_info(). */ function wing_entity_info() { $ret = array(); $ret['wing_workflow'] = array( 'access callback' => 'wing_workflow_access', 'admin ui' => array( 'controller class' => 'WingWorkflowUIController', // 'file' => '', // 'file path' => '', 'menu wildcard' => '%entity_object', 'path' => 'admin/content/wing/workflow' ), 'base table' => 'wing_workflow', 'bundle of' => 'wing_state', 'controller class' => 'WingWorkflowController', 'entity class' => 'WingWorkflow', 'entity keys' => array( 'id' => 'wid', 'label' => 'title', 'module' => 'module', 'name' => 'name', 'status' => 'status', ), 'export' => array( 'default hook' => 'default_wing_workflows', ), 'exportable' => TRUE, 'features controller class' => 'WingWorkflowFeaturesController', 'fieldable' => FALSE, 'label' => t('Wing: Workflow'), 'label callback' => 'entity_class_label', 'load hook' => 'wing_workflow_load', // Enable hook_workflow_load(). 'module' => 'wing', 'uri callback' => 'entity_class_uri', 'view modes' => array( 'full' => array( 'label' => t('Full'), 'custom settings' => FALSE, ), 'summary' => array( 'label' => t('Summary'), 'custom settings' => FALSE, ), 'simple' => array( 'label' => t('Simple'), 'custom settings' => FALSE, ), ), 'views controller class' => 'WingWorkflowViewsController', ); $ret['wing_state'] = array( 'access callback' => 'wing_state_access', 'admin ui' => array( 'controller class' => 'WingStateUIController', // 'file' => '', // 'file path' => '', 'menu wildcard' => '%entity_object', 'path' => 'admin/content/wing/state/%entity_object' ), 'base table' => 'wing_state', 'bundle keys' => array('bundle' => 'workflow'), 'bundles' => array(), 'controller class' => 'WingStateController', 'entity class' => 'WingState', 'entity keys' => array( 'id' => 'sid', 'bundle' => 'workflow', 'label' => 'title', 'module' => 'module', 'name' => 'name', 'status' => 'status', ), 'export' => array( 'default_hook' => 'default_wing_states', ), 'exportable' => TRUE, 'features controller class' => 'WingStateFeaturesController', 'fieldable' => TRUE, 'label' => t('Wing: State'), 'label callback' => 'entity_class_label', 'load hook' => 'wing_state_load', 'module' => 'wing', 'uri callback' => 'entity_class_uri', 'view modes' => array( 'full' => array( 'label' => t('Full'), 'custom settings' => FALSE, ), 'summary' => array( 'label' => t('Summary'), 'custom settings' => FALSE, ), 'simple' => array( 'label' => t('Simple'), 'custom settings' => FALSE, ), ), 'views controller class' => 'WingStateViewsController', ); // Add bundle info but bypass entity_load() as we cannot use it here. $workflows = db_select('wing_workflow', 'ww') ->fields('ww') ->execute() ->fetchAllAssoc('name'); foreach ($workflows as $workflow_name => $workflow) { $ret['wing_state']['bundles'][$workflow_name] = array( 'label' => $workflow->title, 'admin' => array( 'path' => 'admin/content/wing/workflow/%entity_object', 'real path' => 'admin/content/wing/workflow/' . $workflow_name, 'bundle argument' => 4, 'access arguments' => array('administer wing'), ), ); } return $ret; } /** * Implements hook_field_info(). * * Define "wing_transition" as a UI-less field. */ function wing_field_info() { $ret = array( 'wing_transition' => array( 'label' => t('Wing: Transition'), 'description' => t('Store access from one workflow state to another.'), 'settings' => array(), 'instance_settings' => array(), 'default_widget' => 'text_textfield', 'default_formatter' => 'text_default', // 'default_widget' => 'wing_transition_widget', // 'default_formatter' => 'wing_transition_default', // 'no_ui' => FALSE, ), ); dsm($ret); return $ret; } /** * Implements hook_field_widget_info(). */ function wing_field_widget_info() { $ret = array( 'text_textfield' => array( 'label' => t('Text field'), 'field types' => array('text'), 'settings' => array('size' => 60), 'behaviors' => array( 'multiple values' => FIELD_BEHAVIOR_DEFAULT, 'default value' => FIELD_BEHAVIOR_DEFAULT, ), ), ); return $ret; } /** * Implements hook_field_widget_info_alter(). */ function wing_field_widget_info_alter(&$info) { if (module_exists('text')) { $info['text_textfield']['field types'][] = 'wing_transition'; } } /** * Implements hook_menu(). */ function wing_menu() { $items = array(); $items['admin/content/wing'] = array( 'title' => 'Wing', 'access arguments' => array('administer wing'), 'page callback' => 'wing_overview', 'file' => 'wing.pages.inc', ); $items['admin/content/wing/info'] = array( 'title' => 'Info', 'type' => MENU_DEFAULT_LOCAL_TASK, ); $items['admin/content/wing/settings'] = array( 'title' => 'Settings', 'type' => MENU_LOCAL_TASK, 'page callback' => 'drupal_get_form', 'page arguments' => array('wing_settings_form'), 'file' => 'wing.admin.inc', 'access arguments' => array('administer wing'), ); return $items; } /** * Implements hook_permission(). */ function wing_permission() { $ret = array( 'administer wing' => array( 'title' => t('Administer Wing'), 'description' => t('Perform administration tasks for Wing.'), ), ); return $ret; } /** * Entity access callback for wing_state. * * @param string $op * 'create', 'update', 'delete' or 'view' * @param WingState $entity * @param stdClass $account * @param string $entity_type * * @return boolean */ function wing_state_access($op, $entity, $account, $entity_type) { dsm(get_defined_vars(), __FUNCTION__); return TRUE; } /** * Entity access callback for wing_workflow. * * @param string $op * 'create', 'update', 'delete' or 'view' * @param WingWorkflow $entity * @param stdClass $account * @param string $entity_type * * @return boolean */ function wing_workflow_access($op, $entity, $account, $entity_type) { dsm(get_defined_vars(), __FUNCTION__); return TRUE; }