I have the following QueryBuilder snippet working as expected:
$restaurants = $qb->select('r.id, r.name, r.addressGpsLat, r.addressGpsLng, r.addressZip, r.addressCity')
->from('BackendBundle:Restaurant', 'r')
->orderBy('r.name', 'ASC');
In our Restaurant entity we calculate ratings based on a relation, which looks like this:
public function getRating()
{
$rating = 0;
$votes = count($this->votes);
foreach ($this->votes as $vote) {
$rating += $vote->getRating();
}
if ($votes == 0) {
return null;
}
return number_format(($rating / $votes), 2, ',', '.');
}
So my question: is there a way I get the result of the getRating() property into my QueryBuilder object? We need it to be a seperate attribute in our JSON response. E.g. { …, "rating":2.2, …}
Any advice on this? Thanks!
Related
I am just trying to get the total value of one of the fields of my documents but it's not working. What am I missing?
#ProductRepository
public function countTotalValue()
{
return $this->createQueryBuilder('a')
->select('SUM(a.price)')
->getQuery()
->getSingleScalarResult()
;
}
I discovered it!
public function countTotalValue()
{
$array = $this->createQueryBuilder()
->select('price')
->hydrate(false)
->getQuery()
->execute()
->toArray()
;
$array = array_column($array, 'price');
return (array_sum($array));
}
It was returning a complex array, I had to stripe it before make the sum.
I am attempting to add the 'AbsoluteLink' property to each DataObject in a DataList and then convert the list to JSON with JSONDataFormatter::convertDataObjectSet().
I have the following function:
public function json() {
$data = ResourceCentreArticlePage::get()->filter('ShowInMenus', '1')->filter('ShowInSearch', '1')->sort('Created', 'DESC');
$pageArray = new ArrayList();
foreach ($data as $page) {
$page->AbsoluteLink = $page->AbsoluteLink();
$pageArray->push($page);
}
// If I dump out the content of $pageArray here the object has the AbsoluteLink property
$jsonFormatter = new JSONDataFormatter();
$jsonData = $jsonFormatter->convertDataObjectSet($pageArray);
// If I dump out the content of $jsonData here there is no AbsoluteLink property
$this->response->addHeader("Content-type", "application/json");
return $jsonData;
}
The problem:
The AbsoluteLink property is removed after running the $pageArray through the convertDataObjectSet method.
What am I missing?
Using $jsonFormatter->setCustomAddFields(); will help here.
Add the following to the Page class:
public function getMyAbsoluteLink() {
return $this->AbsoluteLink();
}
For example to the Page.php:
class Page extends SiteTree {
public function getMyAbsoluteLink() {
return $this->AbsoluteLink();
}
}
And use that "magic field" like this:
public function json() {
$pages = Page::get()
->filter('ShowInMenus', '1')
->filter('ShowInSearch', '1')
->sort('Created', 'DESC');
$jsonFormatter = new JSONDataFormatter();
// add your custom field
$jsonFormatter->setCustomAddFields(["MyAbsoluteLink"]);
$jsonData = $jsonFormatter->convertDataObjectSet(
$pages
);
return $jsonData;
}
Note the $jsonFormatter->setCustomAddFields(["MyAbsoluteLink"]); and I removed the array manipulation.
Also I removed your array manipulation. How the convertDataobjectSet function works it seems you can't amend the objects before it runs.
So we have such dql
$oQuery = $this->createQueryBuilder('assets')
->addSelect('flags')
->addSelect('types')
->addSelect('groups')
->leftJoin('Site\MainBundle\Entity\123\invFlags', 'flags', Join::WITH, 'assets.flag = flags.flagID')
->leftJoin('Site\MainBundle\Entity\123\invTypes', 'types', Join::WITH, 'assets.typeID = types.typeID')
->leftJoin('Site\MainBundle\Entity\123\invGroups', 'groups', Join::WITH, 'types.groupID = groups.groupID');
if (!empty($aFilter)) {
$bFirst = true;
foreach ($aFilter as $sKey => $sValue) {
if ($bFirst) {
$oQuery->where($oQuery->expr()->eq('assets.' . $sKey, $sValue));
$bFirst = false;
continue;
} else {
if ($sValue === null) {
$oQuery->andWhere($oQuery->expr()->isNull('assets.' . $sKey));
}
}
}
}
return $oQuery->getQuery()->getResult();
We call it from repository and have result... BUT. In sql query ($oQuery->getQuery()->getSQL()) I see all columns and proper left join I need, but NOT in result. Why it happens? When I return '->getScalarResult()' I receive all needed data but like array and with prefix of tables
array(38) {
["assets_id"]=>string(4) "4558"
["assets_characterID"]=>string(8) "90206263"
["assets_parentItemID"]=>NULL
Can I anyhow get simple 'combined' object' with all get methods?
ADD:
Forgot to say that there are no relations in entities.
As I don't want id values from a select with createQuery, but the select command doesn't allow omitting id (primary key) from the actual query (using "partial") I need to remove the id's from the result from getArrayResult()
I made this small recursive key remover static class:
class arrayTool
{
public static function cleanup($array, $deleteKeys)
{
foreach($array as $key => $value )
{
if(is_array( $value))
{
$array[$key] = self::cleanup($array[$key], $deleteKeys);
} else {
if (in_array($key, $deleteKeys)) unset($array[$key]);
}
}
return $array;
}
}
Which is called by an array containing one or more keys to be removed from the result, of any array depth:
$array = arrayTool::cleanup($array, array('id', 'id2'));
I have a small symfony2 application where a user can create pages. Each page should be accessible via the route /{user_slug}/{page_slug}. I have the entities user and page and I use the sluggable behavior for both entities. In order to find the correct page the combination of user_slug and page_slug has to be unique.
What is the best way to check that the combination of user_slug and page_slug is uniqe?
Try this in your prepository:
public function findByUsernameAndSlug($username, $slug)
{
$em = $this->getEntityManager();
$query = $em->createQuery("
SELECT g
FROM Acme\PagesBundle\Entity\Page p
JOIN p.owner u
WHERE u.username = :username
AND p.slug = :slug
")
->setParameter('username', $username)
->setParameter('slug', $slug);
foreach ($query->getResult() as $goal) {
return $goal;
}
return null;
}
Before you persist the entity in your service-layer check whether given combination of user and page slug are unique, if not modify the page slug (append -2 or something like that) or throw an exception:
public function persistPage(Page $page) {
$userSlug = $page->getUser()->getSlug();
$pageSlug = $page->getSlug();
if ($this->pagesRepository->findOneBySlugs($userSlug, $pageSlug) != null) {
// given combination already exists
throw new NonUniqueNameException(..);
// or modify the slug
$page->setSlug($page->getSlug() . '-2');
return $this->persistPage($page);
}
return $this->em->persist($page);
}
// PagesRepository::findOneBySlugs($userSlug, $pageSlug)
public function findOneBySlugs($userSlug, $pageSlug) {
$query = $this->em->createQueryBuilder('p')
->addSelect('u')
->join('p.user', 'u')
->where('p.slug = :pageSlug')
->where('u.slug = :userSlug;)
->getQuery();
$query->setParameters(combine('userSlug', 'pageSlug'));
return $query->getSingleResult();
}