@@ -92,6 +92,8 @@ class DataDefinition implements PropertyListInterface {
9292
9393 protected $ options = NULL ;
9494
95+ protected ?OptionsSortOrder $ optionsOrder = NULL ;
96+
9597 protected $ validators = [];
9698
9799 /**
@@ -698,6 +700,11 @@ public function setOptionsArray(array $options_array): self {
698700 return $ this ;
699701 }
700702
703+ public function setOptionsSorting (OptionsSortOrder $ order ): self {
704+ $ this ->optionsOrder = $ order ;
705+ return $ this ;
706+ }
707+
701708 public function hasOptions (): bool {
702709 return !empty ($ this ->options ) || !empty ($ this ->optionSet );
703710 }
@@ -708,19 +715,61 @@ public function hasOptions(): bool {
708715 * These can be either the options set directly on this definition, or
709716 * obtained dynamically from an option set definition.
710717 *
718+ * The options are returned sorted by option weight, and then the sort order
719+ * set on this definition. If not specified, this defaults to the order in
720+ * which the options were added to the definition.
721+ *
711722 * @return \MutableTypedData\Definition\OptionDefinition[]
712723 * An array of option definitions, keyed by the option values.
713724 */
714725 public function getOptions (): array {
715726 if ($ this ->optionSet ) {
716- return $ this ->optionSet ->getOptions ();
727+ $ options = $ this ->optionSet ->getOptions ();
717728 }
718729 elseif ($ this ->options ) {
719- return $ this ->options ;
730+ $ options = $ this ->options ;
720731 }
721732 else {
722- return [];
733+ $ options = [];
734+ }
735+
736+ $ options_sorting = $ this ->getOptionsSorting () ?? OptionsSortOrder::Original;
737+
738+ if ($ options_sorting == OptionsSortOrder::Original) {
739+ // Get the order in which the items were added to the options array in the
740+ // definition (or in which they're returned from the option set definition).
741+ // This is an array of all option values, keyed by the option value, whose
742+ // values are increasing integers.
743+ $ added_order = array_flip (array_keys ($ options ));
744+
745+ uasort ($ options , function ($ a , $ b ) use ($ added_order ) {
746+ // Options with the same weight are sorted by the order they were added
747+ // to the options array.
748+ if ($ a ->getWeight () == $ b ->getWeight ()) {
749+ return $ added_order [$ a ->getValue ()] <=> $ added_order [$ b ->getValue ()];
750+ }
751+ else {
752+ return $ a ->getWeight () <=> $ b ->getWeight ();
753+ }
754+ });
723755 }
756+ elseif ($ options_sorting == OptionsSortOrder::Label) {
757+ uasort ($ options , function ($ a , $ b ) {
758+ // Options with the same weight are sorted by label.
759+ if ($ a ->getWeight () == $ b ->getWeight ()) {
760+ return strcmp ($ a ->getLabel (), $ b ->getLabel ());
761+ }
762+ else {
763+ return $ a ->getWeight () <=> $ b ->getWeight ();
764+ }
765+ });
766+ }
767+
768+ return $ options ;
769+ }
770+
771+ public function getOptionsSorting (): ?OptionsSortOrder {
772+ return $ this ->optionsOrder ;
724773 }
725774
726775 public function setValidators (string ...$ validators ): self {
0 commit comments