VBO action on pending node revision (using Revisioning) publishes the revision I have a View listing pending node revisions (using Revisioning). I have several actions, like changing the node author, which are executed using Views Bulk Operations. Executing, for example, the "Change author" action should update the author, but keep the revision in pending state. However, the revision gets published, and becomes the new, current revision.

Anyone else run into this issue? I've been digging around both VBO and Revisionings source code, but I cannot find out which one is to "blame". VBO is correctly loading the pending revision, and executing the action on it. Revisioning's node hooks are correctly invoked as well. Auto-publishing is disabled, and Revisioning does not get into that code flow (I put tracer code in there to make sure it doesn't). So this leads me to think VBO or Entity are at fault, but I can't put my finger on it.

So, I found out where the issue is coming from.

Basically, Revisioning works as follows:

A node gets saved by Drupal. Drupal doesn't care much about the status.
If the node is published, it remains published. It is important to realize
that, when using Revisioning, if a node has a published revision, for
Drupal the node has a status of 1, regardless of the pending, unpublished
revision. Upon saving, Drupal simply stores a new revision, and updates
the node database row, pointing the revision ID to this new revision.
Revisioning kicks in, with revisioning_node_update(). It checks the
revision_operation property. Based on its value, it "reverts" what Drupal
just did, setting the revision ID in the node table back to the previous
revision. This is what keeps the published revision one step behind the
pending revision.

Now, this revision_operation property is only set when in context of a node form. When using VBO (or any way to trigger actions, for that matter), Revisioning doesn't see the revision_operation property, and revisioning_node_update() doesn't revert the revision ID.

We could patch this in Revisioning, but the project hasn't received much attention lately (for the D7 version). So this is how I solved it (I have several actions, but I'll give the example of the node_assign_owner_action action):

/**
 * Implements hook_action_info().
 */
function mymodule_action_info() {
  return array(
    'mymodule_assign_to_user_action' => array(
      'type' => 'node',
      'label' => t("Assign to user (Revisioning compatible)"),
      'configurable' => TRUE,
      'behavior' => array('changes_property'),
      'triggers' => array('node_presave'),
    ),
  );
}

/**
 * Assign a node to a user.
 *
 * We need a custom action for this, as actions are not entirely compatible with
 * Revisioning. We need to tweak the node a bit to force a pending revision to
 * stay that way. node_assign_owner_action() does not allow this. See
 * _mymodule_actions_reset_revision_operation() for an explanation on why we
 * need this.
 *
 * @see node_assign_owner_action()
 * @see node_action_info()
 */
function mymodule_assign_to_user_action($node, $context = array()) {
  // Simply proxy to node_assign_owner_action().
  node_assign_owner_action($node, $context);

  // Make sure the revision_operation property is correctly set.
  _mymodule_actions_reset_revision_operation($node);
}

/**
 * Configuration form for mymodule_assign_to_user_action().
 *
 * @see mymodule_assign_to_user_action()
 * @see node_assign_owner_action_form()
 */
function mymodule_assign_to_user_action_form($context = array()) {
  return node_assign_owner_action_form($context);
}

/**
 * Validation callback for mymodule_assign_to_user_action_form().
 *
 * @see mymodule_assign_to_user_action()
 * @see node_assign_owner_action_validate()
 */
function mymodule_assign_to_user_action_validate($form, $form_state) {
  node_assign_owner_action_validate($form, $form_state);
}

/**
 * Submission callback for mymodule_assign_to_user_action_form().
 *
 * @see mymodule_assign_to_user_action()
 * @see node_assign_owner_action_submit()
 */
function mymodule_assign_to_user_action_submit($form, $form_state) {
  return node_assign_owner_action_submit($form, $form_state);
}

/**
 * Set the correct node revision_operation property.
 *
 * @param object $node
 *    The node on which the action is performed.
 */
function _mymodule_actions_reset_revision_operation($node) {
  module_load_include('inc', 'revisioning', 'revisioning_api');

  $is_moderated_content = isset($node->revision_moderation) ?
    $node->revision_moderation :
    revisioning_content_is_moderated($node->type, $node);

  $node->revision_operation = (int) $node->is_pending + (int) $is_moderated_content;
}

Thanks to this, we can still use actions provided by core or other modules, but we need to wrap them in another, Revisioning compatible action. When calling _mymodule_actions_reset_revision_operation(), we use the same logic as Revisioning is using when altering the node form.

It now works.


How does bandwidth optimization work? I have optimized to combine all CSS and JavaScript files in my site.

.

If I run Yslow in Firefox to see the components loaded for this site, it shows that it loads 8 JavaScript files, and 8 CSS files.

Why aren't these files combined?

Aggregated CSS and JS files in Drupal 7 are split up into groups, so you'll naturally get more files than you're used to seeing in Drupal 6.

I won't go in to the whole thing as there's already an excellent article out there that explains it in good detail.

  D7 uses a new strategy to address this - aggregates are split into three groups:
  CSS_SYSTEM, CSS_DEFAULT, and CSS_THEME for styles, and JS_LIBRARY, JS_DEFAULT, and JS_THEME for Javascript. Each group is further subdivided into files that load on every page, and files that load conditionally based on the 'every_page' option. Note this option has some potential for confusion - it doesn't cause the file to be loaded on every page - it's merely a "hint" to the core system to place it in that group.

  Ultimately, the intent of these divisions is to group files into functional groups that are smaller and less likely to be split by an errant conditional style or script. We get separate files for core libraries, the theme, and page-specific files. Looking at the results, a stock Drupal 7 outputs eight stylesheets (including browser styles), while D6 only has three in the default install. Is this optimal? The answer will be different for each site.

If it's causing you problems, you might want to have a look at the Core Library module:

  This module changes the Drupal core aggregation mecanism process. It greatly reduces I/O and aggregated number of files, and improves chances of client cache hit, therefore while it produces bigger aggregated files, it reduces greatly the bandwidth utilization while users browse.


How to render all the contents of a view in a custom module? I have created a view with 4 blocks. Rose,lilly,sunflower,jasmine. All the blocks have common fields. Now i want to display all the contents of the view in my custom module.  When I tried the below code, I can access only the first block (ie)Rose. How can i get all the values of a view in my custom module?

