camelCase parameters in setter in PhpStorm - jetbrains-ide

I have under_score named properties in my class like transaction_id or web_order_item_id. And I want to customize the parameter name in my setters when I generate it.
For now it generate this:
/**
* #param int $original_transaction_id .camelCase()
*/
public function setOriginalTransactionId(int $original_transaction_id): void
{
$this->original_transaction_id = $original_transaction_id;
}
But I want this:
/**
* #param int $originalTransactionId .camelCase()
*/
public function setOriginalTransactionId(int $originalTransactionId): void
{
$this->original_transaction_id = $originalTransactionId;
}
I have tried to change this behavior in Settings/Editor/File and Code Templates/Code/Php Setter Method but I couldn`t found ability to do it.
There is a variable in the template:
${NAME}
But it returned value in this form $OriginalTransactionId instead $originalTransactionId

You can try using Apache Velocity StringUtils here, like
#set($Setter_param = ${StringUtils.removeAndHump(${PARAM_NAME})})
#set($Setter_param = $Setter_param.substring(0,1).toLowerCase() + $Setter_param.substring(1))
/**
* #param ${TYPE_HINT} $${Setter_param}
*/
public ${STATIC} function set${NAME}(#if (${SCALAR_TYPE_HINT})${SCALAR_TYPE_HINT} #end$${Setter_param})#if (${VOID_RETURN_TYPE}):void #end
{
#if (${STATIC} == "static")
self::$${FIELD_NAME} = $${Setter_param};
#else
$this->${FIELD_NAME} = $${Setter_param};
#end
}

Related

Change output names in API return object

I am very new to nodejs and typescript.
I have try to provide an API via express.
I have try to return a custom object on my API who looks like that :
export class Auction {
private _currentPrice:number = 0;
private _auctionName:string;
public constructor(currentPrice: number , auctionName: string) {
this._currentPrice = currentPrice;
this._auctionName = auctionName;
}
/**
* Getter auctionName
* #return {string}
*/
public get auctionName(): string {
return this._auctionName;
}
/**
* Setter auctionName
* #param {string} value
*/
public set auctionName(value: string) {
this._auctionName = value;
}
/**
* Setter currentPrice
* #param {number } value
*/
public set currentPrice(value: number ) {
this._currentPrice = value;
}
/**
* Getter currentPrice
* #return {number }
*/
public get currentPrice(): number {
return this._currentPrice;
}
}
But what I have seen is that the answer of my API is something like :
{"_currentPrice":0,"_auctionName":"toto"}
I was expecting something like
{"currentPrice":0,"auctionName":"toto"}
Is there any way to automaticaly convert it to the format I want ?
This is happening because when the TypeScript is compiled to JavaScript, objects created by that class have public _currentPrice and _auctionName properties (because TypeScript "private" properties are only private in terms of TypeScript's type system) and they don't have their own currentPrice and auctionName properties (they inherit them from their prototype, which has them as accessor properties). JSON.stringify only includes "own" properties.
You can deal with it in a few ways:
By using simple properties for currentPrice and auctionName. You have public accessors for both get and set for both properties, so there doesn't seem to be any reason to use private properties to hold their values. Or,
By providing your own toJSON method for the class:
toJSON() {
return {currentPrice: this._currentPrice, auctionName: this._auctionName};
}
Despite the name "toJSON", this method isn't supposed to return JSON; it's supposed to return the value for the object that should be converted to JSON. So in this case, you return an object with the properties you want the returned JSON to have.
A third solution would be to use JavaScript's own private properties (they're supported in up-to-date Node.js versions) and "own" accessors for them on the objects, but I don't think TypeScript supports JavaScript's private properties yet.

Intervene template rendering

I have a controller method which I am using to "collect" variables to be assigned to template. I have overridden controller's render() method to merge "collected" and render parameters and assign them to template.
Example:
class Controller extends \Symfony\Bundle\FrameworkBundle\Controller\Controller
{
private $jsVars = [];
protected function addJsVar($name, $value)
{
$this->jsVars[$name] = $value;
}
public function render($view, array $parameters = [], Response $response = null)
{
return parent::render($view, array_merge($parameters, ['jsVars' => $this->jsVars], $response);
}
public function indexAction()
{
// collect variables for template
$this->addJsVar('foo', 'bar');
return $this->render('#App/index.html.twig', ['foo2' => 'bar2']);
}
}
I just upgraded to Symfony 3.4 which complains that since Symfony4 I am not allowed to override render() method as it will be final.
How could I make it work seamlessly, i.e without defining a new method?
I know about Twig globals but these dont help me
I could use a service to collection variables and inject that service to Twig but that seems odd
Are there events I could listen, e.g TwigPreRender or smth?
You can render a controller from inside Twig like that:
{{ render(controller('App\\Controller\\YourController::yourAction', { 'args': 'hi' })) }}
Documentation here
Seems that there is no easy way.
Basically there are 2 options:
create your own template engine by extending current Symfony\Bundle\TwigBundle\TwigEngine
decorate current templating engine service templating.engine.mytwig
I chose the latter.
Few explanations:
I created service templating.engine.mytwig which decorates current engine templating.engine.twig. Class will get current ´TwigEngine` as input and I'll delegate most of the stuff to it
The class also needs to be twig extension by implementing \Twig_ExtensionInterface (or extending \Twig_Extension was sufficient for me). Also service needs to have tag twig.extension. Otherwise you'll end up having errors such as "Cannot find private service 'assetic' etc"
setParameter/getParameter are for collecting and returning parameters
Then I added shortcut methods to my Controller - setJsVar
Twig template requires also handling of those variables, preferably somewhere in the layout level. But that is not included here
One could you this solution to collect arbitrary template parameters, e.g if you want to assign from another method or whatever
It would be good idea to clear collected parameters after render
Was that all worth it? I dont know :) Cannot understand why Symfony team chose to make Controller::render final in the first place. But anyway here it is:
TwigEnging class:
namespace My\CommonBundle\Component\Templating\MyTwigEngine;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Bundle\TwigBundle\TwigEngine;
use Symfony\Component\HttpFoundation\Response;
class MyTwigEngine extends \Twig_Extension implements EngineInterface
{
/**
* #var TwigEngine $twig Original Twig Engine object
*/
private $twig;
/**
* #var array $parameters Collected parameters to be passed to template
*/
private $parameters = [];
/**
* MyTwigEngine constructor.
*
* #param TwigEngine $twig
*/
public function __construct(TwigEngine $twig)
{
$this->twig = $twig;
}
/**
* "Collects" parameter to be passed to template.
*
* #param string $key
* #param mixed $value
*
* #return static
*/
public function setParameter($key, $value)
{
$this->parameters[$key] = $value;
return $this;
}
/**
* Returns "collected" parameter
*
* #param string $key
* #return mixed
*/
public function getParameter($key, $default = null)
{
$val = $this->parameters[$key] ?? $default;
return $val;
}
/**
* #param string|\Symfony\Component\Templating\TemplateReferenceInterface $name
* #param array $parameters
*
* #return string
* #throws \Twig\Error\Error
*/
public function render($name, array $parameters = array())
{
return $this->twig->render($name, $this->getTemplateParameters($parameters));
}
/**
* #param string $view
* #param array $parameters
* #param Response|null $response
*
* #return Response
* #throws \Twig\Error\Error
*/
public function renderResponse($view, array $parameters = array(), Response $response = null)
{
return $this->twig->renderResponse($view, $this->getTemplateParameters($parameters), $response);
}
/**
* #param string|\Symfony\Component\Templating\TemplateReferenceInterface $name
*
* #return bool
*/
public function exists($name)
{
return $this->twig->exists($name);
}
/**
* #param string|\Symfony\Component\Templating\TemplateReferenceInterface $name
*
* #return bool
*/
public function supports($name)
{
return $this->twig->supports($name);
}
/**
* #param $name
* #param array $parameters
*
* #throws \Twig\Error\Error
*/
public function stream($name, array $parameters = array())
{
$this->twig->stream($name, $this->getTemplateParameters($parameters));
}
/**
* Returns template parameters, with merged jsVars, if there are any
* #param array $parameters
* #return array
*/
protected function getTemplateParameters(array $parameters = [])
{
$parameters = array_merge($this->parameters, $parameters);
return $parameters;
}
}
Decorator service (services.yml):
services:
templating.engine.mytwig:
decorates: templating.engine.twig
class: My\CommonBundle\Component\Templating\MyTwigEngine
# pass the old service as an argument
arguments: [ '#templating.engine.mytwig.inner' ]
# private, because you probably won't be needing to access "mytwig" directly
public: false
tags:
- { name: twig.extension }
Base controller alteration:
namespace My\CommonBundle\Controller;
use My\CommonBundle\Component\Templating\MyTwigEngine;
abstract class Controller extends \Symfony\Bundle\FrameworkBundle\Controller\Controller
{
/**
* Allows to set javascript variable from action
*
* It also allows to pass arrays and objects - these are later json encoded
*
* #param string $name Variable name
* #param mixed $value - string|int|object|array
*
* #return static
*/
protected function setJsVar($name, $value)
{
/** #var MyTwigEngine $templating */
$templating = $this->getTemplating();
if (!$templating instanceof MyTwigEngine) {
throw new \RuntimeException(sprintf(
'Method %s is implemented only by %s', __METHOD__, MyTwigEngine::class
));
}
$jsvars = $templating->getParameter('jsVars', []);
$jsvars[$name] = $value;
$templating->setParameter('jsVars', $jsvars);
return $this;
}
/**
* Returns templating service
* #return null|object|\Twig\Environment
*/
private function getTemplating()
{
if ($this->container->has('templating')) {
$templating = $this->container->get('templating');
} elseif ($this->container->has('twig')) {
$templating = $this->container->get('twig');
} else {
$templating = null;
}
return $templating;
}
}

