Symfony 4: Returning only active records - symfony

I would like to only get records where the active indicator is true:
class Question {
/**
* One Question has one Figure
* #ORM\OneToOne(targetEntity="QuestionFigure", mappedBy="question")
*/
private $figure;
public function getFigure()
{
$criteria = Criteria::create()->where(Criteria::expr()->eq("active", true));
return $this->figure->matching($criteria);
}
When I do this, I get the error:
Attempted to call an undefined method named "matching" of class
I believe this is because the matching method can only be applied to an ArrayCollection which $this->figure is not. What would be a similar way of achieving this same result?
Edit based on answer provided by Ihor Kostrov:
getActive() is returning nothing. Testing this out, this works:
public function getFigure()
{
if (!empty($this->figure) && $this->figure->getId() === 1) {
return $this->figure;
}
return null;
}
But changing the id to 2 does not work ($this->figure->getId() === 2). I am thinking this is because of the one-to-one relationship doctrine only fetches one row?

Yes, you have OneToOne, so you cat try this
public function getFigure(): ?QuestionFigure
{
if (!empty($this->figure) && $this->figure->getActive()) {
return $this->figure;
}
return null;
}

No! You must not have logic in your entity!
To have all question with have QuestionFigure active you must configure a repository and you implement a method.

Related

Api platform aliasing filters for nested resources

I'm currently using API Platform and its default SearchFilter and it works as intended.
However, filtering on a deep relationship between resources can be heavy by its quite long query string in the url. (I have got multiple entities like this.)
For instance I want to search every books listed in the stores of a specific country :
{url}/books?department.store.city.country.name=italy
Is there any way to edit the #ApiFilter(SearchFilter::class, properties={}) in order to get simply at the end ?
{url}/books?country_filter=italy
Thanks !
Thank you for your advices,
After some (hours of) researches, I came to the conclusion to extend the SearchFilter when creating my personnal CountryFilter :
In my entity class :
/*
* #ApiFilter(CountryFilter::class, properties={
* "country_filter": "department.store.city.country.name",
* })
*/
In my App\Filter\CountryFilter.php :
<?php
namespace App\Filter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use Doctrine\ORM\QueryBuilder;
final class CountryFilter extends SearchFilter
{
protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
{
foreach($this->properties as $alias => $propertyName){
if($alias == $property){
$property = $propertyName;
break;
}
}
/*
if (
null === $value ||
!$this->isPropertyEnabled($property, $resourceClass) ||
!$this->isPropertyMapped($property, $resourceClass, true)
) {
return;
}
*/
// The rest of the SearchFilter.php copy/pasted code ...
}
public function getDescription(string $resourceClass): array
{
// ....
}
}
You can make your one custom api filter and add your own logic in it.Call it country_filter and pass one value only, after that a custom query will search in database and return the rows. To make one you have to extend the AbstractFilter class and after that you have to add this filter it in your entity. A good tutorial from official site is here and the next chapter here

how to access annotation of an property(class,mappedBy,inversedBy)

Good morning,
Is it exist an function where I pass an entity and the propertyName and return me the mappedBy,inversedBy and absoluteClassName of an Entity.
The goal is to use the __call to create automatic getteur/setteur and addFucntion bidirectionnal.
I don't want to use generates Entities I want all getteur,setteur and add Function use __call.
But i can"t do an addBirectionnal if i don't know if the relation is many to many or one to many and if i don't know the name of the mappedBy.
my code:
public function __get($p){
return $this->$p;
}
public function __set($p,$v){
$this->$p = $v;
return $this;
}
public function __call($name,$arguments){
if(substr($name,1,3)=='et')
$name2 = substr(3);
if($name[0] == 'g'){
return $this->$name2;
}else{//substr($name,0,1) == 's'
$this->$name2 = $arguments[0];
/*for a one to one*/
/*$mappedByName= getmappedByOrInversedBy(get_class($name),$name2);
if($mappedByName){
$this->$name->$mappedByName = $this;/
}*/
return $this;
}
}
}
I need getmappedByOrInversedBy, thanks.
edit: I try this
public function test(){
$str = "AppBundle\Entity\Group";
$mapping = new \Doctrine\ORM\Mapping\ClassMetadataInfo($str);
$d = $mapping->getAssociationMappedByTargetField('trad');
var_dump($d);
return $this->render('default/index.html.twig', array(
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..'),
));
}
class Group
{
...
/**
* #ORM\OneToOne(targetEntity="Traduction",inversedBy="grp")
*/
protected $trad;
}
Result : Undefined index: trad
The ClassMetadataInfo is what you are looking for.
Creates an instance with the entityName :
$mapping = new \Doctrine\ORM\Mapping\ClassMetadataInfo($entityNamespaceOrAlias);
Then, get the informations you want :
Get all association names: $mapping->getAssociationNames();
Get the join column of an association:
$mapping->getSingleAssociationJoinColumnName($fieldName);
Get the mappedBy column of an association:
$mapping->getAssociationMappedByTargetField($fieldName);
...
Look at the class to know which method you can access.
Hopes it's what you expect.
EDIT
As you can access the EntityManager (i.e. from a controller), use :
$em = $this->getDoctrine()->getManager();
$metadata = $em->getClassMetadata('AppBundle:Group');
To be sure there is no problem with your entity namespace, try :
print $metadata->getTableName();
To retrieve the associations of the entity, use :
$metadata->getAssociationNames();
And to get the mapping informations of an existing association, use :
$metadata->getAssociationMapping($fieldName);
And to get all the association mappings of your entity, use:
$metadata->getAssociationMappings();