$view = views_get_view(myblock_block');
$view->set_display('Rose'); // page_1 or block_1 ... block_n, ...page_n
$view->set_items_per_page(0);
$view->execute();
$result = $view->result;

I've always used views_embed_view to do this. The first parameter is the machine name of your view, the second is the display id. Example:

$view_rose_output = views_embed_view('myblock_block', 'rose');
$view_lily_output = views_embed_view('myblock_block', 'lily').

If your view takes any arguments you can pass that in to the views_embed_view after the first two arguments.

Note that views_embed_view returns the rendered html of the view. If this is what you want, great! Otherwise, I've used the views_post_render hook to alter the output. The function header looks like this:

HOOK_views_post_render(&$view, &$output, &$cache)

where $output is the rendered html, and $view gives you the view object.


How to dynamically change the CSS style of a node-type? I want to modify dynamically the style of a page in base of your content type:
I tried with a preprocess function insert this code:

if(isset($variables['node'])){
  if($variables['node']->type=='article'){
    drupal_add_css(drupal_get_path('theme','my_theme').'/css/style_node_article.css');
  }
  if($variables['node']->type=='page'){
    drupal_add_css(drupal_get_path('theme','my_theme').'/css/style_node_page.css');
  }
}

This doesn't set the right CSS if I change page from article to page...
Thanks

Unless you have a ton of CSS you should add the CSS for all the nodes and use the node type class on the wrapper div of the node.

I can't remember the exact classes you can view them in the source. You could do something like this

.node {}
.node-page {}
.node-blog {}

Where the first class is on all nodes and the latter is dynamic for the node.


insert advertisement block within views list I have a view that output the content nodes as grid. (instigram style). How to insert an advertisement block in a random location within the views list.

Node
Node
.
.
Advertisement
.
.
Node
Node

You can override the format specific template like views-view-unformatted.tpl.php (you can find the right file based on your requirement) and then use some custom code like

  <?php if (($id % 2) == 0): ?>
    Do what-ever you want to do here.
  <?php endif; ?>

This module hosted on github https://github.com/pedroposada/custom_views_nthrow seems to do the same more modularly.

Instructions : http://www.pedroposada.com/blog/insert-whatever-every-nth-row-views.html-0


Decryption failed because the HMAC could not be validated - error on Migration d2d dashboard page I'm trying to migrate Drupal 6 to Drupal 7 with Migrate d2d module. Problem is that I get 2 errors on Migrate dashboard page:

Decryption failed because the HMAC could not be validated.
Migration c9b87f5afFile could not be constructed.

And they are repeating many times. I can run migrate process, but custom defined field values are not migrated since I didn't map them. I can't access field mapping page because of this error.

Any idea how to resolve this?

I am not sure this will help you, but I ran into this error while using webforms:

  Decryption failed because the HMAC could not be validated.

My issue was I tried to encrypt a webform field after there was already unencrypted data saved for that field in the database. So when I tried to view the results of my webform, I would get the above error because it was trying to decrypt data that was not encrypted.

Perhaps this is what is happening when you try to migrate?

My solution was to manually clear the data from the database. Once I did that, I was able to get to the webform results page in the drupal admin and clear the data from there to be sure all evidence of it was gone. Because I am in development this was an ok solution.

I am guessing clearing the data will not work for you, but perhaps this will help point you in the right direction.


Should I use Libraries API if I only wish to use a 3rd-party library for my own custom module? version detection, duplicate declaration I wish to use phpFlickr 3rd-party php library in developing my own custom module.

I considered Libraries API to centrally manage phpFlickr in sites/all/libraries but have some questions:

What happens if there are other contrib modules that also use phpFlickr and manage it through Libraries API? If my module registers phpFlickr with Libraries API then would there not be a duplicate entry with Libraries API? Does it know if more than one module wants to use it?
In general, how can I check for a minimum version of a library? with hook_libraries_info() a regular expression can be used to find the version, but there doesn't seem to be an explanation as to how to check for a minimum version.

I've already looked at the documentation for Libraries API and found it to be insufficient regarding examples ( https://www.drupal.org/node/1342238 ). I also looked at a page stating contrib modules that apparently used Libraries API ( https://www.drupal.org/node/1570568 ) but when I examined the code, it didn't seem to be the case, i.e. in the twitter module, I looked for "_libraries_info" but could not find it.

I think the answer would be to check for an API module that wraps the 3rd-party code inside a Drupal module, in my case this would be the Flickr API module, which has been fixed to use Libraries API:

https://www.drupal.org/node/2301991

If there isn't a wrapper for the 3rd-party code, then this would be the case to make one, by oneself.


INPUT query for cache_menu returns mysql #2006 error in MAMP This actually happens when I want to import a db from a live site to a local site in MAMP.

Running mac osx 10.6.8 and MAMP 2.0.5.

I googled this mysql error and most people seem to have this solved by increasing the memory_limit value in /Applications/MAMP/bin/php5.3.6/conf/php.ini. I set it to 512M. And yes I made sure MAMP is running php 5.3.6.

...anyway increasing the memory size didn't solve the issue obviously

then I went looking at the error logs under Applications/MAMP/logs/php_error.log and Applications/MAMP/logs/mysql_error_log.err but both don't have any recent log information at all actually which is quite bizarre as well.

What I can also tell you is that the last VALUE which the query wants to INSERT INTO 'cache_menu' is very very large.

Here's the query that gives the #2006 error:

INSERT INTO `cache_menu` (`cid`, `data`, `expire`, `created`, `headers`, `serialized`) VALUES ('links:admin_menu:tree-data:9942fb041052f49f910af3e0190b9115', 0x613a323a7b733a343a2274726565223b613a31303a7b693a333635313b613a323a7b733a343a226c696e6b223b613a33373a7b733a31343a226c6f61645f66756e6374696f6e73223b4e3b733a31363a22746f5f6172675f66756e6374696f6e73223b4e3b733a31353a226163636573735f63616c6c6261636b223b4e3b733a31363a226163636573735f617267756d656e7473223b4e3b733a31333a22706167655f63616c6c6261636b223b4e3b733a31343a22706167655f617267756d656e7473223b4e3b733a353a227469746c65223b4e3b733a31343a227469746c655f63616c6c6261636b223b4e3b733a31353a227469746c655f617267756d656e7473223b4e3b733a343a2274797065223b4e3b733a31313a226465736372697074696f6e223b4e3b733a393a226d656e755f6e616d65223b733a31303a2261646d696e5f6d656e75223b733a343a226d6c6964223b733a343a2233363531223b733a343a22706c6964223b733a313a2230223b733a393a226c696e6b5f70617468223b733a373a223c66726f6e743e223b733a31313a22726f757465725f70617468223[...]

Backup and migrate exports the database automatically without (large) values in the cache_menu table. Thus, re-exporting the database using the backup and migrate module solved the issue.


Drupal Commerce Rules & Custom Actions When the checkout process is complete I'd like to record the SKU and the user ID in a separate table in my database.

Is the best approach to use the Rules module, using the 'Completing the checkout process' event and writing a custom action?

If so, how would I be best going about this?

Advice on how best to achieve the above would be appreciated.

I don't know of any modules that enable you to write db records in rules actions.

I guess you could write a custom rules action to write to your custom table and grab all the data in rules but it's just as easy to do something like below using  hook_commerce_checkout_complete:

The trickiest part is obtaining the SKU

<?php
  function hook_commerce_checkout_complete($order) {
    $ow = entity_metadata_wrapper('commerce_order', $order);

    foreach ($ow->commerce_line_items as $line_item) {
     $sku = $line_item->commerce_product->sku->value();

     $record = array(
      'uid' => $uid,
      'order_id' => $order->order_id,
      'order_numer' => $order->order_number,
      'sku' => $sku,
     );
     drupal_write_record('my_custom_table', $record);
    }
  }
?>

Hope this helps.


How to disable links for anonymous users for SOME, but not all link items? The link issue here is video links, which are for brightcove.com hosted videos. Now some important background:

  The site is a directory of company-produced videos. It requires login in order to view anything.
  However the user can assemble a list of videos (like a cart or wish list) and send a URL for that list to a non-authorized person; that person can view the video links and read text info about the video, but can't access other parts of the site.
  But some of the videos are designated as "not shareable." So even though it's OK to share links to most of the video pages and for anonymous users to play the video link, we need to exclude the "non-shareable" videos from being playable.
The link field is only one of the fields in a node of this content type. The node itself must remain accessible to the anonymous user; it is only the video link that needs to be variably accessible or not accessible to anonymous.

Can anyone suggest a strategy for making some but not all video links not accessible to the anonymous user?

I would create a view of the videos and control access by role.  if you need control at the field level, I'm sure there is a module for that or you can use a field template.


What are the advantages of using Apache Solr over the core search module? The Apache Solr Search Integration module project page states:

  Solr search can be used as a replacement for core content search and
  boasts both extra features and better performance.

What exactly are these extra features?  (Or if there are too many, in what kind of use cases would I want to use Apache Solr?)

My site is hosted on Pantheon and they provide Apache Solr at no additional charge.  Would this be something I definitely want to set up?  Only set up in certain cases?

This article gives a thorough and straight-forward answer to your question.

  Performance improvements with Apache Solr

  High traffic sites running search queries against the database can start to degrade the site’s overall performance if the database becomes the bottleneck. This is also true for lower traffic sites with lots of content. Complex search queries can be slow to run.

  Requirements for features such as faceted search (see below) are becoming increasingly common. This can be delivered in conjunction with Drupal core search using the Faceted Search module but the inherent scalability and performance implications are well documented by the module’s maintainers.

   Other useful Apache Solr features

  Apache Solr also supports indexing and searching multiple sites (imagine internal intranet site and external corporate site), indexing attachments (eg PDFs, Excel documents) and recommended content blocks driven by a node’s taxonomy. The module page and the Acquia Search overview both have a good overview of the Apache Solr features that Drupal supports.


How can I change the default branch of a contributed module? If you're more used to GitLab than Drupal.org, you might spend a while hunting through settings there to figure out how to change the default branch - or concluding that you simply can't. I'm posting this q&a in case it saves someone else the hassle of either time waster.

Fwiw, if you are looking for the non-Drupal.org answer, see https://docs.gitlab.com/ee/user/project/repository/branches/#default-branch or https://stackoverflow.com/questions/30987216/change-default-branch-in-gitlab

Turns out it's a setting on your Drupal.org version of the module page. Visit edit > default branch on the page-specific menu of your module.

At the time of creating this question, the documentation page from 2012 (last updated 2015) is still close enough to be helpful.


Is it possible to select a row with tableselect.js? Drupal includes tableselect.js in a view I am using that uses views bulk operations.  I am wondering if it is possible to use the table select code to select a row by id or some other selector.  My goal is for the select all checkbox to get checked if all rows are selected.

Here is the tableselect code:

Drupal.behaviors.tableSelect = function (context) {
  $('form table:has(th.select-all):not(.tableSelect-processed)', context).each(Drupal.tableSelect);
};

Drupal.tableSelect = function() {
  // Do not add a "Select all" checkbox if there are no rows with checkboxes in the table
  if ($('td input:checkbox', this).size() == 0) {
    return;
  }

  // Keep track of the table, which checkbox is checked and alias the settings.
  var table = this, checkboxes, lastChecked;
  var strings = { 'selectAll': Drupal.t('Select all rows in this table'), 'selectNone': Drupal.t('Deselect all rows in this table') };
  var updateSelectAll = function(state) {
    $('th.select-all input:checkbox', table).each(function() {
      $(this).attr('title', state ? strings.selectNone : strings.selectAll);
      this.checked = state;
    });
  };

  // Find all <th> with class select-all, and insert the check all checkbox.
  $('th.select-all', table).prepend($('<input type="checkbox" class="form-checkbox" />').attr('title', strings.selectAll)).click(function(event) {
    if ($(event.target).is('input:checkbox')) {
      // Loop through all checkboxes and set their state to the select all checkbox' state.
      checkboxes.each(function() {
        this.checked = event.target.checked;
        // Either add or remove the selected class based on the state of the check all checkbox.
        $(this).parents('tr:first')[ this.checked ? 'addClass' : 'removeClass' ]('selected');
      });
      // Update the title and the state of the check all box.
      updateSelectAll(event.target.checked);
    }
  });

  // For each of the checkboxes within the table.
  checkboxes = $('td input:checkbox', table).click(function(e) {
    // Either add or remove the selected class based on the state of the check all checkbox.
    $(this).parents('tr:first')[ this.checked ? 'addClass' : 'removeClass' ]('selected');

    // If this is a shift click, we need to highlight everything in the range.
    // Also make sure that we are actually checking checkboxes over a range and
    // that a checkbox has been checked or unchecked before.
    if (e.shiftKey && lastChecked && lastChecked != e.target) {
      // We use the checkbox's parent TR to do our range searching.
      Drupal.tableSelectRange($(e.target).parents('tr')[0], $(lastChecked).parents('tr')[0], e.target.checked);
    }

    // If all checkboxes are checked, make sure the select-all one is checked too, otherwise keep unchecked.
    updateSelectAll((checkboxes.length == $(checkboxes).filter(':checked').length));

    // Keep track of the last checked checkbox.
    lastChecked = e.target;
  });
  $(this).addClass('tableSelect-processed');
};

Drupal.tableSelectRange = function(from, to, state) {
  // We determine the looping mode based on the the order of from and to.
  var mode = from.rowIndex > to.rowIndex ? 'previousSibling' : 'nextSibling';

  // Traverse through the sibling nodes.
  for (var i = from[mode]; i; i = i[mode]) {
    // Make sure that we're only dealing with elements.
    if (i.nodeType != 1) {
      continue;
    }

    // Either add or remove the selected class based on the state of the target checkbox.
    $(i)[ state ? 'addClass' : 'removeClass' ]('selected');
    $('input:checkbox', i).each(function() {
      this.checked = state;
    });

    if (to.nodeType) {
      // If we are at the end of the range, stop.
      if (i == to) {
        break;
      }
    }
    // A faster alternative to doing $(i).filter(to).length.
    else if (jQuery.filter(to, [i]).r.length) {
      break;
    }
  }
};

The answer is to forget about tableSelect.js and trigger the appropriate eventHandler when setting the checkboxe's attribute to 'checked'.

Here is the code:

var checkbox = tr.find('td input:checkbox');
checkbox.attr('checked', 'checked').triggerHandler('click');

http://drupal.org/node/1477522


PDOException when populating file field programaticalily? I'm creating a drupal commerce product programatically and trying to populate it with a file using the following code:

$new_product = commerce_product_new($product_type);

$new_product->created = $new_product->changed = time();

$new_product->field_pdf[LANGUAGE_NONE][0] = $extras['file'];

commerce_product_save($new_product);

This is the value of $extras['file'];

Keys: fid, uri, filename, filemime, uid, status, timestamp, filesize Values: 135, public://pdfs/test2_106.pdf, test2.pdf, application/pdf, 0, 1, 1356742160, 3908

My problem is I get this error:

PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'field_pdf_display' cannot be null: INSERT INTO {field_data_field_pdf} (entity_type, entity_id, revision_id, bundle, delta, language, field_pdf_fid, field_pdf_display, field_pdf_description) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8); Array ( [:db_insert_placeholder_0] => commerce_product [:db_insert_placeholder_1] => 113 [:db_insert_placeholder_2] => 115 [:db_insert_placeholder_3] => policy [:db_insert_placeholder_4] => 0 [:db_insert_placeholder_5] => und [:db_insert_placeholder_6] => 128 [:db_insert_placeholder_7] => [:db_insert_placeholder_8] => ) in field_sql_storage_field_storage_write() (line 448 of /var/www/clients/client1/web10/web/modules/field/modules/field_sql_storage/field_sql_storage.module).

I have absolutely no idea what the problem might be. Can anyone point me in the right direction?

A file field item is not the same thing as a file object/array. You need to set the keys as defined in file_field_schema, which means fid, display and description.


Author who is not a user - Does a module exist? I am about to write a custom module to allow for non-user authors (called Authors for the rest of this question).

Use Case is really the corporate website

Person publishing content to the website is not the author
Actual authors are many and potentially multiple on a specific article
There is no reason to create the authors as users on the CMS

Functional suggestions/ideas

When editing an article the editor can select one or many "Authors"
for the article.
If none is selected then the creator of the article
is displayed as the Author.
Author would be used in place of User
when article displays on the front end.
If configured Authors would
have a block on a node showing Author content fields (image, role
...).
Users can be associated with an Author through an Entity
reference field.
Re-use profiles on corporate About the Team page

Am I crazy, does a module exist, should I just create them as system users with no privileges and use an existing module? Just seems wrong to give manage users rights to website editor so that they can edit these profiles.

The solution was clearly provided by @Clive in his comment:

  users only make sense in the context of authorisation. Since you don't
  want/need that, you should just create an 'Author' content type and
  use that to store your authors and use EntityReference to relate them
  as Nikhil suggested

If a logged in user needs to be associated with a user in order to pre-fill this author display field you could have an entity reference on the user profile page.
If this needs to be a module, use features module to export:

Author content type
Author entity reference on users
Author field base with form field and display handling

I never actually created a module for this.


Modify parent entity from within custom field formatter How can I modify parent entity's output from within my custom field. I am writing a custom field that adds css class to blocks. Everything is set, except I don't know how to modify the parent entity.

You can do this from inside the field formatter.  Each of the $items passed into the viewElements method has a getEntity() method that will give you the entity.

class MyFieldFormatter extends FormatterBase {

  public function viewElements(FieldItemListInterface $items, $langcode) {
    $entity = $items[0]->getEntity();
  }

}

However, this is not recommended since it inverts the normal control flow. In normal situations, everything needed to render a field is a value on a column in the field itself.  Grabbing the entity is icky, but is definitely possible for strange edge cases.


Can I use Ubercart Stock to monitor individual components of a product? For example, I'm selling Hamburgers.

Hamburgers require the following ingredients:

Bread
Beef
Tomato
Lettuce
Onions

For every one hamburger sold, stock decrement should be: 1 Bread, 1 Beef, 2 Tomatoes, 1 Lettuce, 3 Onions.

The ingredients will never be sold individually, they collectively make one product.

Is it possible to do this?

It is. Make your hamburger a product kit which is made up of products, bread, beef, tomato, lettuce and onion. When you sell a hamburger Ubercart will be smart enough to control stock of the ingredients.


How to track user logins I need to track user logins so I know how often "UserA" is logging into my site.
Can anyone recommend a method to do this? Module or code?

I think you are looking for User Stats module.

  Provides commonly requested user statistics for themers, IP address
  tracking and Views integration. Statistics are:

  days registered;
  join date;
  days since last login;
  days since last post;
  post count;
  login count;
  user online/offline;
  IP address;


Setting custom key names for exported JSON view fields I have a result set similar to this (using Views RESTful Export):

My question, how to change created_1 key and name it something else?

From views you can configure the custom name/alias for fields from Fields | Settings option under Format.
Check the screenshot for reference


Why isn't my custom form element theme function being called? In my module I have a function that returns a form:

function mymodule_myform($form, &$form_state) {
    $form['fs_refine'] = array('#type' => 'fieldset');
    $form['fs_refine']['refine'] = array(
        '#type' => 'checkboxes',
        '#theme' => 'toggles',
        '#title' => t('Refine results by category:'),
        '#options' => array(
            1 => t('Cat 1'),
            2 => t('Cat 2'),
            3 => t('Cat 3')),
        '#default_value' => array(1, 2, 3)
    );
    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Submit')
    );
    return $form;
}

