Annotate parameter as function accepting several types as params for closure compiler - google-closure-compiler

I want to annotate a parameter to a method call to be a function accepting two parameters, first being Error or null and second being an Object or Array of objects. However I seem to not be able to figure out the correct annotation - compiler always gives Bad type annotation.
Example:
/**
* Allows to predefine the callback for a named 'run' method. This is
* useful mostly for application code that has only one consumer for any
* particular named request.
*
* #param {!string} run_name The name of the run to register default callback
* for.
* #param {function(Error, (Array.<Object>|Object)): undefined} callback The callback
* function to execute for the named request if no other callback is provided
* with the request.
*/
_.registerRunCallback = function(run_name, callback) {
this.internalImplementation(run_name, callback);
};
I am not sure if this is actually possible, but I find it to be better than using unknown type.
So my question is how do I do that.

Related

Route with a lot of optional parameters in Symfony

I got a lot of products, and it can be filter with a lot of different parameters.
So user input search parameter in a form, and then the list is filter by those parameters.
I have try to create a route like this :
/**
* Display a list of product
* #Route("/product/list/{name}/{price_min}/{price_max}/{publish_date}/{supplier_code}", name="product_list")
*/
public function listProduct(){
// ... Check parameters format and then escape special caracters
// ... Display product logic
return $this->render('Product/product_list.html.twig', $array_params_view);
}
I know you can provide optional parameter, but this solution looks really bad to me...
I think there might be another solution.
I have think to use the Request instead of a lot of parameter, but if I do so, I loose the fonctionality of nice and easily readable URL, and maybe it'll be more difficult to manage routing.
I don't know what is the best solution for search functionnality.
If you use route for search into your list, I think you need to read this : link
Query String is a better way for search.
// the query string is '?foo=bar'
$request->query->get('foo');
// returns 'bar'
/**
* Display a list of product
*
* #Route("/list/", name="product_list")
*
* #param Request $request
*
*/
public function listProduct(Request $request)
{
$name = $request->query->get('name');
$price_min = $request->query->get('price_min');
$price_max = $request->query->get('price_max');
$publish_date = $request->query->get('publish_date');
$supplier_code = $request->query->get('supplier_code');
$list_products = $this->getListProducts($name,$price_min,$price_max,$publish_date,$supplier_code);
//Next code
......
}
You would only have to control within the getListProducts function
or whatever you call it, that the arguments can arrive as null

Symfony getUser type hinting

I find it somewhat annoying to have to constantly use #var on getUser. It seems sloppy.
So I was thinking about starting to use this instead
<?php
// in the controller
$user = Customer::isCustomer($this->getUser());
// in the entity
/**
* #param Customer $user
*
* #return Customer
*/
public static function isCustomer(Customer $user)
{
return $user;
}
Is this a good idea? Bad idea? Horrible idea?
A type hint is the better option in this case.
Why would you write more code by adding checks manually rather than adding a simple type hint to your param.
Your four lines of codes representing two conditions give exactly the same result as:
/**
* #param Customer|null $user
*
* #return Customer|null
*/
public static function isCustomer(Customer $user = null)
{
// If $user is null, it works
// If $user is a Customer instance, it works
// If it's other, an exception is thrown
return $user;
}
Type hinting optimises and give more readability to a code.
It's a convention in symfony2, php and more.
It's commonly used as a constraint (or contract) with you and your method.
Also, it's the only alternative for an interface or an abstract class to add requirement to a parameter, because they don't have a body, and so cannot write conditions.
Update
In SensioLabs Insight, Object type hinting represents a warning using the following message :
The parameter user, which is an object, should be typehinted.
Because the verb should is used, I consider it's not a mandatory requirement, just a very good practice in case of it doesn't cause any problem.
Also, you can use the example you given without making your code horrible.

How to document a controller in symfony?

I'm trying to document my project. I want to document my controller. Before my Action I have:
/**
* Description: xxx
* #param parameters of my function Action
* #return views of the action
*/
The return value here will show:
Why?
Thanks
EDIT:
A standard controller:
public function myControllerAction(Request $request) {
return $this->render('AppBundle:Default:index.html.twig');
}
The reason is that the first word after #return is considered the type of the returned data according to the official phpDocumentor docs:
#return datatype description
#return datatype1|datatype2 description
The #return annotation expects the data type as a first argument, before the description. In your case you've specified the data type as views which hasn't been included with a use statement, so PHP assumes it belongs to the current namespace and you get \AppBundle\Controllers\views. The return type of a controller must be a Symfony\Component\HttpFoundation\Response. So you want:
#return \Symfony\Component\HttpFoundation\Response description
or if you already have a use statement for Response:
#return Response description
In some cases you might want to be more specific if you are always returning a specific subclass of response, like:
BinaryFileResponse
JsonResponse
RedirectResponse
StreamedResponse

