|
30 | 30 | trait EscapeTrait |
31 | 31 | { |
32 | 32 | /** |
33 | | - * Escapes the given 'name'. A name is an unquoted literal in a Cypher query, such as variables, |
34 | | - * types or property names. |
| 33 | + * Escapes a 'name' if it needs to be escaped. |
| 34 | + * A 'name' in cypher is any string that should be included directly in a cypher query, |
| 35 | + * such as variable names, labels, property names and relation types |
| 36 | + * |
| 37 | + * Note that empty strings are usually not allowed as names, so these should not be passed to this function. |
| 38 | + * However, some neo4j versions do not crash on empty string as variable name, so let's just escape them anyways. |
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 ($name !== '' && 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