I render the form with:

drupal_render(drupal_get_form('mymodule_myform'));

I have the following functions in my module:

function theme_toggles($vars) {
    die;
}

function mymodule_theme_toggles($vars) {
    die;
}

function mymodule_toggles($vars) {
    die;
}

I want to call a theme function for my checkboxes form element so that I can customise the HTML output of each checkbox. My theme functions are obviously not being called, because my page would by dying if one of them was.

How do I fix this and theme my form elements using #theme?

OK, so you need several things combined in order for this to work:

#theme => unique_name_for_theme_function on the form element.
In your template.php mytemplate_theme() function you need to return an array something like: array( 'unique_name_for_theme_function' => array('function') => 'myfunc') );. This was the bit I was missing.
Then in your template.php you need to add a myfunc. I found it easiest to just google "Drupal theme_form_element", "Drupal theme_checkboxes" or whatever, and then copy paste the code I found in to a mytemplate_theme_checkboxes function which I then modified to suit my needs.
Then you need to flush cache for Drupal to find your theme function.


Customizable combo select multiple and autocomplete My client wants an input element for a custom form to behave like this:

Dropdown checkbox multiple
Autosuggest field

So if we have a list of countries (Spain, UK, USA), it can display all the elements, and allows to select several of them. And if it is a long list of countries, you could search by entering the few letters, and only those items which match the entered letters would appear.

As for the first behaviour, I have found the following module "Dropdwon checkboxes". As for the second one, I haven't found any module so far, but in the wild there is this example (see example: Filtering mode: (filter existing list) ).

Any idea on how could I get the result? Maybe injecting some custom Javascript (jQuery) code into the multiple checkbox customized with the first module, to add the autocomplete capabilities?

As you suggest you have achieved the first one so supposing you have a dropdown with values then you can use the jQuery plugin / javascript to make the select an Autocomplete field. You can use select2

Thanks


How to add where clause to custom Drupal view I am fetching data from two table to my view using View API. How can I add where clause to my view?

My actual SQL query is like:

select field1,field2,field3,t2field4 from table1,table2 where t2field=field1

I come across hook_view_alter() but I dont know how to implement that.
Can I use any filter handler in my views.inc file?

You can implement hook_view_query_alter() to add where condition.

function MODULE_NAME_views_query_alter(&$view, &$query) {
  if ($view->name == 'view_name') {
    $query->add_where(1,'node.nid',$value,'=');
  }
}


How can I use some Javascript to force a fieldset to stay open How can some Javascript or CSS be used to keep a field set open when the page is refreshed?

I am using a module with a form in a fieldset that is automatically closed whenever the page is opened or refreshed. I don't want to touch the module code or write a module to fix it. Is there some Javascript or CSS that can be used to fix it, ie like CSS Injector or Javascript injector?

You could definitely do that with some custom JS, but it might not be worth the trouble as there's a pre-built module which does what you need:
Fieldset collapser

Whenever a user clicks on a collapsible fieldset header to toggle the "collapsed" state, the new state is being saved - uniquely for every form fieldset possible. Depending on the user's being registered with your site or not, this happens either in his user account data or locally on his computer using cookies.
When the same form is called the next time, the fieldset states are restored to what they were last time. For registered users, this happens already on your server while preparing the form. Anonymous users will still see a little form animation by an invisible hand but then also be happy with their favorite fieldset states.


Does Drupal support Multitenancy? I have not been able to determine whether Drupal supports multitenancy:

  Multitenancy refers to a principle in software architecture where a
  single instance of the software runs on a server, serving multiple
  client-organizations (tenants).

Specifically, I am interested in a single Drupal installation supporting multiple user organizations that would share the same environment but be able to have separate interface configurations and settings, and otherwise being totally unaware of other tenants (users).

An example would be a single install of Drupal being used to serve up multiple organizational websites in a SaaS type offering.

Does anyone have any information on this?

One of the strengths of Drupal is that it's not just a tool for building a single website. It can be used equally well for managing multiple companion sites together. This capability has existed for many years, but is not always well understood.

And in true Drupal fashion, modern Drupal has several different options available for users looking to run a series of Drupal sites together, each with its own trade-offs.

Separate installs
Features-based installs
Multi-site
Domain Access
Organic Groups
Mix and match

Separate installs :
Sometimes the best strategy is to not unify sites at all. In this case, any similarity between different sites is largely coincidental. If there will be a large number of sites then some automation tools such as Drush or Aegir may make spinning up new sites easier, but from a site building perspective they are different sites.

Features-based installs :
As a slight variation of separate installs, it's possible to run multiple installs with the Features module. For those not yet familiar with it (and you should be), Features is essentially an automation tool for those pieces of configuration that Drupal allows to be mirrored to code so that they may be checked into version control. These days much (but sadly not all) of Drupal's configuration can be feature-ized. The most effective configuration components to manage this way include content types, views, panels, and image styles.

Multi-site :
For years Drupal has had the ability to run multiple sites off of a single install base. In this case, there is a single copy of Drupal's code base but each college or department has its own settings.php file, which points to a different database. From a site builder perspective, this is almost the same as having separate installs. Every site must be configured independently, but every site may also be configured independently. Each site may also live on its own domain or in subdirectories, although the latter requires some symbolic link trickery and editing the Apache .htaccess file to make work.

Domain Access :
Domain Access (DA) is actually an access control module that uses the node grants system. With DA, a site administrator can point multiple domains to a single Drupal install. Drupal will then self-filter any nodes in the system to display only on specific domains. There is still a single database, single code base, single user base, and single content pool.

Organic Groups :
With OG, each node (any entity, really) can be made into a "group", and then other nodes can be associated to one or more groups. Depending on the configuration, that could impact navigation, path aliases, theme selection, and so forth, to give the impression of different "sites".

