Skip to content

Instantly share code, notes, and snippets.

@ifranco88
Created September 20, 2024 10:11
Show Gist options
  • Save ifranco88/04bbce2aa8fa6762ee97325a4e1e83d2 to your computer and use it in GitHub Desktop.
Save ifranco88/04bbce2aa8fa6762ee97325a4e1e83d2 to your computer and use it in GitHub Desktop.
A PHP Class to render php arrays into Javascript variables.
<?php
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Support\Jsonable;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Support\Collection;
use Illuminate\Support\HtmlString;
class Javascript implements Arrayable, Jsonable, Renderable
{
protected $namespace = null;
/**
* @var Collection
*/
protected $vars;
public function __construct($namespace = null)
{
$this->namespace = $namespace;
$this->vars = collect();
}
public function add($name, $content)
{
$vars = $this->vars->toArray();
if(is_array($name)){
foreach($name as $key => $content){
$this->vars = collect(data_set($vars, $key, $content));
}
return $this;
}
$this->vars = collect(data_set($vars, $name, $content));
return $this;
}
public function remove($name)
{
$this->vars->forget($name);
return $this;
}
public function get($name, $default = null)
{
return $this->vars->get($name, $default);
}
public function toArray()
{
$this->vars->toArray();
}
public function toJson($options = 0)
{
return $this->vars->toJson();
}
public function render()
{
// TODO: Si se actualiza a una versión de Laravel más reciente, se puede utilizar 'reduce' en lugar de map + implode. El problema es que en la versión actual reduce no tiene la calve del array.
$varDeclarations = $this->declareNamespaceVar() . PHP_EOL . implode('', $this->vars->map(function ($value, $key) {
return $this->declareVar($key, $value);
})->toArray());
return $this->declareScript($varDeclarations);
}
protected function declareScript($content, $type = 'text/javascript')
{
return $content ? new HtmlString("<script type='{$type}'>{$content};</script>") : '';
}
protected function declareNamespaceVar()
{
if (empty($this->namespace)) {
return '';
}
return "window['{$this->namespace}'] = window['{$this->namespace}'] || {};";
}
protected function declareVar($name, $value)
{
$value = $this->varValue($value);
return "{$this->varNamespace($name)} = " . json_encode($value) . ';' . PHP_EOL;
}
public function varNamespace($name)
{
return $this->namespace ? "window['{$this->namespace}']['{$name}']" : "window['{$name}']";
}
/**
* Comprueba el valor que va a ir como valor de la variable de Javascript.
* Si el valor es una función anónima se ejecutará y el valor resultante de la función lo asignará a la variable de Javascript.
*
* @param $value
*
* @return mixed
*/
protected function varValue($value)
{
if (is_callable($value)) {
return $value();
}
if (is_array($value)) {
foreach ($value as $k => $v) {
$value[$k] = $this->varValue($v);
}
}
return $value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment