Array to string conversion SYmfony Sql - php

I have an sql request:
$listUsers=$connection->prepare("SELECT u.id as userid From user u , account a where (a.id_parent=$id_account OR a.id=$id_account) and u.id_account=a.id ");
$listUsers->execute();
$users=$listUsers->fetchColumn();
but fetchColumn return just one result, and I want a set of list user id to use it in the next request.
$listPush=$connection->prepare("select id from Table_name where id_user in (?));
$listPush->bindValue(1, $users);
$listPush->execute();
$idpushs=$listPush->fetchColumn();
but this return just one result. Any Idea to replace fetchColumn by other request or using doctrince.

With your logic, you can simply fetch all your users and implode it.
$listUsers=$connection->prepare("SELECT u.id as userid From user u , account a where (a.id_parent=$id_account OR a.id=$id_account) and u.id_account=a.id ");
$listUsers->execute();
$users=$listUsers->fetchAll();
$userIds = array();
foreach ($users as $user) {
$userIds[] = $user['userid'];
}
$users = implode(',', $userIds); //that hurts me so hard to code like this with symfony :'(
Fetch colum will only return the column of the next row. So for your second piece of code, you can loop over results.
But, if you're are using a framework like symfony, you have many other ways to make it cleaner. Just check out the symfony doc to use repository relations and more generally doctrine

Related

(Laravel) only retrieving users that have a relationship

In my site I have users and items. Users can create items. I want to get an array that has all users, where the users which have an item go first and the users which do not have an item go after.
So far I have done this:
$users = User::all();
foreach($users as $user) {
if ($user->item) {
$sortedUsers + $user;
}
// now loop again and add users without relationship
This is pretty inefficient and I'm sure there's a much better way to do it.
You can query on the existence of a relationship
$users = User::has('items')->with('items')->get();
with that syntax you are telling laravel to fetch all users that have a item and to eager load the items;
Edit:
After reading it does not look like you actually want the items just the users that have a item in that case all you need is
$users = User::has('items')->get();
Without seeing the relation of Items to Users I'm not sure if this will work but you can try the following:
$users = Users::select('users.*')->orderBy('items.id')->with('items')->get();
Or it might work with just:
$users = Users::orderBy('items.id')->with('items')->get();
Update
$users = Users::orderBy('items.id')->join('items', 'items.user_id', '=', 'users.id')->get();
you can try
$users = User::with('item')->get();
foreach ($users as $user) {
echo $User->item->name;
}
You can use has() to get users with items and doesntHave() to get users without items:
$withItems = User::has('items')->get();
$withoutItems = User::doesntHave('items')->get();
And then merge() two collections:
$users = $withItems->merge($withoutItems);
You said you want an array, so you can convert result into an array with toArray()
$array = $users->toArray();

QueryBuilder/Doctrine Select join groupby

So recently I have been thinking and can't find a solution yet to this problem since my lack of development with doctrine2 and symfony query builder.
I have 2 tables:
Goals: id,user_id,target_value...
Savings: id,goal_id,amount
And I need to make a select from goals (all the informations in my table are from the goals table, except that I need to make a SUM(amount) from the savings table on each goal, so I can show the user how much did he saved for his goal)
This is the MySQL query:
select
admin_goals.created,
admin_goals.description,
admin_goals.goal_date,
admin_goals.value,
admin_goals.budget_categ,
sum(admin_savings.value)
from admin_goals
inner join admin_savings on admin_savings.goal_id=admin_goals.id
where admin_goals.user_id=1
group by admin_goals.id
It returns what I want but I have no idea how to implement it with doctrine or query builder, can you please show me an example in both ways?
I highly appreciate it !
I am going to assume you need this fields only and not your AdminGoals entity. On your AdminGoalsRepository you can do something like this:
public function getGoalsByUser(User $user)
{
$qb = $this->createQueryBuilder('goal');
$qb->select('SUM(savings.value) AS savings_value')
->addSelect('goal.created')
->addSelect('goal.description')
->addSelect('goal.goalDate')
->addSelect('goal.value')
->addSelect('goal.budgetCat') //is this an entity? it will be just an ID
->join('goal.adminSavings', 'savings', Join::WITH))
->where($qb->expr()->eq('goal.user', ':user'))
->groupBy('goal.id')
->setParameter('user', $user);
return $qb->getQuery()->getScalarResult();
}
Keep in mind that the return object will be an array of rows, each row is an associated array with keys like the mappings above.
Edit
After updating the question, I am going to change my suggested function but going to leave the above example if other people would like to see the difference.
First things first, since this is a unidirectional ManyToOne between AdminSavings and AdminGoals, the custom query should be in AdminSavingsRepository (not like above). Also, since you want an aggregated field this will "break" some of your data fetching. Try to stay as much OOP when you are not just rendering templates.
public function getSavingsByUser(User $user)
{
$qb = $this->createQueryBuilder('savings');
//now we can use the expr() function
$qb->select('SUM(savings.value) AS savings_value')
->addSelect('goal.created')
->addSelect('goal.description')
->addSelect('goal.goalDate')
->addSelect('goal.value')
->addSelect('goal.budgetCat') //this will be just an ID
->join('savings.goal', 'goal', Join::WITH))
->where($qb->expr()->eq('goal.user', ':user'))
->groupBy('goal.id')
->setParameter('user', $user);
return $qb->getQuery()->getScalarResult();
}
Bonus
public function FooAction($args)
{
$em = $this->getDoctrine()->getManager();
$user = $this->getUser();
//check if user is User etc depends on your config
...
$savings = $em->getRepository('AcmeBundle:AdminSavings')->getSavingsByUser($user);
foreach($savings as $row) {
$savings = $row['savings_value'];
$goalId = $row['id'];
$goalCreated = $row['created'];
[...]
}
[...]
}
If you use createQuery(), then you can do something like this:
$dqlStr = <<<"DSQL"
select
admin_goals.created,
admin_goals.description,
admin_goals.goal_date,
admin_goals.value,
admin_goals.budget_categ,
sum(admin_savings.value)
from admin_goals
inner join admin_savings on admin_savings.goal_id=admin_goals.id
where admin_goals.user_id=1
group by admin_goals.id
DSQL;
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery($dqlStr);
$query->getResult();
On the other hand, if you would like to use createQueryBuilder(), you can check this link: http://inchoo.net/dev-talk/symfony2-dbal-querybuilder/

