Mapper.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. /**
  7. * Utility class for mapping data between objects or arrays
  8. */
  9. namespace Magento\Framework\DataObject;
  10. /**
  11. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  12. * @SuppressWarnings(PHPMD.NPathComplexity)
  13. */
  14. class Mapper
  15. {
  16. /**
  17. * Convert data from source to target item using map array
  18. *
  19. * Will get or set data with generic or magic, or specified Magento Object methods, or with array keys
  20. * from or to \Magento\Framework\DataObject or array
  21. * :)
  22. *
  23. * Map must either be associative array of keys from=>to
  24. * or a numeric array of keys, assuming from = to
  25. *
  26. * Defaults must be assoc array of keys => values. Target will get default, if the value is not present in source
  27. * If the source has getter defined instead of magic method, the value will be taken only if not empty
  28. *
  29. * Callbacks explanation (when $from or $to is not array):
  30. * for $from:
  31. * <\Magento\Framework\DataObject> => $from->getData($key) (default)
  32. * array(<\Magento\Framework\DataObject>, <method>) => $from->$method($key)
  33. * for $to (makes sense only for \Magento\Framework\DataObject):
  34. * <\Magento\Framework\DataObject> => $from->setData($key, <from>)
  35. * array(<\Magento\Framework\DataObject>, <method>) => $from->$method($key, <from>)
  36. *
  37. * @param array|\Magento\Framework\DataObject|callback $from
  38. * @param array|\Magento\Framework\DataObject|callback $to
  39. * @param array $map
  40. * @param array $defaults
  41. * @return array|object
  42. */
  43. public static function &accumulateByMap($from, $to, array $map, array $defaults = [])
  44. {
  45. $get = 'getData';
  46. if (is_array(
  47. $from
  48. ) && isset(
  49. $from[0]
  50. ) && is_object(
  51. $from[0]
  52. ) && isset(
  53. $from[1]
  54. ) && is_string(
  55. $from[1]
  56. ) && is_callable(
  57. $from
  58. )
  59. ) {
  60. list($from, $get) = $from;
  61. }
  62. $fromIsArray = is_array($from);
  63. $fromIsVO = $from instanceof \Magento\Framework\DataObject;
  64. $set = 'setData';
  65. if (is_array(
  66. $to
  67. ) && isset(
  68. $to[0]
  69. ) && is_object(
  70. $to[0]
  71. ) && isset(
  72. $to[1]
  73. ) && is_string(
  74. $to[1]
  75. ) && is_callable(
  76. $to
  77. )
  78. ) {
  79. list($to, $set) = $to;
  80. }
  81. $toIsArray = is_array($to);
  82. $toIsVO = $to instanceof \Magento\Framework\DataObject;
  83. foreach ($map as $keyFrom => $keyTo) {
  84. if (!is_string($keyFrom)) {
  85. $keyFrom = $keyTo;
  86. }
  87. if ($fromIsArray) {
  88. if (array_key_exists($keyFrom, $from)) {
  89. if ($toIsArray) {
  90. $to[$keyTo] = $from[$keyFrom];
  91. } elseif ($toIsVO) {
  92. $to->{$set}($keyTo, $from[$keyFrom]);
  93. }
  94. }
  95. } elseif ($fromIsVO) {
  96. // get value if (any) value is found as in magic data or a non-empty value with declared getter
  97. $value = null;
  98. if ($shouldGet = $from->hasData($keyFrom)) {
  99. $value = $from->{$get}($keyFrom);
  100. } elseif (method_exists($from, $get)) {
  101. $value = $from->{$get}($keyFrom);
  102. if ($value) {
  103. $shouldGet = true;
  104. }
  105. }
  106. if ($shouldGet) {
  107. if ($toIsArray) {
  108. $to[$keyTo] = $value;
  109. } elseif ($toIsVO) {
  110. $to->{$set}($keyTo, $value);
  111. }
  112. }
  113. }
  114. }
  115. foreach ($defaults as $keyTo => $value) {
  116. if ($toIsArray) {
  117. if (!isset($to[$keyTo])) {
  118. $to[$keyTo] = $value;
  119. }
  120. } elseif ($toIsVO) {
  121. if (!$to->hasData($keyTo)) {
  122. $to->{$set}($keyTo, $value);
  123. }
  124. }
  125. }
  126. return $to;
  127. }
  128. }