danielebarchiesi@4: $value) { danielebarchiesi@4: $instance = $value['instance']; danielebarchiesi@4: if (empty($instance['settings']['behaviors']['prepopulate']['status'])) { danielebarchiesi@4: continue; danielebarchiesi@4: } danielebarchiesi@4: $settings = $instance['settings']['behaviors']['prepopulate']; danielebarchiesi@4: danielebarchiesi@4: if ((!empty($settings['skip_perm']) && user_access($settings['skip_perm'])) || ($id && empty($settings['action_on_edit']))) { danielebarchiesi@4: // User has access to skip the action, or the entity is already danielebarchiesi@4: // saved, but "Apply action on edit", is disabled. danielebarchiesi@4: continue; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: $field = $value['field']; danielebarchiesi@4: danielebarchiesi@4: // Store prepopulated values in the form state to make them persistent, danielebarchiesi@4: // in case the form is rebuilt by AJAX requests. danielebarchiesi@4: $field_name = $field['field_name']; danielebarchiesi@4: danielebarchiesi@4: if ($ids = entityreference_prepopulate_get_values($field, $instance)) { danielebarchiesi@4: $form_state['entityreference_prepopulate'][$instance['entity_type']][$instance['bundle']][$field_name] = $ids; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: if ($ids || ($id && !empty($settings['action_on_edit']))) { danielebarchiesi@4: // New entity with prepopualte values, or an existing entity, danielebarchiesi@4: // we might need to disable/ hide the group-audience field. danielebarchiesi@4: if ($settings['action'] == 'disable') { danielebarchiesi@4: $form[$field_name][$lang]['#disabled'] = TRUE; danielebarchiesi@4: } danielebarchiesi@4: elseif ($settings['action'] == 'hide') { danielebarchiesi@4: // We don't hide the field via hook_field_access(), as the danielebarchiesi@4: // default value won't be set. danielebarchiesi@4: $form[$field_name]['#access'] = FALSE; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: elseif (in_array($settings['fallback'], array('form_error', 'redirect'))) { danielebarchiesi@4: $message = t('Field @label must be populated via URL.', array('@label' => $instance['label'])); danielebarchiesi@4: if ($settings['fallback'] == 'form_error') { danielebarchiesi@4: form_error($form, $message); danielebarchiesi@4: } danielebarchiesi@4: elseif ($settings['fallback'] == 'redirect') { danielebarchiesi@4: drupal_set_message($message, 'notice'); danielebarchiesi@4: drupal_goto(); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Implements hook_field_access(). danielebarchiesi@4: */ danielebarchiesi@4: function entityreference_prepopulate_field_access($op, $field, $entity_type, $entity, $account) { danielebarchiesi@4: if ($op != 'edit' || $field['type'] != 'entityreference') { danielebarchiesi@4: return; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: if (empty($entity)) { danielebarchiesi@4: // $entity might be NULL, so return early. danielebarchiesi@4: // @see field_access(). danielebarchiesi@4: return; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: list($id,,$bundle) = entity_extract_ids($entity_type, $entity); danielebarchiesi@4: if ($id) { danielebarchiesi@4: // Entity is already saved. danielebarchiesi@4: return; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: $instance = field_info_instance($entity_type, $field['field_name'], $bundle); danielebarchiesi@4: if (empty($instance['settings']['behaviors']['prepopulate']['status'])) { danielebarchiesi@4: return; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: $settings = $instance['settings']['behaviors']['prepopulate']; danielebarchiesi@4: if (!empty($settings['skip_perm']) && user_access($settings['skip_perm'])) { danielebarchiesi@4: return; danielebarchiesi@4: } danielebarchiesi@4: $ids = entityreference_prepopulate_get_values($field, $instance); danielebarchiesi@4: danielebarchiesi@4: if (!$ids && $settings['fallback'] == 'hide') { danielebarchiesi@4: return FALSE; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Field default value callback. danielebarchiesi@4: * danielebarchiesi@4: * Set the default from the URL context. This works even if the widget is danielebarchiesi@4: * not shown, e.g. due to restricted field access. danielebarchiesi@4: * danielebarchiesi@4: * @todo Check field cardinality. danielebarchiesi@4: */ danielebarchiesi@4: function entityreference_prepopulate_field_default_value($entity_type, $entity, $field, $instance, $langcode) { danielebarchiesi@4: $items = array(); danielebarchiesi@4: if ($ids = entityreference_prepopulate_get_values($field, $instance)) { danielebarchiesi@4: $items = array(); danielebarchiesi@4: foreach ($ids as $id) { danielebarchiesi@4: $items[] = array('target_id' => $id); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: return $items; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Wrapper function to get context (e.g. from URL or OG-context). danielebarchiesi@4: * danielebarchiesi@4: * @param $entity_type danielebarchiesi@4: * The entity type the entity. danielebarchiesi@4: * @param $entity danielebarchiesi@4: * The entity object that is being checked. danielebarchiesi@4: * @param $field danielebarchiesi@4: * The field info array. danielebarchiesi@4: * @param $instance danielebarchiesi@4: * The instance info array. danielebarchiesi@4: * @param $validate danielebarchiesi@4: * Determine if access validation should be performed. Defaults to TRUE. danielebarchiesi@4: * danielebarchiesi@4: * @return danielebarchiesi@4: * Array of IDs a user may view. danielebarchiesi@4: */ danielebarchiesi@4: function entityreference_prepopulate_get_values($field, $instance, $validate = TRUE) { danielebarchiesi@4: if (!$instance['settings']['behaviors']['prepopulate']['status']) { danielebarchiesi@4: // Do nothing when prepopulate is disabled for this field. danielebarchiesi@4: return; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: $field_name = $field['field_name']; danielebarchiesi@4: danielebarchiesi@4: $cache = &drupal_static(__FUNCTION__, array()); danielebarchiesi@4: $identifier = array( danielebarchiesi@4: $instance['entity_type'], danielebarchiesi@4: $instance['bundle'], danielebarchiesi@4: $field_name, danielebarchiesi@4: $validate, danielebarchiesi@4: ); danielebarchiesi@4: danielebarchiesi@4: if (module_exists('og') && og_is_group_audience_field($field_name)) { danielebarchiesi@4: if (empty($instance['field_mode'])) { danielebarchiesi@4: // Group audience field, but no field-mode provided. danielebarchiesi@4: // So we iterate over the "default" and possibly "admin" field-modes, danielebarchiesi@4: // and return those values together. danielebarchiesi@4: $ids = array(); danielebarchiesi@4: $field_modes = !user_access('administer group') ? array('default') : array('default', 'admin'); danielebarchiesi@4: foreach ($field_modes as $field_mode) { danielebarchiesi@4: $instance['field_mode'] = $field_mode; danielebarchiesi@4: if ($og_ids = entityreference_prepopulate_get_values($field, $instance)) { danielebarchiesi@4: $ids = array_merge($ids, $og_ids); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // Return the values. danielebarchiesi@4: return $ids; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: $identifier[] = $instance['field_mode']; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: $identifier = implode(':', $identifier); danielebarchiesi@4: danielebarchiesi@4: if (isset($cache[$identifier])) { danielebarchiesi@4: return $cache[$identifier]; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: $cache[$identifier] = $ids = array(); danielebarchiesi@4: danielebarchiesi@4: // Check if we have cached values. danielebarchiesi@4: if (!$ids) { danielebarchiesi@4: $ids = entityreference_prepopulate_get_values_from_cache($field, $instance); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // Check if we have OG-context integration. danielebarchiesi@4: if (!$ids) { danielebarchiesi@4: $ids = entityreference_prepopulate_get_values_from_og_context($field, $instance); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // Check if there are values in the URL. danielebarchiesi@4: if (!$ids) { danielebarchiesi@4: $ids = entityreference_prepopulate_get_values_from_url($field, $instance); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: if (!$ids || !$validate) { danielebarchiesi@4: // No IDs found, or no validation is needed. danielebarchiesi@4: $cache[$identifier] = $ids; danielebarchiesi@4: return $ids; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: $handler = entityreference_get_selection_handler($field, $instance); danielebarchiesi@4: if (!$ids = $handler->validateReferencableEntities($ids)) { danielebarchiesi@4: $cache[$identifier] = FALSE; danielebarchiesi@4: return; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // Check access to the provided entities. danielebarchiesi@4: $target_type = $field['settings']['target_type']; danielebarchiesi@4: entity_load($target_type, $ids); danielebarchiesi@4: foreach ($ids as $delta => $id) { danielebarchiesi@4: $entity = entity_load_single($target_type, $id); danielebarchiesi@4: if (!$entity || !entity_access('view', $target_type, $entity)) { danielebarchiesi@4: unset($ids[$delta]); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: $cache[$identifier] = $ids; danielebarchiesi@4: return $ids; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Get the values from the cached form. danielebarchiesi@4: * danielebarchiesi@4: * @param $field danielebarchiesi@4: * The field info array. danielebarchiesi@4: * @param $instance danielebarchiesi@4: * The instance info array. danielebarchiesi@4: * danielebarchiesi@4: * @see danielebarchiesi@4: * entityreference_prepopulate_get_values() danielebarchiesi@4: */ danielebarchiesi@4: function entityreference_prepopulate_get_values_from_cache($field, $instance) { danielebarchiesi@4: // Try to get the form out of cache. danielebarchiesi@4: if (!$form_build_id = isset($_GET['form_build_id']) ? $_GET['form_build_id'] : isset($_POST['form_build_id']) ? $_POST['form_build_id'] : NULL) { danielebarchiesi@4: return; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: $field_name = $field['field_name']; danielebarchiesi@4: danielebarchiesi@4: $form_state = array(); danielebarchiesi@4: form_get_cache($form_build_id, $form_state); danielebarchiesi@4: danielebarchiesi@4: // If successful, get the value from the form_state. danielebarchiesi@4: return isset($form_state['entityreference_prepopulate'][$instance['entity_type']][$instance['bundle']][$field_name]) ? $form_state['entityreference_prepopulate'][$instance['entity_type']][$instance['bundle']][$field_name] : FALSE; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Get values for prepopulating fields via URL. danielebarchiesi@4: * danielebarchiesi@4: * @param $field danielebarchiesi@4: * The field info array. danielebarchiesi@4: * @param $instance danielebarchiesi@4: * The instance info array. danielebarchiesi@4: * danielebarchiesi@4: * @see danielebarchiesi@4: * entityreference_prepopulate_get_values() danielebarchiesi@4: */ danielebarchiesi@4: function entityreference_prepopulate_get_values_from_url($field, $instance) { danielebarchiesi@4: $field_name = $field['field_name']; danielebarchiesi@4: if (!empty($_GET[$field_name]) && is_string($_GET[$field_name])) { danielebarchiesi@4: return explode(',', $_GET[$field_name]); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Get values for prepopulating fields OG-context. danielebarchiesi@4: * danielebarchiesi@4: * @param $field danielebarchiesi@4: * The field info array. danielebarchiesi@4: * @param $instance danielebarchiesi@4: * The instance info array. danielebarchiesi@4: * danielebarchiesi@4: * @see danielebarchiesi@4: * entityreference_prepopulate_get_values() danielebarchiesi@4: */ danielebarchiesi@4: function entityreference_prepopulate_get_values_from_og_context($field, $instance) { danielebarchiesi@4: $field_name = $field['field_name']; danielebarchiesi@4: danielebarchiesi@4: if (!module_exists('og_context') || !og_is_group_audience_field($field_name) || !$og_context = og_context()) { danielebarchiesi@4: return; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: if ($og_context['group_type'] != $field['settings']['target_type']) { danielebarchiesi@4: // Context is of invalid group-type. danielebarchiesi@4: return; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: return array($og_context['gid']); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Return a form element with crafted links to create nodes for a group. danielebarchiesi@4: * danielebarchiesi@4: * @param $entity_type danielebarchiesi@4: * The entity type of the referenced entity. danielebarchiesi@4: * @param $entity_id danielebarchiesi@4: * The entity ID of the referenced entity. danielebarchiesi@4: * @param $destination danielebarchiesi@4: * Optional; The destination after a node is created. Defaults to the danielebarchiesi@4: * destination passed in the URL if exists, otherwise back to the current danielebarchiesi@4: * page. danielebarchiesi@4: * @param $types danielebarchiesi@4: * Optional; An array of type names. Restrict the created links to the given danielebarchiesi@4: * types. danielebarchiesi@4: */ danielebarchiesi@4: function entityreference_prepopulate_create_node_links($entity_type, $entity_id, $field_name, $destination = NULL, $types = NULL) { danielebarchiesi@4: $wrapper = entity_metadata_wrapper($entity_type, $entity_id); danielebarchiesi@4: $field = field_info_field($field_name); danielebarchiesi@4: danielebarchiesi@4: $entity = entity_load_single($entity_type, $entity_id); danielebarchiesi@4: list(,, $bundle) = entity_extract_ids($entity_type, $entity); danielebarchiesi@4: danielebarchiesi@4: $types = isset($types) ? $types : array_keys(node_type_get_types()); danielebarchiesi@4: $names = array(); danielebarchiesi@4: foreach ($types as $type_name) { danielebarchiesi@4: if ($field['settings']['target_type'] != $entity_type) { danielebarchiesi@4: // The entity type isn't referenced by the field. danielebarchiesi@4: continue; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: if (!empty($field['settings']['handler_settings']['target_bundles']) && !in_array($bundle, $field['settings']['handler_settings']['target_bundles'])) { danielebarchiesi@4: // The entity bundle isn't referenced by the field. danielebarchiesi@4: continue; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: $instance = field_info_instance('node', $field_name, $type_name); danielebarchiesi@4: if (empty($instance['settings']['behaviors']['prepopulate']['status'])) { danielebarchiesi@4: // The field doesn't exist on the node type, or doesn't have prepopulate danielebarchiesi@4: // enabled. danielebarchiesi@4: continue; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: if (!node_access('create', $type_name)) { danielebarchiesi@4: continue; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: $names[$type_name] = node_type_get_name($type_name); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: if (empty($names)) { danielebarchiesi@4: return; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // Sort names. danielebarchiesi@4: asort($names); danielebarchiesi@4: danielebarchiesi@4: // Build links. danielebarchiesi@4: $options = array( danielebarchiesi@4: 'query' => array($field_name => $entity_id) + drupal_get_destination(), danielebarchiesi@4: ); danielebarchiesi@4: danielebarchiesi@4: $items = array(); danielebarchiesi@4: foreach ($names as $type => $name) { danielebarchiesi@4: $items[] = array('data' => l($name, 'node/add/' . str_replace('_', '-', $type), $options)); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: $element = array(); danielebarchiesi@4: $element['entityreference_prepopulate'] = array( danielebarchiesi@4: '#theme' => 'item_list', danielebarchiesi@4: '#items' => $items, danielebarchiesi@4: ); danielebarchiesi@4: danielebarchiesi@4: return $element; danielebarchiesi@4: }