Mix and match :
When planning a large-scale Drupal rollout, it's also possible to consider combining strategies. For instance, both Domain Access and Organic Groups can run on their own Drupal instance that just so happens to be multi-site... and have other Drupal sites hosted on it as well. Workbench can be used for administration of content on a single Drupal instance independently of whether it uses DA or OG, and can easily be enabled on multiple instances on the same install as well. As of this writing Workbench does not integrate with either module, so for instance Organic Groups or Domains cannot be used to define "sections" in Workbench, but such integration is possible.

Conclusion

Drupal offers a variety of solutions to address multiple sites with shared and separate content. As with all things Drupal there is no right solution — just options for your specific needs. Evaluate your goals and make decisions based on them; you may find that Domain Access is a better fit for your content editors or a multi-site setup is much easier to manage for your system administrators.


Custom entity types with multiple value properties I'm creating a custom entity type, that has the following base field (defined in a class that extends ContentEntityBase)

public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
  $fields['recipient_id'] = BaseFieldDefinition::create('entity_reference')
    ->setLabel(t('Recipient(s)'))
    ->setDescription(t('The recipient(s)'))
    ->setSetting('target_type', 'user')
    ->setSetting('handler', 'default')
    ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
    ->setDisplayOptions('view', array(
      'label' => 'above',
      'type' => 'entity_reference_label',
      'weight' => -3,
    ))
    ->setDisplayOptions('form', array(
      'type' => 'entity_reference_autocomplete',
      'settings' => array(
        'match_operator' => 'CONTAINS',
        'size' => 60,
        'autocomplete_type' => 'tags',
        'placeholder' => '',
      ),
      'weight' => -3,
    ))
    ->setDisplayConfigurable('form', TRUE)
    ->setDisplayConfigurable('view', TRUE);
}

I've set the field to have unlimited cardinality. I'm trying to create the getters and setters for this field, however I'm not finding any examples of entity types with multiple values.

I need to create the following getters and setters:

// Add a single recipient to the entity
public function setRecipient()
// retrieve all recipients for the entity
public function getRecipients()

Does anyone have an example of how to set up these functions to work with a multiple value field?

// Add a single recipient to the entity
public function setRecipient()

What now, add or set? If it is adding to the existing list, I'd recommend to name it addRecipient().

I'd also recommend to name the field recipients or so, to indicate that it has multiple values.

You can add an item to a field item list with \Drupal\Core\TypedData\ListInterface::appendItem(), for example $this->get('recipient_id')->appendItem($recipient_entity_or_id_or_value_array)

To get all referenced entities, there is a referencedEntities() method on entity reference field item lists, or you can use a loop.


How to code custom entity to access more than one database table? I have an entity that uses two tables, when I describe it in hook_entity_info() as far as I know I can only tell it about the base table. The base table is subscriber, I also have a table disease_catagories which stores the results of a select list. (stores the subscriber id, and the taxonomy term id. It can store any number of items with the same subscriber id and different taxonomy term ids)

I need the entity to contain an array of those taxonomy term ids, but I don't know how to connect that database table with the base table. are there any good articles that discuss how to attach a second table to the entity (maybe as field data)?

Entity API itself can only interact with one base table for joining to fields, querying with EntityFieldQuery, loading/saving revisions, etc, but you can use more than one table for storage if you implement your own storage controller which you can specify in your hook_entity_info().

You'll want to subclass DrupalDefaultEntityController and override the load() method and buildQuery() method if you want some EntityFieldQUery support.

If you are using Entity API module, you'll want to extend EntityAPIController and override the save(), load(), and delete() methods for full CRUD support.


How to add item into a paragraphs I'm trying to create Paragraphs programatically, to store an Indesign File with the images linked to it, so I have my paragraph type with some fields

field_indesign_file : (limited to one value)
field_indesign_image : (illimited number of images)

Currently the creation is OK :

$paragraph = Paragraph::create([
  'type' => 'indesign',
  'field_indesign_file' => [
    'target_id' => $indesign->id(),
  ],
  'field_indesign_image' => [
    'target_id' => ${'image'.'3'}->id(),
  ],
]);

but I don't know in advance how many pictures I'll have attached to the indesign file, so Id' like to be able to add other values to the field_indesign_image.

I tried using

$paragraph->field_indesign_image[LANGUAGE_NONE][1]['value'] = [
        'target_id' => ${'image'.'1'}->id()
    ];

and

$paragraph->field_indesign_image->appendItem(
      [
        'target_id', ${'image'.'3'}->id()
      ]
    );

but none of this method worked, I didn't find a lot of documentation and sometimes answers to other topic are a bit too complicated for me to understand since I'm a beginner at drupal 8.

Finally I used a dynamic array

$tabImage[]["target_id"]

and inserted it

'field_indesign_rendition' => $tabImage,


How can I programmatically disable the "Preview" button in a content type? I have a content-type that has been created via hook_install. I want to set the "Preview" option to disabled. Currently it defaults to "optional". How can I change this in hook_install when I create the content type?

For programming disabling use special variable:

variable_set('node_preview_' . $content_type, '0');

For default node options "Published" (status), "Promoted" (promote), "Sticky" (sticky) and "New revision" (revision) use variable "node_options_" . $content_type, which takes array as a value.
Example can be found in standard installation profile:

// Default "Basic page" to not be promoted and have comments disabled.
variable_set('node_options_page', array('status'));


Should we document AJAX-callback parameters? Considering the PHPCS warning:

  phpcs: Hook implementations should not duplicate @param documentation

Is there any way to tell PHPCS that the function is an AJAX-callback (so that such warnings are generated)?

Or, Should we document all AJAX-callback parameters, with @param PHPDoc?

Background:

There was a discussion in our company about the below AJAX-callback function:

/**
 * Prevents popup's redirection from dashboard to another link.
 *
 * Users were redirected to another page as soon as the Event-creation
 * popup form was submitted, just added an AJAX handler to submit button
 * which prevents the redirect using ajax,
 * and when there is any error on the form, the message is sent to the popup.
 */
function _MYMODULE_popup_submit(array &$form, FormStateInterface $formState) {
  // ...
}

Where one developer insisted on adding @param PHPDoc comments to each AJAX-callback like:

/**
 * Prevents popup's redirection from dashboard to another link.
 *
 * Users were redirected to another page as soon as the Event-creation
 * popup form was submitted, just added an AJAX handler to submit button
 * which prevents the redirection using ajax,
 * and when there is any error on the form, the message is sent to the popup.
 *
 * @param array &$form
 *   All data of the form.
 * @param \Drupal\Core\Form\FormStateInterface $formState
 *   State of the form.
 *
 * @return \Drupal\Core\Ajax\AjaxResponse
 *   Returns the data back as AjaxResponse object.
 */
function _amt_dayview_popup_submit(array &$form, FormStateInterface $formState) {
  // ...
}

And the other considered it as understandable and that it should not be documented:

  ... remember that PHPCS will warn you every time we use @param on any hook, like "phpcs: Hook implementations should not duplicate @param documentation", and just because PHPCS can not differ AJAX-callback from normal functions it does not mean that we should do this ...

Edit: The feature request is created for this on Drupal.org.

Is there any way to tell PHPCS that the function is an AJAX-callback (so that such warnings are generated)?

Yes, it's as simple as implementing hooks except that instead of "Implements hook_", it starts with "Implements callback_".

The only problem is that currently (August 2019) it is not supported by Drupal's PHPCS standard and you don't get any warnings yet.

  Or, Should we document all AJAX-callback parameters, with @param PHPDoc?

That too is an option, for your newly hired dev interns, but especially when there was no official definition in any existing *.api.php file and when you do not want to write your own *.api.php file.

Source:

In Drupal's Official-documentation of August 2019, we can find below Callback implementation:

/**
 * Implements callback_batch_finished().
 */
function _node_mass_update_batch_finished($success, $results, $operations) {
  // …
}

  Note: Unlike hooks any callback starts with an underscore (i.e. it is "_MYMODULE_descreptive_name").

Callback definition example:

In our case, because Drupal's own *.api.php files did not cover AJAX-callbacks, we added our own *.api.php file to prevent copy/paste until Drupal's own *.api.php files cover that section as well, something like below:

<?php

/**
 * @file
 * Callbacks and hooks related to MYPROJECT system.
 */

/**
 * @addtogroup callbacks
 * @{
 */

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Form\FormStateInterface;

/**
 * Callback for AJAX events.
 *
 * AJAX callback functions can be used to update existing or
 * add new form fields, update values in form fields and more,
 * while users can still interact with the form.
 *
 * @param array &$form
 *   All data of the form.
 * @param \Drupal\Core\Form\FormStateInterface $formState
 *   State of the form.
 *
 * @return \Drupal\Core\Ajax\AjaxResponse
 *   Returns the data back as AjaxResponse object.
 */
function callback_form_ajax(array &$form, FormStateInterface $formState) {
  // Here we do something meaningful with the results.
  $response = new AjaxResponse();
  $response->addCommand(new HtmlCommand('#message-box', 'my message.'));
  return $response;
}

/**
 * @} End of "addtogroup callbacks".
 */

/**
 * @addtogroup hooks
 * @{
 */

/* Place any hook definitions here. */

/**
 * @} End of "addtogroup hooks"
 */

Callback implementation example:

/**
 * Implements callback_form_ajax().
 *
 * Prevents popup's redirection from dashboard to another link.
 *
 * Users were redirected to another page as soon as the Event-creation
 * popup form was submitted, just added an AJAX handler to submit button.
 * which prevents the redirect using ajax,
 * and when there is any error on the form, the message is sent to the popup.
 */
function _amt_dayview_popup_submit(array &$form, FormStateInterface $formState) {
  // ...
}


Trying to get content type from a node entity I'm trying to get the content type from a node entity.

The entity is being loaded as follows:

$synclist = entity_load_single('entity_synclist', $qid);

Now, how would I then get the content type? Would it be as simple as:

$contenttype = $synclist->type;

Or do I have to do some other Drupal magic?

You're not loading a node there, you're loading an entity of type entity_synclist. Its bundle key might be type, but it depends on what's defined in the module's implementation of hook_entity_info().

To be sure, you can get that information from the entity definition and use it to get the bundle like so:

$info = entity_get_info('entity_synclist');
$bundle_key = $info['entity keys']['bundle'];

$synclist = entity_load_single('entity_synclist', $qid);
$bundle = $synclist->$bundle_key;


Error when executing drush sql-sanitize Drush sql-sanitize doesn't work on my test install.

drush @pfdevd6mg sql-sanitize --sanitize-password=newpassword
PHP Warning:  Module 'curl' already loaded in Unknown on line 0

The following operations will be done on the target database:
 * Reset passwords and email addresses in users table
 * Truncate Drupal's sessions table

Do you really want to sanitize the current database? (y/n): y
Sanitize query failed.

