Doctrine findBy with OR condition - doctrine-orm

Is it possible to use OR statement in Doctrine findBy() method?
I know that given array is interpreted as case1 AND case2...
Like this
$this->repos['notif']->findBy(array('status' => 1, 'status' => 2, 'status' => 3);
Stands for
SELECT * FROM `notif` WHERE status=1 AND status=2 AND status=3;
Now I need something to stand for:
SELECT * FROM `notif` WHERE status=1 OR status=2 OR status=3;
Is there a way to get all cases?

You can write:
$this->repos['notif']->findBy(array('status' => array(1, 2, 3)));
and that should work too.

I know that this is old question. Anyways, it's possible to use Criteria for the complex queries (in Doctrine 2 at least):
$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria
->orWhere($criteria->expr()->contains('domains', 'a'))
->orWhere($criteria->expr()->contains('domains', 'b'));
$groups = $em
->getRepository('Group')
->matching($criteria);

As far as I know this is not a supported feature by Doctrine to use IN() queries with findby. You could do two things:
Implement a findByStatus(array $statusTypes) method in your (custom) 'notif' repository class. If you like this approach I can give you a example.
Convert your findBy to the following:
$qb = $this->repos['notif']->createQueryBuilder('n');
$data = $qb->where($qb->expr()->in('status', array(1,2,3)))->getQuery()->getResult();
That should work either :)

If you are using MongoDB and need more complex queries, like "less than" linked together with OR, but cannot use a query builder, this also works with this syntax:
->findBy(array(
'$or' => array(
array('foo' => array('$lt' => 1234)),
array('$and' => array(
array('bar' => 45678),
array('baz' => array('$lt' => 89013))
))
)
));
Or as a solution for your question:
->findBy(array(
'$or' => array(
array('status' => 1),
array('status' => 2),
array('status' => 3),
)
));

Related

WP_Query meta_query REGEXP

