Does the Drupal FAPI support more than one AJAX callback? I am using FAPI's AJAX property to save nodes asynchronously. When the associated AJAX callback gets called, it gets passed the $form and $form_state parameters respectively. I then simply call drupal_render($form) from the AJAX callback and voilá, the node edit page is refreshed asynchronously. This works well.

The problem that I am having is that I am only replacing the form, but I also want to replace the page title. The page title is not part of the node edit form; so I could change the node title on the edit form, but the page title would remain stale when saving and refreshing the form (note: the edited title does get saved into the db). I cannot target an element sitting higher in the DOM hierarchy because (ie, by changing pointing the wrapper to the body) because the AJAX callback is only aware of the form's contents.

drupal_render($form) works great, but I have the fear that if I where to point the wrapper to the body (or somewhere near it) and render the whole page, that this would have unintended consequences (such as skipping certain rendering steps, resulting in incomplete DOM data). That's why I thought of maybe adding a second AJAX callback to the form submit action: one for handling the form itself, another AJAX callback for handling the page title. Do you know if having more than one callback is possible? Can you think of a way of targeting two separate wrappers using FAPI's AJAX? Do you know if the path (instead of callback) property provides a solution for my problem? If path does work feel free to augment your answer with a short example.

Please limit answers to functionality supported by Drupal core. I am not interested in third-party modules that use their own javascript logic (ie, ctools, etc).

Sample code:

// Add ajaxified save button in hook_form_FORM_ID_alter (foo_form_node_form_alter).
$form['actions']['ajax_save']['#type'] = 'submit';
$form['actions']['ajax_save']['#access'] = TRUE;
$form['actions']['ajax_save']['#value'] = 'Save';
$form['actions']['ajax_save']['#submit'] = array(0 => 'foo_node_form_submit');
$form['actions']['ajax_save']['#weight'] = 9;

$form['actions']['ajax_save']['#ajax'] = array(
  'wrapper' => $form['#node']->type. '-node-form',
  'callback' => 'foo_ajax_callback',
  'method' => 'replace',
    'effect' => 'fade',
);

...

function foo_ajax_callback(&$form, &$form_state = null) {

  $commands = array('#type' => 'ajax', '#error' => FALSE, '#commands' => array());
  $output = drupal_render($form);
  $commands['#commands'][] = ajax_command_insert(NULL, $output);
  // Prepend status messages to the node form.
  $commands['#commands'][] = ajax_command_prepend(NULL, theme('status_messages'));
  // Update the title on the page.
  $commands['#commands'][] = ajax_command_insert(NULL, $output);

return $commands;
}

Yes, you can solve it with core Drupal AJAX framework. You are already using $commands, you just need one more custom command.

Javascript code to provide new command:

(function ($) {
  Drupal.ajax.prototype.commands.change_title = function(ajax, response, status) {
    // Update the <title> element.
    document.title = response.data;

    // Update the page title.
    response.data = response.prefix + response.data;
    this.insert(ajax, response, status);
  }

})(jQuery);

PHP code to call this command:

  $commands['#commands'][] = array(
    'command' => 'change_title',
    'method' => 'html',
    // Selector targets Drupal 7's default theme
 title (Bartik 7.12).
    'selector' => 'div#branding h1.page-title',
    'data' => check_plain($form_state['node']->title),
    'settings' => NULL,
    'prefix' => 'Edit '. node_type_get_name($form_state['node']). ' ',
  );

Original idea is taken from here.


Weird activites in my site. Is my site hacked? Since long time I have been noticing some weird activity going on on my website.

For example:

The includes folder was deleted
CSS files were modified
Node edit access was given to anonymous users

I was thinking it could be human error by my team, but I can confirm they are not doing anything as such because they are just updating the content without touching the site configuration.

I see these users which we never created:

martinm14vxbyycdniot/fallsatj@hotmail.com
qhzcedrichjergsj/obscenehail72mbb@seznam.cz

They show as blocked users and I don't see any content created by them. I searched for the email ids and found they are marked as spammers but dont know what it is. These things are really worrying me. Does anyone know what might be going on?

Is my website hacked?

Update:

few minutes after posting this (and after deleting above users) this user is crated

qhzcedrichjergsj/obscenehail72mbb@seznam.cz

If your site is set up to allow people to register for the site, but requires administrator approval before they're activated (pretty common set up for Drupal), then spammers will manage to register accounts, but the accounts created like that will show as blocked users until they're approved.  That may explain why these blocked accounts exist.  If this is the case, then this is normal, and no grounds for concern.

To make sure only admins can create accounts, navigate to Home » Administration » Configuration » People » Account Settings and tick the radio button "Administrators only" for "Who can register accounts?".

As for the other "weird" stuff you've noticed (includes folder deleted, CSS files modified, node edit access given to anonymous users): It gives grounds for concern, but it is impossible to tell whether it is caused by malicious actions from outsiders, or human error by some careless admin.

If node edit access were given to anonymous users, but no node was ever defaced or otherwise maliciously altered because of this, I would lean in the direction of human error.


Programmatically import users and create each for them organic groups I have a function that allows me to create users from the data of an external database:

  function _loginuser_authenticate_validate($form, &$form_state) {
    global $user;

    // Use external database.
    db_set_active('external_database');
    // …
  }

Now I want to create, for each user from the external database, two groups (each group with four Drupal users, a group administrator, and three normal members).
I can create a group with og_insert_group($node);.
I can also create an admin for this group with og_save_subscription($node->nest, $node->uid, array ('is_active' => 1, 'is_admin' => 1));.

I don't know how to create multiple groups, and add members to these groups.
I also do not know where to put the code to create groups in the LoginUser module, or in another module.

Your explanation seems a little bit confused. Creation of an OG is as simply as creating a node.

So from what I understood you wish :

Get a user data from external source (how you perform this ? by cron ?)
Create a group for each user
Assign that user as group admin ?

Is it what you want to perform ?

Also take a look here :

http://drupalcontrib.org/api/drupal/contributions%21og%21og.module/7


How to define path in anchor tag in blocks? I'm working on localhost server and I added an anchor tag like below in block.

Contact

In front page it goes to the path directly, but if it is other than front page, it added the current path also, for example

http://localhost/r4launch/content/contactus

It add the "content" in front of the path, then it return "page not found".

how to define path in anchor tag ? or is that anything I'm missing ?

You can use the base_path() function to get the url with trailing slash '/'


Drupal::request()->request->all() returns an empty array I have a custom controller that expects POST data. I had it working fine in 8.1.0 retrieving the data using \Drupal::request()->request->all() and \Drupal::request()->request->get($myvar).

Now, without any changes in my custom module, \Drupal::request()->request->all() is returning an empty array, and \Drupal::request()->request->get($myvar) is returning NULL.

Between the time it was working and when the issue arose, my hosting service Pantheon updated their Drupal 8 version from 8.1.0 to 8.1.1 and then 8.1.2. I suspect something may have changed then that affected this.

How can I fix this?

EDIT: Thanks for the comments, still not quite working...

Route YAML:

mymodule.foobar:
  path: '/foobar'
  options:
    _auth: [ 'basic_auth' ]
  defaults:
    _controller: '\Drupal\mymodule\Controller\FooBarController::foobar'
    _title: 'foobar'
  requirements:
    _user_is_logged_in: 'TRUE'
    _permission: 'administer site configuration'

Controller:

<?php
namespace Drupal\mymodule\Controller;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
/**
 * Class FooBarController.
 *
 * @package Drupal\mymodule\Controller
 */
class FooBarController extends ControllerBase {
  /**
   * Provides content for the /mymodule/foobar path.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The current request
   */
  public function foobar(Request $request) {
    $content = $request->getContent();
    $data = array();
    $data['a'] = $request->get('foo');
    $data['b'] = $request->request->get('foo');
    $data['c'] = \Drupal::requestStack()->getCurrentRequest()->request->get('foo');
    $data['e'] = $request->request->all();
    $data['f'] = $content;

    $request = \Drupal::requestStack()->getCurrentRequest();
    $content = $request->getContent();
    $data['g'] = $request->get('foo');
    $data['h'] = $request->request->get('foo');
    $data['j'] = $request->request->all();
    $data['k'] = $content;

    return new JsonResponse((object) $data);
  }
}

Postman Request:

Note: This was working before with this exact code, correctly using basic HTTP authentication. There have been no changes other than these variations to my controller, and core updates.

Any more ideas?

Try this:

$request = \Drupal::requestStack()->getCurrentRequest()->query->all();

Sidenote: Using a Controller you shouldn't use "\Drupal::..." static request call. Instead, you always have in your controller's enter point function a "Request $request" object as a last argument.


How do I display data in a dynamically created page I have a form on the page that has multiple fields, one of which is a path (www.sample.com/PATH). With form data that I have, I need to forward to that dynamic page, and display form data (5 nodes for example).

This is the code I am using.

function MODULE_menu() {
  $items = array();
  $items['admin/URL_TO_SEE_FORM'] = array(
    'title' => 'Some title',
    'description' => 'Desc',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('MODULE_form'),
    'access arguments' => array('administer users'),
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}

function MODULE_form($form, &$form_state) {

  $form['form_path'] = array(
    '#type' => 'textfield',
    '#title' => t('Path'),
    '#size' => 60,
    '#maxlength' => 128,
    'autocomplete_path' => FALSE,
    '#required' => TRUE,
  );

  // other code that get's different data with ajax etc.

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );

  return $form;
}

function MODULE_form_validate($form, &$form_state) {
  // some validation
}

function MODULE_form_submit($form, &$form_state) {

  $form_path = trim($form_state['values']['form_path']);

  $nodes = $form_state['values']['nodes'];
  // I need to get content from nodes ids whic should be easy

  // Need to set content to page under www.sample.com/$form_path

  $form_state['redirect'] = $form_path;
}

How can I do it?

I've managed to do it by using Views module.

On first submit, I would dynamically create view, and on each concurrent submit I would create additional view display (page).


Event "After cloning a node" by node clone module is not working I am trying to use the event "After cloning a node" provided by Node clone module for Rules integration but its not working.Do any one came across this issue before?