Symfony2 set class variable with init or construct methods

Have recently been using Symfony2 after using ZF for some time.
I am having problems trying to do something relatively simple, I think.
The following code is within a controller:
private $current_setid = "";
public function __construct() {
$current_set = $this->getCurrentSet();
if ($current_set == "") {
return $this->redirect($this->generateUrl('selectset'));
}
$this->current_setid = $current_set;
}
public function getCurrentSet() {
$session = $this->get("session");
$set = $session->get('set');
return $set;
}
public function setCurrentSet($setid) {
$session = $this->get("session");
$session->set('set', "$setid");
}
If I use __construct() I get errors like:
Fatal error: Call to a member function get() on a non-object in
I have tried using __init() and init() both of which do not seem to get called.
Can anyone point me in the right direction? Is there a simple way to do this or do I have to look into event listeners?
Have you tried getting your session like they do in official documentation?
$session = $this->getRequest()->getSession();
$foo = $session->get('foo');
Basically get fetch dependencies from container and container in the Controller is injected using setter dependency injection. You just not have container in the time of __construct yet.
Just ended up opting for placing a check in every method in the class. Seems silly to have to do that but I find I often have to do that in Symfony2 with the lack of init, postDispatch type methods like ZF has.
Even trying to remove the check to another method was counter productive as I still had to check the return from that method as $this->redirect does not seem to work unless it is within an Action method. For example:
public function isSetSet() {
$current_set = $this->getCurrentSet();
if ($current_set == "") {
$url = $this->generateUrl('selectset');
return $this->redirect($url);
}
return TRUE;
}
public function someAction() {
$check = $this->isSetSet();
if($check != TRUE){
return $check;
}
...
}
So each method needs that 4 line check but the whole check can be done in 4 lines anyway so no need for that extra method:
public function anotherAction() {
$current_setid = $this->getCurrentSet();
if ($current_setid == "") {
return $this->redirect($this->generateUrl('selectset'));
}
...
}

Actionscript 3 introspection -- function names

