public function testValueChangedEvents()
 {
     $listener = Mockery::mock(ValueChangedListenerInterface::CLASS);
     $listener->shouldReceive('onValueChanged')->with(ValueChangedEvent::CLASS)->twice();
     $article_type = $this->getTypeMock();
     $embed_type = new ParagraphType($article_type, $article_type->getAttribute('content_objects'));
     $embedd_entity = $embed_type->createEntity(['title' => 'Hello world', 'content' => 'Foobar lorem ipsum...']);
     $embed_attribute = new EmbeddedEntityListAttribute(self::ATTR_NAME, $this->getTypeMock(), [EmbeddedEntityListAttribute::OPTION_ENTITY_TYPES => [ParagraphType::CLASS]]);
     $value = $embed_attribute->createValueHolder();
     $value->addValueChangedListener($listener);
     $entity_list = $value->getValue();
     $entity_list->push($embedd_entity);
     $embedd_entity->setValue('title', 'Kthxbye');
     $this->assertInstanceOf(EntityList::CLASS, $entity_list);
     $this->assertEquals(1, $entity_list->getSize());
 }
 protected function createEmbeddedTypeMap()
 {
     $entity_type_map = parent::createEmbeddedTypeMap();
     foreach ($entity_type_map as $embedded_type) {
         $entity_implementor = $embedded_type->getEntityImplementor();
         $entity_reflection = new ReflectionClass($entity_implementor);
         if (!$entity_reflection->implementsInterface(EntityReferenceInterface::CLASS)) {
             throw new RuntimeException(sprintf('Invalid reference-type (%s) given to %s. Only instance of %s accepted.', $this->getName(), $entity_implementor, EntityReferenceInterface::CLASS));
         }
     }
     return $entity_type_map;
 }
 protected function buildFieldFilterSpec(EmbeddedEntityListAttribute $embed_attribute)
 {
     $filter_parts = [];
     $parent_attribute = $embed_attribute->getParent();
     while ($parent_attribute) {
         $filter_parts[] = $parent_attribute->getName();
         $parent_attribute = $parent_attribute->getParent();
     }
     $filter_parts[] = $embed_attribute->getName();
     $filter_parts[] = 'referenced_identifier';
     return implode('.', $filter_parts);
 }