I have created the issue as a bug in issue queue of node clone module.

Any pointers on this?

Your issue seems to be confirmed by some other users also now.

Comment #9 of that issue contains a patch that might possibly solve it.

Another possible solution (patch) is included in comment #8 of that issue, proposed by the module maintainer. With a comment like "Not sure about the use case ..."

The issue is currently in status "Needs review", so maybe you might (still) have an appropriate use case to get that issue in RTBC status?


Hosting a directory of legacy static HTML files on Drupal My clients has a folder of static HTML files from 1999. I want to upload the folder to Drupal and then use an iframe to frame it in. I know it sounds awful but that's all he has the budget for. How can I get Drupal to ignore the entire directory and serve up the files "as is"? It is required that the files be hosted on the same domain.

As long as you're using the default rewrite rules you don't need to do anything.

Drupal's .htaccess file contains this:

# Pass all requests not referring directly to files in the filesystem to
# index.php. Clean URLs are handled in drupal_environment_initialize().
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.php [L]

So requests for existing files won't be re-written, the file will just be served.


Facebook Wall module I'm trying to use the Facebook wall module for the first time. I've installed it, created a Facebook App and thought that I'd entered all the right configuration information on both. However, the Facebook Wall/Settings/Page Information is telling me that it's "Not able to connect with Facebook".

Quite happy to accept that I've done something wrong but not a clue where to turn to diagnose what's happening as there doesn't appear to be any more information. Can anyone give me any pointers please?

If there's a good resource to guide me that would be really helpful - for example there seem to be different types of Access token, which one should I be using?

You have to check the permission to write to a user's wall, either during signup or doing it manually later - looks like you are missing that permission. You need to get appropriate permission from the facebook.


Run hook_nodeapi("pre save") but only on inserts, not on updates For hook_nodeapi(), I want it to run on "presave," but only on inserts, not on updates. How can I do that?

You can know if it an update or insert by looking the $node->nid value. If you've a number it's an update otherwise an insert.

You can see an example directly on the documentation.


Hide field results not matching exposed filter I have an Autocomplete (Tags style) field with multiple values in the field.

I'm using exposed filters to display nodes with one or more values in the Autocomplete field matching the filters.

I want the node field to display only the matched values, not all of them when rendered in a view.

For example. Say I have three nodes with the following field values:

Then I apply exposed filters of Orange and Grape. This results in the following (as Node A does not contain these values):

What I want is values not in the exposed filters to also disappear, so the user can see exactly what selected fields matched the node. Like so:

I assume this can be done using the Global PHP field, but really need some help to figure it out.

I managed to do this by creating a module that implements hook_views_pre_render()

Your field values will need to be taxonomy references for this to work, like so:

function MyModule_views_pre_render(&$view) {
    // Set the view we want to work with
    if ($view->name=='your_view') {
        // print out your array, so you know what you have (comment out in live site)
        drupal_set_message('<pre>' . print_r($view->result, TRUE) . '</pre>');
        // Check to see if the filter has been triggered, otherwise you will get errors
        if (isset($view->exposed_input['exposed_filter_name'])) {
            foreach($view->result as $result_id => $result) {
                // cycle through each view result row, check that each result exists in the exposed filter. if it does not, then remove it.
                foreach ($result->field_your_field as $field_id => $field_val) {
                    //find the TID related to your result
                    $field_tid = $result->field_your_field[$field_id]['raw']['target_id'];
                    // Check if the TID is missing from the exposed filter values
                    if (array_search($field_tid, $view->exposed_input['exposed_filter_name']) === false) {
                        // Now look through your field values to find the TID missing from the values
                        if (($key = array_search($field_val, $result->field_your_field)) !== false) {
                            // And remove it
                            unset($result->field_your_field[$key]);
                        }
                    }
                }
            }
        }
    }
    // Finally re-number array to account for missing elements - i.e. [1],[3],[4],[6] to [1],[2],[3],[4] (optional, but tidier)
    $result->field_your_field = array_values($result->field_your_field);
}

Note that field_your_field is written like that because you need to append an extra field_ to the machine name. e.g. machine name field_my_field would become field_field_my_field


Is there a module for showing only posts in some defined date? I would like to make a calendar addon for my website, which would look something similiar to http://www.nikerigarun.lv/ this (scroll it a bit downwards, on the right side). The funcionality would be to show only posts from some selected date, is there such a module for that and if there is, could you please recommend me one?

This is done with the Views module. Create a new view of content with a display type of 'block', and set it up as an unformatted list of teasers with links, then click 'Continue and edit'.

Add a filter on Content:Posted Day, and choose your conditions like 'is greater than' 'offset' '-10 days'.

You can then set any other views parameters to get what you want.

Save your view and go to admin/structure/block to find your block and place it where you want it.


Create a Corresponding Entity Reference preset programmatically I'm using the CER module in Drupal 7. Is there a way to create a preset programmatically?

[EDIT]

Almost a year later, I found a better way (the entity_import way actually did not work).

CERs are entities. The best way to create one is using $cer = entity_create('cer', array('bundle' => 'cer'));   adding appropriate values to the fields of the created entity, and saving it by using entity_save('cer', $cer);

=======================

Finally figured it out. You can use the entity_import function.

Create a variable containing a JSON-like string of the entity (which you can get by exporting a CER entity), something like:

$j = '{
  "identifier" : "node:time_slot:field_ref_student*commerce_line_item:registration:field_ref_slots",
  "cer_bidirectional" : { "und" : [ { "value" : "1" } ] },
  "cer_enabled" : { "und" : [ { "value" : "1" } ] },
  "cer_weight" : { "und" : [ { "value" : "0" } ] },
  "cer_left" : { "und" : [ { "path" : "node:time_slot:field_ref_student" } ] },
  "cer_right" : { "und" : [ { "path" : "commerce_line_item:registration:field_ref_slots" } ] },
  "rdf_mapping" : []
}';
Then import and save:

$e = entity_import('cer', $j);
entity_save('cer', $e);


New path creation through hook menu problem I have installed Drupal 7. I created new module (.module file and .info file), enabled the module, and gave the permission to menu item also. If I go to localhost/siva/shop/catalog/products, it redirects to the home page.

function displayproducts_menu() {
  $items = array();

  $items['shop/catalog/products'] = array(
    'title' => 'Products',
    'description' => 'Configure the cart page display and settings.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('displayproducts_show_form'),
    'access arguments' => array('view displayproducts'),
    'file' => 'uc_cart.admin.inc',
  );
  return $items;
}

function displayproducts_permission() {
  $perms = array(
    'view displayproducts' => array(
      'title' => t('view displayproducts'),
    ),
  );

  return $perms;
}

function displayproducts_show_form(){
    echo "hello world";
}

Why does this happens?

You form function callback is incorrect you need to return a valid form, try this code:

function displayproducts_show_form($form, &$form_state){
  $form['item1'] = array(
   '#markup' => "hello world",
  );
  // @TODO: include more form items.
  return $form;
}

Documentation: FAPI

Make sure that this function is in your uc_cart.admin.inc file as you indicate in the hook menu declaration: 'file' => 'uc_cart.admin.inc', if it is in your main module file (.module) remove this line and clear the caches again.


How to add discount for final subtotal in ubercart? I am using Ubercart in Drupal 7. I need to add discount offer based on price.

For example:

if total purchase price $100 then 25% discount.
If total purchase price $200 then 45%.
and so on.

I used the uc_discount module but it's not working according me.

Try Ubercart Simple Discount

This module works with rules, so you can add a condition in rules.
You may not get an 'easy plug and play' module for doing this, but the result you want may be possible with some Rules


Drupal commerce and multiple products sharing SKU I have a commerce shop, and a question about product "sharing" SKU.

I have products which is sold as single products, but also in a box.

Lets say I have "Product A" with price $ 1 , with SKU 00001.

I have a box with 10 x "product A" which on the website should appear as "Product A box" and price $ 9. (I need it to be the same product, but shown as separate "product"

I need it because, if I have two separate products, then I can't be sure I have the correct amount in stock.

Is that even possible ?

You can handle that with Commerce Product Bundle. Some details about it, from its project page:

  This module extends Drupal Commerce by allowing the site admin to
  collect a number of existing products together in a bundle, and offer
  them at a new bundle price, with a new bundle SKU.

  You can define products that consists of other products. They are all
  combined in one add to cart form which works like the core add to cart
  form. The bundle is then represented by one order line item. This
  allows the maximum compatibility with other modules such as shipping
  or payment modules.

As an alternative, there is also Commerce Bundle. Some details about it, from its project page:

  Implements product bundles for Drupal Commerce. For example, you want
  to offer products A, B, and C for a lower cost if purchased together
  rather than standalone. Notable features include setting the prices at
  the bundle group or product level, and product attribute support.

Note: if you wonder how those to modules compare to each other, then this might help (= quote from the Commerce Product Bundle project page):

  Commerce Bundle also allows creating product bundles. Customers add a bundle to their cart, but the component products show in checkout and order history. It therefore doesn't allow assigning an overall price to the bundle (but it has some neat ways to assign prices to component products). With Commerce Product Bundle, the bundle, not the component products, show in checkout and order history. Therefore an overall price can be assigned to the bundle


How do I change the primary key? I have created an update that adds a fields to an existing database table. I would like to add that field to the list of primary keys already defined. How do I do this? Do I need to execute the following code?

db_drop_primary_key('table_name');
db_change_field('table_name', 'field_name', 'field_name',
array('type' => 'int', 'not null' => TRUE, 'unsigned' => TRUE),
array('primary key' => array(...list of field names...)));

I essentially recreate either an existing field or the new one I just added. Is there a simpler method where I can just add the field name to primary key list?

Very close. In a hook_update_N:

// Drop all primary keys.
db_drop_primary_key('table_name');
// Add primary keys.
db_add_primary_key('table_name', array('field_a', 'field_b'...);

See db_drop_primary_key and db_add_primary_key for details and links to usage.


How to create Media video youtube entity programmatically? I have file with multiple Youtube URLs such as:
https://www.youtube.com/watch?v=asddasOds32
https://www.youtube.com/watch?v=kjh234hknnn
https://www.youtube.com/watch?v=iZ53yuirewn
...

I need to fill Media content with video entities with data from this file.
Can I have some example code to solve this task?

Code example:
use Drupal\media\Entity\Media;

$media = Media::create([
  'bundle'      => 'my_youtube',
  'uid'         => 1,
  'name'        => 'my_video',
   'field_media_oembed_video' => [
    'value' => 'https://www.youtube.com/watch?v=iZ53oOOTsdc',
   ],
]);

$media->save();


How can I exclude admin(uid=1) for "Views Argument PHP Validator code" which limit a view to a User’s uid value? I have a page view with a menu tab and URL looks like  my-site.com/user/%/my-view

I use return $argument == $GLOBALS['user']->uid; for default argument.
And then I would like to limit the argument to only the currently logged-in user’s uid but how can I exclude admin role (uid=1)?

After reading this article I tried this but didn't work.

global $user;
if($user->uid != 1){
return $argument == $GLOBALS['user']->uid;
}

What I need to achieve is:
Admin role(uid=1) can see my-site.com/user/%/my-view for all users but the rest of the users can see only the view according to their uid.

That is a basic PHP problem, it does not concern Drupal so much. You want to admit access to the admin user always, so you will want to exclude that user's user id of any checks. However, your logic is wrong. The correct version would be

global $user;
return ($user->uid == 1 || $user->uid == $argument);

Which firstly returns true if the user is the admin user and secondly returns true if the user id matches the argument.


Ajax comment form error with Fivestar I have a page that loads the comments section via Ajax once the user scrolls down to the comment section via a custom Drupal ajax callback I defined:

Comments are loaded fine, and using a custom module I'm able to delete, edit, reply and preview comments via Ajax successfully.

The Comment form is loaded via Ajax as well, using this function:

http://paste2.org/p/2757034

Now, here's the problem.

When the comment form isn't a reply to another comment, if I preview the comment and then save, I get this error:

  The form has become outdated. Copy any unsaved work in the form below and then reload this page.

Now, here is the code that's generating the form after it's previewed:

http://paste2.org/p/2757036

I tried drupal_rebuild_form() instead of drupal_build_form, but I had no success.
I searched a lot for a workaround but couldn't find one.

EDIT:
It appears that Fivestar is causing the problem. After disabling Fivestar, the form is submitted successfully. However I can't remove fivestar from this page.

Here's what's in $form_state when I click in the preview button:

This is actually a really annoying Fivestar bug:

http://drupal.org/node/1370526#comment-5367970

The problem is now fixed.


What tpl should I choose for this faq page? What's the template that controls the /faq-page (from the FAQ Module in Drupal 7)?
I've read the explanation at the top of each tpl file inside the module, but can´t understand what file should I override.

When I enter the /faq-page url, I have the categories. When I click each category, they open in a new page.
So I've tried the faq-category-new-page.tpl.php

But it won't work. I've copied the tpl into my theme, opened it and added some css classes. They won't work (even when I've flushed cache).

What template should I choose? Thanks!
Rosamunda

The most simple solution would be to copy all of the 9 templates from the module directory to your theme, and then add a simple output and see where and how they are used. You can later delete the ones you don't need to modify.

The templates used seems to be based on the configuration settings though, so keep that in mind.


Why can't I comment on a module' project page on drupal.org? I can't comment on the project page https://drupal.org/project/awssdk

Why is it so?

The module seems to work with long out-dated AWS SDK for PHP 1.6.2 so I just want to make a comment there to suggest the contributors to update the module and the documentation.

The project page of the module you've mentioned or any other module/theme/distribution is meant only have a brief description, and releases of that particular project.

If you need to contact any of the maintainer of the project, you should use the issue queue of the project which could be found at : https://drupal.org/project/issues/{project_name} just replace {project_name} with the project name, in your case awssdk.

Detailed reading here : Use the issue queue.

And if you feel that the project is not being updated / supported for quite some time and the bugs aren't being fixed, and you intend to fix them you have an option to take over the maintainership of the project.

More reading here : Dealing with unsupported (abandoned) projects.


how do i use subquery in db_api condition? I am using drupal 7 and i would like to create subquery in condition clause with db_api. With db_query it goes something like this:

select *
from some_table_1
where some_table_1.something =
 (select max(some_table_2.something)
  from some_table_2
  where some_table_1.id = some_table_2.id
);

Among other, I was trying it with

$query->condition('some_table_1.something', $subquery);

and i cant get it to work.

How can i do that?

If I understand you properly you need to use a standard where clause rather than a condition in your sub query, e.g.

$subquery = db_select('some_table_2');
$subquery->where('some_table_1.id = some_table_2.id');

...

$query->condition('some_table_1.something', $subquery);


How to add a script to checkout (for affiliate partner programme)? Original question:
I want to add a script to an order on checkout completion or even better with the rule 'when an order is first paid in full'. But I don't know how or where exactly.

Why I need it:
we want to use an external affiliate partner programme for PPS (pay per sale). So when a customer is coming from site A to our shop and orders somthing, the owner of site A gets a certain percentage of the sale.
In order for that to work, I need to add a script to the checkout. Or better add the script when the order is paid in full. I use tokens for the UID, order number and total amount in the script I got from the external affiliate partner.

The script looks like this:

<script type="text/javascript" src="https://track.adcocktail.com/tracking_sale.php?t=s&kid=xxxx&lv=0&bestid=[commerce-order:order-number]&wert=[commerce-order:commerce_order_total]&beschreibung=[commerce-order:mail-username]"></script>

I tried adding it by a rule "add a variable" (on checkout completion) but that doesn't do anything.
When I add the script to the order as a text field in the checkout, I can't use the tokens (they aren't recognized) and the script is run every time I do something to that order so it appears more than once in the affiliate overview.

Does someone know how I can make this script work ?

(I hope my question is clear. If not, just ask.)

Drupal Commerce Kickstart 7.x-2.25
Drupal 7.38

EDIT:

I don't need to activate the script on checkout completion, but 30 days after the order is paid in full. So after the 30 days the customer legally has to return goods. And that's not so easily done as adding the script on checkout completion.

Does anyone has an idea on how to make a rule for it ?

I would add the script by implementing hook_commerce_checkout_complete in a custom module. You also have access to the order in the function.

function MYMODULE_commerce_checkout_complete($order) {
  drupal_add_js(
   'https://track.adcocktail.com/...',
    array('type' => 'external')
  );
}

You need to debug the variable $order to find the values you stated, [commerce-order:order-number] etc.


How to auto-assign a term based on a combination of terms from three other vocabularies? This is a very odd scenario, so bear with me:

I'm importing data from a CSV file via the Feeds module to create product reference nodes. There are 3 columns that contain a term (let's call the columns "Code Types"), so naturally, I set up 3 vocabularies for the product reference nodes to use and mapped/imported the Code Type's terms into each. The client had determined long ago that the terms would not make much sense to the customers, so being able to search for products by selecting a combination of terms would not be helpful. To combat this, new user-friendly keywords were added on the client's old site by assigning each a combination of the 3 terms. I'm trying to replicate this for the new site, and it's driving me insane.

I first began by adding the same 3 Code Type vocabularies to a new 4th "Product Keywords" vocabulary (Yes, terms within terms). After no luck with term or entity reference fiddling, EVA, etc., I decided referencing would go smoother if I made the Keywords a content type with the 3 Code Type term reference fields instead of its own vocabulary. I'm still open to either option, though.

What has to happen is that a product reference node is automatically assigned the Keyword term that exactly matches its 3 Code Type term reference fields, and not all Code Type term reference fields have to have a value. Here are some examples:

Product #42 has:
CodeType1 = "Red"
CodeType2 = "Wheel"
CodeType3 = "Hot Dog"

Product #216 has:
CodeType1 = [empty]
CodeType2 = [empty]
CodeType3 = "Hot Dog"

Keyword "Sloth" has:
CodeType1 = "Red"
CodeType2 = "Wheel"
CodeType3 = "Hot Dog"

Keyword "Muffin" has:
CodeType1 = [empty]
CodeType2 = [empty]
CodeType3 = "Hot Dog"

Product #42 needs to have the keyword "Sloth" automatically assigned to it.

Product #216 needs to have the keyword "Muffin" automatically assigned to it.

Sorry for the longwindedness. It's urgent, and I'm edging toward panic mode. Any ideas? Please?

These are some ideas to accomplish this through Drupal (rather than Excel).

You could do this with a combination of custom modules and Rules, or solely with Rules (which might be a bit more laborious). I'm focusing on the version only with Rules. I haven't tested this, so there may be some adjustments needed.

1. Create a "Catalog" content type that catalogs all combinations of codetypes

Create a content type that will act as a "catalog of codetypes", containing all possible combinations of codetypes and their unique keyword assigned to each combination. This would take an initial investment of time for someone to enter all combinations. Be sure to enter a special code (like the string "empty") when a codetype is not present in a specific combination.

2. Create a View of the "Catalog" content type with three Contextual Filters that filter for a specific combination of the 3 codetypes

(This step needs to be tested and possible tweaked quite a bit). You would need to define the path as /catalog/%/%/% to create placeholders for empty codetypes. There would be 3 Contextual Filters for each of the 3 codetype fields in the catalog. Be sure to provide the fixed default value "empty" in the configuration of When the filter value is not in the URL. The result of this View would be a single record that contains the specific combination of codetypes.

3. Install View Bulk Operations and add it to the View

After enabling it, add a VBO field to the View created in step 2. There is no need to select a specific operation. This field will be used to load the single catalog record into Rules later on.

4. Create a Rule that reacts to new (imported) Product nodes being saved

This Rule will react to the Products being created through the use of Feeds. Basically it needs to load a list of entity objects from the VBO you created above. Pass the three codetypes as arguments the the View.

5. Use the Rule to Set data value of the Keyword field in each of the imported Products.

This step may require some tweaking. You will need to bring into scope the Keyword field of the Catalog record provided by the View. That may involve creating a separate Component that has a condition that brings it to scope, or installing Conditional Rules to create an if statement that brings it to scope. Once the Keyword field of the Catalog node is brought into scope, you use its value to assign it to the Keyword field of the imported Product

So, that's it in a nutshell. You could replace several of the steps with code in a custom module, and avoid using VBO and Rules altogether - you would use EntityFieldQuery to load the Catalog node with the three codetypes, and hook_node_insert() to react to the Product node being imported/created. There may be alternative hooks in the Feeds API that may make this possible too.

I hope this helps... Let me know if you have questions.


How do I overwrite meta tags? In Drupal 7 I used this to unset unneeded elements and total overwrite meta tags:

function MYTHEME_html_head_alter(&$head_elements) {
  // Unset all.
  $remove_array = array(
    'system_meta_content_type',
    'system_meta_generator',
    'system_shortcut_icon',
    'metatag_canonical',
  );
  foreach ($remove_array as $key) {
    if ($head_elements[$key]) {
      unset($head_elements[$key]);
    }
  }
  // Optimize the mobile viewport.
  $head_elements['mobile_viewport'] = array(
    '#type' => 'html_tag',
    '#tag' => 'meta',
    '#weight' => -10,
    '#attributes' => array(
        'name' => 'viewport',
        'content' => 'initial-scale=1.0, maximum-scale=1.0, user-scalable=no, width=device-width',
    ),
  );
  // ...
  // Many other my META tags
  // ...
}

But in Drupal 8 this doesn't work anymore. New elements such as $head_elements['mobile_viewport'] don't get added.

And old meta tags, such as

<meta name="Generator" content="Drupal 8 (https://www.drupal.org)">
<meta name="MobileOptimized" content="width">
<meta name="HandheldFriendly" content="true">
<link rel="shortcut icon" href="http://example.com/core/misc/favicon.ico" type="image/vnd.microsoft.icon">

are still in <head>. How can I remove them and add others instead in Drupal 8?

The invocation of the hook_html_head_alter was removed from Drupal core.
Issue - Remove invocation of hook_html_head_alter().

D8 has a new hook to achieve it : hook_page_attachments_alter().

Code from the change record :

function MYTHEME_page_attachments_alter(array &$page) {
    $viewport = [
      '#type' => 'html_tag',
      '#tag' => 'meta',
      '#attributes' => [
        'name' => 'viewport',
        'content' => 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no',
      ],
    ];
    $page['#attached']['html_head'][] = [$viewport, 'viewport'];
  }


migrate drupal site , error occured, the site was down I migrate my site from WinServer2003 to CentOS ,  with the following step:
1. migrate the database to the CentOS server with .sql files backup.
2.copy all the website root file to the new server.

when i  visited some node an error occured:

according to the message  there was a table or view was missing, but there was no such a table or view in the old system(win2003)

how can i fix the problem, any suggestions are appreciated, Thanks in advanced.

when i do some config (i delete the text format: filter HTML), the site  was completely down.
 when visit it just show an error:

i am really confused.

I solved the problem,  the link : https://www.drupal.org/node/1882292  i just follow the #11 's method and create the image_dimensions table.


Update the date field to the date & time of the node being updated I am sure that I am missing something very simple here, so I hope somebody can put me on the right track.

Use Case:

I have a simple content type "Article"
A date field of type: "Date and Time" is attached to this content
type.
Using any of "Rules" or "Business rules" module, I need when
updating a node of type "Article", to set the value of the "date
field" to be equal to the "date and time" of the node being
updated.

What is the right token that must be used ?

So far:

I have been trying for days with no success, I have tried to use the below token but yet no sucess:

[node:changed:custom:D-M-Y-H:i:s]
[node:changed:custom:D-M-Y H:i:s]
[node:changed:custom:D/M/Y H:i:s]
[node:changed:custom:DMYHis]

Any help PLEASE!!

UPDATE #1:

The real use case:

I am using the "Field Timer" module in my project which
provides field formatters for core module Datetime to display timer or countdown as a formatter.

So every time the node is updated, I want to set the "date field" to the current "date and time" of the node being updated (+) 20 minutes.

For Example if the current date & time of the node being updated is: 31/12/2018 15:00:00 so I want to set the "date & time" field value to: 31/12/2018 15:20:00

So the countdown formatter will start from 20 minutes and down until 0 minute.

Thank you,

Nodes already have a 'changed' property that would track this. Any reason why you don't want to use that? You can use {{ node.getChangedTime() }} in a Twig template for the raw value, or you can preprocess the node and take the changed value and format the date to your need into a new variable for the template. This way you don't need another field and Rules and reduce a lot of overhead.


Can you get the itok value programmatically? I appreciate the 7.20 security measure that requires a itok parameter for generating new images, but I need to expose that to Services / AJAX driven projects.

Can you get the image token programmatically so that JavaScript can build valid image urls for any size dynamically?

I would like to avoid $conf['image_allow_insecure_derivatives'] = TRUE; unless someone has a project to apply this same security measure on a user session level as opposed to per image

It should be possible to get the token via a custom ajax callback that returns:

$token_query = array(IMAGE_DERIVATIVE_TOKEN => image_style_path_token($style_name, $original_uri));

From a custom menu router path or services callback.


Get the vocabulary ID by term object? I need to get vocabulary ID by term object.Please see attched screenshot for term object.

You should be able to use the getVocabularyId() function on the term object like:
$vocabulary_id = $term->getVocabularyId();

See https://api.drupal.org/api/drupal/core%21modules%21taxonomy%21src%21Entity%21Term.php/function/Term%3A%3AgetVocabularyId/8.2.x.


Is it necessary to cache external api requests? I am working on a custom module to pull tweets.  Is it necessary for me to cache my request to Twitter's API, if I have both Drupal 8's Internal Page Cache and Dynamic Page Cache enabled?  Can I just rely on the Page Cache?

For instance, if I set some data to cache for every 3 minutes, but the page cache is set for every 5 minutes, my custom data cache time will be ignored, and my data will be cached every five minutes, correct?

For reference, I meant to set my custom cache like so:

$cid = 'my_custom_module_id';
if ($cache = \Drupal::cache()->get($cid)) {
  $mydata = $cache->data;
} else {
  $mydata = [DO MY API CALL STUFF!]
  \Drupal::cache()->set($cid, $mydata, 180);
}

Depends. Do you display this on a specific page? Or on multiple pages? Is it a page, a block... ? Do you have many authenticated users?

If it's a single page callback or a block that's always the same, then it's possibly fine to not cache it yourself. That only makes sense when you call your code on many different pages.

If you also have a lot of users, especially with different roles, multiple languages or or cache contexts that might vary but always the same API call, then it might make sense again to cache it yourself.


Problem with Views 7.x-3.0 - Column not found I just updated the views from 7.x-3.0-rc1
 to version 7.x-3.0 and now I'm getting the following error when executing my view:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'field_data_field_category.nid' in 'on clause'

The generated query looks like this:

SELECT node.title AS node_title,
       node.nid AS nid,
       node_field_data_field_category.title AS node_field_data_field_category_title,
      'node' AS field_data_field_color_node_entity_type,
      'node' AS field_data_field_image_node_entity_type,
      'node' AS field_data_field_sale_node_entity_type
FROM {node} node
LEFT JOIN {field_data_field_category} field_data_field_category ON node.nid =
                                      field_data_field_category.entity_id AND
                                      (field_data_field_category.entity_type = 'node' AND
                                      field_data_field_category.deleted = '0')
LEFT JOIN {node} node_field_data_field_category ON field_data_field_category.nid =
                 node_field_data_field_category.nid
LEFT JOIN {field_data_field_gender} field_data_field_gender ON node.nid =
                                    field_data_field_gender.entity_id AND
                                    (field_data_field_gender.entity_type = 'node' AND
                                    field_data_field_gender.deleted = '0')
WHERE (((node.type IN  ('product')) AND (node.status = '1') AND
        (field_data_field_gender.field_gender_value IN  ('0', '1'))));

I see that the field_data_field_category.nid should be field_data_field_category.field_category_nid, but how do I solve this without using something like hook_query_alter?

The problem was in the references module, I found this patch wich solved the problem.


Making a custom form element AJAX aware How should I go about making my custom Drupal 7 Form element support AJAX events, just like other standard FAPI elements?

For example, with a drop-down list, I would do this:

$element['book'] = array(
  '#type' => 'select',
  '#title' => t('Book'),
  '#options' => $books,
  '#default_value' => $default_book,
  '#ajax' => array(
    'wrapper' => 'replace-me',
    'callback' => 'replacement-callback',
    'method' => 'replace',
  ),
);

But now that '#type' is my own custom element, the '#ajax' property is ignored. This is what I have implemented thus far:

function mymodule_element_info() {
  return array(
    'customelement' => array(
      '#input'          => TRUE,
      '#process'        => array('customelement_process'),
      '#theme'          => array('customelement'),
      '#theme_wrappers' => array('form_element'),
      '#tree'           => TRUE,
    ),
  );
}

function mymodule_theme($existing, $type, $theme, $path) {
  return array(
    'customelement' => array(
      'render element' => 'element',
    ),
  );
}

function theme_customelement($variables) {
  // render some elements
  return $output;
}

function form_type_customelement_value($element, $input = FALSE, &$form_state) {
  // manipulate form values
  return $input
}

function customelement_process($element, &$form_state, $complete_form) {

  // build the compound form array
  $element['#tree'] = TRUE;

  $element['book'] = array(
    '#type' => 'select',
    '#title' => t('Book'),
    '#options' => $books,
    '#required' => true,
  );

  $element['chapter'] = array(
    '#type' => 'textfield',
    '#title' => t('Chapter'),
    '#size' => 3,
    '#maxlength' => 3,
    '#required' => true,
  );

  return $element;

}

Using my custom element in a form goes like this:

function mymodule_menu() {
  $items = array();

  $items['path/to/page'] = array(
    'title'            => 'Test form',
    'type'             => MENU_LOCAL_TASK,
    'weight'           => 30,
    'page callback'    => 'drupal_get_form',
    'page arguments'   => array('mymodule_callback_testform'),
    'access callback'  => 'user_access',
    'access arguments' => array('mymodule_admin'),
  );

  return $items;
}