does alias aren't possible ?

EDIT: Using Drush 8

ERROR 1146 (42S02) at line 1: Table 'provence-formation_pfdevd6mg.users' doesn't exist
Sanitize query failed.

Quote from Moshe Weitzman, main drush developer

  Database prefixing is no longer supported by Drush. Its a relic from a
  prior era.

March, 2017.


Using Memcache Effectively with Drupal 7 Multisite I am setting a hit ratio of 55% on our memcache instance (v1.4.4) and am wondering what can be done to improve the hit ratio. We're in a multisite setup (30+ sites), with two load balanced web servers; there is an instance of memcached on each web server.

In the settings.php, I have:

$conf['memcache_servers'] = array(
         '11.22.33.44:11211' => 'default',
         '11.22.33.45:11211' => 'default',
      );
$conf['memcache_bins'] = array('cache' => 'default');
$conf['memcache_key_prefix'] = $_SERVER['SERVER_NAME'];

I am looking at using bins to improve hit ratio, but have come across some suggestions that the latest memcache module does this already, but I am unsure as the instructions with the module contain directions on setting up bins.

If bins are they way to go, how do you determine what (table?) needs to have its own bin? These are the cache tables that I have in my sites:

cache
cache_admin_menu (empty)
cache_block (empty)
cache_bootstrap
cache_field
cache_filter (empty)
cache_form (empty)
cache_image (empty)
cache_media_xml (empty)
cache_menu
cache_page (empty)
cache_path (empty)
cache_token (empty)
cache_update (empty)
cache_views
cache_views_data (empty)
ctools_css_cache (empty)
ctools_object_cache (empty)

In addition to bins, what else can I be doing to improve memcached usage?

Many thanks!

After much research, here is what has helped our hit ratio and memcached usage:

Upgraded memcached to 1.4.10 (the latest version with performance improvements)
Enabled binary format and compression
Use the default for bins

Our memcached conf in settings.php looks something like this now:

$conf['memcache_bins'] = array('cache' => 'default');
$conf['memcache_options'] = array(
  Memcached::OPT_COMPRESSION => TRUE,
  Memcached::OPT_BINARY_PROTOCOL => TRUE,
  );
$conf['memcache_persistent'] = TRUE;
$conf['memcache_key_prefix'] = $_SERVER['SERVER_NAME'];

Biggest Gains

The biggest gain for us was enabling compression, even though the documentations states that it increases CPU cycles. We have 4 CPUs allocated to our VM, and have not noticed a difference. Time for memcached calls went from ~1250ms to ~150ms (obtained from NewRelic) for creating a piece of content (custom Article in our case).

Hit Ratio