示例#4
0
 /**
  * Generates and adds fake data for a embed entities.
  *
  * @param EntityInterface $entity an instance of the entity to fill with fake data.
  * @param EmbeddedEntityListAttribute $attribute instance of the EmbeddedEntityListAttribute to fill with fake data.
  * @param array $options array of options to customize fake data creation.
  *
  * @return void
  */
 protected function addEmbeddedEntityList(EntityInterface $entity, EmbeddedEntityListAttribute $attribute, array $options = array())
 {
     $options_clone = $options;
     $entity_collection = new EntityList();
     $embedded_type_map = $attribute->getEmbeddedEntityTypeMap();
     $min_count = $attribute->getOption('min_count', 0);
     $max_count = $attribute->getOption('max_count', 3);
     $inline_mode = $attribute->getOption('inline_mode', false);
     if (true === $inline_mode) {
         $number_of_new_embed_entries = 1;
     } else {
         $number_of_new_embed_entries = $this->faker->numberBetween($min_count, $max_count);
     }
     // add new entities to collection for embed types
     for ($i = 0; $i < $number_of_new_embed_entries; $i++) {
         $embed_type = $this->faker->randomElement($embedded_type_map->getValues());
         $new_entity = $this->createFakeEntity($embed_type, $options_clone, $entity);
         $entity_collection->addItem($new_entity);
     }
     $this->setValue($entity, $attribute, $entity_collection, $options);
 }
 /**
  * @return array
  */
 protected function getEmbeddedCommands(EmbeddedEntityListAttribute $attribute, array $values, EntityInterface $parent_entity = null)
 {
     $errors = [];
     $affected_identifiers = [];
     $attribute_name = $attribute->getName();
     $embedded_entity_list = $parent_entity ? $parent_entity->getValue($attribute_name) : new EntityList();
     $builder_list = new CommandBuilderList();
     foreach ($values as $position => $embedded_values) {
         if (!isset($embedded_values['@type'])) {
             $value_path = sprintf('%s.%d.@type', $attribute_name, $position);
             $errors[$value_path]['@incidents'][] = ['path' => $attribute->getPath(), 'incidents' => ['invalid_type' => ['reason' => 'missing']]];
             continue;
         }
         $embed_type_prefix = $embedded_values['@type'];
         unset($embedded_values['@type']);
         $embed_type = $attribute->getEmbeddedTypeByPrefix($embed_type_prefix);
         if (!$embed_type) {
             $value_path = sprintf('%s.%d.@type', $attribute_name, $position);
             $errors[$value_path]['@incidents'][] = ['path' => $attribute->getPath(), 'incidents' => ['invalid_type' => ['reason' => 'unknown']]];
             continue;
         }
         /*
          * Filter entities from the entity by incoming payload identifiers. If the
          * identifier is not matched then prepare an 'add' command, otherwise a 'modify'.
          */
         $affected_entity = $embedded_entity_list->filter(function ($embedded_entity) use($embedded_values) {
             return $embedded_entity instanceof EntityInterface && isset($embedded_values['identifier']) && $embedded_entity->getIdentifier() === $embedded_values['identifier'];
         })->getFirst();
         if (!$affected_entity) {
             $builder_list->push((new self($embed_type, AddEmbeddedEntityCommand::CLASS))->withParentAttributeName($attribute_name)->withPosition($position)->withValues($embedded_values));
         } else {
             $affected_identifiers[] = $affected_entity->getIdentifier();
             $modified_values = $this->filterUnmodifiedValues($affected_entity, $embedded_values);
             // prepare a modify command if values or position has changed
             if (!empty($modified_values) || $embedded_entity_list->getKey($affected_entity) != $position) {
                 $builder_list->push((new self($embed_type, ModifyEmbeddedEntityCommand::CLASS))->fromEntity($affected_entity)->withParentAttributeName($attribute_name)->withPosition($position)->withValues($modified_values));
             }
         }
     }
     /*
      * Iterate the attribute entity list and prepare remove commands for
      * any embedded entities with no incoming payload, or compensate for commands
      * which already exist.
      */
     foreach ($embedded_entity_list as $embedded_entity) {
         // if an entity is not found in the payload then we do compensation checks to make
         // sure we don't inadvertently add an existing entity
         if (!in_array($embedded_entity->getIdentifier(), $affected_identifiers)) {
             // look for any add command which has no difference in values for the current entity
             $command_key = null;
             foreach ($builder_list as $key => $command_builder) {
                 if ($command_builder->getCommandClass() === AddEmbeddedEntityCommand::CLASS && empty($this->filterUnmodifiedValues($embedded_entity, $command_builder->getValues()))) {
                     $command_key = $key;
                     break;
                 }
             }
             if (!is_null($command_key)) {
                 // remove the unnecessary add command if the entity already exists in the entity
                 $builder_list->splice($command_key);
             } else {
                 // the entity was not found in the payload so we can prepare removal
                 $builder_list->push((new self($embedded_entity->getType(), RemoveEmbeddedEntityCommand::CLASS))->fromEntity($embedded_entity)->withParentAttributeName($attribute_name));
             }
         }
     }
     $build_result = $builder_list->build();
     if (!empty($errors)) {
         if ($build_result instanceof Error) {
             $errors = array_merge($errors, $build_result->get());
         }
         return Error::unit($errors);
     }
     return $build_result;
 }
 public function testGetEmbedByPrefix()
 {
     $embed_attribute = new EmbeddedEntityListAttribute(self::ATTR_NAME, $this->getTypeMock(), [EmbeddedEntityListAttribute::OPTION_ENTITY_TYPES => [WorkflowStateType::CLASS]]);
     $workflow_state_type = $embed_attribute->getEmbeddedTypeByPrefix('workflow_state');
     $this->assertInstanceOf(WorkflowStateType::CLASS, $workflow_state_type);
 }