ConditionallyLoadsAttributes.php 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. namespace Illuminate\Http\Resources;
  3. use Illuminate\Support\Arr;
  4. trait ConditionallyLoadsAttributes
  5. {
  6. /**
  7. * Filter the given data, removing any optional values.
  8. *
  9. * @param array $data
  10. * @return array
  11. */
  12. protected function filter($data)
  13. {
  14. $index = -1;
  15. $numericKeys = array_values($data) === $data;
  16. foreach ($data as $key => $value) {
  17. $index++;
  18. if (is_array($value)) {
  19. $data[$key] = $this->filter($value);
  20. continue;
  21. }
  22. if (is_numeric($key) && $value instanceof MergeValue) {
  23. return $this->merge($data, $index, $this->filter($value->data), $numericKeys);
  24. }
  25. if ($value instanceof self && is_null($value->resource)) {
  26. $data[$key] = null;
  27. }
  28. }
  29. return $this->removeMissingValues($data, $numericKeys);
  30. }
  31. /**
  32. * Merge the given data in at the given index.
  33. *
  34. * @param array $data
  35. * @param int $index
  36. * @param array $merge
  37. * @param bool $numericKeys
  38. * @return array
  39. */
  40. protected function merge($data, $index, $merge, $numericKeys)
  41. {
  42. if ($numericKeys) {
  43. return $this->removeMissingValues(array_merge(
  44. array_merge(array_slice($data, 0, $index, true), $merge),
  45. $this->filter(array_values(array_slice($data, $index + 1, null, true)))
  46. ), $numericKeys);
  47. }
  48. return $this->removeMissingValues(array_slice($data, 0, $index, true) +
  49. $merge +
  50. $this->filter(array_slice($data, $index + 1, null, true)));
  51. }
  52. /**
  53. * Remove the missing values from the filtered data.
  54. *
  55. * @param array $data
  56. * @param bool $numericKeys
  57. * @return array
  58. */
  59. protected function removeMissingValues($data, $numericKeys = false)
  60. {
  61. foreach ($data as $key => $value) {
  62. if (($value instanceof PotentiallyMissing && $value->isMissing()) ||
  63. ($value instanceof self &&
  64. $value->resource instanceof PotentiallyMissing &&
  65. $value->isMissing())) {
  66. unset($data[$key]);
  67. }
  68. }
  69. return ! empty($data) && is_numeric(array_keys($data)[0])
  70. ? array_values($data) : $data;
  71. }
  72. /**
  73. * Retrieve a value based on a given condition.
  74. *
  75. * @param bool $condition
  76. * @param mixed $value
  77. * @param mixed $default
  78. * @return \Illuminate\Http\Resources\MissingValue|mixed
  79. */
  80. protected function when($condition, $value, $default = null)
  81. {
  82. if ($condition) {
  83. return value($value);
  84. }
  85. return func_num_args() === 3 ? value($default) : new MissingValue;
  86. }
  87. /**
  88. * Merge a value based on a given condition.
  89. *
  90. * @param bool $condition
  91. * @param mixed $value
  92. * @return \Illuminate\Http\Resources\MissingValue|mixed
  93. */
  94. protected function mergeWhen($condition, $value)
  95. {
  96. return $condition ? new MergeValue(value($value)) : new MissingValue;
  97. }
  98. /**
  99. * Merge the given attributes.
  100. *
  101. * @param array $attributes
  102. * @return \Illuminate\Http\Resources\MergeValue
  103. */
  104. protected function attributes($attributes)
  105. {
  106. return new MergeValue(
  107. Arr::only($this->resource->toArray(), $attributes)
  108. );
  109. }
  110. /**
  111. * Retrieve a relationship if it has been loaded.
  112. *
  113. * @param string $relationship
  114. * @param mixed $value
  115. * @param mixed $default
  116. * @return \Illuminate\Http\Resources\MissingValue|mixed
  117. */
  118. protected function whenLoaded($relationship, $value = null, $default = null)
  119. {
  120. if (func_num_args() < 3) {
  121. $default = new MissingValue;
  122. }
  123. if (! $this->resource->relationLoaded($relationship)) {
  124. return $default;
  125. }
  126. if (func_num_args() === 1) {
  127. return $this->resource->{$relationship};
  128. }
  129. if ($this->resource->{$relationship} === null) {
  130. return null;
  131. }
  132. return value($value);
  133. }
  134. /**
  135. * Execute a callback if the given pivot table has been loaded.
  136. *
  137. * @param string $table
  138. * @param mixed $value
  139. * @param mixed $default
  140. * @return \Illuminate\Http\Resources\MissingValue|mixed
  141. */
  142. protected function whenPivotLoaded($table, $value, $default = null)
  143. {
  144. if (func_num_args() === 2) {
  145. $default = new MissingValue;
  146. }
  147. return $this->when(
  148. $this->resource->pivot &&
  149. ($this->resource->pivot instanceof $table ||
  150. $this->resource->pivot->getTable() === $table),
  151. ...[$value, $default]
  152. );
  153. }
  154. /**
  155. * Transform the given value if it is present.
  156. *
  157. * @param mixed $value
  158. * @param callable $callback
  159. * @param mixed $default
  160. * @return mixed
  161. */
  162. protected function transform($value, callable $callback, $default = null)
  163. {
  164. return transform(
  165. $value, $callback, func_num_args() === 3 ? $default : new MissingValue
  166. );
  167. }
  168. }