The taxonomy system changed a lot since Drupal 6. What is the best way to get all taxonomy term IDs associated with a single node in Drupal 7?
$node = node_load($nid);
$terms = field_view_field('node', $node, 'field_tags', array('default'));
Where do you want to get these terms ? In a module, a theme ...?
Did you take a look at :
http://api.drupal.org/api/drupal/modules--taxonomy--taxonomy.module
The field_data_field_tags table just covers the default Tags field, that might or might not exist and you might have other taxonomies too.
However, taxonomy.module still maintains the taxonomy_term_data/taxonomy_index tables which you can query:
SELECT tid FROM {taxonomy_index} WHERE nid = :nid
Or if you want a specific vocabulary ID:
SELECT ti.tid FROM {taxonomy_index} ti INNER JOIN {taxonomy_term_data} ttd ON ttd.tid = ti.tid WHERE ti.nid = :nid AND vid = :vid
Completely untested.
Related
Good time of day!
There is such config Sphinx
source txtcontent : ru_config
{
sql_query = SELECT `id` as `txt_id`, 1 as index_id, `type_id`,`content_type_id`, `title`, `annonce`, `content` FROM `TxtContent` WHERE `status` = 1 AND `content_type_id` != 14
sql_attr_uint = index_id
sql_attr_uint = type_id
}
The entire table is indexed, and is stored in one large search index.
When it comes to find what is in it then all works OK
But today the task was to search for categories
The categories described in the field and have a type_id of type int
How in php using SphinxAPI to perform such a search?
Standard search looks like this.
$sphinxClient = new SphinxClient();
$sphinxClient->SetServer("127.0.0.1", 3312 );
$sphinxClient->SetLimits( 0, 700,700 );
$sphinxClient->SetSortMode(SPH_SORT_RELEVANCE);
$sphinxClient->SetArrayResult( true );
$result = $sphinxClient->Query( $this->query, 'txtcontent provider item');
I tried to add
$sphinxClient->SetFilter('type_id','1');
To search only where type_id = 1 but it didn't help.
Actually how can I search for a specific category? option to find everything in php to let go of the result excess is not considered (otherwise, the search will then be saturada existing limit) how to do it "properly" via the API without placing each topic in a separate search index?
setFilter takes an Array of values. And they need to be numeric (type_id is a numeric attribute)
$sphinxClient->SetFilter('type_id',array(1));
The sphinxapi class actully uses assertions to detect invalid data like this, which I guess you have disabled (otherwise would of seen them!).
I'm using the following query to join two tables. Table gz_topics features basic information, such as page Title and Subtitle, while the articles for each page are stored in table gz_articles_topics_intro. GZ.URL is actually a variable that matches each page's URL, but I'm using "Birds" here as an example.
$Zext = mysql_fetch_assoc(mysql_query("SELECT GZ.N, GZ.URL, GZ.Title, GZ.Live,
AI.URL, AI.Article, AI.Pagedex
FROM gz_topics GZ
LEFT JOIN gz_articles_topics_intro AI ON AI.URL = GZ.URL
WHERE GZ.URL LIKE 'Birds' AND GZ.Live = 1"));
It works fine. The problems begin when I put my articles in three separate tables and try to join them...
$Zext = mysql_fetch_assoc(mysql_query("SELECT GZ.N, GZ.URL, GZ.Title, GZ.Live,
Art.URL, Art.Article, Art.Pagedex,
AI.URL, AI.Article, AI.Pagedex, AN.URL, AN.Article, AN.Pagedex
FROM gz_topics GZ
LEFT JOIN gz_articles_topics Art ON Art.URL = GZ.URL
LEFT JOIN gz_articles_topics_intro AI ON AI.URL = GZ.URL
LEFT JOIN gz_articles_topics_names AN ON AN.URL = GZ.URL
WHERE GZ.URL LIKE '$MyURL' AND GZ.Live = 1"));
When I paste it into SQL, it works just fine, displaying all the data, including the article. But no values display on my page.
This is the code I use to display the article:
$Article = $Zext['Article'];
echo $Article;
I've tried inner joins and outer joins, while loops, etc., but nothing seems to work. My PHP/MySQL skills are intermediate, and I don't have a clue what the problem is because, as I said, it works fine when I paste it into SQL, and I don't see any error messages.
The problem must be right under my nose, because this looks pretty simple - even for me. ;)
Thanks for any tips.
On edit: I fixed one mistake, and my query is now displaying items from the table gz_topics, like the page title. However, it still doesn't display the article.
Problem 1) You have three columns with the same name "Article"
Art.Article, AI.Article, AN.Article
You may rename them like this:
Art.Article AS Article1, AI.Article AS Article2, AN.Article AS Article3
And then you can use the appropriate column (1, 2 or 3):
$Article = $Zext['Article1'];
Problem 2) If the contents are plain text (not HTML), you should escape the output:
echo htmlentities($Article);
This code is used to get a specific list of ID's from one table, then use those ID's to get the information from another table. Once I get all the information from the 2nd table, I am attempting to sort the data alphabetically based on a field in the 2nd table.
Example, I am getting the name based on a correlating ID and then want to display the entire result in alphabetical order by name (artist_name).
Here is the code I have. When I execute this without the sort(), it works fine but is not in alphabetical order. When I add the sort() in the 2nd while statement, the page looks the same but the name and other data do not display. The source code in the browser shows that the results are being accounted for but the sort must be preventing the variables or information from being displayed for some reason.
I haven't used a sort function before and I tried looking at some examples but couldn't really find something specific to my situation. Any and all help would be greatly appreciated. I have already looked at the PHP manual for sort so no need to send me a link to it ;-)
<?php $counter = 0;
$artistInfo = mysql_query("SELECT DISTINCT event_url_tbl.artist_id FROM event_url_tbl WHERE (SELECT cat_id FROM artist_tbl WHERE artist_tbl.artist_id = event_url_tbl.artist_id) = 1");
while ($aID = mysql_fetch_array($artistInfo))
{
$getArtistInfo = mysql_query("SELECT * FROM artist_tbl WHERE artist_id = '" . $aID['artist_id'] . "'");
while($artist = mysql_fetch_array($getArtistInfo))
{
sort($artist);?>
<a class="navlink" href="<?=HOST?><?=$artist['page_slug']?>/index.html">
<?=$artist['artist_name']?>
</a><br />
<?php }
}
?>
Your best bet, as a commenter mentioned, is to use an ORDER BY clause in SQL.
SELECT *
FROM artist_tbl
WHERE artist_id = XXX
ORDER BY artist_name ASC
The other commenter who suggested using PDO or mysqli is also correct, but that's a different issue.
To answer your specific question about sorting, according to the manual,
Blockquote Note: This function assigns new keys to the elements in array. It will remove any existing keys that may have been assigned, rather than just reordering the keys.
This means all of your array keys ('page_slug', 'artist_name', etc) are wiped out. So when you try to refer to them later, there is no data there.
Were you to use this method, you would want to use asort to sort an associative array.
However, you don't want to use sort here. What you're sorting is the variables for one row of data (one individual artists), not all of your artists. So if you think of each artist row as an index card full of data (name, id#, page slug, etc) all you're doing is moving those items around on the card. You're not reorganizing your card catalog.
Using an order by clause in the SQL statement (and rewriting in PDO) is your best bet.
Here is how I would rewrite it. I have to take some guesses at the SQL because I'm not 100% sure of your database structure and what you're specifically trying to accomplish, but I think this would work.
$query_str = "
SELECT
artist.name,
artist.page_slug
FROM
artist_tbl AS artist
INNER JOIN event_tbl AS event
ON event.artist_id = artist.artist_id
WHERE
artist.cat_id = 1
ORDER BY
artist.name ASC";
$db_obj = new PDO (/*Connection stuff*/);
$artists_sql = $db_obj->prepare ($query_str);
$artists_sql->execute ();
while ($artist = $artists_sql->fetch (PDO::FETCH_ASSOC)) {
$return_str .= "<a class='navlink' href='{HOST}
{$artist['page_slug']}/index.html'>
{$artist['artist_name']}</a><br/>";
}
echo $return_str;
In all honesty, I would probably create an artist class with a display_link method and use PDO's fetchObject method to instantiate the artists, but that's getting ahead of ourselves here.
For now I stuck with procedural code. I don't usually like to mix my HTML and PHP so I assign everything to a return string and echo it out at the end. But this is close to what you had, using one SQL query (in PDO - seriously worth starting to use if you're creating new code) that should give you a list of artists sorted by name and their associated page_slugs.
You could do all of this in one query:
SELECT * FROM event_url_tbl AS event
INNER JOIN artist_tbl AS artist ON event.artist_id = artist.id
ORDER BY artist.name DESC;
This cuts out a lot of the complexity/foreaches in your script. You'll end up with
Label1 (Label 1 details..) Artist1 (Artist1 details..)
Label1 (Label 1 details..) Artist2 (Artist1 details..)
Label2 (Label 2 details..) Artist3 (Artist1 details..)
Always good to bear in mind "one query is better than many". Not a concrete rule, just if it's possible to do, try to do it. Each query has overheads, and queries in loops are a warning sign.
Hopefully that helps
I'm using Verve Meta Boxes. I want to make a menu out of one of the custom fields. How can I return all of the custom field values? For example, if I had a custom select field called "fruit" and as options I have "apples", "oranges", and "bananas", how could I get a complete list of those values, as an array perhaps? I can get the ones associated with a post:
get_post_custom_values('fruit')
…but I can't work out how to get the whole list.
Thank you in advance!
In case someone still wondering:
global $wpdb;
$results = $wpdb->get_results( 'SELECT DISTINCT meta_value FROM wp_postmeta WHERE meta_key LIKE "FIELD_NAME"', OBJECT );
Just make sure your postmeta table is "wp_postmeta" (default) and change FIELD_NAME with the name you created for the field in the admin.
You could do it the regular wordpress way by using the get_post_meta function in your loop.
Try this one out:
$fruits = trim(get_post_meta($post->ID,'fruits',true));
$fruits_array = explode(',',$fruits);
foreach($fruits_array as $f){
echo $f.'<br/>';
}
Basically you need to separate your fruits name with comma in your custom field so that you will be able to explode them into array and echo the values one by one.
Thanks,Dave
I wasn't able to find an elegant solution. What I ended up doing was loop through all of the posts and kept a record of unique values as I can across them, creating an array. Then I used that array to make my navigation.
I'm trying to filter my orders which are returned back by the magento API by a customer attribute. I tried several approaches but nothing seem to work.
I'm using Magento 1.4.1.1 atm and the api does this at the moment:
$billingAliasName = 'billing_o_a';
$shippingAliasName = 'shipping_o_a';
$collection = Mage::getModel("sales/order")->getCollection()
->addAttributeToSelect('*')
->addAddressFields()
->addExpressionFieldToSelect(
'billing_firstname', "{{billing_firstname}}", array('billing_firstname'=>"$billingAliasName.firstname")
)
->addExpressionFieldToSelect(
'billing_lastname', "{{billing_lastname}}", array('billing_lastname'=>"$billingAliasName.lastname")
)
->addExpressionFieldToSelect(
'shipping_firstname', "{{shipping_firstname}}", array('shipping_firstname'=>"$shippingAliasName.firstname")
)
->addExpressionFieldToSelect(
'shipping_lastname', "{{shipping_lastname}}", array('shipping_lastname'=>"$shippingAliasName.lastname")
)
->addExpressionFieldToSelect(
'billing_name',
"CONCAT({{billing_firstname}}, ' ', {{billing_lastname}})",
array('billing_firstname'=>"$billingAliasName.firstname", 'billing_lastname'=>"$billingAliasName.lastname")
)
->addExpressionFieldToSelect(
'shipping_name',
'CONCAT({{shipping_firstname}}, " ", {{shipping_lastname}})',
array('shipping_firstname'=>"$shippingAliasName.firstname", 'shipping_lastname'=>"$shippingAliasName.lastname")
);
Which is the default API call I guess. Now I just want to join a customer attribute called update - how do I achieve this simple task?
Or is this not possible on a flat table like sales_flat_order?
Whenever I need to do this I use something like:
Joining An EAV Table (With Attributes) To A Flat Table
It's not well optimised but you should be able to pick out the parts you need.
PS.
I think I'll explain what I mean by optimised since it's important. In the heart of the method is this bit:
->joinLeft(array($alias => $table),
'main_table.'.$mainTableForeignKey.' = '.$alias.'.entity_id and '.$alias.'.attribute_id = '.$attribute->getAttributeId(),
array($attribute->getAttributeCode() => $field)
);
If you know MySQL then you'll know it will only pick one index when joining a table, the more specific the better. In this case only the entity_id and attribute_id fields are being used so MySQL is restricted to those. Both columns are indexed but the cardinality is low.
If the condition also included the entity type then MySQL would have the choice of using IDX_BASE which indexes the columns entity_type_id,entity_id,attribute_id,store_id in that order (it needs to process them left to right). So something like this results in a much improved EAV performance - depending on how many rows on the 'left' table it could be several hundred- or thousand-fold better.
$alias.'.entity_type_id='.$entityType->getId().' AND main_table.'.$mainTableForeignKey.' = '.$alias.'.entity_id AND '.$alias.'.attribute_id = '.$attribute->getAttributeId().' AND '.$alias.'.store_id=0'