CompilesJsonPaths.php
TLDR
This file, located at src/Illuminate/Database/Concerns/CompilesJsonPaths.php
, contains a trait called CompilesJsonPaths
. This trait provides methods for manipulating JSON selectors and paths.
Methods
wrapJsonFieldAndPath
This method takes a JSON selector as input and splits it into the field and the optional path. It then wraps each part separately.
wrapJsonPath
This method wraps a given JSON path. It takes the path value and an optional delimiter as input. It replaces any occurrences of backslashes and single quotes in the path value. It then splits the path into segments using the delimiter, wraps each segment, and joins them with a dot. Finally, it returns the wrapped JSON path.
wrapJsonPathSegment
This method wraps a given JSON path segment. It takes the path segment as input. If the segment ends with one or more square brackets (indicating array access), it separates the key and the brackets. If the key is not empty, it wraps it with double quotes. It then returns the wrapped path segment.
<?php
namespace Illuminate\Database\Concerns;
use Illuminate\Support\Str;
trait CompilesJsonPaths
{
/**
* Split the given JSON selector into the field and the optional path and wrap them separately.
*
* @param string $column
* @return array
*/
protected function wrapJsonFieldAndPath($column)
{
$parts = explode('->', $column, 2);
$field = $this->wrap($parts[0]);
$path = count($parts) > 1 ? ', '.$this->wrapJsonPath($parts[1], '->') : '';
return [$field, $path];
}
/**
* Wrap the given JSON path.
*
* @param string $value
* @param string $delimiter
* @return string
*/
protected function wrapJsonPath($value, $delimiter = '->')
{
$value = preg_replace("/([\\\\]+)?\\'/", "''", $value);
$jsonPath = collect(explode($delimiter, $value))
->map(fn ($segment) => $this->wrapJsonPathSegment($segment))
->join('.');
return "'$".(str_starts_with($jsonPath, '[') ? '' : '.').$jsonPath."'";
}
/**
* Wrap the given JSON path segment.
*
* @param string $segment
* @return string
*/
protected function wrapJsonPathSegment($segment)
{
if (preg_match('/(\[[^\]]+\])+$/', $segment, $parts)) {
$key = Str::beforeLast($segment, $parts[0]);
if (! empty($key)) {
return '"'.$key.'"'.$parts[0];
}
return $parts[0];
}
return '"'.$segment.'"';
}
}