Getting the last item from a Drupal db_fetch_object - drupal

What's the best way to do this? I've been falling back onto doing a while() loop over the result and snagging the last one as it goes by, but this seems a little, um, inelegant. D7 offers some help here, but is there any advice out there for D6? Thanks!

Why not reverse the order of your query and limit to 1 and get that?
Something like:
$result = db_query_range("SELECT * FROM {table} ORDER BY field DESC", 0, 1);
http://api.drupal.org/api/drupal/includes--database.mysql.inc/function/db_query_range/6

In general case (no engine tips like for mysql), use:
$query = 'SELECT nid, title from {node} WHERE type="page"';
$query_count = 'SELECT count(*) from {node} WHERE type="page"';
$count = db_result(db_query($query_count)); // $query_count
$last_record = db_fetch_object(db_query_range($query, $count-1, 1));
If query use ordering, just use "counter-ordering":
$query = 'SELECT nid, title from {node} WHERE type="page" ORDER BY nid ASC';
// ...
$counterquery = 'SELECT nid, title from {node} WHERE type="page" ORDER BY nid DESC LIMIT 0,1';
$last_record = db_fetch_object(db_query($counterquery));

Try to use db_last_insert_id()

Related

how to execute mysql raw query in drupal

SELECT SUM(visits) AS totalvisits
FROM (SELECT visits FROM dip_website_visits WHERE nid=20339 ORDER BY date DESC LIMIT 12) AS T
How to convert this SQL query to Drupal query? Can we use db_query for this?
You can convert it to Drupal query like this:
$subquery = \Drupal::database()->select('dip_website_visits');
$subquery->addField('dip_website_visits', 'visits');
$subquery->condition('nid', 20339);
$subquery->orderBy('date', 'desc');
$subquery->range(0, 12);
$query = \Drupal::database()->select($subquery);
$query->addExpression('sum(visits)', 'totalvisits');
$results = $query->execute()->fetchAssoc();

Doctrine left join on unrelated entity

Is there any way to do this. I'm getting more and more confused trying different things.
I have an entity conferences that can have a place.
Places are in a many to one relationship with city.
In my query I'm trying to retrieve the city info but can't seem to retrieve it in the same place result.
This is the query used:
$qbt = $this->_em->createQueryBuilder();
$qbt
->select('conference', 'diffusion', 'speaker', 'placediff', 'confcity')
->from('AppBundle:Conference', 'conference')
->leftJoin('conference.diffusion', 'diffusion')
->leftJoin('conference.speaker','speaker')
->leftJoin('conference.place','placediff')
->leftJoin('AppBundle:City', 'confcity', 'WITH', 'confcity.id = placediff.city');
return $qbt
->getQuery()
->setHint(\Doctrine\ORM\Query::HINT_INCLUDE_META_COLUMNS, true)
->useQueryCache(true)
->useResultCache(true, 3600)
->getArrayResult();
This is what is returns, currently have only one conference.
Would love to have the second array inside place though.
Any ideas on how to accomplish this? Much obliged ~
(UPDATE) In the meantime I switched to raw sql query but really looking for a way to do this using dql
public function rawConf()
{
$conn = $this->getEntityManager()->getConnection();
$sql = 'SELECT
c0_.id AS id,
c0_.startAt AS startat,
c0_.comment AS comment,
d1_.id AS diffusion_id,
d1_.hour AS diffusion_hour,
s2_.id AS speaker_id,
c0_.place_id AS place_id,
c0_.sponsor_id AS sponsor_id,
c0_.tour_id AS tour_id_8,
d1_.movie_id AS diffusion_movie_id,
s2_.contact_id AS speaker_contact_id,
c6_.name AS ville_name,
c6_.postal AS ville_post,
c6_.department as ville_depart
FROM
conference c0_
LEFT JOIN conference_diffusion c3_ ON c0_.id = c3_.conference_id
LEFT JOIN diffusion d1_ ON d1_.id = c3_.diffusion_id
LEFT JOIN conference_speaker c4_ ON c0_.id = c4_.conference_id
LEFT JOIN speaker s2_ ON s2_.id = c4_.speaker_id
LEFT JOIN place p5_ ON c0_.place_id = p5_.id
LEFT JOIN city c6_ ON (c6_.id = p5_.city_id)';
$stmt = $conn->prepare($sql);
$stmt->execute();
return $stmt->fetchAll();
}
You should get "city" from "place" as "$city" is a property of Place entity. Try this simplified query to see it works:
$qbt = $this->_em->createQueryBuilder();
$qbt
->select('conference')
->addSelect('place')
->addSelect('city')
->from('AppBundle:Conference', 'conference')
->innerJoin('conference.place', 'place')
->innerJoin('place.city', 'city')
;
And if it works - you could easily add more joins if you need.

How to 'order by' a variable in Python and SQL?