function mymodule_callback_testform() {
  $form = array();

  $form['test_element'] = array(
    '#type' => 'customelement',
    '#title' => 'Custom element test',
    '#required' => TRUE,
    '#ajax' => array(
      ... // this has no effect :(
    ),
  );

  return $form;
}

But unfortunately it doesn't "magically" support AJAX. I would like to trigger a Drupal AJAX event when any sub-element of my custom element has triggered certain events.

It has no effect because Drupal doesn't know what event to fire on.

If you look at the switch statement in ajax_pre_render_element() you can see that it has default events for all core element types. But it it doesn't know about your element type, and no event is provided, so it doesn't know how to continue. It returns the element as-is rather than attempt to make a decision its not qualified to make.

To fix you should just be able to pick an appropriate event for the code to fire on, e.g.

$form['test_element'] = array(
  '#type' => 'customelement',
  '#title' => 'Custom element test',
  '#required' => TRUE,
  '#ajax' => array(
    'event' => 'click',
    ...
  ),
);


How do I automatically do an SQL insert when creating a new node? When creating a new node of a certain type, I want an SQL insert to be made at the same time.
The insert operation needs to use the node ID from the node just created, such as INSERT INTO my_own_db (nid) VALUES ('last inserted node id').

You've to create your own module and after use a hook_node_insert you'll receive a $node object with all informations you need.


How do I redirect a domain but keep the URL structure? I have example.com and example.co.uk. They both point to the same Drupal installation on my server, so both domains load the exact same site.
I am now trying to redirect the .co.uk to the .com domain. I have tried using the following lines in the .htaccess file, but it always redirects to /index.php.
RewriteCond %{HTTP_HOST} ^example.co.uk
RewriteRule ^(.*) https://example.com/$1 [P]

The following lines didn't work either.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.co.uk$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]

The site redirects. but it doesn't keep the URL structure as it should. If I go to example.co.uk, I get redirected to example.com. If I go to example.co.uk/node/1, I get redirect to example.com/index.
How can I set up the correct redirect?

Your second variant is close to the goal. But it needs some edits. Firstly, you should escape all dots in RewriteCond, so it will be
RewriteCond %{HTTP_HOST} ^example\.co\.uk$ [NC]

Secondly you need to edit RewriteRule to change regular expression and append request uri:
RewriteRule ^ https://example.com%{REQUEST_URI} [L,R=301]

It also matters where you place the code. Your second variant is right. It's best to place code just after RewriteEngine on
Final code will be:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.co\.uk$ [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,R=301]


How can I install modules using the FTP method? I got a error when trying to install modules. What should I set up for the FTP? I just learned Drupal. Who knows what happen? I am using Drupal 7.7.

As kalabro said:

Make sure the folder /sites/default is OWNED by the user that executes the drupal scripts.

On most Ubuntu installations, this is the user Apache user www-data.

chown www-data sites/default


js file in custom module's library is not attached when big pipe is running I have a custom module, filter_component, that provides a form. In the form I have:

$form['#attached']['library'][] = 'filter_component/filter-component';

In filter_component.libraries.yml I have:

filter-component:
  version: 1.x
  js:
    js/filter_component.js: {}
  dependencies:
    - core/jquery
    - core/jquery.once

filter_component.js begins with:

(function ($, Drupal) {
    Drupal.behaviors.filterComponent = {
        attach: function (context, settings) {
            $('.block-filter-component', context).once('filterComponent').each(function() {

Everything works fine, but only if big_pipe is disabled. When it is enabled, the code is not attached and the js file is not listed in page source or in browser tools as a source.

So it turns out that it was big pipe, but unrelated to my module. Elsewhere on the page a profile image is loaded to appear next to the user name, and if the user has none, a default image. It seems that if a 404 is returned (in this case because part of the oath did not yet exist to match the path supplied for the image), when big pipe goes to load it and gets the 404, downstream js is not loaded.


How can I "merge" two fields when a form is submitted? I have a form from a unique content type which has two fields, when I submit that form, I wish the value entered in the second field was "included" in the end of the first field and then the content type saves.

Like

field1, value: "John"
field2, value: "Doo"

but when the content type is saved, this happens:

field1, value: "John Doo" // the space which divide the two words is required as well.
field2, value: "Doo"

thanks.

I would suggest you hook_node_presave() for this. Write this function somewhere in your custom module, just print the $node array. You would found all the fields value there that you can alter accordingly. Your code should be something like this.

function mymodule_node_presave($node) {
  if ($node->type == 'content type name') {
   // Append last name field value with first name field.
  }
}

This hook function get executed before node_save() that will save your changes in db.


Thumbnails limit max first 6 images I'm using Drupal 7 and create a module for my content thumbnail images frontpage display. Working this:

 if(count($p_detail->field_slide) > 0){
            $output .= '
';
            $output .= '
';
            $i=6;
            foreach($p_detail->field_slide['und'] as $thumb):
                $img_path = $thumb['uri'];
                $img_url = image_style_url('tmb_240x117', $img_path);
                $img_file = 'title.'" />';

                $output .= '

                                    '.$img_file.'

0'.$i.'

';
                $i--;
            endforeach;
            $output .= '
';
            $output .= '
';
        }

My thumbnails, field_slide and i want only first 6 thumbnails (if have 6 images... for exam, have 2 images, display 2 thumbnails)

How can i do this?

If I understand you correctly then you just need to break out of the foreach loop after you got 6 thumbnails saved in the $output variable. With that addition the end of your loop would look like this:

if ($i == 1) break;
$i--;
endforeach;


not found in Multi language site with only session detection I have a multilingual site with 3 enabled languages.
Default language is English
I've only setup my language options to use the "Session" detection method.
I dont to use URL language options.
when i create node in English node and set pathauto for url with token [node:author]/[node:content-type]/[node:nid]

is work in default language only when i switch language to another this token is not work.
for example when i create node in another language this path not work.

http://example.com/reza/news/324  this does not work (this node is created in arabic site)
http://example.com/ar/reza/news/324 this works but i don't want to user this url i want use this example http://example.com/reza/news/324?lan=ar

The problem was resolved: When we create a new content type, the "Multilingual support" in "Publishing options" should be set to "Enabled, with translation."


Show and require field if birthday (date field) is less than 18 years old I have a field that should be visible and required if the user selects a date that would make them less than 18 years old. If they are over 18, the field should be hidden and not required. Right now, I am using this:

In birthday.js:

(function ($) {

$(document).ready(function() {
    $('#edit-field-minor-agreement').hide();
});

$(document).on('change', '#edit-field-dob-und-0-value-year, #edit-field-dob-und-0-value-month, #edit-field-dob-und-0-value-day', function() {
    var yyyy = $("#edit-field-dob-und-0-value-year").find(":selected").val();
    var m = $("#edit-field-dob-und-0-value-month").find(":selected").val();
    var d = $("#edit-field-dob-und-0-value-day").find(":selected").val();

    if ( $('#edit-field-dob-und-0-value-year').val() && $('#edit-field-dob-und-0-value-year').val() && $('#edit-field-dob-und-0-value-year').val() ){
        dateString = m + "/" + d + "/" + yyyy;
        var today = new Date();
        var birthDate = new Date(dateString);
        var age = today.getFullYear() - birthDate.getFullYear();
        var m = today.getMonth() - birthDate.getMonth();
        if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
            age--;
        }
        console.log("Birth date: " + dateString);
        console.log("Age: " + age);
    }

    if(age<18) {
        $('#edit-field-minor-agreement').show();
    } else {
        $('#edit-field-minor-agreement').hide();
    }

});
})(jQuery);

It is successfully setting the visibility, but I can't seem to figure out how to make it required. Any help is appreciated.

Here is a working solution. Huge thanks to @nikathone for assistance.

/**
 * Implements hook_form_FORM_ID_alter() for record_node_form.
 */
function mrpeanut_form_record_node_form_alter(&$form, &$form_state, $form_id) {
  if (!empty($form['field_dob']) && !empty($form['field_minor_agreement'])) {
    $form['field_minor_agreement']['#prefix'] = '
';
    $form['field_minor_agreement']['#suffix'] = '
';
    $is_younger = TRUE;
    $values = !empty($form_state['values']) ? $form_state['values'] : array();
    $dob_date_combo_element = &$form['field_dob']['und'][0];
    $dob_date_combo_element['#ajax'] = [
      'callback' => 'mrpeanut_form_record_node_form_minor_agreement_callback',
      'wrapper' => 'edit-field-minor-agreement-wrapper',
      'effect' => 'fade',
    ];

    if (!empty($values['field_dob']['und'][0]['value'])) {
      $dob = new DateTime($values['field_dob']['und'][0]['value']);
      $now = new DateTime();
      $age = $now->diff($dob)->y;
      $is_younger = $age < 18;
    }

    $form['field_minor_agreement']['und']['#access'] = $is_younger;
    $form['field_minor_agreement']['und'][0]['#required'] = $is_younger;
  }
}

/**
 * Ajax callback for minor agreement.
 */
function mrpeanut_form_record_node_form_minor_agreement_callback($form, $form_state) {
  return $form['field_minor_agreement'];
}


How to get value properly from form field? I search the best way to get value from  form field, and I would like to know if my code section below it's the only way to get value from field ($value = $var[0]['value']) or if it's possible to write this better:

/**
 * Implements hook_form_alter().
 */
function my_module_form_alter(&$form, FormStateInterface $form_state, $form_id){
  if ($form_id == 'node_bibliographie_form') {

    $form['#validate'][] = 'node_bibliographie_form_validate';

    foreach (array_keys($form['actions']) as $action) {
      if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
       $form['actions'][$action]['#submit'][] = 'my_module_bibliographie_form_submit';
      }
    }
  }
}

function my_module_bibliographie_form_submit(&$form, FormStateInterface $form_state){
  // Get the submitted entity.
  $key        = $form_state->getValue('field_key');
  $id_dossier = $form_state->getValue('field_dossier_reference');

  if (isset($id_dossier) && isset($key) &&  !empty($key) && !empty($id_dossier)) {
    kint($id_dossier[0]['target_id']);
    //ugly ?
    $collection_key = $key[0]['value'];
   }
}

If  you need to get the value of the array you can use below method.

 $values = $form_state->getValue(array('name_of the array', 'key'));


EntityMetaDataWrapper exception when calling commerce_cart_product_add() In brief, I'm trying to create and order and add a line-item as part of a form submission callback. Here's the sauce:

if (!commerce_cart_order_session_exists())
{
    $order = commerce_cart_order_new();
    $order->log = t("Created by $product_type checkout page.");
    commerce_cart_order_session_save($order->order_id);
} else
{
    $order = commerce_order_load($form_state['order']->order_id);
}
$wrapper = entity_metadata_wrapper('commerce_order', $order);
$sku = get_sku($product_type, $adj_age);
commerce_cart_product_add($uid = 0, $sku = 2, $quantity = 1, $display_uri = NULL, $combine = FALSE);

I'm getting the following error:

EntityMetadataWrapperException: Missing data values. in EntityMetadataWrapper->value() (line 83 of /srv/www/mtairy.toomodernmedia.com/public_html/sites/all/modules/entity/includes/entity.wrapper.inc).

In some very similar case I was getting the same error message, but in the commerce_cart_product_add function definition where the metadatawrapper was being called.

If I comment out the commerce_cart_product_add() line I can instantiate an order object. Not sure what I'm doing wrong here.

You are using commerce_cart_product_add wrong.

You can pretty much replace your entire code with:

$product_id = ...; // You need to product id, from somewhere, you can get it from the SKU
commerce_cart_product_add_by_id($product_id);


How do I block individual content items from search engines? I need to create multiple landing pages for my food business running a Drupal 7 site, same page, different prices, offers, coupons, different OGP tags for Facebook posts etc.

So I will have dozens of multiple identical content pages, and I don't want to be penalized by Google. I could do this via Robots.txt or .htaccess, but is there a way to do this at the content page item level?

Use Metatag module for this purpose. Go to configuration page of metatag module and you can prevent google to index your node type.

Hope it will help.


Facing trouble in insertion of data in to table after creating table by using hook_update_N function I have created a table by using hook_update_N() function. After creation, if i am trying to insert data into table but it is not storing. Is there any thing else is there to do after creating table by using hook_update_N()..?

If you're using drupal_write_record, be aware of this warning in the documentation

  Do not use drupal_write_record() within hook_update_N() functions, since the database schema cannot be relied upon when a user is running a series of updates. Instead, use db_insert() or db_update() to save the record.

You should be using db_insert or db_update instead.


Two different sites, two installations, no database or core sharing I've finished configuring a Drupal site using localhost (Mamp) but I have to wait some weeks until it gets uploaded to external host.

Now in the meantime I'd like to start developing another site that has nothing to do with the first one (different database, users, modules, etc). That is: I'd like to 'park' the old site and start creating the new one (new Drupal 7 installation) without affecting the first one.

I'm using Mamp 3.0.7.2 and the server route is default (Mamp--- htdocs)

Any hint on what to begin with?

Thank you

put your drupal sites in separate subdirectories of htdocs, e.g .../htdocs/site1, ...htdocs/site2
access your sites using the mamp localhost url, e.g. http://localhost/site1

If you know how, you can also create virtualhosts in /Applications/MAMP/conf/apache/httpd.conf and edit /etc/hosts on your mac, so that you can access the sites with whichever url you choose, such as:

http://site1.local

Databases: just upload your databases using MAMP's phpmyadmin, and edit your sites' settings.php to use the respective databases.


Comments and Testimonials on Profile 2 Profiles Is there a way of enabling either comments or a guestbook/testimonial functionality on Profile 2 Profiles?

I've read discussions on here about implementing on User Account Pages but not for the Profile 2 Profiles module.

Any ideas?

There is a module called reply, that is intended as a solution for fieldable comments on non-node entities and should work with any entities created via the Entity API module, which includes profile2 entities.


Layout on Commerce checkout pages Drupal Commerce.

On admin/commerce/config/checkout/form you can move around checkout panes between pages. This is cool!

It allows e.g. to move all panes on one page.

Now what I am trying to figure out is how to make a more interesting layout for this page. E.g. by "grouping" the panes into layout regions / columns, like I would for a node display.

Any ideas?

You can get at that with the commerce functions hook_commerce_checkout_page_info() and hook_commerce_checkout_pane_info(); with more documentation on that here: http://www.drupalcommerce.org/developer-guide/core-architecture/info-hooks/checkout-info-hooks#checkout-pane.

It's a little complicated because the panes, pages, and forms are hard-coded into DC's checkout logic. There are a couple of modules that let you override and specify your own pages or other cart functions https://drupal.org/project/dc_co_pages, and https://drupal.org/project/commerce_cart_view_override

You'll probably need to do any serious changing by coding your own module calling the commerce functions/pages you need for your use case.


Query Database to Fill Dropdown Form API #states I am trying to develop a pretty complicated form. Essentially the user selects from Education, health, or water quality. Then using states the correct follow up questions are asked before all this data is submitted.

However, whenever I try to populate with a db query it acts funny. For example. Health and Education but have a dropdown select for years. Each should load the years available from the database and populate accordingly. However, the health dropdown select for year (which comes after the education) populates its self with the education's years. If I do a dpm to see what year the health year query gets, it is right, but it does not display on the dropdown.

I hope that makes sense. To sum it up: I have two queries to populate two different year forms. However, both populate themselves with the first query, even though the second one returns the right variables.

Here is the code:

$form['data_set'] = array(
    '#type' => 'select',
    '#title' => t('Please Select a Topic'),
    '#options' => array(
        'education' =>t('Education'),
        'health'    =>t('Health'),
        'water'     =>t('Water'),
    ),
    '#required' => TRUE,
);
// If User Selects Education
$form['education'] = array (
    '#type' => 'fieldset',
    '#title' => t('What Education Information are you looking for?'),
    '#states' => array(
        'visible' => array(
            ':input[name="data_set"]' => array('value' => 'education'),
        ),
    ),
);

    //Query DB for Rows
    $query = db_select('hp_education_years');
    $query->fields('hp_education_years', array('id', 'years',));
    $query->orderBy('years', 'ASC');
    $results = $query->execute();

    //define rows
    $options = array();
    foreach ($results as $result) {
        $options[$result->id] = array(
            $result->years,
        );
    }
    $form['education']['year'] = array(
        '#type' => 'select',
        '#title' => t('Year'),
        '#options' => $options,
        '#states' => array(
            'visible' => array(
                ':input[name="data_set"]' => array('value' => 'education'),
            ),
        ),
    );
    $form['education']['level'] = array(
        '#type' => 'select',
        '#title' => t('Level'),
        '#options' => array(
            'primary' => 'Primary',
            'jhs' => 'JHS',
            'shs' => 'SHS',
        ),
    );
    $form['education']['sector'] = array(
        '#type' => 'checkboxes',
        '#title' => t('Sector'),
        '#options' => array(
            'public' => t('Public'),
            'private' => t('Private'),
        ),
    );

//if user selects health
$form['health'] = array (
    '#type' => 'fieldset',
    '#title' => t('What Health Information are you looking for?'),
    '#states' => array(
        'visible' => array(
            ':input[name="data_set"]' => array('value' => 'health'),
        ),
    ),
);

    //Query DB for Rows
    $query1 = db_select('hp_health_years');
    $query1->fields('hp_health_years', array('id', 'year',));
    $query1->orderBy('year', 'ASC');
    $results1 = $query1->execute();

    //define rows
    $options1 = array();
    foreach ($results1 as $result1) {
        $options1[$result1->id] = array(
            $result1->year,
        );
    }
dpm($result1->year);
    $form['health']['year'] = array(
        '#type' => 'select',
        '#title' => t('Year'),
        '#options' => $options,
    );

You have the same variable ($options) for both fields. Use $options for $form['education']['year'] and $options1 for $form['health']['year'].


How to temporarily replace Drupal with static HTML pages? I'm a JavaScript dev with no Drupal experience.

I'm working with a church to redesign their Drupal site after their dev moved on without leaving any notes/documentation/etc. In the meantime, I'd like to put up a few static html pages in place of the Drupal site, without getting rid of all the Drupal data.

Can I just "turn off" Drupal, so that routes that are now currently powered by Drupal (ie: church.org/worship) will instead render the static file version (ie: church.org/worship/index.html)?

Is leveraging Drupal's "maintenance mode" a possible solution? I found this article, https://drupalden.co.uk/static-maintenance-page-replace-drupals-default-maintenance-mode-page, on replacing the default maintenance page, but what about other routes too?

Drupal only kicks in when a file does not exist. So if you create HTML files at the same path where a Drupal page existed, the HTML file will be shown, and Drupal will not be instantiated.

Example: You have a path named /node/4.

If you create a folder in your webroot named 'node', and a file named 4, it will be picked up instead of Drupal being instantiated, even if Drupal exists in the webroot. You may need to do some work to set the headers of the file as text/html though, since there is no file extension on the file to tell the processor that it's an HTML file.


How to use ajax callback on auto complete field inside a block settings form? public function blockForm($form, FormStateInterface $form_state) {
    $form = parent::blockForm($form, $form_state);
    $selected = 'value of a field';
    $form['node'] = [
      '#type' => 'entity_autocomplete',
      '#title' => $this->t('My content type'),
      '#target_type' => 'node',
      '#selection_settings' => [
        'target_bundles' => ['bundle'],
      ],
      '#ajax' => [
        'callback' => [$this, 'my_ajax_callback'],
        'wrapper' => 'my-specializations',
      ],
    ];

    $form['first_select'] = [
      '#type' => 'select',
      '#options' => [0 => 'x', 1 => 'y'],
      '#title' => 'doctor',
      '#ajax' => [
        'callback' => [$this, 'my_ajax_callback'],
        'wrapper' => 'my-specializations',
      ],
    ];

    $form['specializations'] = [
      '#type' => 'select',
      '#title' => $this->t('Specializations'),
      '#options' => $this->specialization($selected),
      '#prefix' => '
',
      '#suffix' => '
',
    ];

    return $form;
  }

 private function specialization($selected) {
    if (!empty($selected)) {
      return ['1' => 'a', '2' => 'b'];
    }
    else {
      return [];
    }
  }

  public function my_ajax_callback(array &$form, FormStateInterface $form_state) {
    return $form['specializations'];
  }

The ajax call back function is not working on auto complete field. How can I make it working on the auto complete field?
And on the first-select it is working but I am getting an error:
TypeError: Argument 1 passed to Drupal\Core\Render\MainContent\AjaxRenderer::renderResponse() must be of the type array, null given, called in /var/www/web/core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php on line 89 in Drupal\Core\Render\MainContent\AjaxRenderer->renderResponse() (line 53 of /var/www/web/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php)
Can you someone tells me, what I am doing wrong?

To answer the title's question
  '#ajax' => [
    'callback' => '::my_ajax_callback',
    'wrapper' => 'my-specializations',
    'event' => 'change', // run ajax on change
    'keypress' => TRUE, // if set to TRUE, then the element's #ajax['event'] will be triggered if the ENTER key is pressed while the element has focus.
  ],


How do I make several displays of one image field in a node? I'm trying to implement a JS image gallery to my project. I've created three image styles:

thumbnails 135x105
gallery 690x430
full 1600x900 (responsive)

Thumbnails are used as a pager for the gallery. By clicking the zoom button, the full image should be loaded and opened in a modal.

The question is, how to use all three image styles with one image field and display them in one node?

On Drupal 7 I've used Gallery Formatter module, but on Drupal 8 it's not working properly.

The task seems to be quite trivial, but i didn't find any answer. May be there is some module or i can set image style to the field in twig template? Thanks in advance!

The right solution would be an image formatter, which is configurable to have multiple instances of the same image with different display options.

If you can't find this in a module, you can improvise in preprocess of the node template:

mytheme.theme:

function mytheme_preprocess_node(&$variables) {
   if (isset($variables['content']['field_image'])) {
    $image = $variables['content']['field_image'];
    $image['0']['#image_style'] = 'gallery';
    $variables['content']['field_image_gallery'] = $image;
    $image['0']['#image_style'] = 'full';
    $variables['content']['field_image_full'] = $image;
}

This code makes a copy of the image field and puts it in two additional fields, each with a different image style. This is for a single value field. I suppose your gallery is a view of multiple nodes with a single image. If there are multiple images in one node you would have to process the images in a loop (a bit more improvisation needed).

If it is a responsive image use this line to change the image style:

$image['0']['#responsive_image_style_id'] = 'gallery';

All three images should be of the same kind (standard or responsive), otherwise there would be some more work to do.


How to create a view that lists all groups and their respective contents? I have used organic groups to implement the 'group' & 'group content' functionality.

I have a group content type.
And, I have a group content content type.

How can I create a view that lists all groups' titles and their respective contents' titles clubbed together with that group?

For eg.

If,

Group 1 has 2 content types: C1 & C2,

Group 2 has 2 content types: C3, C4 & C5,

Group 3 has 2 content types: C6,

Group 4 has 2 content types: C7 & C8,

Then expected result is:

Group 1: C1, C2
Group 1: C3, C4 & C5
Group 1: C6
Group 1: C7, C8

Create a view that lists all content of type "Group Content"
Add a relationship OG membership: Group Node from OG membership and make it mandatory

 - Add field Group Title and exclude it from display choose relationship above

Use Group By Option in Display settings and group by Group Title

And the output will be

Find view export below.. Content type names are group and group_content

$view = new view();
$view->name = 'group_group_content';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'Group - Group Content';
$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'] = 'Group - Group Content';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$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'] = 'default';
$handler->display->display_options['style_options']['grouping'] = array(
  0 => array(
    'field' => 'title_1',
    'rendered' => 1,
    'rendered_strip' => 0,
  ),
);
$handler->display->display_options['row_plugin'] = 'fields';
/* Relationship: OG membership: Group Node from OG membership */
$handler->display->display_options['relationships']['og_membership_related_node_group']['id'] = 'og_membership_related_node_group';
$handler->display->display_options['relationships']['og_membership_related_node_group']['table'] = 'og_membership';
$handler->display->display_options['relationships']['og_membership_related_node_group']['field'] = 'og_membership_related_node_group';
$handler->display->display_options['relationships']['og_membership_related_node_group']['required'] = TRUE;
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
/* Field: Content: Title */
$handler->display->display_options['fields']['title_1']['id'] = 'title_1';
$handler->display->display_options['fields']['title_1']['table'] = 'node';
$handler->display->display_options['fields']['title_1']['field'] = 'title';
$handler->display->display_options['fields']['title_1']['relationship'] = 'og_membership_related_node_group';
$handler->display->display_options['fields']['title_1']['label'] = 'Group';
$handler->display->display_options['fields']['title_1']['exclude'] = TRUE;
/* Sort criterion: Content: Post date */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'node';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 1;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
  'group_content' => 'group_content',
);

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['path'] = 'group---group-content';


Implementing LDAP with exsisting user base We are in the experimental stages of implementing LDAP in our Drupal 6 environment, using the LDAP integration module. LDAP is installed and working in our dev environment and now we are looking at different transition plans. We have a fairly substantial user base (couple hundred user in the DB) although realistically we have only a few dozen active users.

My first thought is to go 'cold turkey' and just drop the Users table and ask all users to just start using LDAP for authentication. I tried this in dev, and while authentication worked, some pages would not load, and I'm wondering is this because there is no longer a user associated with these pages?

So along with the specific question above I'm wondering what is the best path for a transition to LDAP on a server with an existing user base? We cannot reliably key off of a username or email to 'sync' the users. That is why I am inclined to start with a clean user table if I can.

You could try having them create the new LDAP accounts and then merging the users. User Merge

  This module helps users to merge together duplicate accounts. It uses a hook system so other modules can do whatever they need to manage their relationships to users.


Is it possible to give inactive accounts a custom error message upon login? I have a site where, when a user is flagged as spam, that user account is blocked.

This is fine, but sometimes a user is blocked by mistake.  When the user tries to log in, since the account is blocked, they just get the default Drupal "wrong username/password" message.

However, I would like to give a custom message ("Sorry, it looks like someone thought your account was spam.  If this is a mistake, please contact us.") when the user account is inactive and attempts to log in.  I'm using the latest version of Drupal 7 and I tried to find a way to do this in Rules but I couldn't come up with anything.

You can alter the login form and add a custom validator where you check if user is blocked and show the error message you want.

If you check the code you'll see that login validator are set by the user_login_default_validators() function. Those validators are:

user_login_name_validate
user_login_authenticate_validate
user_login_final_validate

What I don't understand is why are you getting the "wrong username/password" (actually the message is "Sorry, unrecognized username or password. Have you forgotten your password?"). The first validator checks if the user is blocked:

/**
 * A FAPI validate handler. Sets an error if supplied username has been blocked.
 */
function user_login_name_validate($form, &$form_state) {
  if (!empty($form_state['values']['name']) && user_is_blocked($form_state['values']['name'])) {
    // Blocked in user administration.
    form_set_error('name', t('The username %name has not been activated or is blocked.', array('%name' => $form_state['values']['name'])));
  }
}

As you can see when a user is blocked the message es "The username %name has not been activated or is blocked".

Anyway, to achieve what you want I think you ca follow the steps:

Implement hook_form_FORM_ID_alter adding your custom validator as
FIRST validator. You have to alter two forms, 'user_login' and
'user_form_block' (tose are the form ids). Use:

array_unshift($form['#validate'], 'my_custom_user_validation');

to add your custom validator as first validator.

Then code your custom validator. It should be same as user_login_name_validate but using your custom message.

Edit: As I've pointed out in my answer and J. Reynolds says the blocked message is not the standard wrong user/password. If you get the blocked user message you can go with J. Reynolds suggestion (just altering the standard user blocked message). If you need to check for any other different condition (for example, blocked and spam role) you can use what I say in this answer.


Views form page with input fields How can I make Views form page with such input fields?

Such view can really help to change meanings of some node field all at once.

Editable Views should do what you are trying to accomplish. It won't allow you to drag the items up/down, but it will allow you to update multiple fields at once.

https://www.drupal.org/project/editableviews

  Editable Views lets you create Views where the fields can be edited. Fields show both the current value and a form to edit it. A 'Save' button allows saving of all the entities shown in the View.


In drupal 7 how to group fields of a view? I have a view to display latest 10 blog pages.
1. I have a title field
2. I have a author field

now I need to group all the titles in one div and all the author in another div.

But views results always have a nested result where respective node's title and author name are together in a same div. Is there any way to separate them?

What about  making two separate versions of the view: 1 page view with title fields and an attachement with author fields, or 1 page with titles, and the other a block with authors?
So you first create a page view with a fields display. When adding fields, you select titles *and you make sure you set the field for "This page only".

Afterwards, on the top of the view, you select "add attachment".
You will have an attachment versin of the view. In this, you add the "title" field.
Again, make sure it's "for this attachment only". Now, go to "Attachment settings and select attach to page.


How to adjust prices depending on quantity and attributes using Drupal Commerce? I am using Drupal Commerce, and have a question about some of the available price/quantity modules. As an example, if people want to buy 1-5 pictures, the price is $49/each, if 6-10, than it is going to be $39 per each.

I found Commerce Price Table (1st) and Commerce Pricelist (2nd) modules for that. Looks like 2nd is more functional, but it is very "new" ... Not sure which one I should go for.

Or should I consider some other module(s) that are also popular for that? Or can I do it right from Drupal Commerce?

What I am actually looking for: a way which can adjust the price depending on quantity and attributes.

Module comparison

I'm not familiar with any other such pricing related modules. It seems to me that you will have to decide between these options:

A stable module (aka the price "table" module).
A module that's on the horizon (aka the price "list" module).

Whenever I have to decide between multiple modules, I often use the (23) criteria that I ever documented in "maintenance scorecards" (within the Community documentation). Those scorecards are actually "applied" to charting modules, but the same criteria can be used, I think, to mostly any type of module comparisons.

I'd be happy to provide some more details (via a next iteration of my answer), but if I was to decide I would definitely go for the stable, commonly used price "table" module. The major "red flag" (= no go) for the newer "list" module is criterium nr 26 (downloads vs reported installs ratio). Correct me if I'm wrong, but only like 10 % of downloads seem to have resulted in sites that continue using it.

Rules is your friend

I would definitely also consider the Rules module, using some custom Rules, something like so:

Events = Calculate Sell Price of Product.
Actions = calculate the price, and set the price to the calculated value.

Not sure (yet) if you'd need some extra 'Conditions' added to this.

Refer to Drupal commerce and rules: changing the product price dynamically for an example of dynamically changing product prices.

Create your own custom Rule

If for some reason you can't get it to work with the Rules module, then I'd consider writing my own custom Rule(s), similar to what is described in Drupal custom Rules how to write your own events conditions, actions and custom object.

The main steps that are detailed in this tutorial are further described below (with the code included below quoted from that link).

Part 1: Defining the Event, Condition and Action

Define the Rules Event

/**
* Implementation of hook_rules_event_info().
* @ingroup rules
*/
function your_module_rules_event_info() {
  return array(
    'your_module_package_bought' => array(
      'label' => t('A package was bought'),
      'module' => 'your_module',
      'arguments' => array(
        'acting_user' => array('type' => 'user', 'label' => t('The user who bought the package.')),
        'package' => array('type' => 'package', 'label' => t('The purchased package.')),
      ),
    ),
  );
}

Define the Rules Condition

/**
 * implementation of hook_rules_condition_info()
 */
function your_module_rules_condition_info() {
  return array(
    'your_module_condition_package_type' => array(
      'label' => t('Type of the package'),
      'arguments' => array(
        'package_id' => array('type' => 'value', 'label' => t('The type of the purchased package.')),
        'package_type' => array('type' => 'string', 'label' => t('The type of the purchased package is')),
      ),
      'module' => 'your_module',
    ),
  );
}

Define the Rules Action

/**
 * Implementation of hook_rules_action_info().
 */
function packages_rules_action_info() {
  return array(
    'your_module_action_change_order_status' => array(
      'label' => t('Change the order status'),
      'arguments' => array(
        'order' => array('type' => 'value', 'label' => t('The order object.')),
      ),
      'module' => 'your_module',
    ),
  );
}

Part 2: Coding the custom Event, Condition and Action

Event:

Somewhere in your custom module, you need to include logic to trigger the event, with something similar to this example (note the your_module_package_bought in it):

  //here the code for buying a package will be located
  //when that code returns that a package was bought trigger the rule
  $order = order_load($oid);//$oid will be the id of the order made
  $package = package_load($pid);//pid will be the id of the bought package
  global $user;
  rules_invoke_event('your_module_package_bought', $user, $package, $order);

Condition:

To evaluate the Rules condition (to check if it is TRUE or FALSE), the function your_module_condition_package_type is executed using the arguments provided. Here is an example of how such function could look like:

function your_module_condition_package_type($pid, $type) {
  $package = package_load($pid);
  return ($package->type == $type) ? true : false;
}

Action:

Somewhere in your custom module, you need to include logic to perform the actual action, in this example it should be done within the function named your_module_action_change_order_status.


Placing Drupal core/modules code outside public_html I've been trying to improve my sites security as I build a Drupal 8 update for my page. One thing I've seen recently is keeping your core code outside the web accessible docroot folder. I've also heard about keeping a copy of the code setup on git so you can easily bring down a clean copy if somehow someone changes something.

What is the current best practice for such a thing? On my server I have an account for the page, within which is public_html where anything actually being sent out to the world is kept. Is it possible to have the Drupal code one level down and then have things run from public_html?

There is some work being done to move as much of core out of DOCROOT, but this is complicated by assets that need to be web accessible, mainly JS, CSS, and images.  So, moving core/modules outside DOCROOT is tough because many of those have all three.

Current thinking is to place the vendor directory outside of DOCROOT to help reduce attack surface area.  Since using composer for all site building is also essentially a best practice now, the drupal-composer/drupal-project template does this, and also will place modules, themes, libraries, and other Drupal stuff in the proper place, while keeping vendor non-web accessible, as it contains the non-Drupal specific dependencies.


How to add secondary exposed form elements using "Better exposed module" in views I just want to know how to add elements like another exposed filter in this advanced tabs.Currently it is empty.

Below the field which will be secondary open MORE OPTIONS and check This is a secondary option check box and save.

After that, it will display in Advanced


How do I display the products and nodes of the same author in the current page? I wish to display a block with the products of the same author as the current page.

Contextual filters work on node pages, but not on product pages.

In contextual filters, I add "Product: Author" but no options are available for products.

There is no check box for products, as for content "Also look for a node and use the author of the node".

Thank you, but that's not my question.

"User 1" created:

product 1, product 2, product 3.
node 1, node 2, node 3.

"User 2" created:

product 4, product 5, product 6.
node 4, node 5, node 6.

When I visit node 5, I have the products and nodes of the same author in a block in the second sidebar:

product 4, product 5, product 6.
node 4, node 6.

When I visit product 3, nothing is displayed. Because the contextual filter does not find the author in the product page.

Normally it should display the products and nodes of the same author in a block in the second sidebar:

product 1, product 2.
node 1, node 2, node 3.

The trick is in the relations and contextual filters.

You need to add a relation to the Author and then another relation to Product using the Author as a relationship, then go to add a Contextual filter Content ID (Provide default value [Content ID from URL]) and use Product as Relationship.

Something like this:


Difference between $form_state['values'] and $form_state['input'] Can someone please tell me the difference between these two variables?

$form_state['values']
$form_state['input']

Optionally some example of action they are used with. I'm wondering especially about using with ajax in drupal form. Which of these should I use in ajax callback to get input values from the form?

The crucial difference here is that in most cases you should be using $form_state['values']; since the data on the $form_state['input'] array is raw and unvalidated.

$form_state['input'] is useful for multi-step forms, assuming you are familiar with how to safely handle raw input.... See form_builder for more information...


Programmatically Create an Array of User Objects and Print in Twig Template MYMODULE.module:

function MYMODULE_preprocess_node(&$variables) {

    if ($variables['node']->bundle() == 'content_type') {

        $currentUserUID = \Drupal::currentUser()->id();
        $recipients = $variables['node']->get('field_user_reference')->getValue();
        $userList = array();

        foreach ($recipients as $recipient) {

            if ($recipient['target_id'] != $currentUserUID) {
                $userList[] = \Drupal\user\Entity\User::load($recipient['target_id']);
            }

        }

        if ($variables['node']->getOwnerId() != $currentUserUID) {
            $userList[] = \Drupal\user\Entity\User::load($variables['node']->getOwnerId());
        }

        $variables['userList'] = $userList;

    }

}

FILENAME.twig.html:

{{ userList | render }}

I've also tried working with:

$recipients = $variables['node']->get('field_user_reference')->view('compact');

and tried to filter the UID in the if statement inside the foreach.

My goal is to gather all users referenced from field_user_reference, and add the owner of the node, while filtering out the currentUser() into a single array. I then need to render that array in a twig template file as a user display mode. In this instance, compact.

I am not sure if my impasse lies in twig rendering, or better preprocessing.

How do you render a preprocessed user object in a twig template file?

Notes:

$recipients = $variables['node']->get('field_user_reference')->view('compact');

does render out the referenced users in the compact view mode, however I cannot seem to filter out the current user with something like $recipient->uid[0]->target_id != $currentUserUID.

Before you can render a list of entities you have to build a render array:

$variables['userList'] = \Drupal::entityTypeManager()
  ->getViewBuilder('user')
  ->viewMultiple($userList, 'compact');

Now Twig is able to render the entities:

{{ userList }}

You don't need |render, because Twig renders arrays automatically.


In Drupal 7 Commerce, how do you change the "View Cart" link in the cart block to something else? In the Cart Block in drupal 7 commerce. How do you change the "View Cart" link. I want to change it to Edit Cart instead.

http://img853.imageshack.us/img853/2502/8yfy.jpg

There's a couple of ways.

You could implement the Commerce hook to adjust the line item summary info

hook_commerce_line_item_summary_link_info_alter

e.g:

/**
 * Implements hook_commerce_line_item_summary_link_info_alter
 */
function MY_MODULE_commerce_line_item_summary_link_info_alter(&$links) {
  if (!empty($links['view_cart'])) {
    $links['view_cart']['title'] = t('View the magical cart');
  }
}

See also commerce_cart_commerce_line_item_summary_link_info for the default data.

Another way, as mentioned by 4life, is with the stringoverrides module or if you aren't using it already, you can change the text in settings.php without an additional module

$conf['locale_custom_strings_en'][''] = array(
  'View cart' => 'View the magical cart',
);

Either of those approaches should work there.


Removal of all markup and overall customization So, hey everyone, I've picked Drupal for my newest project, and after checking out the code and a couple of case studies. I think that it's a perfect fit, but I have some concerns about the markup and customization.

I like to write my own markup, and hardcode things like menu items, remove unnecessary clutter, most JS, and really just give the website a life of its own.

What I'm really asking is if any of you had done (or attempted to do) a similar thing and if it's possible to remove absolutely all of the markup and JS (I don't really need any JS) Drupal adds to the frontend without breaking things to hell?

I'd appreciate any kind of help or guidance.

you can customize drupal as deeply and drastically as you please. typically that requires more intimate knowledge of how drupal works.

For alot of field based modifications the Display Suite module allows per-field HTML Reset to customize the HTML outputted per field. A lighter weight approach to the same idea of "resetting" how drupal outputs a field is the Fences module.

With regards to JS there is hook_js_alter which you may use the remove/alter what javascript files are loaded on the page.

All the HTML for the page can be tweaked from the html.tpl.php file used by your installed theme (or the base core supplied html.tpl file).

Have I done allll of these?! No, but I have used hook_js_alter to conditionally include JS on some pages via a module. I have for example removed all sidebars and unset I think most of the CSS found in <head> by conditionally supplying my own template file to a menu path via hook_menu:

Load custom template from MENU_CALLBACK

So there are tons of utilities to do this in Drupal. How these utilities play with 3rd party modules you want to leverage on your site ... or just how much custom work you want to do on your own website -- I leave as an exercise for you.