public function save($data) { if (isset($data['exFormID'])) { return parent::save($data); } $requestControls = (array) $this->request->request->get('controlID'); $entityManager = \Core::make('database/orm')->entityManager(); $session = \Core::make('session'); $sessionControls = $session->get('block.express_form.new'); if (!$this->exFormID) { // This is a new submission. $c = \Page::getCurrentPage(); $name = $data['formName'] ? $data['formName'] : t('Form'); // Create a results node $node = ExpressEntryCategory::getNodeByName(self::FORM_RESULTS_CATEGORY_NAME); $node = \Concrete\Core\Tree\Node\Type\ExpressEntryResults::add($name, $node); $entity = new Entity(); $entity->setName($name); $entity->setIncludeInPublicList(false); $generator = new EntityHandleGenerator($entityManager); $entity->setHandle($generator->generate($entity)); $entity->setEntityResultsNodeId($node->getTreeNodeID()); $entityManager->persist($entity); $entityManager->flush(); $form = new Form(); $form->setName(t('Form')); $form->setEntity($entity); $entity->setDefaultViewForm($form); $entity->setDefaultEditForm($form); $entityManager->persist($form); $entityManager->flush(); // Create a Field Set and a Form $field_set = new FieldSet(); $field_set->setForm($form); $entityManager->persist($field_set); $entityManager->flush(); $indexer = $entity->getAttributeKeyCategory()->getSearchIndexer(); if (is_object($indexer)) { $indexer->createRepository($entity->getAttributeKeyCategory()); } } else { // We check save the order as well as potentially deleting orphaned controls. $form = $entityManager->getRepository('Concrete\\Core\\Entity\\Express\\Form')->findOneById($this->exFormID); /** * @var $form Form * @var $field_set FieldSet */ $field_set = $form->getFieldSets()[0]; $entity = $form->getEntity(); } $attributeKeyCategory = $entity->getAttributeKeyCategory(); // First, we get the existing controls, so we can check them to see if controls should be removed later. $existingControls = $form->getControls(); $existingControlIDs = array(); foreach ($existingControls as $control) { $existingControlIDs[] = $control->getId(); } // Now, let's loop through our request controls $indexKeys = array(); $position = 0; foreach ($requestControls as $id) { if (isset($sessionControls[$id])) { $control = $sessionControls[$id]; if (!in_array($id, $existingControlIDs)) { // Possibility 1: This is a new control. if ($control instanceof AttributeKeyControl) { $key = $control->getAttributeKey(); $type = $key->getAttributeType(); $settings = $key->getAttributeKeySettings(); // We have to merge entities back into the entity manager because they have been // serialized. First type, because if we merge key first type gets screwed $type = $entityManager->merge($type); // Now key, because we need key to set as the primary key for settings. $key = $entityManager->merge($key); $key->setAttributeType($type); $key->setEntity($entity); $key->setAttributeKeyHandle((new AttributeKeyHandleGenerator($attributeKeyCategory))->generate($key)); $entityManager->persist($key); $entityManager->flush(); // Now attribute settings. $settings->setAttributeKey($key); $settings = $entityManager->merge($settings); $entityManager->persist($settings); $entityManager->flush(); $control->setAttributeKey($key); $indexKeys[] = $key; } $control->setFieldSet($field_set); $control->setPosition($position); $entityManager->persist($control); } else { // Possibility 2: This is an existing control that has an updated version. foreach ($existingControls as $existingControl) { if ($existingControl->getId() == $id) { if ($control instanceof AttributeKeyControl) { $settings = $control->getAttributeKey()->getAttributeKeySettings(); $key = $existingControl->getAttributeKey(); $type = $key->getAttributeType(); $type = $entityManager->merge($type); // question name $key->setAttributeKeyName($control->getAttributeKey()->getAttributeKeyName()); $key->setAttributeKeyHandle((new AttributeKeyHandleGenerator($attributeKeyCategory))->generate($key)); // Key Type $key = $entityManager->merge($key); $key->setAttributeType($type); $type = $control->getAttributeKey()->getAttributeType(); $type = $entityManager->merge($type); $key->setAttributeType($type); $settings = $control->getAttributeKey()->getAttributeKeySettings(); $settings->setAttributeKey($key); $settings = $settings->mergeAndPersist($entityManager); // Required $existingControl->setIsRequired($control->isRequired()); // Finalize control $existingControl->setAttributeKey($key); $indexKeys[] = $key; } else { if ($control instanceof TextControl) { // Wish we had a better way of doing this that wasn't so hacky. $existingControl->setHeadline($control->getHeadline()); $existingControl->setBody($control->getBody()); } } // save it. $entityManager->persist($existingControl); } } } } else { // Possibility 3: This is an existing control that doesn't have a new version. But we still // want to update its position. foreach ($existingControls as $control) { if ($control->getId() == $id) { $control->setPosition($position); $entityManager->persist($control); } } } $position++; } // Now, we look through all existing controls to see whether they should be removed. foreach ($existingControls as $control) { // Does this control exist in the request? If not, it gets axed if (!is_array($requestControls) || !in_array($control->getId(), $requestControls)) { $entityManager->remove($control); } } $entityManager->flush(); $category = new ExpressCategory($entity, \Core::make('app'), $entityManager); $indexer = $category->getSearchIndexer(); foreach ($indexKeys as $key) { $indexer->updateRepositoryColumns($category, $key); } // Now, we handle the entity results folder. $resultsNode = Node::getByID($entity->getEntityResultsNodeId()); $folder = Node::getByID($data['resultsFolder']); if (is_object($folder)) { $resultsNode->move($folder); } $data['exFormID'] = $form->getId(); $this->clearSessionControls(); parent::save($data); }
/** * @param $control \Concrete\Core\Entity\Express\Control\AttributeKeyControl * @param \SimpleXMLElement $xml */ public function import(\SimpleXMLElement $xml, Entity $entity) { $control = new \Concrete\Core\Entity\Express\Control\AttributeKeyControl(); $control->setCustomLabel((string) $xml['custom-label']); if ((string) $xml['required'] == '1') { $control->setIsRequired(true); } $control->setId((string) $xml['id']); $category = new ExpressCategory($entity, $this->application, $this->entityManager); if (isset($xml->attributekey)) { $ak = $xml->attributekey; $type = $this->application->make('Concrete\\Core\\Attribute\\TypeFactory')->getByHandle((string) $ak['type']); $key = $category->import($type, $ak); $control->setAttributeKey($key); } return $control; }