I've had a look at this solution here. But I don't quite fully understand what is going on, hence I don't know how to use a similar technique in my code.
order = "Movies.Rating_IMDB ASC"
general = db.execute (
"""
SELECT Movies.Movie_ID, Movies.Name, Movies.Year, Movies.Image
FROM Movie_Genre
JOIN Movies ON Movie_Genre.Movie_ID = Movies.Movie_ID
JOIN Genres ON Movie_Genre.Genre_ID = Genres.Genre_ID
WHERE Genres.Genre = ?
ORDER BY ?;
""",
(str(selectedGenre), order,)
)
basic = general.fetchall()

wordpress exclude posts from loop if only has one specific category

I have this category which is "community-posts" I don't want it to appear on my homepage loop so I added this to my query
<?php query_posts(array('showposts' => 4,'category__not_in' => $id_communityposts,));?>
This is working fine with me but some "community-posts" I want them to be featured on the homepage loop. (exception)
so I want to only exclude the posts that has one category as "community-posts" if it has this category and more its shows normally.
First thing do not use query_posts - it should never be used as it alter the main query. Use get_posts instead - it's much safer and perform the same task.
To answer your question, let's first imagine how the query would look in SQL (assuming your $id_communityposts is equal to 2) :
SELECT DISTINCT wp_posts.*
FROM wp_posts, wp_postmeta
LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
LEFT JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id)
WHERE
wp_posts.ID = wp_postmeta.post_id AND
(
(wp_term_taxonomy.taxonomy = 'category' AND wp_term_taxonomy.term_id NOT IN(2))
OR
(wp_postmeta.meta_key = 'featured' AND wp_postmeta.meta_value = 1)
)
ORDER BY wp_posts.post_date DESC
LIMIT 4
So we query the post, post meta and taxonomy tables and make two possible conditions:
The category ID is not 2, OR
The featured meta key of the post is set to 1 (change this to whatever key / value depending of how you store the "featured" information).
For that kind of specific cases, get_posts isn't really good to play with - querying the DB with WPDB will give you much more flexibility.
$posts = $wpdb->get_results(
"SELECT DISTINCT $wpdb->posts.*
FROM $wpdb->posts, $wpdb->postmeta
LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE
$wpdb->posts.ID = $wpdb->postmeta.post_id AND
(
($wpdb->term_taxonomy.taxonomy = 'category' AND $wpdb->term_taxonomy.term_id NOT IN(2))
OR
($wpdb->postmeta.meta_key = 'featured' AND $wpdb->postmeta.meta_value = 1)
)
ORDER BY $wpdb->posts.post_date DESC
LIMIT 4"
);
Let me know if you run into any issue as it is an untested query.
If I understood the question correctly , The simplest solution, not involving complicated SQL would be something along the lines of :
// NOT TESTED !
if ( count(get_the_category()) > 1 ) { // this means there are more than single category
// show the desired posts
} else {
// dont show
}
read get_the_category() in codex
Along the same logic lines you could also use wp_get_post_categories

Mass delete unpopular Tags

Mass delete unpopular Tags
I have 1000's of tags and I would like to simply delete all tags that aren't used more than X times... i.e. 5 times.
Does anyone know of a simple way to do this? Even straight SQL would totally ROCK!
Doing with with an SQL command is going to be your best bet. The tables wp_terms, wp_term_relationships, and wp_term_taxonomy are the ones of interest. WordPress keeps track of relationships with wp_term_taxonomy.count. So this help make life easier.
-- remove terms
DELETE FROM wp_terms WHERE term_id IN (SELECT term_id FROM wp_term_taxonomy WHERE taxonomy = 'tag' AND count <= 5;)
-- remove all relationships
DELETE FROM wp_term_relationships WHERE term_taxonomy_id IN (SELECT term_taxonomy_id FROM wp_term_taxonomy WHERE taxonomy = 'tag' AND count <= 5;)
-- remove taxonomy entry
DELETE FROM wp_term_taxonomy WHERE taxonomy = 'tag' AND count <= 5;
Note: I would strongly suggest making a backup of these tables before running the commands above.
Make sure to back up the database first
DELETE a,c FROM wp_terms AS a
LEFT JOIN wp_term_taxonomy AS c ON a.term_id = c.term_id
LEFT JOIN wp_term_relationships AS b on b.term_taxonomy_id = c.term_taxonomy_id
WHERE ( c.taxonomy = 'post_tag' AND c.count <= 5 );
On the last line, you could also modify c.count <= 5 and replace 5 with any number of your choice.
Jasons answer worked except in my install, the name of the taxonomy was 'post_tag' not 'tag'
$x = 5; // set this to any number
$sql = "SELECT `name` FROM `wp_terms`";
$result = mysql_query($sql);
$count = array();
while($row = mysql_fetch_assoc($result))
{
$count[$name]++;
}
foreach($count as $key = $value)
{
if($value < $x)
{
$sql2 = "DELETE FROM `wp_terms` WHERE `name` = '". $key ."'";
$result2 = mysql_query($sql2);
}
}
There's more efficient ways of doing it but this will do the job.
Edit: make a backup first. I'm not entirely sure that that table is exclusive to tags.

Resources