|
16 | 16 | use CodeIgniter\HTTP\RequestInterface; |
17 | 17 | use CodeIgniter\Validation\Exceptions\ValidationException; |
18 | 18 | use CodeIgniter\View\RendererInterface; |
| 19 | +use Config\Services; |
19 | 20 | use Config\Validation as ValidationConfig; |
20 | 21 | use InvalidArgumentException; |
| 22 | +use LogicException; |
21 | 23 | use TypeError; |
22 | 24 |
|
23 | 25 | /** |
@@ -660,47 +662,70 @@ public function loadRuleGroup(?string $group = null) |
660 | 662 | * |
661 | 663 | * and the following rule: |
662 | 664 | * |
663 | | - * 'required|is_unique[users,email,id,{id}]' |
| 665 | + * 'is_unique[users,email,id,{id}]' |
664 | 666 | * |
665 | 667 | * The value of {id} would be replaced with the actual id in the form data: |
666 | 668 | * |
667 | | - * 'required|is_unique[users,email,id,13]' |
| 669 | + * 'is_unique[users,email,id,13]' |
668 | 670 | */ |
669 | 671 | protected function fillPlaceholders(array $rules, array $data): array |
670 | 672 | { |
671 | | - $replacements = []; |
| 673 | + foreach ($rules as &$rule) { |
| 674 | + $ruleSet = $rule['rules']; |
672 | 675 |
|
673 | | - foreach ($data as $key => $value) { |
674 | | - $replacements["{{$key}}"] = $value; |
675 | | - } |
| 676 | + foreach ($ruleSet as &$row) { |
| 677 | + if (is_string($row)) { |
| 678 | + $placeholderFields = $this->retrievePlaceholders($row, $data); |
| 679 | + |
| 680 | + foreach ($placeholderFields as $field) { |
| 681 | + $validator ??= Services::validation(null, false); |
676 | 682 |
|
677 | | - if ($replacements !== []) { |
678 | | - foreach ($rules as &$rule) { |
679 | | - $ruleSet = $rule['rules'] ?? $rule; |
| 683 | + $placeholderRules = $rules[$field]['rules'] ?? null; |
680 | 684 |
|
681 | | - if (is_array($ruleSet)) { |
682 | | - foreach ($ruleSet as &$row) { |
683 | | - if (is_string($row)) { |
684 | | - $row = strtr($row, $replacements); |
| 685 | + // Check if the validation rule for the placeholder exists |
| 686 | + if ($placeholderRules === null) { |
| 687 | + throw new LogicException( |
| 688 | + 'No validation rules for the placeholder: ' . $field |
| 689 | + ); |
685 | 690 | } |
686 | | - } |
687 | | - } |
688 | 691 |
|
689 | | - if (is_string($ruleSet)) { |
690 | | - $ruleSet = strtr($ruleSet, $replacements); |
691 | | - } |
| 692 | + // Check if the rule does not have placeholders |
| 693 | + foreach ($placeholderRules as $placeholderRule) { |
| 694 | + if ($this->retrievePlaceholders($placeholderRule, $data)) { |
| 695 | + throw new LogicException( |
| 696 | + 'The placeholder field cannot use placeholder: ' . $field |
| 697 | + ); |
| 698 | + } |
| 699 | + } |
| 700 | + |
| 701 | + // Validate the placeholder field |
| 702 | + if (! $validator->check($data[$field], implode('|', $placeholderRules))) { |
| 703 | + // if fails, do nothing |
| 704 | + continue; |
| 705 | + } |
692 | 706 |
|
693 | | - if (isset($rule['rules'])) { |
694 | | - $rule['rules'] = $ruleSet; |
695 | | - } else { |
696 | | - $rule = $ruleSet; |
| 707 | + // Replace the placeholder in the rule |
| 708 | + $ruleSet = str_replace('{' . $field . '}', $data[$field], $ruleSet); |
| 709 | + } |
697 | 710 | } |
698 | 711 | } |
| 712 | + |
| 713 | + $rule['rules'] = $ruleSet; |
699 | 714 | } |
700 | 715 |
|
701 | 716 | return $rules; |
702 | 717 | } |
703 | 718 |
|
| 719 | + /** |
| 720 | + * Retrieves valid placeholder fields. |
| 721 | + */ |
| 722 | + private function retrievePlaceholders(string $rule, array $data): array |
| 723 | + { |
| 724 | + preg_match_all('/{(.+?)}/', $rule, $matches); |
| 725 | + |
| 726 | + return array_intersect($matches[1], array_keys($data)); |
| 727 | + } |
| 728 | + |
704 | 729 | /** |
705 | 730 | * Checks to see if an error exists for the given field. |
706 | 731 | */ |
|
0 commit comments