diff --git a/src/Entity/Poll.php b/src/Entity/Poll.php index d5edb50..12d837d 100644 --- a/src/Entity/Poll.php +++ b/src/Entity/Poll.php @@ -7,7 +7,6 @@ namespace Drupal\poll\Entity; -use Drupal\Component\Utility\SafeMarkup; use Drupal\Core\Entity\ContentEntityBase; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; @@ -246,9 +245,13 @@ class Poll extends ContentEntityBase implements PollInterface { ->setLabel(t('Language code')) ->setDescription(t('The poll language code.')); - $fields['choice'] = BaseFieldDefinition::create('poll_choice') + $fields['choice'] = BaseFieldDefinition::create('entity_reference') ->setLabel(t('Choice')) - ->setDescription(t('Enter a poll choice and default vote.')) + ->setSetting('target_type', 'poll_choice') + ->setDescription(t('Enter the poll choices.')) + // The number and order of choices may not be translated, only the + // referenced choices. + ->setTranslatable(FALSE) ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) ->setSetting('max_length', 255) ->setDisplayOptions('form', [ @@ -388,8 +391,8 @@ class Poll extends ContentEntityBase implements PollInterface { public function getOptions() { $options = array(); if (count($this->choice)) { - foreach ($this->choice as $option) { - $options[$option->chid] = SafeMarkup::checkPlain($option->choice); + foreach ($this->choice as $choice_item) { + $options[$choice_item->target_id] = $choice_item->entity->label(); } } return $options; @@ -403,8 +406,8 @@ class Poll extends ContentEntityBase implements PollInterface { public function getOptionValues() { $options = array(); if (count($this->choice)) { - foreach ($this->choice as $option) { - $options[$option->chid] = $option->vote; + foreach ($this->choice as $choice_item) { + $options[$choice_item->target_id] = 1; } } return $options; @@ -413,12 +416,35 @@ class Poll extends ContentEntityBase implements PollInterface { /** * {@inheritdoc} */ + public function preSave(EntityStorageInterface $storage) { + parent::preSave($storage); + foreach ($this->choice as $choice_item) { + if ($choice_item->entity && $choice_item->entity->needsSaving()) { + $choice_item->entity->save(); + $choice_item->target_id = $choice_item->entity->id(); + } + } + } + + /** + * {@inheritdoc} + */ public static function postDelete(EntityStorageInterface $storage, array $entities) { parent::postDelete($storage, $entities); + // Delete votes. foreach ($entities as $entity) { $storage->deleteVotes($entity); } + + // Delete referenced choices. + $choices = []; + foreach ($entities as $entity) { + $choices = array_merge($choices, $entity->choice->referencedEntities()); + } + if ($choices) { + \Drupal::entityTypeManager()->getStorage('poll_choice')->delete($choices); + } } /** diff --git a/src/Entity/PollChoice.php b/src/Entity/PollChoice.php new file mode 100644 index 0000000..eb42818 --- /dev/null +++ b/src/Entity/PollChoice.php @@ -0,0 +1,93 @@ +set('question', $question); + return $this; + } + + /** + * {@inheritdoc} + */ + public function needsSaving($new_value = NULL) { + // If explicitly set, return that value. otherwise fall back to isNew(), + // saving is always required for new entities. + $return = $this->needsSave !== NULL ? $this->needsSave : $this->isNew(); + + if ($new_value !== NULL) { + $this->needsSave = $new_value; + } + + return $return; + } + + /** + * {@inheritdoc} + */ + public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { + $fields['id'] = BaseFieldDefinition::create('integer') + ->setLabel(t('Choice ID')) + ->setReadOnly(TRUE) + ->setSetting('unsigned', TRUE); + + $fields['uuid'] = BaseFieldDefinition::create('uuid') + ->setLabel(t('UUID')) + ->setReadOnly(TRUE); + + $fields['choice'] = BaseFieldDefinition::create('string') + ->setLabel(t('Choice')) + ->setRequired(TRUE) + ->setTranslatable(TRUE) + ->setSetting('max_length', 255) + ->setDisplayOptions('form', array( + 'type' => 'string_textfield', + 'weight' => -100, + )); + + $fields['langcode'] = BaseFieldDefinition::create('language') + ->setLabel(t('Language code')) + ->setDescription(t('The poll language code.')); + + return $fields; + } + +} diff --git a/src/Plugin/Field/FieldFormatter/PollChoiceDefaultFormatter.php b/src/Plugin/Field/FieldFormatter/PollChoiceDefaultFormatter.php deleted file mode 100644 index 05f14f3..0000000 --- a/src/Plugin/Field/FieldFormatter/PollChoiceDefaultFormatter.php +++ /dev/null @@ -1,38 +0,0 @@ - $item) { - $elements[$delta] = array('#markup' => $item->choice); - } - return $elements; - } - -} diff --git a/src/Plugin/Field/FieldType/PollChoiceItem.php b/src/Plugin/Field/FieldType/PollChoiceItem.php deleted file mode 100644 index 4e72c17..0000000 --- a/src/Plugin/Field/FieldType/PollChoiceItem.php +++ /dev/null @@ -1,102 +0,0 @@ -setLabel(t('Choice ID')); - $properties['choice'] = DataDefinition::create('string') - ->setLabel(t('Choice')); - $properties['vote'] = DataDefinition::create('integer') - ->setLabel(t('Vote')); - - return $properties; - } - - /** - * {@inheritdoc} - */ - public static function schema(FieldStorageDefinitionInterface $field_definition) { - return array( - 'columns' => array( - 'chid' => array( - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'choice' => array( - 'type' => 'varchar', - 'length' => 512, - 'not null' => TRUE, - ), - 'vote' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => FALSE, - ), - ), - 'indexes' => array( - 'chid' => array('chid'), - ), - 'primary key' => array('chid'), - ); - } - - /** - * {@inheritdoc} - */ - public function isEmpty() { - $value = $this->get('choice')->getValue(); - return $value === NULL || $value === ''; - } - - /** - * {@inheritdoc} - */ - public function getConstraints() { - $constraint_manager = \Drupal::typedDataManager() - ->getValidationConstraintManager(); - $constraints = parent::getConstraints(); - $constraints[] = $constraint_manager->create('ComplexData', array( - 'choice' => array( - 'Length' => array( - 'max' => static::POLL_CHOICE_MAX_LENGTH, - 'maxMessage' => t('%name: the choice field may not be longer than @max characters.', array( - '%name' => $this->getFieldDefinition()->getLabel(), - '@max' => static::POLL_CHOICE_MAX_LENGTH - )), - ) - ), - )); - return $constraints; - } - -} diff --git a/src/Plugin/Field/FieldWidget/PollChoiceDefaultWidget.php b/src/Plugin/Field/FieldWidget/PollChoiceDefaultWidget.php index 6784ff7..a6b1b65 100644 --- a/src/Plugin/Field/FieldWidget/PollChoiceDefaultWidget.php +++ b/src/Plugin/Field/FieldWidget/PollChoiceDefaultWidget.php @@ -7,6 +7,7 @@ namespace Drupal\poll\Plugin\Field\FieldWidget; +use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Field\WidgetBase; use Drupal\Core\Form\FormStateInterface; @@ -20,7 +21,7 @@ use Drupal\Core\Form\FormStateInterface; * module = "poll", * label = @Translation("Poll choice"), * field_types = { - * "poll_choice" + * "entity_reference" * } * ) */ @@ -35,15 +36,35 @@ class PollChoiceDefaultWidget extends WidgetBase { * {@inheritdoc} */ public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { - $element['chid'] = array( + $langcode = $this->getCurrentLangcode($form_state, $items); + + /* @var \Drupal\poll\PollChoiceInterface $choice */ + $choice = $items[$delta]->entity; + if ($choice) { + // If target translation is not yet available, populate it with data from + // the original choice. + if ($choice->language()->getId() != $langcode && !$choice->hasTranslation($langcode)) { + $choice->addTranslation($langcode, $choice->toArray()); + } + + // Initiate the choice with the correct translation. + $choice = $choice->getTranslation($langcode); + } + + $element['target_id'] = array( '#type' => 'value', - '#value' => $items[$delta]->chid, + '#value' => $choice ? $choice->id() : NULL, ); + $element['langcode'] = array( + '#type' => 'value', + '#value' => $langcode, + ); + $element['choice'] = array( '#type' => 'textfield', '#placeholder' => t('Choice'), '#empty_value' => '', - '#default_value' => isset($items[$delta]->choice) ? $items[$delta]->choice : '', + '#default_value' => $choice ? $choice->choice->value : NULL, '#prefix' => '