Adding a new global variable in twig

I'm trying to get data for a new field added in login page. What I've done:
Modify AccountController.php login function adding new parameter: $this->_app->login($user, $client, !empty($data['rememberme']))
In Userfrosting.php login function i've set it in application: $this->client = $client;
In setupTwigUserVariables funtion added twig global: $twig->addGlobal("client", $this->client);
The problem is that in a template, {{client.id}} returns nothing. Any help will be appreciated.
In UserFrosting 4, you should create a Twig extension in your Sprinkle's src/Twig/ directory, and add the variable to the return value for getGlobals.
Your situation is a little tricky, since I'm not sure how client can be a global variable but at the same time depend on $data['client_id'] - which appears to be a request parameter. For now, I'll assume that you're submitting this parameter with any requests that require the client variable.
<?php
/**
* Stack Overflow
*
* #link https://stackoverflow.com
*/
namespace UserFrosting\Sprinkle\Site\Twig;
use Interop\Container\ContainerInterface;
use UserFrosting\Sprinkle\Site\Database\Models\Client;
/**
* Extends Twig functionality for the Site sprinkle.
*
* #author Jose Luis
*/
class Extension extends \Twig_Extension
{
protected $services;
protected $config;
public function __construct(ContainerInterface $services)
{
$this->services = $services;
$this->config = $services->config;
}
public function getName()
{
return 'myproject';
}
public function getGlobals()
{
try {
$currentUser = $this->services->currentUser;
// Assumes the client_id is being submitted as a query string (url) parameter
$clientId = $this->services->request->getQueryParam('client_id');
$client = Client::where('client_id', clientId)->where('userid', $currentUser->id)->first();
} catch (\Exception $e) {
$client = null;
}
return [
'client' => $client
];
}
}
You will then need to register this extension in your Sprinkle's service provider class:
<?php
/**
* Stack Overflow
*
* #link https://stackoverflow.com
*/
namespace UserFrosting\Sprinkle\Site\ServicesProvider;
use UserFrosting\Sprinkle\Site\Twig\Extension as JoseExtension;
/**
* Services provider for the Site sprinkle.
*
* #author Jose Luis
*/
class ServicesProvider
{
/**
* Register extended user fields services.
*
* #param Container $container A DI container implementing ArrayAccess and container-interop.
*/
public function register($container)
{
/**
* Extends the 'view' service with Jose's Twig Extension.
*/
$container->extend('view', function ($view, $c) {
$twig = $view->getEnvironment();
$extension = new JoseExtension($c);
$twig->addExtension($extension);
return $view;
});
}
}
Yes, I know that there is a lot of boilerplate here. However once you set these up the first time, it is easy to add new variables/functions/filters to the Twig environment and new services to your Sprinkle in the future.

