Skip to content

bor-attila/cakephp-ptj

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CakePHP - Php to Javascript

Easily pass PHP variables to Javascript

This Plugin requires: CakePHP >=4.x

Installation

You can install this plugin into your CakePHP application using composer.

The recommended way to install composer packages is:

composer require bor-attila/cakephp-ptj

Enable the plugin in your Application.php:

$this->addPlugin('PhpToJavascript');

In View\AppView.php add this to the initialize method:

$this->loadHelper('PhpToJavascript.PhpToJavascript');

TL;DR

Instead of

echo $this->Html->scriptBlock('var user = ' . json_encode(['firtname' => 'John', 'lastname' => 'Connor', 'age' => 15]));

just use (in layout)

<html>
    <head>
        <?php
            $this->PhpToJavascript->add([
                'user' => ['firtname' => 'John', 'lastname' => 'Connor', 'age' => 15],
                'language' => 'hu_HU'
            ]);
            // or ..
            $this->PhpToJavascript->add('key', 'value');
        ?>
    </head>
    <body>
        ...

        <?= $this->PhpToJavascript->get(); ?> <!-- Place before all of your script tags -->
        <?= $this->Html->script(['libraries.min', '....']); ?>
        <?= $this->fetch('script') ?>
    </body>
</html>

In the client side you can use:

p('user'); // Object { firtname: "John", lastname: "Connor", age: 15 }

When and why ?

When you build a hybrid CakePHP and Javascript application, sometimes you want to pass some variable to client. Sure, you can build an API for this - but since the request has already "reached the controller" (to get the template) you can simply "echoes" the variables and if you want to have a nice way to do this - you can use this plugin.

I think this is a better way than building an API, for example, just to know: user's IP address, the current user id, the current language, etc ...

Configuration

The default configuration is:

'function' => 'p',
'storage' => '__phptojavascript',
'encode' => [
    'options' => 0,
    'depth' => 512,
],
'cache' => [
    'enabled' => true,
    'key' => '__phptojavascript',
    'config' => 'default',
]
  • function the name of the function which helps to reach your stored variable.
  • storage the name of the global javascript variable where your php variables are stored. Just make sure this is an unique variable name.
  • encode parameters of the json_encode function
  • cache the global function always generated by based on function and storage configuration. You can use this parameter to store it.

Usage (PHP)

//add multiple variable at once
$this->PhpToJavascript->add([
    'user' => $user,
    'language' => $lang
]);

//adding simple number if does not exists `var1`
$this->PhpToJavascript->add('var1', 1);

//adding array if does not exists `user`, note that you don't need to call json_encode. The plugin will do it for you
$this->PhpToJavascript->add('user', ['firtname' => 'John', 'lastname' => 'Connor', 'age' => 15]);

//setting and array if exists, will be overwritten
$this->PhpToJavascript->set('user', ['firtname' => 'John', 'lastname' => 'Connor', 'age' => 15]);

//or remove before $this->PhpToJavascript->get() is called
$this->PhpToJavascript->remove('user');

//prints the main javascript file containing the window.__phptojavascript variable and the p function
echo $this->PhpToJavascript->get();

Usage (Javascript)

//the default p function
p(string key, function mutator, default);

p('not_exists'); // undefined

p('user', null, false); // { .... }

p('not_exists', null, false); // false

p('user'); // Object { firtname: "John", lastname: "Connor", age: 15 }
p('user', user => user.age); // 15

// from version 1.1, the second parameter can be a default value or a mutator
// p(string key, any default);

// if the requested key WAS NOT found
//
// 1. then the second parameter is returned if there is only 2 parameter given
console.assert(p('not_exists', false) === false);
// 2. then the second parameter is ignored, and the third parameter is returned if there is 3 parameter or more
console.assert(p('not_exists', 'ignored', false) === false);
// 3. then the default result is undefined
console.assert(typeof p('not_exists') === 'undefined');

// if the requested key WAS found
//
// 1. then the value stored on the PHP side will be returned
console.assert(p('user') === window.__phptojavascript.user);
// 2. and the second parameter is a function, then the result will be 'mutated' by the function
console.assert(p('user', x => x.age) === 15);
// 3. and the second parameter is not a function, then the value stored on the PHP side will be returned and the other
// parameters are ignored
console.assert(p('user', 'not a function, so this is ignored', 'default value, but ignored') === window.__phptojavascript.user);

Bundle the main function or extending

You can use the generate_php_js command to generate a static file with the p function. The command to generates a static js file with the window.__phptojavascript = {}; p = ... initialization. You can extend it or bundle it - your choose, but don't forget to tell this to the get method.

bin/cake generate_php_js
echo $this->PhpToJavascript->get(false);

This prevents generating and including the main function into the js output.

Todo

Tests.