How to order results with findBy() in Doctrine - php

I am using the findBy() method on a Doctrine repository:
$entities = $repository->findBy(array('type'=> 'C12'));
How can I order the results?

The second parameter of findBy is for ORDER.
$ens = $em->getRepository('AcmeBinBundle:Marks')
->findBy(
array('type'=> 'C12'),
array('id' => 'ASC')
);

$ens = $em->getRepository('AcmeBinBundle:Marks')
->findBy(
array(),
array('id' => 'ASC')
);

$cRepo = $em->getRepository('KaleLocationBundle:Country');
// Leave the first array blank
$countries = $cRepo->findBy(array(), array('name'=>'asc'));

Related

Mongo mapper use aggregation framework

Can someone please point out my error, trying to sum a field(amount) using userId field?
https://fatfreeframework.com/3.6/mongo-mapper
Here is my code, this is returning me all documents matched with userId but not the sum.
$f3 = \Base::instance();
$mapper = new \DB\Mongo\Mapper($f3->get('MongoDB'),'transactions');
$filter = array('userId'=>'452');
$options = array(
array(
'group' => array(
'_id' => array('userId' => $userId),
'amount' => array('$sum' => 'amount')
)
)
);
$data = $mapper->find($filter, $options);
echo "<pre>";
print_r($data);
exit;
The mongo mapper uses the db.collection.group() method rather than the aggregation framework. Therefore you won't be able to call accumulators such as $sum.
Instead you must use the following syntax:
$group = [
'keys'=>['userId'=>1],
'initial'=>['sum'=>0],
'reduce'=>'function(obj,result){result.sum+=obj.amount;}',
'finalize'=>'function(result){}',
);
$data = $mapper->find($filter, ['group'=>$group]);

Laravel: Nesting query join results in a sub array

NOTE Please do not suggest using Eloquent, this is specifically for the Laravel query builder.
For performance reasons we are using Query Builder to retrieve results from a table:
DB::table('posts')->get();
If we then want to join a relation onto that query:
DB:table('posts')
->leftJoin('comments', 'posts.id', '=', 'comments.post_id')
->get();
The results are merged into the array of each post:
[
'id' => 1,
'title' => 'My Blog Post',
'content' => '<h1>This is a post</h1><p>hello world</p>',
'post_author' => 'Billy',
'comment' => 'This is a comment',
'comment_author' => 'Andrew',
]
How can we have the joined results placed into a nested array? Such as:
[
'id' => 1,
'title' => 'My Blog Post',
'content' => '<h1>This is a post</h1><p>hello world</p>',
'post_author' => 'Billy',
'comment' => [
'id' => 22,
'comment' => 'This is a comment',
'comment_author' => 'Andrew',
],
]
Dont think its doable out of the box without Eloquent.
You can go the primitive route:
$results = DB:table('posts')
->leftJoin('comments', 'posts.id', '=', 'comments.post_id')
->select('posts.*', 'comments.*', 'comments.id as comments_id')
->get();
foreach($results as &$result)
{
$result['comment'] = [
'id' => $result['comment_id'],
'comment' => $result['comment'],
'comment_author' => $result['comment_author']
];
unset($result['comment_author'], $result['comment_id']);
}
Since you work with DB facade and not Eloquent, and cannot use built-in with() method, you have to implement it yourself:
$posts = DB::table('posts')->get()->toArray();
$comments = DB::table('comments')->get()->toArray();
foreach($posts as &$post)
{
$post->comments = array_filter($comments, function($comment) use ($post) {
return $comment->post_id === $post->id;
});
}
return $posts;
If you want to get rid of post_id for comments entries, you can do:
$posts = DB::table('posts')->get()->toArray();
$comments = DB::table('comments')->get()->toArray();
foreach($posts as &$post)
{
$comments = array_filter($comments, function($comment) use ($post) {
return $comment->post_id === $post->id;
});
$post->comments = array_map(function ($comment) {
unset($comment->id);
return $comment;
}, $comments);
}
return $posts;
(I guess the runtime would be similar to with(), since after-all MySql does not provide this functionality out-of-the-box).
Here some new information:
$data= $DB->select("select posts.*,comments from posts left join comments on posts.id = comments.post_id");
I am not sure it is work or not but you can try
You can try with this
$data= $DB->select("select *,(select json_agg(datas) from (select * from comments where posts.id=comments.post_id) as datas) as comments from posts;");
But you may need to decode at comments as well

How to order joined results in Phalcon Framework

