public static function saveExpo_exist($d, $nid) { $node = node_load($nid); $node->setTitle($d['title']); $node->field_authoremail->setValue($d['email']); $node->field_author_plain->setValue($d['author']); $node->field_public->setValue($d['public']); //tag field_tag Entity reference if (is_array($d['body'])) { $body_value = ['format' => 'rich_html_base', 'value' => $d['body']['value']]; } else { $body_value = ['format' => 'rich_html_base', 'value' => $d['body']]; } //if(is_array($d['body'])) $body_value = $d['body']['value']; //else $body_value = $d['body']; $node->field_body->setValue($body_value); if ($d['featuredimage']) { if (is_array($d['featuredimage'])) { $target_id = $d['featuredimage']['target_id']; if ($node->field_featuredimage) { $node->field_featuredimage->setValue(['target_id' => $target_id]); } } } $node->save(); $fcbundle = 'field_collitem'; $cnt = count($node->{$fcbundle}); for ($i = 0; $i < $cnt; $i++) { $fcid = $node->field_collitem[$i]->value; $fcitem = \Drupal\field_collection\Entity\FieldCollectionItem::load($fcid); $fcitem->delete(); } $node->{$fcbundle} = []; //foreach ($node->{$fcbundle} as $key => $value) { // unset($node->{$fcbundle}[$key]); //} //$node->save(); foreach ($d['collitems'] as $item) { $collitem = ['field_name' => 'field_collitem']; $collitem['field_target'] = array('value' => $item['target']); if ($item['annotation']) { $collitem['field_annotation'] = $item['annotation']; } $fcitem = FieldCollectionItem::create($collitem); $fcitem->setHostEntity($node, false); $node->{$fcitem->bundle()}[] = array('field_collection_item' => $fcitem); $fcitem->save(true); } $node->save(); return $node; }
/** * Submit callback to remove an item from the field UI multiple wrapper. * * When a remove button is submitted, we need to find the item that it * referenced and delete it. Since field UI has the deltas as a straight * unbroken array key, we have to renumber everything down. Since we do this * we *also* need to move all the deltas around in the $form_state->values * and $form_state input so that user changed values follow. This is a bit * of a complicated process. */ public static function removeSubmit($form, FormStateInterface $form_state) { $button = $form_state->getTriggeringElement(); $delta = $button['#delta']; // Where in the form we'll find the parent element. $address = array_slice($button['#array_parents'], 0, -4); $address_state = array_slice($button['#parents'], 0, -3); // Go one level up in the form, to the widgets container. $parent_element = NestedArray::getValue($form, array_merge($address, array('widget'))); $field_name = $parent_element['#field_name']; $parents = $parent_element['#field_parents']; $field_state = static::getWidgetState($parents, $field_name, $form_state); // Go ahead and renumber everything from our delta to the last // item down one. This will overwrite the item being removed. for ($i = $delta; $i <= $field_state['items_count']; $i++) { $old_element_address = array_merge($address, array('widget', $i + 1)); $old_element_state_address = array_merge($address_state, array($i + 1)); $new_element_state_address = array_merge($address_state, array($i)); $moving_element = NestedArray::getValue($form, $old_element_address); $moving_element_value = NestedArray::getValue($form_state->getValues(), $old_element_state_address); $moving_element_input = NestedArray::getValue($form_state->getUserInput(), $old_element_state_address); // Tell the element where it's being moved to. $moving_element['#parents'] = $new_element_state_address; // Move the element around. $form_state->setValueForElement($moving_element, $moving_element_value); $user_input = $form_state->getUserInput(); NestedArray::setValue($user_input, $moving_element['#parents'], $moving_element_input); $form_state->setUserInput($user_input); // Move the entity in our saved state. if (isset($field_state['field_collection_item'][$i + 1])) { $field_state['field_collection_item'][$i] = $field_state['field_collection_item'][$i + 1]; } else { unset($field_state['field_collection_item'][$i]); } } // Replace the deleted entity with an empty one. This helps to ensure that // trying to add a new entity won't ressurect a deleted entity from the // trash bin. $count = count($field_state['field_collection_item']); $field_state['field_collection_item'][$count] = FieldCollectionItem::create(['field_name' => $field_name]); // Then remove the last item. But we must not go negative. if ($field_state['items_count'] > 0) { $field_state['items_count']--; } // Fix the weights. Field UI lets the weights be in a range of // (-1 * item_count) to (item_count). This means that when we remove one, // the range shrinks; weights outside of that range then get set to // the first item in the select by the browser, floating them to the top. // We use a brute force method because we lost weights on both ends // and if the user has moved things around, we have to cascade because // if I have items weight weights 3 and 4, and I change 4 to 3 but leave // the 3, the order of the two 3s now is undefined and may not match what // the user had selected. $input = NestedArray::getValue($form_state->getUserInput(), $address); // Sort by weight. uasort($input, '_field_collection_sort_items_helper'); // Reweight everything in the correct order. $weight = -1 * $field_state['items_count']; foreach ($input as $key => $item) { if ($item) { $input[$key]['_weight'] = $weight++; } } $user_input = $form_state->getUserInput(); NestedArray::setValue($user_input, $address, $input); $form_state->setUserInput($user_input); static::setWidgetState($parents, $field_name, $form_state, $field_state); $form_state->setRebuild(); }
public function getFieldCollectionItem($create = FALSE) { if (isset($this->field_collection_item)) { return $this->field_collection_item; } elseif (isset($this->value)) { // By default always load the default revision, so caches get used. $field_collection_item = FieldCollectionItem::load($this->value); if ($field_collection_item !== NULL && $field_collection_item->getRevisionId() != $this->revision_id) { // A non-default revision is a referenced, so load this one. $field_collection_item = \Drupal::entityTypeManager()->getStorage('field_collection_item')->loadRevision($this->revision_id); } return $field_collection_item; } elseif ($create) { $field_collection_item = FieldCollectionItem::create(['field_name' => $this->getFieldDefinition()->getName()]); // TODO: Uncomment or delete /* $field_collection_item->setHostEntity($this->getEntity(), FALSE); */ return $field_collection_item; } return FALSE; }
/** * Tests CRUD. */ public function testCRUD() { /** @var \Drupal\node\NodeInterface $node */ /** @var \Drupal\field_collection\FieldCollectionItemInterface $field_collection_item */ list($node, $field_collection_item) = $this->createNodeWithFieldCollection('article'); $this->assertEqual($field_collection_item->id(), $node->{$this->field_collection_name}->value); $this->assertEqual($field_collection_item->revision_id->value, $node->{$this->field_collection_name}->revision_id); // Test adding an additional field_collection_item. $field_collection_item_2 = FieldCollectionItem::create(['field_name' => $this->field_collection_name]); $field_collection_item_2->{$this->inner_field_name}->setValue(2); $node->{$this->field_collection_name}[1] = array('field_collection_item' => $field_collection_item_2); $node->save(); $this->nodeStorage->resetCache([$node->id()]); $node = Node::load($node->id()); $this->assertTrue(!empty($field_collection_item_2->id()) && !empty($field_collection_item_2->getRevisionId())); $this->assertEqual(count(FieldCollectionItem::loadMultiple()), 2); $this->assertEqual($field_collection_item->id(), $node->{$this->field_collection_name}->value); $this->assertEqual($field_collection_item->getRevisionId(), $node->{$this->field_collection_name}[0]->revision_id); $this->assertEqual($field_collection_item_2->id(), $node->{$this->field_collection_name}[1]->value); $this->assertEqual($field_collection_item_2->getRevisionId(), $node->{$this->field_collection_name}[1]->revision_id); // Make sure deleting the field collection item removes the reference. $field_collection_item_2->delete(); $this->nodeStorage->resetCache([$node->id()]); $node = Node::load($node->id()); $this->assertTrue(!isset($node->{$this->field_collection_name}[1])); // Make sure field_collections are removed during deletion of the host. $node->delete(); $this->assertIdentical(FieldCollectionItem::loadMultiple(), array()); // Try deleting nodes with collections without any values. $node = $this->drupalCreateNode(array('type' => 'article')); $node->delete(); $this->nodeStorage->resetCache([$node->id()]); $node = Node::load($node->id()); $this->assertFalse($node); // Test creating a field collection entity with a not-yet saved host entity. $node = $this->drupalCreateNode(array('type' => 'article')); $field_collection_item = FieldCollectionItem::create(['field_name' => $this->field_collection_name]); $field_collection_item->{$this->inner_field_name}->setValue(3); $field_collection_item->setHostEntity($node); $field_collection_item->save(); // Now the node should have been saved with the collection and the link // should have been established. $this->assertTrue(!empty($node->id())); $this->assertTrue(count($node->{$this->field_collection_name}) == 1 && !empty($node->{$this->field_collection_name}[0]->value) && !empty($node->{$this->field_collection_name}[0]->revision_id)); // Again, test creating a field collection with a not-yet saved host entity, // but this time save both entities via the host. $node = $this->drupalCreateNode(array('type' => 'article')); $field_collection_item = FieldCollectionItem::create(array('field_name' => $this->field_collection_name)); $field_collection_item->{$this->inner_field_name}->setValue(4); $field_collection_item->setHostEntity($node); $node->save(); $this->assertTrue(!empty($field_collection_item->id()) && !empty($field_collection_item->getRevisionId())); $this->assertTrue(count($node->{$this->field_collection_name}) == 1 && !empty($node->{$this->field_collection_name}[0]->value) && !empty($node->{$this->field_collection_name}[0]->revision_id)); }