I am trying to iterate through each of the members of an object. For each member, I check to see if it is a function or not. If it is a function, I want to get the name of it and perform some logic based on the name of the function. I don't know if this is even possible though. Is it? Any tips?
example:
var mems: Object = getMemberNames(obj, true);
for each(mem: Object in members) {
if(!(mem is Function))
continue;
var func: Function = Function(mem);
//I want something like this:
if(func.getName().startsWith("xxxx")) {
func.call(...);
}
}
I'm having a hard time finding much on doing this. Thanks for the help.
Your pseudocode is close to doing what you want. Instead of using getMemberNames, however, which can get private methods, you can loop over the members with a simple for..in loop, and get the values of the members using brackets. For example:
public function callxxxxMethods(o:Object):void
{
for(var name:String in o)
{
if(!(o[name] is Function))
continue;
if(name.startsWith("xxxx"))
{
o[name].call(...);
}
}
}
Dan Monego's answer is on the money, but only works for dynamic members. For any fixed instance (or static) members, you'll have to use flash.utils.describeType:
var description:XML = describeType(obj);
/* By using E4X, we can use a sort of lamdba like statement to find the members
* that match our criteria. In this case, we make sure the name starts with "xxx".
*/
var methodNames:XMLList = description..method.(#name.substr(0, 3) == "xxx");
for each (var method:XML in methodNames)
{
var callback:Function = obj[method.#name];
callback(); // For calling with an unknown set of parameters, use callback.apply
}
Use this in conjunction with Dan's answer if you have a mix of dynamic and fixed members.
I've done some work and combined both approaches. Mind you, it works only for publicly visible members - in all other cases null is returned.
/**
* Returns the name of a function. The function must be <b>publicly</b> visible,
* otherwise nothing will be found and <code>null</code> returned.</br>Namespaces like
* <code>internal</code>, <code>protected</code>, <code>private</code>, etc. cannot
* be accessed by this method.
*
* #param f The function you want to get the name of.
*
* #return The name of the function or <code>null</code> if no match was found.</br>
* In that case it is likely that the function is declared
* in the <code>private</code> namespace.
**/
public static function getFunctionName(f:Function):String
{
// get the object that contains the function (this of f)
var t:Object = getSavedThis(f);
// get all methods contained
var methods:XMLList = describeType(t)..method.#name;
for each (var m:String in methods)
{
// return the method name if the thisObject of f (t)
// has a property by that name
// that is not null (null = doesn't exist) and
// is strictly equal to the function we search the name of
if (t.hasOwnProperty(m) && t[m] != null && t[m] === f) return m;
}
// if we arrive here, we haven't found anything...
// maybe the function is declared in the private namespace?
return null;
}
greetz,
tox

Can I get some advice on JavaScript delegates?

I'm rusty with delegates and closures in JavaScript, and think I came across a situation where I'd like to try to use one or both.
I have a web app that behaves a lot like a forms app, with fields hitting a server to change data on every onBlur or onChange (depending on the form element). I use ASP.NET 3.5's Web Services and jQuery to do most of the work.
What you need to know for the example:
isBlocking() is a simple mechanism to form some functions to be synchronous (like a mutex)
isDirty(el) checks to make sure the value of the element actually changed before wasting a call to the server
Agent() returns a singleton instance of the WebService proxy class
getApplicationState() passes a base-64 encoded string to the web service. This string represents the state of the application -- the value of the element and the state are passed to a service that does some calculations. The onSuccess function of the web service call returns the new state, which the client processes and updates the entire screen.
waitForCallback() sets a flag that isBlocking() checks for the mutex
Here's an example of one of about 50 very similar functions:
function Field1_Changed(el) {
if (isBlocking()) return false;
if (isDirty(el)) {
Agent().Field1_Changed($j(el).val(), getApplicationState());
waitForCallback();
}
}
The big problem is that the Agent().Field_X_Changed methods can accept a different number of parameters, but it's usually just the value and the state. So, writing these functions gets repetitive. I have done this so far to try out using delegates:
function Field_Changed(el, updateFunction, checkForDirty) {
if (isBlocking()) return false;
var isDirty = true; // assume true
if (checkForDirty === true) {
isDirty = IsDirty(el);
}
if (isDirty) {
updateFunction(el);
waitForCallback();
}
}
function Field1_Changed(el) {
Field_Changed(el, function(el) {
Agent().Field1_Changed($j(el).val(), getTransactionState());
}, true);
}
This is ok, but sometimes I could have many parameters:
...
Agent().Field2_Changed($j(el).val(), index, count, getApplicationState());
....
What I'd ultimately like to do is make one-linen calls, something like this (notice no getTransactionState() calls -- I would like that automated somehow):
// Typical case: 1 value parameter
function Field1_Changed(el) {
Field_Changed(el, delegate(Agent().Field1_Changed, $j(el).val()), true);
}
// Rare case: multiple value parameters
function Field2_Changed(el, index, count) {
Field_Changed(el, delegate(Agent().Field1_Changed, $j(el).val(), index, count), true);
}
function Field_Changed(el, theDelegate, checkIsDirty) {
???
}
function delegate(method) {
/* create the change delegate */
???
}
Ok, my first question is: Is this all worth it? Is this harder to read but easier to maintain or the other way around? This is a pretty good undertaking, so I may end up putting a bounty on this one, but I'd appreciate any help you could offer. Thanks!
UPDATE
So, I've accepted an answer based on the fact that it pointed me in the right direction. I thought I'd come back and post my solution so that others who may just be starting out with delegates have something to model from. I'm also posting it to see if anybody wants to try an optimize it or make suggestions. Here's the common Field_Changed() method I came up with, with checkForDirty and omitState being optional parameters:
function Field_Changed(el, args, delegate, checkForDirty, omitState) {
if (isBlocking()) return false;
if (!$j.isArray(args) || args.length == 0) {
alert('The "args" parameter in Field_Changed() must be an array.');
return false;
}
checkForDirty = checkForDirty || true; // assume true if not passed
var isDirty = true; // assume true for updates that don't require this check
if (checkForDirty === true) {
isDirty = fieldIsDirty(el);
}
if (isDirty) {
omitState = omitState || false; // assume false if not passed
if (!omitState) {
var state = getTransactionState();
args.push(state);
}
delegate.apply(this, args);
waitForCallback();
}
}
It handles everything I need it to (check for dirty, applying the application state when I need it to, and forcing synchronous webservice calls. I use it like this:
function TransactionAmount_Changed(el) {
Field_Changed(el, [cleanDigits($j(el).val())], Agent().TransactionAmount_Changed, true);
}
cleanDigits strips out junk characters the user may have tried to type in. So, thanks to everyone, and happy coding!
OK, few things:
Delegates are extremely simple in javascript since functions are first class members.
Function.apply lets you call a function with an array of arguments.
So you can write it this way
function Field_Changed(delegate, args)
{
if (isBlocking()) return false;
if (isDirty(args[0])) { //args[0] is el
delegate.apply(this, args);
waitForCallback();
}
}
And call it as:
Field_Changed(Agent().Field2_Changed, [el, getApplicationState(), whatever...]);
I have been using the following utility function that I wrote a long time ago:
/**
* #classDescription This class contains different utility functions
*/
function Utils()
{}
/**
* This method returns a delegate function closure that will call
* targetMethod on targetObject with specified arguments and with
* arguments specified by the caller of this delegate
*
* #param {Object} targetObj - the object to call the method on
* #param {Object} targetMethod - the method to call on the object
* #param {Object} [arg1] - optional argument 1
* #param {Object} [arg2] - optional argument 2
* #param {Object} [arg3] - optional argument 3
*/
Utils.createDelegate = function( targetObj, targetMethod, arg1, arg2, arg3 )
{
// Create an array containing the arguments
var initArgs = new Array();
// Skip the first two arguments as they are the target object and method
for( var i = 2; i < arguments.length; ++i )
{
initArgs.push( arguments[i] );
}
// Return the closure
return function()
{
// Add the initial arguments of the delegate
var args = initArgs.slice(0);
// Add the actual arguments specified by the call to this list
for( var i = 0; i < arguments.length; ++i )
{
args.push( arguments[i] );
}
return targetMethod.apply( targetObj, args );
};
}
So, in your example, I would replace
function Field1_Changed(el) {
Field_Changed(el, delegate(Agent().Field1_Changed, $j(el).val()), true);
}
With something along the lines
function Field1_Changed(el) {
Field_Changed(el, Utils.createDelegate(Agent(), Agent().Field1_Changed, $j(el).val()), true);
}
Then, inside of Agent().FieldX_Changed I would manually call getApplicationState() (and encapsulate that logic into a generic method to process field changes that all of the Agent().FieldX_Changed methods would internally call).
Closures and delegates in JavaScript:
http://www.terrainformatica.com/2006/08/delegates-in-javascript/
http://www.terrainformatica.com/2006/08/delegates-in-javascript-now-with-parameters/

Resources