Let's pretend I'm working on a magazine, where a Category (like "sport", "art" an so on) can contain several Articles. Therefore I want to extract all articles for a specific category. In Phalcon I usually do:
$category = \Models\Category::findFirst(array(
'conditions' => 'id = ?1',
'bind' => array(1 => $id)
));
Then:
foreach ($category->Article as $article) {
// do something with $article
}
It works great, but I would like to sort those Articles - say - date wise, ascending. How could I accomplish that?
You should use get prefix in your for..loop statement, so your code should like this :
foreach ($category->getArticle(array('order' => 'date DESC')) as $article) {
// do something with $article
}
The main Docs explains more examples.
Try it & get your results.
M2sh answer is all important and actual, I just will post a secondary way, just using model designed for articles:
$page = 5; // eg. 5th page of results
$limit = 100; // eg. 100 results per page
$articles = \Models\Articles::find(array(
'conditions' => 'category_id = :cid:',
'bind' => array(
'cid' => $id
),
'order' => 'date DESC, id DESC',
'limit' => $limit,
'offset' => $page * $limit
));
It's possible to use such set of parameters in M2sh way aswell.
One more for completeness. I will borrow from yergo to illustrate the differences:
$page = 5;
$limit = 100;
$articles = \Models\Articles::query()
->where('category_id= :cid:', array('cid' => $id)
->orderBy('date DESC, id DESC')
->limit($limit)
->offset($page * $limit)
->query();

How to make associative array using PHP for loop to use in Yii 2 array map()?

I would like to make an associative array using PHP for loop to use in Yii2 map() method.
The array will look like in bellow format-
$listArray = [
['id' => '1', 'name' => 'Peter/5'],
['id' => '2', 'name' => 'John/7'],
['id' => '3', 'name' => 'Kamel/9'],
];
The id and name will be changed through each iteration of the loop. Here, the name will always hold customized value after some calculation inside the loop.
Finally, the list will be used in map() method like as following
$listData=ArrayHelper::map($listArray,'id','name');
I can use map() method directly after using the Active Record to find the list array and then use that in map() method. But it does not a give me way to use custom value for the name attribute.
$listArray = UserList::find()
->where(['status' => 1])
->orderBy('name')
->all();
$listData=ArrayHelper::map($listArray,'id','name');
How can achieve this? Direct source code example would be really great for me.
Thanks in advance.
I'm assuming you want to query an ActiveRecord for data then transfer the data into a simple array.
$listData = [];
$listArray = UserList::find()
->where(['status' => 1])
->orderBy('name')
->all();
foreach($listArray as $user){
$customName = $user->name . $this->someCalculation();
$listData[] = ["id" => $user->id, "name" => $customName];
}
Or you could use the ArrayHelper class like this:
$listArray = UserList::find()
->where(['status' => 1])
->orderBy('name')
->all();
$listData = ArrayHelper::toArray($listArray , [
'app\models\UserList' => [
'id',
'name' => function ($listArray ) {
return $listArray->word . strlen($listArray->word); // custom code here
},
],
]);
I think the preferred way of doing this by defining custom calculation rule in UserList model as:
public function getCustomRuleForUser(){
// Do what ever you want to do with your user name.
return $this->name.'Your custom rule for name';
}
And use as:
$userList = UserList::find()->all();
$listData=ArrayHelper::map($userList,'id','customRuleForUser');
Now, you have your custom rule for username list in $listData.
$model_userprofile = UserProfile::find()->where(['user_id' => Yii::$app->user->id])->one();
$model_userprofile1 = UserProfile::find()
->select('user_id')
->where(['group_id' => $model_userprofile->group_id])->all();
$listData = [];
foreach($model_userprofile1 as $user){
$id = $user->user_id;
$listData[] = ["id" => $id];
}
$dataProvider = new ActiveDataProvider
([
'query' => User::find()
->select('id,username,email')
->Where(['id' => $listData])
->orderBy(['id' => SORT_DESC]),
'pagination' => ['pagesize' => 15]]);
return $this->render('index',['dataProvider'=> $dataProvider]);

Laravel 4 paginate and orderBy

Normaly I call my database like this :
$data = array(
'one' => MyORM::paginate($this->per_page),
);
return View::make('project.index')->with($data);
But I also want to use an OrderBy so I can use:
$data = array(
'test' => MyORM::orderBy('date', 'DESC')->get(),
);
return View::make('project.index')->with($data);
But I don't know how I can "merge" the two codes?
I can also use :
$data = array(
'test2' => DB::table('martialp')
->orderBy('date', 'DESC')
->paginate(4)
);
But my class MyORM for exemple is useless with this previous code.
$data = MyORM::orderBy('date', 'DESC')->paginate(15);
return View::make('project.index', compact('data'));

Categories