I want to show a subscribe/unsubscribe link on a forum topic list page, along with each of the topics in the list. I have all the info for the subscribe link in the $topic variable in mytheme_preprocess_forum_topic_list():
foreach ($variables['topics'] as $id => $topic) {
Assuming that I want to call notifications_get_link() to get the unsubscribe link, how can I obtain the subscription id (SID) for any existing subscription for the topic node?
I suppose I ought to call notifications_user_get_subscriptions(), but the documentation is a bit thin. An example would be great.
My solution finds exactly one subscription for the current node if one exists and composes either a susbcribe or unsubscribe link that is made available to the template:
// find subscription
$subs = notifications_user_get_subscriptions(
$user->uid,
'node',
$topic->nid,
$topic,
FALSE);
// compose link
$destination = "?destination=forum/idea-exchange";
if ($subs) {
foreach ($subs as $key => $sub) {
$link = notifications_get_link('unsubscribe', array(
'sid' => $sub->sid,
'confirm' => FALSE));
$variables['topics'][$id]->subscribe_link =
'<a class="unsubscribe" href="/'.$link['href'].
$destination.'">'.t('Stop tracking this topic').'</a>';
break;
}
}
else {
$link = notifications_get_link(
'subscribe',
array('uid' => $user->uid,
'type' => 'thread',
'fields' => array('nid' => $topic->nid),
'confirm' => FALSE));
$variables['topics'][$id]->subscribe_link =
'<a class="subscribe" href="/'.
$link['href'].$destination.'">'.t('Track this topic').'</a>';
}
I ended up using a CCK Computed Field for this so that I can include it in a View. See this for more context.
Related
I'm using the following code to add attributes with terms:
$taxonomy = 'pa_' . $attr['name']; // The attribute taxonomy
if (!taxonomy_exists($taxonomy)) {
global $wpdb;
$insert = $wpdb->insert(
$wpdb->prefix . 'woocommerce_attribute_taxonomies',
array(
'attribute_name' => $attr['name'],
'attribute_label' => $attr['name'],
'attribute_public' => 0
),
array('%s', '%s', '%d')
);
if (is_wp_error($insert)) {
throw new WC_API_Exception('woocommerce_api_cannot_create_product_attribute', $insert->get_error_message(), 400);
}
// Clear transients
delete_transient('wc_attribute_taxonomies');
}
if (!term_exists($attr['value'], $attr['name'])) {
wp_insert_term($attr['value'], $attr['name']);
}
$term_slug = get_term_by('name', $attr['value'], $attr['name'])->slug; // Get the term slug
wp_set_post_terms($product_id, $attr['value'], $attr['name'], true);
// Set/save the attribute data in the product variation
update_post_meta($variation_id, 'attribute_' . $taxonomy, $term_slug);
// Assign to the product
wp_set_object_terms($product_id, $attr['value'], $taxonomy, true);
$att = array($taxonomy => array(
'name' => $taxonomy,
'value' => $attr['value'],
'is_visible' => '1',
'is_variation' => '1',
'is_taxonomy' => '1',
));
update_post_meta($product_id, '_product_attributes', $att);
However, the first time the code runs it adds the attributes without terms. If I run it a second time, only then does it add the terms to the previously added attributes.
Why is that?
Edit: The problem seems to start at the following line:
$term_slug = get_term_by('name', $attr['value'], $attr['name'])->slug
It simply doesn't yet recognize the newly created taxonomy. Only at the next run.
But why? Is there a function that can be used to "refresh" the attributes, or the $wp_attributes variable, which seems to be closely related?
Thanks!
It is hard to debug without looking at the live site. However, I think it could be something to do with this code:
if (!term_exists($attr['value'], $attr['name'])) {
wp_insert_term($attr['value'], $attr['name']);
}
On first request the term is inserted yet it will not be part of WordPress main query until further requests.
Again, this is mostly guessing as I need to see the actual implementation.
I use such a method to create a taxonomy.
public function setAttribute($attributeArgs)
{
$attributeId = wc_attribute_taxonomy_id_by_name($attributeArgs['slug']);
if ($attributeId === 0) {
$attributeId = wc_create_attribute($attributeArgs);
register_taxonomy('pa_' . $attributeArgs['slug'], ['product'], []);
} else {
$attributeId = wc_update_attribute($attributeId, $attributeArgs);
}
return [
'id' => $attributeId,
'args' => $attributeArgs,
];
}
An important line in this code is register_taxonomy('pa_' . $attributeArgs['slug'], ['product'], []);
Without this line, I had the same problem.
I'm new at Drupal 7, so I have a question.
I have my own content type Writers that includes such fields as Title, Years of life, Photo, Description.
I have a task to display 3 random Writers at page. Actual I've done it with help of Views module, but I want to do it myself.
So I created my own module random_content like that:
<?php
function random_content_help($path, $arg) {
switch ($path) {
case "admin/help#random_content":
return '<p>'. t("Displays random content") .'</p>';
break;
}
}
function random_content_block_info() {
$blocks['random_content'] = array(
'info' => t('Random content'),
'cache' => DRUPAL_CACHE_PER_ROLE,
);
return $blocks;
}
function random_content_contents() {
$query = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->condition('type', 'writers')
->orderBy('rand()')
->range(0,3)
->execute();
return $query;
}
function random_content_block_view($delta = '') {
switch($delta){
case 'random_content':
$block['subject'] = t('Random content');
if(user_access('access content')) {
$result = random_content_contents();
$items = array();
foreach ($result as $node){
$items[] = array(
'data' => l($node->title, 'node/' . $node->nid) . '</br>',
);
}
if (empty($items)) {
$block['content'] = t('No data availible.');
} else {
$block['content'] = theme('item_list', array(
'items' => $items));
}
}
}
return $block;
}
As you can see, I've learned only to add links to particular content. But how can I display full information including Title, Years of life, Photo and Description?
To display the full node, or parts of it you need to load the node. E.g.
$my_node = node_load($nid);
$render_array = array();
$render_array['title'] = array(
'#type' => 'markup',
'#markup' => $my_node->title
);
$author = field_get_items('node', $my_node, 'field_author','und');
$render_array['author'] = array(
'#type' => 'markup',
'#markup' => $author[0]['safe_value']
);
// or as some like to do it
$render_array['author'] = array(
'#type' => 'markup',
'#markup' => $my_node->field_author['und'][0]['value']
);
echo drupal_render($render_array);
Note the 'und' constant means the language is undefined. If you have translation/language enabled and different content for different languages you would have to use 'en', 'de' etc. for the appropriate language.
You can also let drupal render the node and then manipulate or retrieve individual items. Like this
$my_node = node_load($nid);
$build = node_view($my_node,'full');
$build['body'][0]['#markup'] = $build['body'][0]['#markup'].' some addition';
$build['field_author'][0]['#markup'] = $build['field_author'][0]['#markup'].' my favorite';
echo drupal_render($build);
The advantage of using this latter method is that then the whole themeing engine kicks in, and all hooks that are set to act on the content etc. Of course, if you only want to retrieve values you don't need that.
Note also, I assume your author field is named field_author. You should check that in the field edit window for the content type.
I'm developing a social network with Buddypress, I created a RSS plugin to pull the RSS feed from the specified websites.
Everything is working, except when the RSS is posted to the activity stream. When I create the activity content to print a link, I set the link target to "_new" to open it in a new page.
Here's the code:
function wprss_add_to_activity_feed($item, $inserted_ID) {
$permalink = $item->get_permalink();
$title = $item->get_title();
$admin = get_user_by('login', 'admin');
# Generates the link
$activity_action = sprintf( __( '%s published a new RSS link: %s - ', 'buddypress'), bp_core_get_userlink( $admin->ID ), '' . attribute_escape( wprss_limit_rss_title_chars($title) ) . '');
/* Record this in activity streams */
bp_activity_add( array(
'user_id' => $admin->ID,
'item_id' => $inserted_ID,
'action' => $activity_action,
'component' => 'rss',
'primary_link' => $permalink,
'type' => 'activity_update',
'hide_sitewide' => false
));
}
It should come up with something like that:
Test
But it prints like that:
Test
Why is this happening?
The 'target' attribute is probably getting stripped by BuddyPress's implementation of the kses filters. You can whitelist the attribute as follows:
function se16329156_whitelist_target_in_activity_action( $allowedtags ) {
$allowedtags['a']['target'] = array();
return $allowedtags;
}
add_filter( 'bp_activity_allowed_tags', 'se16329156_whitelist_target_in_activity_action' );
This probably won't retroactively fix the issue for existing activity items - it's likely that they had the offending attribute stripped before being stored in the database. But it should help for future items.
Is it possible to add an action on the /admin/content page. We got "publish selected content" or "delete selected content" etc etc...
http://screencast.com/t/v2ZMedCqy3g
I'm trying to add an action here from a module installation.
Thanks
You need to implement hook_node_operations(). You can look at the pathauto_node_operations() as example.
function pathauto_node_operations() {
$operations['pathauto_update_alias'] = array(
'label' => t('Update URL alias'),
'callback' => 'pathauto_node_update_alias_multiple',
'callback arguments' => array('bulkupdate', array('message' => TRUE)),
);
return $operations;
}
Notices that the callback specified takes an array of node ids, plus the additional callback arguments as you specified in your hook implementation (see above example).
// The call back specified above ^
function pathauto_node_update_alias_multiple(array $nids, $op, array $options = array()) {
$options += array('message' => FALSE);
$nodes = node_load_multiple($nids);
foreach ($nodes as $node) {
pathauto_node_update_alias($node, $op, $options);
}
if (!empty($options['message'])) {
drupal_set_message(format_plural(count($nids), 'Updated URL alias for 1 node.', 'Updated URL aliases for #count nodes.'));
}
}
I created a small module for altering forms called "form_mods". The form I'm altering is the "user_profile_form". I added a category for extra fields called "Profile".
I created a select field in the Drupal admin called "profile_state" and I'm altering it in my module to have a key => value list of states and It's working for me when logged in as an admin but an anonymous user that's trying to register sees an empty states select field. Is there a permissions issue here? I tried to add 'access' => user_access('access content') to the field but that didn't work. Here is my code:
function form_mods_form_alter($form, $form_state, $form_id) {
switch ($form_id) {
## user_profile_form ###################################################################################
case 'user_profile_form': // This is our form ID.
//echo '###'.$form['_category']['#value'].'###';
if($form['_category']['#value'] == 'Profile'){
// Modify the states dropdown list
$states = load_states_list();
$form['Profile']['profile_state'] = array(
'#type' => 'select',
'#title' => t('State'),
'#options' => $states,
'#required' => TRUE,
'#default_value' => isset($form['Profile']['profile_state']['#default_value']) ? $form['Profile']['profile_state']['#default_value'] : '',
'#element_validate' => array('profile_state_validate')
);
}
####################################################################################
break;
}
}
function load_states_list() {
$states = array('' => '-- Select a state'); // add a default empty value
$results = db_query("SELECT * FROM {states_list} ORDER BY name ASC");
while ($state = db_fetch_array($results)) {
$states[$state['code']] = $state['name'];
}
return $states;
}
Thanks
First of all, are you sure you're function ever gets run? Having the function named the way you do, I don't think it is. If the module name is "form_mods", your function should be called
function form_mods_form_alter
Or...since you're only modifying the user_profile_form form, you could use the function name
function form_mods_user_profile_form_alter
Now, the reason it isn't working is because you don't have the & in front of the $form in the parameter list. The & basically passes the variable as reference, and so any changes you make to the $form variable will be saved and passed back to the calling function. So, your function should look like
function form_mods_form_alter(&$form, &$form_state, $form_id) {
OR
function form_mods_user_profile_form_alter(&$form, &$form_state) {
Reference: http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hook_form_alter/6
Thank you mikesir87 for the reference link. I figured out my problem.
There are 2 different forms that are using those fields I created. They have different form id's. I have to look for "user_profile_form" and "user_register" form id's.
Here is my new code that works:
function form_mods_form_alter($form, $form_state, $form_id) {
if( (($form_id == 'user_profile_form') && ($form['_category']['#value'] == 'Profile')) || ($form_id == 'user_register') ){
// Modify the states dropdown list
$states = form_mods_load_states_list();
$form['Profile']['profile_state'] = array(
'#type' => 'select',
'#title' => t('State'),
'#options' => $states,
'#required' => TRUE,
'#default_value' => isset($form['Profile']['profile_state']['#default_value']) ? $form['Profile']['profile_state']['#default_value'] : ''
);
}
}
thanks