How can I set a default value in Doctrinemongodb document?

How can I set the default value in field.
In my document I need to set default value false for field emailnotify
In mogodb th default value should be zero.
Check my document
namespace xxx\xxxBundle\Document;
use FOS\UserBundle\Document\User as BaseUser;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\Document
*/
class User extends BaseUser
{
/**
* #MongoDB\Id(strategy="auto")
*/
protected $id;
/**
* #MongoDB\Boolean
*/
protected $emailnotify;
/**
* Sets the emailnotify.
*
* #param boolean $emailnotify
*
* #return User
*/
public function setEmailnotify($emailnotify)
{
$this->emailnotify = (Boolean) $emailnotify;
return $this;
}
/**
* #return boolean
*/
public function isEmailnotify()
{
return $this->emailnotify;
}
}
I have found that setting the default value in the constructor works
public function __construct() {
$this->emailnotify = false;
}
Of course just setting the class variable to false will work for most parts if you use Doctrine to fetch the Document again afterwards, but the property will not be persisted to MongoDB like with the above.

How to automatically escape variables in a Zend Framework 2 view

A lot of times in a Zend Framework 2 view I'll be calling $this->escapeHtml() to make sure my data is safe. Is there a way to switch this behaviour from a blacklist to a whitelist?
PS: Read an article from Padraic Brady that suggests that automatic escaping is a bad idea. Additional thoughts?
You could write your own ViewModel class which escapes data when variables are assigned to it.
Thanks to Robs comment, I extended the ZF2 ViewModel as follows:
namespace Application\View\Model;
use Zend\View\Model\ViewModel;
use Zend\View\Helper\EscapeHtml;
class EscapeViewModel extends ViewModel
{
/**
* #var Zend\View\Helper\EscapeHtml
*/
protected $escaper = null;
/**
* Proxy to set auto-escape option
*
* #param bool $autoEscape
* #return ViewModel
*/
public function autoEscape($autoEscape = true)
{
$this->options['auto_escape'] = (bool) $autoEscape;
return $this;
}
/**
* Property overloading: get variable value;
* auto-escape if auto-escape option is set
*
* #param string $name
* #return mixed
*/
public function __get($name)
{
if (!$this->__isset($name)) {
return;
}
$variables = $this->getVariables();
if($this->getOption('auto_escape'))
return $this->getEscaper()->escape($variables[$name]);
return $variables[$name];
}
/**
* Get instance of Escaper
*
* #return Zend\View\Helper\EscapeHtml
*/
public function getEscaper()
{
if (null === $this->escaper) {
$this->escaper = new EscapeHtml;
}
return $this->escaper;
}
}
In a Controller it could be used like this:
public function fooAction()
{
return new EscapeViewModel(array(
'foo' => '<i>bar</i>'
));
//Turn off auto-escaping:
return new EscapeViewModel(array(
'foo' => '<i>bar</i>'
),['auto_escape' => false]);
}
Question:
I would appreciate it if soemebody would comment, if this is best practice or if there is a better and ecp. more efficient and resource-saving way?

Resources