ValidationData.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <?php
  2. namespace Illuminate\Validation;
  3. use Illuminate\Support\Arr;
  4. class ValidationData
  5. {
  6. /**
  7. * Initialize and gather data for the given attribute.
  8. *
  9. * @param string $attribute
  10. * @param array $masterData
  11. * @return array
  12. */
  13. public static function initializeAndGatherData($attribute, $masterData)
  14. {
  15. $data = Arr::dot(static::initializeAttributeOnData($attribute, $masterData));
  16. return array_merge($data, static::extractValuesForWildcards(
  17. $masterData, $data, $attribute
  18. ));
  19. }
  20. /**
  21. * Gather a copy of the attribute data filled with any missing attributes.
  22. *
  23. * @param string $attribute
  24. * @param array $masterData
  25. * @return array
  26. */
  27. protected static function initializeAttributeOnData($attribute, $masterData)
  28. {
  29. $explicitPath = static::getLeadingExplicitAttributePath($attribute);
  30. $data = static::extractDataFromPath($explicitPath, $masterData);
  31. if (! str_contains($attribute, '*') || str_ends_with($attribute, '*')) {
  32. return $data;
  33. }
  34. return data_set($data, $attribute, null, true);
  35. }
  36. /**
  37. * Get all of the exact attribute values for a given wildcard attribute.
  38. *
  39. * @param array $masterData
  40. * @param array $data
  41. * @param string $attribute
  42. * @return array
  43. */
  44. protected static function extractValuesForWildcards($masterData, $data, $attribute)
  45. {
  46. $keys = [];
  47. $pattern = str_replace('\*', '[^\.]+', preg_quote($attribute, '/'));
  48. foreach ($data as $key => $value) {
  49. if ((bool) preg_match('/^'.$pattern.'/', $key, $matches)) {
  50. $keys[] = $matches[0];
  51. }
  52. }
  53. $keys = array_unique($keys);
  54. $data = [];
  55. foreach ($keys as $key) {
  56. $data[$key] = Arr::get($masterData, $key);
  57. }
  58. return $data;
  59. }
  60. /**
  61. * Extract data based on the given dot-notated path.
  62. *
  63. * Used to extract a sub-section of the data for faster iteration.
  64. *
  65. * @param string $attribute
  66. * @param array $masterData
  67. * @return array
  68. */
  69. public static function extractDataFromPath($attribute, $masterData)
  70. {
  71. $results = [];
  72. $value = Arr::get($masterData, $attribute, '__missing__');
  73. if ($value !== '__missing__') {
  74. Arr::set($results, $attribute, $value);
  75. }
  76. return $results;
  77. }
  78. /**
  79. * Get the explicit part of the attribute name.
  80. *
  81. * E.g. 'foo.bar.*.baz' -> 'foo.bar'
  82. *
  83. * Allows us to not spin through all of the flattened data for some operations.
  84. *
  85. * @param string $attribute
  86. * @return string
  87. */
  88. public static function getLeadingExplicitAttributePath($attribute)
  89. {
  90. return rtrim(explode('*', $attribute)[0], '.') ?: null;
  91. }
  92. }