johnnymast /
rivescript-php
| 1 | <?php |
||
| 2 | /* |
||
| 3 | * This file is part of Rivescript-php |
||
| 4 | * |
||
| 5 | * (c) Johnny Mast <[email protected]> |
||
| 6 | * |
||
| 7 | * For the full copyright and license information, please view the LICENSE |
||
| 8 | * file that was distributed with this source code. |
||
| 9 | */ |
||
| 10 | |||
| 11 | namespace Axiom\Rivescript\Cortex\Triggers; |
||
| 12 | |||
| 13 | use Axiom\Rivescript\Cortex\Input; |
||
| 14 | use Axiom\Rivescript\Traits\Regex; |
||
| 15 | |||
| 16 | /** |
||
| 17 | * Alternation class |
||
| 18 | * |
||
| 19 | * The Alternation class determines if a provided trigger |
||
| 20 | * is an Alternation. |
||
| 21 | * |
||
| 22 | * PHP version 7.4 and higher. |
||
| 23 | * |
||
| 24 | * @category Core |
||
| 25 | * @package Cortext\Triggers |
||
| 26 | * @author Johnny Mast <[email protected]> |
||
| 27 | * @license https://opensource.org/licenses/MIT MIT |
||
| 28 | * @link https://github.com/axiom-labs/rivescript-php |
||
| 29 | * @since 0.4.0 |
||
| 30 | */ |
||
| 31 | class Alternation extends Trigger |
||
| 32 | { |
||
| 33 | use Regex; |
||
| 34 | |||
| 35 | /** |
||
| 36 | * The Regex pattern to find sets |
||
| 37 | * in the trigger. |
||
| 38 | * |
||
| 39 | * Note: This pattern ignores the set if a @ character |
||
| 40 | * is inside to make sure we don't confuse them with arrays. |
||
| 41 | * |
||
| 42 | * @var string |
||
| 43 | */ |
||
| 44 | protected string $pattern = "/(\()(?!\@)(.+?=*)(\))/ui"; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * Parse the trigger. |
||
| 48 | * |
||
| 49 | * @return bool|string |
||
| 50 | */ |
||
| 51 | public function parse(string $trigger, Input $input): bool |
||
| 52 | { |
||
| 53 | if ($this->matchesPattern($this->pattern, $trigger) === true) { |
||
| 54 | $triggerString = $trigger; |
||
| 55 | $matches = $this->getMatchesFromPattern($this->pattern, $triggerString); |
||
| 56 | $sets = []; |
||
| 57 | |||
| 58 | /** |
||
| 59 | * Replace every "set" in the trigger to their index number |
||
| 60 | * found in the string. |
||
| 61 | * |
||
| 62 | * Example: |
||
| 63 | * |
||
| 64 | * "I (am|love) a robot. I like (my|style)" |
||
| 65 | * |
||
| 66 | * Will be replaced with: |
||
| 67 | * |
||
| 68 | * "I {0} a robot. I like {1}" |
||
| 69 | */ |
||
| 70 | foreach ($matches as $index => $match) { |
||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
| 71 | $set = explode("|", $match[2]); |
||
| 72 | |||
| 73 | if (count($set) > 0) { |
||
| 74 | $triggerString = str_replace($match[0], "{{$index}}", $triggerString); |
||
| 75 | $sets [] = $set; |
||
| 76 | } |
||
| 77 | } |
||
| 78 | |||
| 79 | $combinations = $this->getCombinations(...$sets); |
||
| 80 | |||
| 81 | if (count($combinations) > 0) { |
||
| 82 | $sentences = []; |
||
| 83 | |||
| 84 | foreach ($combinations as $combination) { |
||
| 85 | $tmp = $triggerString; |
||
| 86 | foreach ($combination as $index => $string) { |
||
| 87 | $tmp = str_replace("{{$index}}", $string, $tmp); |
||
| 88 | } |
||
| 89 | |||
| 90 | $sentences [] = trim($tmp); |
||
| 91 | } |
||
| 92 | |||
| 93 | $result = array_filter($sentences, static function (string $sentence) use ($input) { |
||
| 94 | return (strtolower($sentence) === strtolower($input->source())); |
||
| 95 | }); |
||
| 96 | |||
| 97 | if (count($result) > 0) { |
||
| 98 | return $input->source(); |
||
|
0 ignored issues
–
show
|
|||
| 99 | } |
||
| 100 | } |
||
| 101 | } |
||
| 102 | return false; |
||
| 103 | } |
||
| 104 | |||
| 105 | /** |
||
| 106 | * Create a set of possible combinations for given arrays. |
||
| 107 | * |
||
| 108 | * Note: This function is taken from stackoverflow.com |
||
| 109 | * first posted by Guilhermo Luna and later edited by user Amlette. |
||
| 110 | * |
||
| 111 | * @see https://stackoverflow.com/questions/8567082/how-to-generate-in-php-all-combinations-of-items-in-multiple-arrays/33259643#33259643 |
||
| 112 | * |
||
| 113 | * @param array ...$arrays A set of arrays to combine. |
||
| 114 | * |
||
| 115 | * @return array|array[] |
||
| 116 | * |
||
| 117 | */ |
||
| 118 | private function getCombinations(array ...$arrays): array |
||
| 119 | { |
||
| 120 | $result = [[]]; |
||
| 121 | foreach ($arrays as $property => $property_values) { |
||
| 122 | $tmp = []; |
||
| 123 | foreach ($result as $result_item) { |
||
| 124 | foreach ($property_values as $property_value) { |
||
| 125 | $tmp[] = array_merge($result_item, [$property => $property_value]); |
||
| 126 | } |
||
| 127 | } |
||
| 128 | $result = $tmp; |
||
| 129 | } |
||
| 130 | return $result; |
||
| 131 | } |
||
| 132 | } |
||
| 133 |