Our hit ratio is now ~70% -- much better than 55% earlier, but not quiet the 90%+ that some have reported ... the quest continues (-:

Hopefully this helps someone else. If you come across other improvements or have corrections/suggestions, please post comments or answers.

Update -- Version of memcahe module

We went from version 1.0-beta4 to 1.0 and our hit ratio now is 87% . I had to restart memcached as hit ratio wasn't going past 70%. We have 64MB allocated to memcached at the moment, so this was not a big deal for us.


Why is INPUT field size different across platforms? OS X vs Windows? I have a drupal created form where I have set the size of the form:

$form['myform']['#size'] = 22;

Now on my windows machine on Chrome / FF / IE / Safari it is a specific size, visually.

When I go to view the same form on my Macbook the same INPUT field is significantly smaller in Chrome / FF / Safari on OS X ??? Even though both obviously have the size = 22 setting?

Why is it not rendering the same size across all platforms??

Size is the char amount that goes into the input field. If you want to style it, use CSS.

.inputbox{
  border: 1px solid #666;
  width: 210px;
  height: 30px;
  font-size: 1em;
}


Running drush as regular user I've recently upgraded to Drush 8, from Drush 6.2 (That was installed using pear).

Drush on cPanel runs fine as root, but when I try to run it as a regular user in a valid Drupal directory I get the error:

Command pm-refresh needs a higher bootstrap level to run - you will need to invoke drush from a more functional Drupal environment to run[error]

this command

Or for just trying to clear cache using drush cc all:

No Drupal site found, only 'drush' cache was cleared

And when I add --debug to the end of a command I get a mysql error with drush:

Access denied for user 'username'@'localhost'

I was able to get to the bottom of this problem.  When I ran drush in debug mode, for example "drush status --debug" it outputted an error that it could not connect to the database.

After hours of digging for some reason on this particular cPanel server there were .my.cnf files in each user's home directory which contained mysql authentication details.  Drush was taking precedence on these credentials and in turn not able to connect to the particular Drupal install's database.  I simply did "rm -rf /home/username/.my.cnf to delete each of these hidden files, then running drush works!


How to programmatically create file entity reference on entity Example with "normal" entity reference.

$node = node_load($nid);
$node->field_reference = array(
  $node->language => array(0 => array(
    'target_id' => $other_nid,
  ))
);
node_save($node);

Now I want to do the same, but on a File entity field instead.
Examining an attached file with devel, the field looks mostly like a plain

$file = file_load($fid);

object, but there's some more data on it, so I'm guessing I will hit problems down the road if I just stick the $file on to the ref, instead of figuring out the proper API call.

The file entity module wraps around the core file field, which defines only three field columns that you need to worry about providing:

fid (file id)
display (boolean indicating if the file is displayed or not)
description (self-explanatory)

You can safely ignore any other values that you find on the field as they'll be discarded anyway when it comes to committing the field data.

If I remember rightly it's the core file module that adds the extra data to the field, which is essentially the file object converted to an array. If you're seeing any other 'foreign' values in there they're probably coming from the file_entity_field_load() function.


How to feature-ize multiple vocabularies applied to multiple content types? Each of my content types is being exported into its own feature. I now need to export several vocabularies that are associated with the content.

Some of the vocabularies are applied to multiple content types. What is my best option for exporting those? Can I export a stand-alone feature that contains all the vocabularies that apply to multiple content types? Or should I associate them all with the most common content type? Or do I have to include each vocabulary in each feature individually?

An important thing to keep in mind is that things start getting messy when multiple features try to export the same thing. For example, have multiple features that export the same Taxonomy vocabulary. When this happens, best case scenario is that you have to update all the features every time you make a change to the vocabulary. Worst case is, well, worse than that. I've heard some horror stories, but never tried it personally; I do my best to keep proper separation.

In your case, I suggest separating the content types and vocabularies into separate Features. For the vocabularies, you can either put them all in one feature or split them up into separate features, whichever you prefer. I tend to keep all the vocabularies in a single feature, which I think makes sense for your situation as well. For the content type Features, you can now list as a dependency the Features module defining the vocabulary used by that content type.


Taxonomy parent terms - pathauto Pattern for taxonomy terms is [term:parent]/[term:name] where car is parent and BMW is child

Path is looking like this when I am on child term page:
www.mysite.com/car/bmw

In menu I have link to /car and when I am there it displays a list of all child terms. Thats fine.

But when I generate XML sitemap I see /car/bmw (all good), but for strange reason there is link taxonomy/term/1 and which leads to page without any content or terms in it, while it should redirect to /car.

There is no /car link found.

To avoid duplicate content I am not sure how to avoid this. I tried recreating all paths bit no luck

Edit:

To elaborate in more details.
Vocabulary has several parents, each 100 childs.
Childs are displaying correctly as i have described above.
For each parent i created separate view to display several fields.
Filter is set to Taxonomy Term: Parent term. Is equal to "value", where value is taxonomy tid. Lets say that for this view value is 1 (term car)
I also have relationship with Identifier: Parent. Require this relationship is on.

Path is set to /car
Menu to Normal menu item "CAR".

When i go on homepage and click on menu item CAR everything is fine.

In meantime i deleted and bulk updated all taxonomy and now instead of getting old /taxonomy/term/1 or "/car" path for tid 1, i got "car-0".

View that is in menu "CAR" is still displaying ok, path is ok ("car"), but sitemap cant find this url but instead finds "car-0".
Going to path "car-0" displaying nothing, not the terms nor the content it is tagged with.

After testing out for a day various combinations it was a problem with a view page that had path same as taxonomy/term/1.

So I renamed the view page path to car/bmw12, deleted taxonomy aliases and recreated them.

It was easy thing to do. I did not think of it earlier as i was lead by assumption that when you use pathauto to recreate paths it would do it for terms no matter if the path was taken in views already.


How do I create a link to a view in Commerce Order listing? I want to create a link on an order dropdown menu in commerce order that is attached to a view.  So for example, when you are looking at the list of orders, there is a drop down menu which has Quick Edit, Payment, Delete, etc.  I want to another element to this drop down menu which points to a view that I have created.

I have successfully added a link this dropdown menu using the following code, but it links to a form.

$items['admin/commerce/orders/%commerce_order/cancel'] = array(
    'title' => 'Cancel',
    'page callback' => 'bh_order_handling_ui_order_cancel_form_wrapper',
    'page arguments' => array(3),
    'access callback' => 'bh_order_handling_ui_cancel_access',
    'access arguments' => array(3),
    'type' => MENU_LOCAL_TASK,
    'weight' => 30,
    'context' => MENU_CONTEXT_INLINE,
);

What I want to do is link to a view that I have created at the path admin/commerce/orders/%/takehomeitems.

I have tried the following, using suggestions from http://zufelt.ca/blog/embedding-view-menu-hook-drupal

$items['admin/commerce/orders/%/takehomeitems'] = array(
        'title' => 'Take Home Items',
        'page callback' => 'views_embed_view',
        'page arguments' => array('bh_view_customer_donation_line_item','default',3),
        'access callback' => 'bh_donate_takehomeorder_access',
        'access arguments' => array(3),
        'type' => MENU_LOCAL_TASK,
        'weight' => 10,
        'context' => MENU_CONTEXT_INLINE,
        'file path' => drupal_get_path('module', 'views'),
        'file' => 'views.module',
);

I needed to call views_embed_view in my own page callback because I needed to pass the commerce order id for my contextual filter.  Here is what I did:

I first defined the menu item.  Note that the path has %commerce_order instead of just %. This is needed to access the order object which has the id.

When creating the view, I put in in a separate path, not the path I used for the $items.  When I tried to use the same path, it didn't work.  I think it is because the $items path is needed to create the listing in the dropdown menu.

I defined the path of my view as something that was not admin/commerce/orders/%commerce_order/takehomeitems
It is important that your view have a contextual filter which takes the order id. My path was /admin/hubadmin/takehomeitems/%

See the bottom of my posted answer for the exported view example.

Then in hook_menu, i defined the following:

 $items['admin/commerce/orders/%commerce_order/takehomeitems'] = array(
   'title' => 'Take Home Items',
   'page callback' => '_bh_donate_takehome_lineitems',
   'page arguments' => array(3),
   'access callback' => 'bh_donate_takehomeorder_access',
   'access arguments' => array(3),
   'type' => MENU_LOCAL_TASK,
   'weight' => 10,
   'context' => MENU_CONTEXT_INLINE,
 );

I then defined the page callback which calls views_embed_view and by passing in the %commerce_order, I am able to get the order id

function _bh_donate_takehome_lineitems($order) {
  return views_embed_view('YOURVIEWNAME', 'YOURDISPLAYID', $order->order_id);
} //DISPLAYID is usually default. To find this out, choose to export your view and look at $handler = $view->new_display('default', 'Master', 'default'); The last parameter is the display id.

This creates a item in the dropdown menu of the order which links to a view. The breadcrumb path points to the order.

Here is my exported view that worked for an example.

$view = new view();
    $view->name = 'bh_view_customer_donation_line_item';
    $view->description = '';
    $view->tag = 'default';
    $view->base_table = 'commerce_order';
    $view->human_name = 'BH View: Customer Take Home Line Items';
    $view->core = 7;
    $view->api_version = '3.0';
    $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

    /* Display: Master */
    $handler = $view->new_display('default', 'Master', 'default');
    $handler->display->display_options['title'] = 'Customer Take Home Line Items';
    $handler->display->display_options['use_more_always'] = FALSE;
    $handler->display->display_options['access']['type'] = 'none';
    $handler->display->display_options['cache']['type'] = 'none';
    $handler->display->display_options['query']['type'] = 'views_query';
    $handler->display->display_options['exposed_form']['type'] = 'basic';
    $handler->display->display_options['pager']['type'] = 'full';
    $handler->display->display_options['pager']['options']['items_per_page'] = '10';
    $handler->display->display_options['style_plugin'] = 'table';
    $handler->display->display_options['style_options']['columns'] = array(
        'vendor_user_reference' => 'vendor_user_reference',
        'commerce_product' => 'commerce_product',
        'quantity' => 'quantity',
        'commerce_unit_price' => 'commerce_unit_price',
        'commerce_total' => 'commerce_total',
    );
    $handler->display->display_options['style_options']['default'] = '-1';
    $handler->display->display_options['style_options']['info'] = array(
        'vendor_user_reference' => array(
            'sortable' => 0,
            'default_sort_order' => 'asc',
            'align' => '',
            'separator' => '',
            'empty_column' => 0,
        ),
        'commerce_product' => array(
            'sortable' => 0,
            'default_sort_order' => 'asc',
            'align' => '',
            'separator' => '',
            'empty_column' => 0,
        ),
        'quantity' => array(
            'sortable' => 0,
            'default_sort_order' => 'asc',
            'align' => '',
            'separator' => '',
            'empty_column' => 0,
        ),
        'commerce_unit_price' => array(
            'sortable' => 0,
            'default_sort_order' => 'asc',
            'align' => '',
            'separator' => '',
            'empty_column' => 0,
        ),
        'commerce_total' => array(
            'sortable' => 0,
            'default_sort_order' => 'asc',
            'align' => '',
            'separator' => '',
            'empty_column' => 0,
        ),
    );
    $handler->display->display_options['style_options']['empty_table'] = TRUE;
    /* Relationship: Commerce Order: Referenced line items */
    $handler->display->display_options['relationships']['commerce_line_items_line_item_id']['id'] = 'commerce_line_items_line_item_id';
    $handler->display->display_options['relationships']['commerce_line_items_line_item_id']['table'] = 'field_data_commerce_line_items';
    $handler->display->display_options['relationships']['commerce_line_items_line_item_id']['field'] = 'commerce_line_items_line_item_id';
    /* Relationship: Commerce Line item: Referenced products */
    $handler->display->display_options['relationships']['commerce_product_product_id']['id'] = 'commerce_product_product_id';
    $handler->display->display_options['relationships']['commerce_product_product_id']['table'] = 'field_data_commerce_product';
    $handler->display->display_options['relationships']['commerce_product_product_id']['field'] = 'commerce_product_product_id';
    $handler->display->display_options['relationships']['commerce_product_product_id']['relationship'] = 'commerce_line_items_line_item_id';
    /* Field: Commerce Product: Vendor User Reference */
    $handler->display->display_options['fields']['vendor_user_reference']['id'] = 'vendor_user_reference';
    $handler->display->display_options['fields']['vendor_user_reference']['table'] = 'field_data_vendor_user_reference';
    $handler->display->display_options['fields']['vendor_user_reference']['field'] = 'vendor_user_reference';
    $handler->display->display_options['fields']['vendor_user_reference']['relationship'] = 'commerce_product_product_id';
    $handler->display->display_options['fields']['vendor_user_reference']['label'] = 'Vendor ';
    $handler->display->display_options['fields']['vendor_user_reference']['element_type'] = '0';
    $handler->display->display_options['fields']['vendor_user_reference']['element_label_colon'] = FALSE;
    $handler->display->display_options['fields']['vendor_user_reference']['element_wrapper_type'] = '0';
    $handler->display->display_options['fields']['vendor_user_reference']['element_default_classes'] = FALSE;
    $handler->display->display_options['fields']['vendor_user_reference']['field_api_classes'] = TRUE;
    /* Field: Commerce Line item: Product */
    $handler->display->display_options['fields']['commerce_product']['id'] = 'commerce_product';
    $handler->display->display_options['fields']['commerce_product']['table'] = 'field_data_commerce_product';
    $handler->display->display_options['fields']['commerce_product']['field'] = 'commerce_product';
    $handler->display->display_options['fields']['commerce_product']['relationship'] = 'commerce_line_items_line_item_id';
    $handler->display->display_options['fields']['commerce_product']['element_type'] = '0';
    $handler->display->display_options['fields']['commerce_product']['element_label_colon'] = FALSE;
    $handler->display->display_options['fields']['commerce_product']['element_wrapper_type'] = '0';
    $handler->display->display_options['fields']['commerce_product']['element_default_classes'] = FALSE;
    $handler->display->display_options['fields']['commerce_product']['type'] = 'commerce_product_reference_sku_link';
    $handler->display->display_options['fields']['commerce_product']['settings'] = array(
        'show_quantity' => 0,
        'default_quantity' => '1',
        'combine' => 1,
        'show_single_product_attributes' => 0,
        'line_item_type' => 'product',
    );
    $handler->display->display_options['fields']['commerce_product']['field_api_classes'] = TRUE;
    /* Field: Commerce Line Item: Quantity */
    $handler->display->display_options['fields']['quantity']['id'] = 'quantity';
    $handler->display->display_options['fields']['quantity']['table'] = 'commerce_line_item';
    $handler->display->display_options['fields']['quantity']['field'] = 'quantity';
    $handler->display->display_options['fields']['quantity']['relationship'] = 'commerce_line_items_line_item_id';
    /* Field: Commerce Line item: Unit price */
    $handler->display->display_options['fields']['commerce_unit_price']['id'] = 'commerce_unit_price';
    $handler->display->display_options['fields']['commerce_unit_price']['table'] = 'field_data_commerce_unit_price';
    $handler->display->display_options['fields']['commerce_unit_price']['field'] = 'commerce_unit_price';
    $handler->display->display_options['fields']['commerce_unit_price']['relationship'] = 'commerce_line_items_line_item_id';
    $handler->display->display_options['fields']['commerce_unit_price']['element_type'] = '0';
    $handler->display->display_options['fields']['commerce_unit_price']['element_label_colon'] = FALSE;
    $handler->display->display_options['fields']['commerce_unit_price']['element_wrapper_type'] = '0';
    $handler->display->display_options['fields']['commerce_unit_price']['element_default_classes'] = FALSE;
    $handler->display->display_options['fields']['commerce_unit_price']['click_sort_column'] = 'amount';
    $handler->display->display_options['fields']['commerce_unit_price']['settings'] = array(
        'calculation' => FALSE,
    );
    $handler->display->display_options['fields']['commerce_unit_price']['field_api_classes'] = TRUE;
    /* Field: Commerce Line item: Total */
    $handler->display->display_options['fields']['commerce_total']['id'] = 'commerce_total';
    $handler->display->display_options['fields']['commerce_total']['table'] = 'field_data_commerce_total';
    $handler->display->display_options['fields']['commerce_total']['field'] = 'commerce_total';
    $handler->display->display_options['fields']['commerce_total']['relationship'] = 'commerce_line_items_line_item_id';
    $handler->display->display_options['fields']['commerce_total']['element_type'] = '0';
    $handler->display->display_options['fields']['commerce_total']['element_wrapper_type'] = '0';
    $handler->display->display_options['fields']['commerce_total']['element_default_classes'] = FALSE;
    $handler->display->display_options['fields']['commerce_total']['click_sort_column'] = 'amount';
    $handler->display->display_options['fields']['commerce_total']['settings'] = array(
        'calculation' => FALSE,
    );
    $handler->display->display_options['fields']['commerce_total']['field_api_classes'] = TRUE;
    /* Contextual filter: Commerce Line Item: Order ID */
    $handler->display->display_options['arguments']['order_id']['id'] = 'order_id';
    $handler->display->display_options['arguments']['order_id']['table'] = 'commerce_line_item';
    $handler->display->display_options['arguments']['order_id']['field'] = 'order_id';
    $handler->display->display_options['arguments']['order_id']['relationship'] = 'commerce_line_items_line_item_id';
    $handler->display->display_options['arguments']['order_id']['default_action'] = 'empty';
    $handler->display->display_options['arguments']['order_id']['title_enable'] = TRUE;
    $handler->display->display_options['arguments']['order_id']['title'] = 'Order %1';
    $handler->display->display_options['arguments']['order_id']['default_argument_type'] = 'fixed';
    $handler->display->display_options['arguments']['order_id']['summary']['number_of_records'] = '0';
    $handler->display->display_options['arguments']['order_id']['summary']['format'] = 'default_summary';
    $handler->display->display_options['arguments']['order_id']['summary_options']['items_per_page'] = '25';
    /* Filter criterion: Commerce Product: Vendor User Reference (vendor_user_reference) */
    $handler->display->display_options['filters']['vendor_user_reference_uid']['id'] = 'vendor_user_reference_uid';
    $handler->display->display_options['filters']['vendor_user_reference_uid']['table'] = 'field_data_vendor_user_reference';
    $handler->display->display_options['filters']['vendor_user_reference_uid']['field'] = 'vendor_user_reference_uid';
    $handler->display->display_options['filters']['vendor_user_reference_uid']['relationship'] = 'commerce_product_product_id';
    $handler->display->display_options['filters']['vendor_user_reference_uid']['operator'] = 'not empty';
    /* Filter criterion: Commerce Line Item: Type */
    $handler->display->display_options['filters']['type']['id'] = 'type';
    $handler->display->display_options['filters']['type']['table'] = 'commerce_line_item';
    $handler->display->display_options['filters']['type']['field'] = 'type';
    $handler->display->display_options['filters']['type']['relationship'] = 'commerce_line_items_line_item_id';
    $handler->display->display_options['filters']['type']['value'] = array(
        'product' => 'product',
    );

    /* Display: Page */
    $handler = $view->new_display('page', 'Page', 'page');
    $handler->display->display_options['path'] = 'admin/hubadmin/takehome-items/%';


How can I indent parts of a Views field? I have a content/node View listing several node fields in an unformated list. The fields are displayed inline since they combine to make a message to users; on their own the fields don't mean much.

As you can see there are 3 fields above; user picture, user name, and the comment body. I have marked the order and the areas of the 3 separate span classes. The problem of course is that when field 3 has more than one line of text the subsequent lines are not indented enough and overlap field 1. I have tried using margin-left and padding-left in combination with the text-indent property, but since field 3 is inline the CSS only ends up indenting the first line instead of the lines after the first as I need. I can display field 3 as a block and this does allow me to have better control, however it places the field on a separate row, and as mentioned previously I need the fields to be displayed inline so that they combine to make a message. In other words, if you see the red line below I would like the field 3 text to wrap and indent in a way that it stays to the right of the red line for lines 2 and after.

So it would end up looking something like below, but of course with the beginning of the lines not clipped.

The only thing I can think of is having 2 copies of field 3, both of which are trimmed. Therefore the first copy would be trimmed to only show 1 line and the second would be trimmed to show everything after the first line, however the problem is that I'm not sure how to trim the beginning of a field. So how can this be achieved?

Put the class clearfix as the row class (format->settings). If your
theme does not have clearfix defined, define it yourself.
Hide the output of the other two fields (click on the field in views
form and you will see this setting 'exclude from display').
Create a global: Custom text field and make sure it is the last
field in the views list of fields.
Rewrite results -> rewrite the output of this global
text field, and from the replacement patterns select field 2 and 3
as tokens. Also add a class for that field in style settings such as
'align-block'. Define it as follows:

align-block {
overflow:hidden;
}

in your css file.

Add a class to your image field such as 'float-left'. Define it as follows:

float-left {
float:left;
}

in your css file.


Assigning CSS classes to exposed widgets in a view? I have several exposed widgets in a view, they allow users to sort stories by date or by tag. However, I am trying to style the block and because each widget is only given a 'views-exposed-widget' class by default, I can't figure out a way to style each widget differently. Is there a simple way to give each widget a different css class or id? I need to set different widths to different divs, etc.

Drupal – Theme the Exposed Filter in Views. Basically make a custom views-exposed-form.tpl.php file at your theme level that is specific to each of the widgets you have setup. You can then adjust the markup in each of the template files to include a unique ID to allow styling specific to each widget.


Show a discount field in the Product display page I want to apply some discounts on products.
I know the Commerce discount module and its UI.
However,it would be much simpler for the site admin to have a second field on the product display for the discount-new lower price.
Is this possible to do?If so how?
thanks

I found the answer,with the use of this module https://www.drupal.org/project/commerce_saleprice


Title in url instead of tid? How can I display the title in URLs instead of the taxonomy ID?

www.abc.com/search-page?tid=01 should be www.abc.com/search-page?title=this-is-the-first-post.

I am using Taxonomy Terms as Search in Views (Configure filter criterion: Content: Has taxonomy term). When I click on taxonomy, I will find more button; when I click i will find "Filter identifier" by default "tid" is present.

When i tried to change that to title, it displayed Page not found.

On Views >> Advanced >> Contextual Filters, I added the field for the title, but even this is not working.

Thanks

I have fixed this, just for other guys who are facing the same issue, I thought to post this.

created a Taxonomy Page with tag selected
save and edit
FIELDS -> add your necessary fields
FILTER CRITERIA -> add: Taxonomy term: Name (exposed)
click on Advance tab to the right side
RELATIONSHIPS -> add : Taxonomy term: Content with term
CONTEXTUAL FILTERS -> add : Taxonomy term: Name

I'm using exposed form "Exposed form in block:Yes" to be displayed as a block and can be assigned to the page.

Search Result in URL : drupal-7/search-new-1?name=tag


temporary://fileh4Oxvi could not be copied, because the destination directory is not properly configured I am using Advagg and Amazons3 Module, which is causing this error:

  temporary://fileh4Oxvi could not be copied, because the destination directory is not properly configured.

Files are getting created in "tmp" folder but that has been not copied to s3 bucket.

I had given the "tmp" folder 755 and even 777, which is not working.
And I even tried Configuring the temporary directory, which is not working even.

Any inputs are really appreciated.

...could not be copied, because the destination directory...

The temp folder is the source in this context, Drupal is complaining that the destination is not writable.

You need to make your public file system (usually sites/default/files) writable by the web server user.


Output Flexifield content as Excel file? I'm using Drupal 6 and Flexifield to create an extensible CCK content type for doing various measurements. The content type is composed of three flexifield fields -- "levels", "rooms" and "fixtures", all of which can have new rows added to them via the "Add another..." button (no min/max to the number of rows in each flexifield sub-type).

The "levels" flexifield sub-type has two fields: level name and total area. The "rooms" flexifield sub-type has three fields: length, width, area. The "fixtures" flexifield sub-type is irrelevant for this part of the project.

What I ultimately need to do is output the "rooms" data as a table, then export that as an XLS file (which is then used by some CAD software somewhere down the line). I've been trying to do this via Views UI and Views Excel Export, but I can't see to make the latter module conform to the Excel template I've been given:

Each room's row in Excel should look something like:

Block Name  |  Roomname  |  Imperial  |  Metric

"Block Name" is the same string for all rows; "Roomname" has to be the name of the room as defined in the "room" flexifield sub-type. The values entered in each room are all either Imperial or Metric as per an option on the main content type, but I'll need some way to populate the correct column based on whichever type of data's been entered, plus convert those values to the other system.

Is Views UI (with Excel Export) the right way to go about this? If so, how do I interact with the "room" flexifield data insomuch that I can make each "Room" object a separate row in the Excel sheet?

Many thanks. This is the last part of a huge project I've been working on for months and will be grateful for any help.

Have you tried the CSV export provided by Views Bonus Pack? It's not true XLS, but does it need to be, as long as it opens in Excel and the data is correct?


Drupal 7 Add Readmore to Basic Page I am new to Drupal, I have requirement to add a readmore link to Basic Page content. That readmore trim the full content.

There are a few 'read more' link modules, like this one: http://drupal.org/project/read_more

There is also the 'teaser' display mode, as on the front page.


How to move nested links in menu edition? In Drupal 8 I created nested menu links. After some days I tried  to move them. Eg. one nested link to one parent menu link but the moving got disabled.

I remember that there were small cross icons with arrows in front of each menu link that were handles to move them before. But now they are not present. How to move the links?

There is no problem on chrome but firefox.

See the picture of the problem:

If you don't have javascript error in the browser console try to click Hide row weight then you will see normal table drag behavior.


Aggregate & Compress CSS / JS Kills Metatag Fieldsets I had to turn on aggregate and compress CSS and JS for my site as the performance was terrible and I was getting a lot of CSS errors (admin bar would disappear intermittently or not load correctly or other CSS errors)

Activating the aggregation improved page load times dramatically and solved all my other CSS issues, however, now I get an error with the metatag module in which the field sets for Open Graph, Facebook etc. won't load as hyperlinks which can be expanded, only plain text.

The issue seems limited to the blog content type.

Any ideas where I can look to solve the issue?

Most likely there is a parse error in a JS and or CSS file. Check the console for any error; fix them and try again.


How to get the content moderation entity related to node entity in drupal 8.2.x? from a content moderation entity, i know how to get the associated node:

 if ($entity->getEntityTypeId() == 'content_moderation_state' ) {
     $article_id=$entity->get('content_entity_id')->getString();
     $article = \Drupal\node\Entity\Node::load($article_id);
 }

What i need to do is the reverse.
Being able from hook_form_alter, to get the content moderation entity related to the node:

 function hook_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id){
  if ($form_id='node_article_edit_form')
  {
    $node=$form_state->getFormObject()->getEntity();
    //$node->get_content_moderation_entity??

}

}