Getting multiple rows using ParamConverter

Hi Im trying to use ParamConverter to get multiple rows from DB but profiler show query with limi 1. Is it possible to get it like that
/**
* #Route("/localization/{code}", name="pkt-index")
* #ParamConverter("localizations", class="PriceBundle:Localization")
*/
after entering localization/0003 I should get more than 100 rows.
EDIT:
I have used repository_method option
and
/*
* #Route("/localization/{id}", name="pkt-index")
* #ParamConverter("localizations", class="PriceBundle:Localization", options={
* "repository_method": "getByLocalizationCode"
* })
*/
but funny thing is that when I change {id} in route it does not work it throws and exception
SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
even if variable exists in entity class, if variable dont exist it throws
Unable to guess how to get a Doctrine instance from the request information.
EXPLANATION
when I change {id} in route it does not work it throws and exception
SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
Here I think symfony treads id like primary key and as parameter to repository method it pass string when I changed this id to something else it pass array
Example
/**
* #Route("/localization/{id}", name="pkt-index")
*/
pass string to method
/**
* #Route("/localization/{code}/{name}", name="pkt-index")
*/
pass array to method
array(
'code' => 003
'name' => localization_name
)
and last
/**
* #Route("/localization/{id}/{name}", name="pkt-index")
*/
will pass string id omit the name
Hope this sounds reasonable.
forgottenbas's answer isn't completely right. #ParamConverter will first try to find one entity by id ...
... then try to match the route variables against db columns to find an entity ...
but essentially it will only convert one entity at a time.
If you would still like to use a paramconverter you would need to write a custom one.
or just use a one-liner inside your controller action:
/**
* #Route("/localization/{code}", name="pkt-index")
*/
public function yourAction($code)
{
$localizations = $this->getDoctrine()->getRepository("YourBundle:Localization")->findBy(array("code" => $code));
// ...
ParamConverter currently can only extract id from request and find one entity from db. Look at
DoctrineParamConverter code. But you can specify your own param converter with some extra logic.

Symfony/Doctrine 2 - Use config parameter in Entity

I have a tree of Employee objects (they are in a tree-like hierarchy, with everyone having one leader, and all leaders having more employees). All the Employees have a integer parameter called units.
/**
* #ORM\Entity
* #ORM\Table(name="employees")
*/
class Employee
{
/**
* #ORM\Id
* #ORM\Column(strategy="AUTO")
*/
protected $id;
/**
* #ORM\OneToMany(targetEntity="Employee", mappedBy="leader")
*/
protected $employees;
/**
* #ORM\ManyToOne(targetEntity("Employee", inversedBy="employees")
*/
protected $leader;
}
I need to get all the employees, who have at most N units, where N is defined in config.yml. At first, I was trying to push $configContainer into $GLOBALS, and use it in ArrayCollection::filter()'s Closure. Now I found a method, so I can use variables in the Closure:
public function getBestEmployees(&$configContainer)
{
return $this->getAllEmployees()->filter(
function bestEmployees($employee) use ($configContainer)
{
return ($employee->getUnits() >= $configContainer->getParameter('best_unit_count'));
}
);
}
Now I wonder if there is any other way to access the configuration parameters from an Entity, or do I really have to pass the whole configContainer as a reference? Or am I doing it totally wrong?
You shouldn't be accessing the service container at all inside entities. The value itself should be passed instead
public function getBestEmployees($bestUnitCount)
{
return $this->getAllEmployees()->filter(function ($employee) use ($bestUnitCount) {
return $employee->getUnits()->count() >= $bestUnitCount;
});
}
Of course, we haven't actually solved the problem yet: the parameter still needs to be fetched from the container somewhere. If this method gets invoked mostly in controller actions, I wouldn't bother doing any extra work to make things cleaner and would pass the container parameter straight in the controller action.
However, should there be a need to get the best employees in a Twig template, for example, it would be nice if it wouldn't be necessary to pass the parameter. One possibility would be using a setter method and passing the parameter down beforehand to each and every entity that gets retrieved from the database. You could do this either in repositories or entitiy managers. The most advanced solution would be to listen to the postLoad event and pass the parameter in an event listener.

Resources