Select MySQL If (ID) In Array

So I trying to build a notification system (CodeIgniter) and not store it in my database by this unique ID. Now I got some problem to using `SELECT query.
Also this is array stored in "value" row:
[{"id":0,"user_id":"1","comment":"That's a Nice Video.","posttime":1403523177,"status":1},{"id":1,"user_id":"4","comment":"Nice to see this..!!","posttime":1403590409,"status":1}]
And this is my (not work) query:
$query = $this->db->get_where('post_meta',array('status'=>1),in_array('user_id', $id));
Ideas?
Note: Notification will be sparated by "user_id".
You should not use in_array('user_id', $id) on that function because it returns boolean.
On the active record page: https://ellislab.com/codeigniter/user-guide/database/active_record.html you can take a look at parameter it takes for get_where() function
$query = $this->db->get_where('mytable', array('id' => $id), $limit, $offset);
Notice how the third parameter takes $limit which talks about the number of data you'll receive. (Leaving this blank will return you all data).
Some code examples:
If you just want to get the data with status = 1, use the following:
$query = $this->db->get_where('post_meta',array('status'=>1));
If you want to get the data with status = 1 and user_id = $id, use the following:
$this->db->like('value', '"user_id":"'.$id.'"');
$query = $this->db->get_where('post_meta',array('status'=>1));
The solution above is not the best, but it should work.
The $this->db->like() function will create rules to get data in value row which has "user_id":"$id" where $id is the value that you define.
What if I want to get all notifications and group them based on their ID?
I usually get all the data and then use PHP to group them into its own array. I think it's cheaper than relying on database to do that (Correct me if i'm wrong).
So use the first code:
$query = $this->db->get_where('post_meta',array('status'=>1));
Then iterate them using foreach() or whatever you find convenient.
$data = array();
foreach($query as $k=>$v) {
// Run a function to get User ID
$user_id = your_function_here($v->value);
if(!isset($data[$user_id]))
$data[$user_id] = array();
// This is just some example to group them together, you can optimize it to your own liking
array_push($data[$user_id],$v);
}
your_function_here() is your function to get the user_id from value row on your database.

What is the correct way to retrieve information from two tables using doctrine ORM

I am trying to perform a simple join on two tables and am having trouble finding the right syntax to use - I know i am missing something simple.
From the 'users' table i need the id (working fine)
and from the 'meta' table i need the last_name (not working)
$q = Doctrine_Query::create()
->from('Users u')
->leftJoin('u.Meta m');
$users = $q->execute();
//attempt 1
foreach($users as $user){
$user_array[$user->id] = $user->last_name;
}
//attempt 2
foreach($users as $user){
$user_array[$user->id] = $user->m.last_name;
}
I've also tried adding an explicit
select(u.id, m.last_name)
to the query but the result is always the same
Uncaught exception 'Doctrine_Record_UnknownPropertyException' with message
'Unknown record property / related component "last_name" on "Users"
Obviously the property I am trying to access is not in the users table.
-The query works fine, as if I don't request the last_name field - my application works as expected..
//proof
foreach($users as $user){
$user_array[$user->id] = 'fake_last_name!';
}
Can anyone provide a simple example of how I'm meant to do this (even a link to a page in the documentation) all of the examples of JOINING DQL in the doucmentation output the query to SQL instead of iterating the results...
Doctrine Documentation: Join Syntax
I managed to work it out...
http://www.doctrine-project.org/documentation/manual/1_2/en/working-with-models
foreach($users as $user){
$user_array[$user->id] = $user->Meta->last_name;
}

Is it possible to use the Drupal api to get a list of users?

I would like to get a list of all the users who have been assigned a certain role. I could write my own SQL but I would like to use the api as much as possible.
You can use entity_load to get array of users. Here is the sample that will create list of all emails for admin users (used to send notification)
<?php
$users = entity_load('user');
$emails = '';
foreach($users as $user) {
if (array_key_exists(3, $user->roles)) {
if (strlen($emails) > 0) {
$emails .= ' ' . $user->mail;
} else {
$emails = $user->mail;
}
}
}
?>
There are generally no Drupal API functions for this sort of task (pulling up entities that match certain criteria). It tends to focus on single-entity CRUD functions in the API; everything else is up to a developer's own SQL skills.
The Views module allows you to build lists of users filtered by role, permission, etc -- but it could easily be overkill.
The SQL that worked for me:
$users = "";
$result = db_query('SELECT users.name AS users_name FROM users users
INNER JOIN users_roles users_roles ON users.uid = users_roles.uid
WHERE users_roles.rid = 4');
while ($existing_user = db_fetch_object($result)) {
if ($users != "") $users .= ", ";
$users .= $existing_user->users_name; // or do whatever
}
echo $users;
Keep in mind this is for Drupal 6 and I'm not sure about the performance of this for large user bases. Not sure about Drupal 7.
One easy option is to use Views to generate the SQL (appears below the view its self when you press the preview button) for you and then use the Drupal SQL abstraction layer to get the results you need if you need to get access to the raw data rather than display a View.
It'd look a bit like this:
$result = db_query('SELECT users.uid AS uid,
users.mail AS users_mail,
users.name AS users_name
FROM users users');
while ($existing_user = db_fetch_object($result)) {
print_r($existing_user); // or do whatever
}
Just add more fields to the view to get the complete query.
In Drupal 8:
$users = \Drupal\user\Entity\User::loadMultiple();
And if you want to get e.g. only admins:
$admins = [];
foreach ($users as $user) {
if ($user->hasRole('administrator')) {
$admins[] = $user;
}
}
I don't know about any API can help to collect users by role. Here you are some link you can get something: http://drupal.org/node/82002.
Although SO is an awesome service I suggest using drupal.org or #drupal channel on irc.freenode.org for Drupal related questions.
Ps.: sometimes SQL is not that evil:)
In Drupal 7, use EntityFieldQuery is the proper way.
In Drupal 8 the following works (in this example, load all users with the administrator role)
\Drupal::service('entity_type.manager')
->getStorage('user')
->loadByProperties(['roles' => 'administrator']);
will return a list of user entities.
To get a list of uids instead, an entity field query:
$query = \Drupal::service('entity_type.manager')->getStorage('user')->getQuery();
$query->condition('roles', 'administrator');
$query->execute();

Categories