i did it with entityQuery

function hook_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id){
 if ($form_id='node_article_edit_form')
  {
    $article=$form_state->getFormObject()->getEntity();
    //get the associated content moderation entity
    $id = Drupal::entityQuery('content_moderation_state')
       ->condition('content_entity_id', $article->id())
        ->execute();

    $stateEntities = Drupal::entityManager()
        ->getStorage('content_moderation_state')
        ->loadMultiple($id);
    $stateEntity=array_values($stateEntities)[0];
    $moderation_state = $stateEntity->get('moderation_state')->getString();
   }
 }


How to create a table during the module installation I'm trying to create a module for Drupal 7 and I need to create 3 tables and populate it. But first i need to create it.

In the file mymodule.install I have got

function mymodule_install() {

}

function mymodule_uninstall() {

}

function myodule_schema() {
  $schema['mymodule_table'] = array(
    'description' => t('First table'),
    'fields' => array(
      'id' => array(
        'description' => t('My unique identifier'),
        'type' => 'int',
        'unsigned' => true,
        'not null' => true,
      ),
      'list' => array(
        'description' => t('list'),
        'type' => 'varchar',
        'not null' => true,
      ),
    ),
    'primary key' => array('id'),
  );
  return $schema;
}

What am I doing wrong?
Every time I test the module, I disable it -> uninstall -> Performance clear cache -> enable it.

You're missing the length property for the varchar column ('list'). length is required so the CREATE TABLE query will fail.

From the Schema API docs:

  All parameters apart from 'type' are optional except that type 'numeric' columns must specify 'precision' and 'scale', and 'varchar' columns must specify 'length'.


How to use drupal_mail() to send emails with custom template I would like to use the drupal_mail() function to send out emails but with a custom HTML template so that they are in keeping with my website design but I am a complete newbie to hooks and modules etc., so I'd appreciate some sort of explanation or beginners guide please.

I can create the template myself, I just need to know how to get drupal_mail() to use it.

