DataObject.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. /**
  7. * Default converter for \Magento\Framework\DataObjects to arrays
  8. *
  9. * @api
  10. */
  11. namespace Magento\Framework\Convert;
  12. class DataObject
  13. {
  14. /** Constant used to mark cycles in the input array/objects */
  15. const CYCLE_DETECTED_MARK = '*** CYCLE DETECTED ***';
  16. /**
  17. * Convert input data into an array and return the resulting array.
  18. * The resulting array should not contain any objects.
  19. *
  20. * @param array $data input data
  21. * @return array Data converted to an array
  22. */
  23. public function convertDataToArray($data)
  24. {
  25. $result = [];
  26. foreach ($data as $key => $value) {
  27. if (is_object($value) || is_array($value)) {
  28. $result[$key] = $this->_convertObjectToArray($value);
  29. } else {
  30. $result[$key] = $value;
  31. }
  32. }
  33. return $result;
  34. }
  35. /**
  36. * Converts a \Magento\Framework\DataObject into an array, including any children objects
  37. *
  38. * @param mixed $obj array or object to convert
  39. * @param array $objects array of object hashes used for cycle detection
  40. * @return array|string Converted object or CYCLE_DETECTED_MARK
  41. */
  42. protected function _convertObjectToArray($obj, &$objects = [])
  43. {
  44. $data = [];
  45. if (is_object($obj)) {
  46. $hash = spl_object_hash($obj);
  47. if (!empty($objects[$hash])) {
  48. return self::CYCLE_DETECTED_MARK;
  49. }
  50. $objects[$hash] = true;
  51. if ($obj instanceof \Magento\Framework\DataObject) {
  52. $data = $obj->getData();
  53. } else {
  54. $data = (array)$obj;
  55. }
  56. } elseif (is_array($obj)) {
  57. $data = $obj;
  58. }
  59. $result = [];
  60. foreach ($data as $key => $value) {
  61. if (is_scalar($value)) {
  62. $result[$key] = $value;
  63. } elseif (is_array($value)) {
  64. $result[$key] = $this->_convertObjectToArray($value, $objects);
  65. } elseif ($value instanceof \Magento\Framework\DataObject) {
  66. $result[$key] = $this->_convertObjectToArray($value, $objects);
  67. }
  68. }
  69. return $result;
  70. }
  71. /**
  72. * Converts the list of objects into an array of the form: [ [ 'label' => <id>, 'value' => <value> ], ... ].
  73. *
  74. *
  75. * The <id> and <value> values are taken from the objects in the list using the $idField and $valueField
  76. * parameters, which can be either the name of the field to use, or a closure.
  77. *
  78. * @param array $items
  79. * @param string|callable $idField
  80. * @param string|callable $valueField
  81. * @return array
  82. */
  83. public function toOptionArray(array $items, $idField, $valueField)
  84. {
  85. $options = [];
  86. foreach ($items as $item) {
  87. $options[] = [
  88. 'value' => $this->_invokeGetter($item, $idField),
  89. 'label' => $this->_invokeGetter($item, $valueField),
  90. ];
  91. }
  92. return $options;
  93. }
  94. /**
  95. * Converts the list of objects into an array of the form: [ <id> => <value>, ... ].
  96. *
  97. *
  98. * The <id> and <value> values are taken from the objects in the list using the $idField and $valueField parameters,
  99. * which can be either the name of the field to use, or a closure.
  100. *
  101. * @param array $items
  102. * @param string|callable $idField
  103. * @param string|callable $valueField
  104. * @return array
  105. */
  106. public function toOptionHash(array $items, $idField, $valueField)
  107. {
  108. $options = [];
  109. foreach ($items as $item) {
  110. $options[$this->_invokeGetter($item, $idField)] = $this->_invokeGetter($item, $valueField);
  111. }
  112. return $options;
  113. }
  114. /**
  115. * Returns the value of the property represented by $field on the $item object.
  116. *
  117. *
  118. * When $field is a closure, the $item parameter is passed to the $field method, otherwise the $field is assumed
  119. * to be a property name, and the associated get method is invoked on the $item instead.
  120. *
  121. * @param mixed $item
  122. * @param string|callable $field
  123. * @return mixed
  124. */
  125. protected function _invokeGetter($item, $field)
  126. {
  127. if (is_callable($field)) {
  128. // if $field is a closure, use that on the item
  129. return $field($item);
  130. } else {
  131. // otherwise, turn it into a call to the item's getter method
  132. $methodName = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $field)));
  133. return $item->{$methodName}();
  134. }
  135. }
  136. }