I am pretty much below beginner level for REGEX/REGEXP and have hit a blocking point in a project I am working in, where I am trying to get the ids for posts that match the search criteria , but I want to restrict the search between 2 sub-strings. I am trying to figure out is how to write the REGEXP in the meta_query:
$args = array(
'post_type'=> 'custom',
'order' => 'DESC',
'posts_per_page' => 10,
'paged' => $page,
'meta_query' => array(
array(
'key' => 'key',
'value' => "title*".$search."*_title",
'compare' => 'REGEXP',
)
),
);
And an example of the field in the DB :
a:302:{s:5:"title";s:10:"Test title";s:6:"_title";s:19:"
Unfortunately none of the combinations I tried based on documentation of SQL REGEXP won't return any values and I am trying to understand how I can pull this off and would appreciate any input.
Also would rather stick to WP_Query for now even though an SQL LIKE "%title%{$search}%_title%" works perfectly , so an alternative solution would be how to set the compare to 'LIKE' and parse it '%' since that is not possible out of the box as the % get escaped I believe.

Missing creative spec facebook

I'm trying to create an ad using the php sdk.
I can create the campaign, targeting, adset, and the creative (which returns a creative_id that I can validate using the graph explorer).
But when I finally run the code to create the ad itself, I get an exception that looks like this:
"error_user_title" => "Missing creative spec"
"error_user_msg" => "No creative spec found for given adgroup."
I just can't find anything referring to this error.
Below is the relevant portion of my code:
$link_data = new AdCreativeLinkData();
$link_data->setData(array(
AdCreativeLinkDataFields::LINK => $route,
AdCreativeLinkDataFields::MESSAGE => $petition_statement,
AdCreativeLinkDataFields::NAME => $banner_title,
AdCreativeLinkDataFields::IMAGE_HASH => $image_hash,
));
$object_story_spec = new AdCreativeObjectStorySpec();
$object_story_spec->setData(array(
AdCreativeObjectStorySpecFields::PAGE_ID => $pageid,
AdCreativeObjectStorySpecFields::INSTAGRAM_ACTOR_ID=>$instagram_id,
AdCreativeObjectStorySpecFields::LINK_DATA=>$link_data
));
$creative = new AdCreative(null,$account_id);
$creative->setData(array(
AdCreativeFields::TITLE => $banner_title,
AdCreativeFields::BODY => $banner_subtitle,
AdCreativeFields::IMAGE_HASH => $image_hash,
AdCreativeFields::OBJECT_TYPE => 'SHARE',
AdCreativeFields::OBJECT_STORY_SPEC=>$object_story_spec
));
$creative->create();
echo 'Creative ID: '.$creative->id . "\n";
$ad = new Ad(null, $account_id);
$ad->setData(array(
AdFields::NAME => $short_name,
AdFields::ADSET_ID => $adset->id,
AdFields::CREATIVE => $creative,
AdFields::TRACKING_SPECS => array(array(
'action.type' => 'offsite_conversion',
'fb_pixel' => $pixel_code,
))
));
$ad->create(array(Ad::STATUS_PARAM_NAME => Ad::STATUS_PAUSED));
Appreciate any help.
I've often said that the only skill you need to be a successful developer is the ability to agonize over a problem for days, read through source code, google it, refactor, rewrite and then realize you forgot something fucking obvious.
AdFields::CREATIVE => $creative,
should read
AdFields::CREATIVE => $creative->id,
But the ability to persist isn't the skill you need. The real skill is to somehow resist the overwhelming urge to chuck your computer out the window and do something productive with your life instead.
After hours of testing it seems Trevor's answer is incorrect. This is the right syntax:
AdFields::CREATIVE => array('creative_id'=>$creative->id)

doctrine 2 returns errror 'proxy directory must be writable'

i am using doctrine 2 with Zendframework 2
i am trying to return an object but keep getting this error:
Your proxy directory must be writable
this is my query:
$this->getEntityManager()
->getRepository('Messages\Entity\Messages')
->findOneBy(array('id' => 6,
'receiverId' => 16
));
However, the same query return an array without any problems re:
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select(array('u'))
->from('Messages\Entity\Messages','u')
->where('u.id = :id')
->andWhere('u.receiverUserId = :receiverId')
->setParameter('receiverId',16)
->setParameter('id',(int)6);
$query = $qb->getQuery();
return $data = $query->getArrayResult();
If you are using Setup::createAnnotationMetadataConfiguration you can simply fix it by
Create the following directory in your project root. data/DoctrineORMModule/Proxy
chmod -R 755 data/DoctrineORMModule/Proxy
In your bootstrap include the path to the data directory as in:
Setup::createAnnotationMetadataConfiguration(array(__DIR__ . "/src/models"), $this->isDevMode, "data/DoctrineORMModule/Proxy")
That fixed it for me.
Proxies are simple classes which extends your actual entities and used internally by doctrine to hydrate associations of your entities by lazy-loading them. Doctrine decides to use or not to use a proxy instances on runtime for different situations and it really depends on your queries and associations in your entities. You may want to read about this subject in-depth at official documentation.
In your case, doctrine trying to generate a proxy class for your Messages entity but your proxy directory is simply not writable as error output's said.
This seems like misconfiguration of DoctineModule. (Assuming that you are using DoctrineORMModule to integrate doctrine with ZF2) Doctrine needs a writeable directory to put that generated proxy classes. For ZF2's view, data directory on application root perfectly fits for this requirement.
Make sure existence of the line below in your public/index.php:
chdir(dirname(__DIR__));
and try to use a configuration like this:
<?php
/**
* module/Application/config/module.config.php
*/
return array(
'router' => array(
// ...
),
// ...
'doctrine' => array(
'driver' => array(
//...
),
/**
* Generating proxies on runtime and using array cache instead of apc(u)
* greatly reduces the performance. So, you may want to override
* this settings on production environment.
*/
'configuration' => array(
'orm_default' => array(
'metadata_cache' => 'array',
'query_cache' => 'array',
'result_cache' => 'array',
'hydration_cache' => 'array',
'generate_proxies' => true,
'proxy_dir' => 'data/DoctrineORMModule/Proxy',
'proxy_namespace' => 'DoctrineORMModule\Proxy',
),
),
)
);
If you are using Fedora 24, enter the following commands:
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/html/YOUR_SITE/data';
restorecon -v '/var/www/html/YOUR_SITE/data'
With this, you are changing the label of the /var/www/html and giving write permission to httpd.

Doctrine2: how to remove leftJoin part of QueryBuilder

I have big fat QueryBuilder that generates sql like in this question. Apparently, all those leftJoins makes my query to crawl.
So I figured I need to fetch only the IDs that match it and later, append
$ids = $cloneOfqb->select("o.id")->resetDqlPart("join")....->getResult() ;
return $qb->andWhere("o.id IN (:ids)")->setParameter("ids", $ids)
The problem:
This would work nicely but resetDqlPart("join") removes all joins, both leftJoin and innerJoin. I use innerJoins a lot as it makes code readable. Is there a way I can reset only leftJoins but leave innerJoins? It doesn't have to be QueryBuilder object, it can be a child like Doctrine\ORM\Query if needed.
There is no way to reset only certain Joins.
I found a little discussion here, and the proposed solution (although no source code is provided) is to override the resetDqlPart() function in Doctrine's QueryBuilder.php.
Dumping $this->_dqlParts['join'] inside that function, the structure for joins appears to be the following: (my example query has an inner join and a left join, and 'e', 'ed', 'eaf' are table aliases)
array (size=1)
'e' =>
array (size=2)
0 =>
object(Doctrine\ORM\Query\Expr\Join)[666]
protected 'joinType' => string 'LEFT' (length=4)
protected 'join' => string 'e.date' (length=6)
protected 'alias' => string 'ed' (length=2)
protected 'conditionType' => null
protected 'condition' => null
protected 'indexBy' => null
1 =>
object(Doctrine\ORM\Query\Expr\Join)[654]
protected 'joinType' => string 'INNER' (length=5)
protected 'join' => string 'e.area_formativa' (length=16)
protected 'alias' => string 'eaf' (length=3)
protected 'conditionType' => null
protected 'condition' => null
protected 'indexBy' => null
You can use "getDqlPart('join')" from query builder to get applied joins, reset them via "resetDqlPart('join')" and then manually remove it from array and add it again through method "add". Not very convenient, but yet possible. Short example:
$joinDqlPart = $queryBuilder->getDQLPart('join');
$queryBuilder->resetDQLPart('join');
unset($joinDqlPart['alias'][0]);
foreach ($joinDqlPart['alias'] as $join) {
$queryBuilder->add('join', [$join->getAlias() => $join], true);
}

Symfony2, Doctrine 2: getResult Object

$posts = $em->find('Application\BlogBundle\Entity\Post',1);
print_r ($posts);
Why I got it?
Barii\BlogBundle\Entity\Post Object ( [id:Barii\BlogBundle\Entity\Post:private] => 1 [title:Application\BlogBundle\Entity\Post:private] => something [body:Application\BlogBundle\Entity\Post:private] => content )
instead of a simple array like this:
array ( [id] => 1,
[title] => "something",
[body] => "content" )
I use it with Symfony 2.
You have a couple options here. As far as I know, you can't find results as arrays from entity repositories by default. Instead, you can do one of two things:
First, you could implement a toArray() method on your entity object (perhaps through a mapped superclass) that simply returns an array of properties.
Second, you could use Doctrine Query Language to pull the information that you need using the getArrayResult() method, perhaps something like this:
$query = $em->createQuery('SELECT p FROM Application\BlogBundle\Entity\Post p WHERE p.id=:pid');
$query->setParameter('tid', $postId);
$result = $query->getArrayResult(); // shortcut for $query->getResult(Query::HYDRATE_ARRAY);
More in-depth documentation on DQL can be found here.