If you are trying to send the mails via your custom module then you can follow the below mentioned guide.
Say, I had one Module called "Commerce Canvas(commerce_canvas)"
 1. First Alter the Drupal's mail function to support links and add other encoding types

/**
 * Implements hook_mail_alter()
 * @param string $message
 */
function commerce_canvas_mail_alter(&$message) {
    $headers = array(
        'MIME-Version' => '1.0',
        'Content-Type' => 'text/html; charset=iso-8859-1; format=flowed',
        'Content-Transfer-Encoding' => '8Bit',
        'X-Mailer' => 'Drupal',
    );
    foreach ($headers as $key => $value) {
        $message['headers'][$key] = $value;
    }
}

Then next, hook the HOOK_mail in your module as

/**
 * Implements hook_mail()
 * @param string $key
 * @param string $message
 * @param unknown_type $params
 */
function commerce_canvas_mail($key, &$message, $params) {

    //Language Selection
    $options = array(
        'langcode' => $message['language']->language,
    );
    switch($key) {
        case "user_payment_notification" :
            $message['subject'] = isset($params['subject']) ? $params['subject'] : $message['subject'] = t('Payment recieved @site-name', array('@site-name' => variable_get('site_name', 'Express Canvas')), $options);
            $message['body'][] = isset($params['body']) ? $params['body'] : NULL;
            if (isset($params['headers']) && is_array($params['headers'])) {
                $message['headers'] += $params['headers'];
            }
            break;
    }
}

Then you need to create a wrapper function to invoke the mail from your module.

function commerce_canvas_mail_send(array $values = array()) {
    $module = $values['module'];
    $key = $values['key'];
    $to = $values['to'];
    $from = $values['form'];
    $language = isset($values['lang']) ? $values['lang'] : language_default();
    $params = array(
        'subject' => $values['subject'],
        'body' => $values['body'],
    );
    if(array_key_exists('headers', $values)) {
        $params['headers'] = $values['headers']; //Assumed as an array
    }
    $send = TRUE;
    $mail = drupal_mail($module, $key, $to, $language, $params, $from, $send);
    if($mail['result']) {
        return TRUE;
    } else {
        $error_msg = 'Failed to send the email in commerce_canvas Module';
        watchdog('canvas-email', $error_msg, array(), WATCHDOG_ALERT);
        return FALSE;
    }
}

This function will send the email and as well as create debug messages if anything happens wrong.
But still you won't be able to send the HTML mail because you need to extend the Drupal 7's default DefaultMailSystem with your own. So need to do as following,

class CommerceCanvasMailSystem extends DefaultMailSystem {
    /**
     * Concatenate and wrap the e-mail body for plain-text mails.
     *
     * @param $message
     *   A message array, as described in hook_mail_alter().
     *
     * @return
     *   The formatted $message.
     */
    public function format(array $message) {
        $message['body'] = implode("\n\n", $message['body']);
        return $message;
    }

    /**
     * Send an e-mail message, using Drupal variables and default settings.
     *
     * @see http://php.net/manual/en/function.mail.php
        * @see drupal_mail()
     *
     * @param $message
     *   A message array, as described in hook_mail_alter().
     * @return
     *   TRUE if the mail was successfully accepted, otherwise FALSE.
     */
    public function mail(array $message) {
        $mimeheaders = array();
        foreach ($message['headers'] as $name => $value) {
            $mimeheaders[] = $name . ': ' . mime_header_encode($value);
        }
        $line_endings = variable_get('mail_line_endings', MAIL_LINE_ENDINGS);
        return mail(
        $message['to'],
        mime_header_encode($message['subject']),
        // Note: e-mail uses CRLF for line-endings. PHP's API requires LF
        // on Unix and CRLF on Windows. Drupal automatically guesses the
        // line-ending format appropriate for your system. If you need to
        // override this, adjust $conf['mail_line_endings'] in settings.php.
        preg_replace('@\r?\n@', $line_endings, $message['body']),
        // For headers, PHP's API suggests that we use CRLF normally,
        // but some MTAs incorrectly replace LF with CRLF. See #234403.
        join("\n", $mimeheaders)
        );
    }
}

Next you need to register a new theme function that will call your custom template file in your hook_theme().

/**
 * Implements hook_theme();
 */
function commerce_canvas_theme($existing, $type, $theme, $path) {
  if($type == 'module') {
    return array(
      'tracking_code_email' => array(
        'variables' => array(
          'image_path' => NULL,
          'user' => NULL,
          'page' => NULL,
        ),
        'template' => 'commerce-canvas-tracking-code',
        'path' => drupal_get_path('module', 'commerce_canvas').'/theme',
      ),

    );
  }
}

Last you need to call this theme function in time of sending the email as,

function a_custom_function($params) {

$email_text_user = theme('tracking_code_email', array(
                    'image_path' => $base_url . '/' . drupal_get_path('module', 'commerce_canvas') . '/images',
                    'user' => null,
                    'page' => array(
                        'greet_text' => t('Thank you for your order at Express Canvas. Your order is ready and has shipped. You may track your order using FedEx tracking with your tracking number: '.$order->field_tracking_number['und']['0']['value'].''),

                    ),
                ));
$sent_to_user = commerce_canvas_mail_send($email_values_user);

}

These are the full snippet to handle the HTML email correctly in Drupal 7 thus in the hook_theme you can give your custom template.


Drupal 8 - How to edit a user as admin without changing the password Does anyone know how to edit user profiles as an administrator in Drupal 8(change roles in my case) without having to know or change the password?

Thanks

You can do it from the command line using drush user-add-role.
To find the exact syntax, type :

drush help urol

Hope it helps.


How to Programmatically add javascript dynamically from a custom module to modify a popup calendar property I need to add a JavaScript code to my custom module, to modify the property in a date popup calendar and make it dynamic.

According to the documentation of the date popup calendar, the syntax for modifying the MaxDate is:

$( ".selector" ).datepicker({
  maxDate: "+1m"
});

I have to write "+1m" dynamically because it may be "+2m", "+3m", etc, it is variable.

How can I write a JavaScript code in my custom module and effect the popup calendar? I am wondering if I use script tag and put the JavaScript code inside it.
In case, how can I do it by js?

You can attach a script to a form using the form's #attached attribute. You can do this in hook_form_alter as follows:

function hook_form_alter(&$form, &$form_state, $form_id)
{
  if($form_id == 'targeted_form')
  {
    $form['#attached']['js'][] = array
    (
      'type' => 'file',
      'data' => drupal_get_path('module', 'my_module') . '/scripts.js',
    );
  }
}

If you need to pass values from PHP to the form, you can attach values using Drupal.settings:

function hook_form_alter(&$form, &$form_state, $form_id)
{
  if($form_id == 'targeted_form')
  {
    $form['#attached']['js'][] = array
    (
      'type' => 'setting',
      'data' => array('myModule' => array('someSetting' => 'some value')),
    );
  }
}

Now the value will be available in your form at:

Drupal.settings.myModule.someSetting

Combine these two techniques to attach a form and pass it some settings.


How to get URL parameters values inside access callback I have a link looking like this:

members/get-certificate/<user_id>/<group_id>/<pass date>

The access callback should work like this:

if($user->uid == <user_id>)
{
    //any user can get his own certificate
    <generate certificate>
}
else
{
    //user with low admin priviledges can generate a certificate for any user
    if (user_access('low admin task'))
    {
        <generate certificate>
    }
    else
    {
        print "Access denied";
    }
}

In hook_menu I wrote this:

$items['members/get-certificate'] = array(
    'page callback'    => 'members_get_certificate',
    'access callback' => 'members_access_get_certificate',
    'access arguments' => array('access content', $user_id),
    'type' => MENU_CALLBACK,
    );

Access callback

function members_access_get_certificate($permission, $user_id)
{
    global $user;

    if ($user_id != $user->uid)
    {
        if (!user_access('low admin task'))
        {
            return false;
        }
    }

    return true;
}

Page callback

function members_get_certificate($user_id, $group_id, $pass_date)
{
    //generate certificate
}

Problem

Unfortunately, $user_id is undefined in members_access_get_certificate and I am unable to do the validation. How can I pass the parameter from URL into the callback?

You can specify arguments in the URL path you are registering by using the "%" character:

$items['members/get-certificate/%'] = array( ... );

You can then pass the argument value to your page callback and/or your access callback by specifying which segment of the URL path to pass. The segments are the parts of the path separated by "/" characters, and you start counting them from 0. So to pass the value of '%' from the above example, you will specify the integer value 2 in your 'access arguments' value:

  'access arguments' => array('access content', 2),

So when a user attempts to access the path 'members/get-certificate/30', the access callback will be passed the argument values 'access content' and '30'. The callback you provided would then have the correct intended values.

Here then is your hook_menu item definition, corrected as outlined above:

$items['members/get-certificate/%'] = array(
    'page callback'    => 'members_get_certificate',
    'access callback' => 'members_access_get_certificate',
    'access arguments' => array('access content', 2),
    'type' => MENU_CALLBACK,
    );


How to add an element into a nested array in twig? I've decided to include opportunities of the bootstrap library in drupal native forum and I'm trying to add new class into a nested array in twig.
Here is my code.

{%  set topics['#rows'][0][0]['class'] = topics['#rows'][0][0]['class']|merge(['col-xs-9', 'col-sm-6']) %}
{%  set topics['#rows'][0][1]['class'] = topics['#rows'][0][1]['class']|merge(['col-xs-3', 'col-sm-2']) %}
{%  set topics['#rows'][0][2]['class'] = topics['#rows'][0][2]['class']|merge(['hidden-xs', 'col-sm-4']) %}

But upon executing the page an error is being displayed.
Here is description of the error.

Twig_Error_Syntax: Unexpected token "punctuation" of value "[" ("end of statement block" expected). в Twig_TokenStream->expect()

Could you clarify me, how to properly add new elements into the compound array ?

I managed to solve the problem via hook_preprocess.
Here's the code

function mytheme_preprocess_table__forum_topic_list(&$vars){
    $vars['header'][0]['attributes']->addClass(['col-xs-9', 'col-sm-6']);
    $vars['header'][1]['attributes']->addClass(['col-xs-3', 'col-sm-2']);
    $vars['header'][2]['attributes']->addClass(['hidden-xs', 'col-sm-4']);

    $vars['rows'][0]['cells'][0]['attributes']->addClass(['col-xs-9', 'col-sm-6']);
    $vars['rows'][0]['cells'][1]['attributes']->addClass(['col-xs-3', 'col-sm-2']);
    $vars['rows'][0]['cells'][2]['attributes']->addClass(['hidden-xs', 'col-sm-4']);
}