|
21 | 21 |
|
22 | 22 | namespace WikibaseSolutions\CypherDSL\Traits; |
23 | 23 |
|
24 | | -use InvalidArgumentException; |
| 24 | +use function preg_match; |
| 25 | +use function sprintf; |
| 26 | +use function str_replace; |
25 | 27 |
|
26 | 28 | /** |
27 | 29 | * Trait for encoding certain structures that are used in multiple clauses in a |
|
30 | 32 | trait EscapeTrait |
31 | 33 | { |
32 | 34 | /** |
33 | | - * Escapes the given 'name'. A name is an unquoted literal in a Cypher query, such as variables, |
34 | | - * types or property names. |
| 35 | + * Escapes a 'name' if it needs to be escaped. |
| 36 | + * @see https://neo4j.com/docs/cypher-manual/4.4/syntax/naming |
| 37 | + * A 'name' in cypher is any string that should be included directly in a cypher query, |
| 38 | + * such as variable names, labels, property names and relation types |
35 | 39 | * |
36 | 40 | * @param string $name |
37 | 41 | * @return string |
38 | 42 | */ |
39 | 43 | public static function escape(string $name): string |
40 | 44 | { |
41 | | - if ($name === "") { |
42 | | - return ""; |
43 | | - } |
44 | | - |
45 | | - if (ctype_alnum($name) && !ctype_digit($name)) { |
| 45 | + if (preg_match('/^\p{L}[\p{L}\d_]*$/u', $name)) { |
46 | 46 | return $name; |
47 | 47 | } |
48 | 48 |
|
49 | | - if (strpos($name, '`') !== false) { |
50 | | - throw new InvalidArgumentException("A name must not contain a backtick (`)"); |
51 | | - } |
| 49 | + return self::escapeRaw($name); |
| 50 | + } |
| 51 | + |
| 52 | + /** |
| 53 | + * Escapes the given $name to be used directly in a CYPHER query. |
| 54 | + * Note: according to https://github.com/neo4j/neo4j/issues/12901 backslashes might give problems in some Neo4j versions. |
| 55 | + */ |
| 56 | + public static function escapeRaw($name) |
| 57 | + { |
| 58 | + // Escape backticks that are included in $name by doubling them. |
| 59 | + $name = str_replace('`', '``', $name); |
52 | 60 |
|
53 | 61 | return sprintf("`%s`", $name); |
54 | 62 | } |
|
0 commit comments