How to count current week publish node by specific user in drupal for specific content-type ?
Something like this should work:
// select the number of nodes that is of a specific content type and
// were created this week by the named user
function <theme>_post_count($user_name, $content_type) {
$query = "SELECT COUNT(*) node_count FROM {node} n
INNER JOIN {users} u ON u.name = :user_name && u.uid = n.uid
WHERE n.type = :content_type &&
WEEK(FROM_UNIXTIME(n.created)) = WEEK(CURRENT_TIMESTAMP())";
$result = db_query($query,
array(
':user_name' => $user_name,
':content_type' => $content_type
))->fetch();
return $result->node_count;
}
You could easily modify the above query to take a uid instead of a user name and so on.
You would then call this function like this:
print 'Articles added by admin during this week: '.<theme>_post_count('admin', 'article');
Related
I have a database with table called "message" with attributtes received, emitter, text, date. I want to select the last message that a user received, with max date.
With this code I get null value but the user have messages in the table:
$message = $this->getEntityManager()
->createQuery(
'SELECT m FROM App\Entity\Message m WHERE
m.receiver = :user
AND
m.createdAt = (SELECT MAX(m1.createdAt) FROM App\Entity\Message AS m1)
'
)
->setParameters([
'user' => $user
])
->getResult();
Your subquery doesn't include the user-condition; it fetches max(created) of messages, which is not necessarily one of the given user. But the subquery approach seems to overcomplicate things anyway.
An easier way would be: select messages of user order by created and limit to 1
in SQL
SELECT m.* FROM messages WHERE user_id=:user ORDER BY created DESC LIMIT 1
in DQL
$this
->getEntityManager()
->createQuery('SELECT m FROM App\Entity\Message m WHERE
m.receiver = :user
AND
m.createdAt = (SELECT MAX(m1.createdAt) FROM App\Entity\Message AS m1)
ORDER BY m.createdAt DESC LIMIT 1
')
->setParameters([
'user' => $user
])
->getResult();
or even simpler (using doctrine repository interface)
$entityMangager
->getRepository(Message::class)
->findOneBy(['user' => $user], ['created' => 'DESC'])
Also: Probably you want to make sure you have an index over user_id, created on that table.
SELECT address
FROM user_address
WHERE username = '$user->name'
ORDER BY time DESC
LIMIT 1
Here is the SQL query that I can understand. How is it possible to convert it into Drupal's 7 PHP? I'm trying to figure that out for a day, and I tried different approaches, but it seems that I am just bad in that.
You can use db_select :
$results = db_select('user_address', 'ua')
->fields('ua', array('address'))
->condition('ua.username', $user->name, '=')
->orderBy('ua.time', 'DESC')
->range(0,1)
->execute()
->fetchAll();
var_dump($results);
Otherwise you can use db_query if you want to write entire SQL :
$results = db_query("SELECT address
FROM user_address
WHERE username = :username
ORDER BY time DESC
LIMIT 1 ", array(':username' => $user->name))->fetchAll();
var_dump($results);
Finally you can use db_query_range :
$page = 0;
$limit = 1
$results = db_query_range("SELECT address
FROM user_address
WHERE username = :username
ORDER BY time DESC",
$page * $limit,
$limit,
array(':username' => $user->name))
->fetchAll();
var_dump($results);
Try this:
$result = db_select('user_address', 'ua')
->fields('ua', array('address'))
->condition('ua.username', $user->name)
->execute()
->fetchAll();
For that we use db_select() or db_query() - first one preferable.
$query = db_select('user_address', 'u');
// Add condition and fields
$query->condition('u.username', ‘james’)
$query->fields('u’ array('u.address'));
// execute it
$result = $query->execute();
foreach ($result as $record) {
// Do something with each $record
}
For more see
https://www.drupal.org/docs/7/api/database-api/dynamic-queries/introduction-to-dynamic-queries.
update: see condition portion. Also, you can put this in a module or php executable area of your site or via drush command line.
Change the username James to match your need
$result = $result = db_select('usr_address','u')
->fields('u',array('address','uid'))
->range(0,1)
->orderby('time', 'DESC')
->condition('u.uid',$uid,'=')
->execute();
here is how it actually worked.
Thank you for your suggestions, but at the end I made it. By myself. Well, kinda ;D
I'm trying to use JoinSqlBuilder to select a data from one of the joined tables, and can't find a way to do that unless I list all columns from that table. Hopefully I'm missing something and it actually can be done.
This is approximately what I have:
var sql = new JoinSqlBuilder<Product, Product>()
.Join<Product, Customer>(src => src.Id, dst => dst.Id)
.Where<Customer>(x => x.Id == Id);
and I want to select everything from a product table. The query above throws an exception complaining about column name collisions, so its clearly does a select from both tables.
Edit: In the end I want to have this sql (never mind the design, its not a real thing):
select
p.* //<-- This is the piece that I'm struggling with
from product p inner join customer c on p.id on c.productId
where blah;
Looks like OrmLite want me to explicitly list all columns I want to return, which I want to avoid.
Note: I'm using 3.9.71 of servicestack. I've not looked at the 4.0 implementation yet.
I think you have a FK relationship problem with your join. Assuming that a product has a customer FK named (CustID), it'd look like this. Additionally, you'd need a POCO to represent the result set, if you are returning a "combination" of the results. I don't think you'll want to return both "ID" columns, and instead return a FK column.
return _factory.Run<ProductCustomer>(conn=>
{
var jn = new JoinSqlBuilder<Product, Customer>();
jn = jn.Join<Product, Customer>(srcProd => srcProd.CustId,
dstCust => dstCust.Id, // set up join Customer.id -> Product.CustId
p => new { p.Id, p.OtherField}, // product table fields returned
c => new { c.Name, c.AddressId}, // customer fields returned
null, //where clause on the product table
cust=>cust.Id = customerId // where clause on the customer table
);
var sql = jn.ToSQL();
return conn.FirstOrDefault<ProductCustomer>(sql);
}
Hope this helps.
Edit: After your Edit, try this:
// set up join Customer.id -> c.ProductId
jn = jn.Join<Product, Customer>(srcProd => srcProd.Id, dstCust => dstCust.productId)
.Where<Customer>(c=>c.Id == custIdParameter);
var sql = jn.ToSql();
You can add a ".Where" again for the
Where<Product>(p=>p.id == foo);
if you need to add more product with your BLAH. This should get you close.
Have you tried the SelectAll extension method?
var sql = new JoinSqlBuilder<Product, Product>()
.Join<Product, Customer>(src => src.Id, dst => dst.Id)
.SelectAll<Product>()
.Where<Customer>(x => x.Id == Id);
i wanna query for all of my categories like this:
$othercategories = $this->getDoctrine()->getRepository('Bundle:Category')->findBy(
array('language' => $language, 'active' => 1),
array('sorting' => 'ASC')
);
what i wanna do is to add another parameter to my query, i want all categories EXCEPT one with a specific id. so like:
WHERE id NOT IN ( 2 )
or
WHERE id <> 2
how can i achieve that?
You can use DQL queries like this
$em = $this->getDoctrine()->getEntityManager();
$query = $em->createQuery( 'SELECT c FROM Bundle:Category c WHERE c.language = :language AND c.active = 1 AND c.id NOT IN ( 2 ) ORDER BY c.language ASC' )
->setParameter('language', $language);
$category= $query->getResult();
Sorry I couldn't test this because I am using my phone to answer this question and I don't know your entity variables. Let me know what changes you did to make it work, it will help others.
For more info check http://symfony.com/doc/master/book/doctrine.html
You can add these queries in repository and reuse them. Refer the Cook book on http://symfony.com/doc/master/cookbook/index.html
Hope this helped.
You can use this syntax if you prefer
$repository = $this->getDoctrine()->getRepository('Bundle:Category');
$queryBuilder = $repository->createQueryBuilder();
$notInCategoryIds = array(2); // Category ids that will be excluded
$queryBuilder->select('c')
->from('Bundle:Category', 'c')
->where('c.language = :language')->setParameter('language', $language)
->andWhere('c.active = :active')->setParameter('active', 1)
->andWhere($queryBuilder->expr()->notIn('c.id', $notInCategoryIds)
->orderBy('c.sorting', 'ASC');
$results = $queryBuilder->getQuery()->getResult();
It's probably going to be more useful for other developers that prefers this syntax
I want to do something like that into Doctrine SQL...
SELECT N.id as n_id, C.id as c_id, T.id as t_id, C.author_id, C.body as comment FROM `news` N
LEFT JOIN thread T on T.id = N.id
LEFT JOIN comment C on C.thread_id = T.id
WHERE 1
So I have made this :
$rsm = new ResultSetMapping;
$rsm->addEntityResult('App\MyBundle\Entity\News', 'N');
$cols = array ('id', 'title','date');
foreach ($cols as $key => $col) {
$rsm->addFieldResult('N', $col, $col);
}
// thread
$rsm->addJoinedEntityResult('App\MyBundle\Entity\Thread' , 'T', 'N', 'thread');
$rsm->addFieldResult('T', 't_id', 'id');
$sql = 'SELECT N.id, N.title, N.date, T.id AS t_id FROM news N ' .
'LEFT JOIN thread T ON T.id = N.id WHERE N.id = 1';
$query = $this->_em->createNativeQuery($sql, $rsm);
But I have an error:
Notice: Undefined index: thread in /vendor/doctrine/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php line 85
I want to precise that there is no member link beetween the 2 entities.
Any ideas please?
Thanks for all
See ya
Sam
According to the docs:
The fourth and last parameter is the name of the field on the parent entity result that should contain the joined entity result.
ref: http://www.doctrine-project.org/docs/orm/2.1/en/reference/native-sql.html#joined-entity-results
you maybe missed to define the thread property in the News class that will receive your joined entity.