Tabbed Multipage Ajaxified Forms I need a way to create a form with tabbed navigation at the top, "save and next"/"save and back" navigation at the bottom, and saving the data for an individual page using ajax, with the following business rules:

-A user may access and work in any part of the form at any time.

-Individual pages can be saved, even if nothing in the rest of the form is filled out.

-Changes in any page result in a "exit without saving? prompt", implemented as a separate module (but which can detect switching between tabs).

I have attempted to do this using fieldgroups: Root is a horizontal tab group, which has a single child in the form of a multipage group, which has 1 tab item child for each page, which in turn each have 1 multipage child, in which I place the forms. The hirarchy looks like this:

Horizontal Tab Group->Multipage Group->Tab Item->Multipage

This doesn't work; apparently the fieldgroups module doesn't let groups search beyond a single level. If they could search beyond that, this may have worked fine and I could have applied the ajaxified multipage fieldgroups module.

What is the best way to go about accomplishing this in D7?

You can look at Multipage jumplist module which provides a block that allows you to access all multipages.

To apply the ajaxified multipage fieldgroups, use: Field Group Ajaxified Multipage module which allows you to enable AJAX for multipage groups
It also provides developers with special variables attached to form array regarding page status to allow them further customize the form (e.g. form_alter) depending on active page (in this case saving your pages).


Make custom form submit data to view filters I have a custom-generated form on a page and it needs to submit data to a view on a different page. I'm currently trying to get this to work by passing the form #validate through a submit hook and then using $form_state['redirect'] = 'customsearch/'; to catch the results. The view has several exposed filters and will ideally set themselves to the data received from the initial custom form page.

It doesn't look as though data is actually making it to the /customsearch/ landing page however. I have enabled the Views Expost module and am watching for POST variables from a PHP field in the landing page view.

The current code including form, validation and redirection can be found over here.

What is the proper 'Drupal' way of passing data from a form to a view with exposed filters? Should I be watching for GET or POST variables or will Drupal pass data with a different set of functions than the ones currently used?

Views exposed filters are using information supplied by the relevant GET parameters so this use case is actually very simple. You only need to build the correct url in your custom form submit handler from the received data and then redirect the user. A basic example to illustrate this:

function mymodule_custom_search_form($form, &$form_state) {
  $form['key1'] = array(
    '#title' => t('Key1'),
    '#type' => 'textfield',
  );
  $form['key2'] = array(
    '#title' => t('Key2'),
    '#type' => 'textfield',
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Search'),
  );

  return $form;
}

function mymodule_custom_search_form_submit($form, &$form_state) {
  $options = array('absolute' => TRUE);
  $key1 = trim($form_state['values']['key1']);
  if ($key1) {
    $options['query']['key1'] = $key1;
  }
  $key2 = trim($form_state['values']['key2']);
  if ($key2) {
    $options['query']['key2'] = $key2;
  }
  $form_state['redirect'] = url('customsearch', $options);
}

If the user submits the form with "key1" value "one" and "key2" value "two" then they will be redirected to "customsearch?key1=one&key2=two". What you need to note is that the GET parameters "key1" and "key2" must match with what you've set in the relevant view: click on your filter criteria -> "MORE" link at the bottom and then check/modify "Filter identifier".


Debugging what has been submitted in a form I would like to like to be able to print out what has been submitted in my form in the submission form. How can I achieve this?

You can display the submitted values in your hook_form_submit() and set it like this (example):

function form_example_tutorial_7_submit($form, &$form_state) {
  drupal_set_message(t('The form has been submitted. name="@first @last", year of birth=@year_of_birth', array(
   '@first' => $form_state['values']['first'],
   '@last' => $form_state['values']['last'],
   '@year_of_birth' => $form_state['values']['year_of_birth'],
  )));
}


Linking an individual term from a vocabulary with all terms from another vocabulary I have two vocabularies/fields, one called Days that has all the days of the week (Mon, Tues, Wedn...) as terms, and another vocabulary/field called Time of Day that has terms (Morning, Midday, Afternoon, Evening, Night, Late).

I'm hoping to use these vocabularies/fields for a type of opening hours style tagging, e.g. X venue is open Monday: Morning, Midday, and Evening, Saturday: Evening, Night, Late, etc.

I'm imagining a situation when I check the box next to 'Monday' the terms in the Time of Day field will become visible and I'll be able to check the 'Morning', 'Midday', and 'Afternoon' boxes. Likewise for when I check any other box next to another Day term.

Can you guys think of a way I could set this up with my field structures?

Thanks in advance!

EDIT: Hey guys, new aspect of this question now. So I'd like to attach tags to different day and opening hour combinations, e.g. Monday Morning X Venue is good for coffee, breakfast, Saturday Night at X Venue is good for cocktails, dancing.

I've currently got a vocabulary of tags. How can I go about linking the tags and the opening hours/days? A heirachy would be an option, but that would make for a hell of a lot of repeated clicking for the user. Any thoughts?

To do a hierarchical taxonomy,  Use Taxonomy Manager and all you need to do is include the hyphen before the child terms, as shown in the answer above when you bulk add terms

You can also use the standard taxonomy manager, and use drag handles to inset children, like I have done below.


How can I specify a "Text Field" as an "Attribute Field Setting" for a Product Variation in Drupal Commerce? I am working with a client that handles distribution for an array of goods that do not fall into traditional sizing schemes (S, M, L). Instead, some products are characterized by length in mm, weight in kg, qty in a kit, etc. Because of the wide array and volume of nodes, it doesn't make sense to create a new vocabulary/category out of so many unrelated terms.

Set 1: 160mm, 180mm, 203mm
Set 2: 1xsm + 2xlg; 2xsm
Set 3: 25 mL, 250 mL, 1 L, 5 L
etc (totally different kinds of sets that are not reused across product types)

I specified a "text field" as "Product specific size", allowing the user to insert whatever size type made sense up to 100 characters. I thought I could use that as a dropdown menu so that the size could be selected by the shopper in the "Add to Cart" form.

However, it looks like that's a no-go for text fields. Because the size varies across other parameters (qty in kit x color), having the variant name be the selection method seems pretty hokey.

What have others done for this use case?

Thanks - keb

6/5 Follow up:

Looking into this further, the "Cart" module calls the "Options" module in order to determine which fields are eligible to be "Add to Cart" form attributes:

// If the current field instance is not locked, is attached to a product
// type, and of a field type that defines an options list...

In the "Options" module, it looks for data that is entered/stored as an array, e.g. a select list, taxonomy list, etc.

Thinking this through, it seems like it won't be possible to call the user-entered data in a text field for multiple Product Variations because it isn't stored in req'd format.

There may be a way to write custom code to work around this, but I relented and made an absurd list of "Product Specific Options" that takes care of the use case. Since most products on the site will be imported, the burden on editor/user won't be too high.


Concatenate $base_url and path_to_theme() I'm used to write this kind of code in .tpl.php files in order to display images (for instance) :

<?php echo $base_url .'/'. path_to_theme();?>

I wonder if it would be possible to concatenate $base_url and path_to_theme() into one single command/variable ?

In hook_preprocess($vars) create a new variable called path_to_theme in $vars by including the following (where $hook is page, node, block etc)

function mymodule_preprocess(&$vars, $hook) {
  $vars['path_to_theme'] = base_path().path_to_theme();
}

Now in virtually all of your theme's template you can use the variable $path_to_theme and it will be the contents of base_path().path_to_theme()

Note, that you can put this in a custom module, or replace mymodule with the name of your theme and you can place it in your theme's template.php

You can use node, page, and other "hook" specific preprocess functions if you only wish to add this variable to specific content of your site.

There are many options for preprocessing nodes, pages etc. which can be read up in:
Setting up variables for use in a template (preprocess and process functions)

Also be sure to read up on the Default baseline variables such as:

  $directory The theme path relative to
  the base install. example:
  "sites/all/themes/myTheme"


getting error when doing the composer install Drupal version was 8.6.2 and moved to new server.
When doing the core update , getting an error like below.

 Problem 1
- remove drupal/drupal No version set (parsed as 1.0.0)|remove drupal/core 8.6.3
- don't install drupal/core 8.6.2|remove drupal/drupal No version set (parsed as 1.0.0)
- don't install drupal/core 8.6.3|remove drupal/drupal No version set (parsed as 1.0.0)
- don't install drupal/core 8.6.x-dev|remove drupal/drupal No version set (parsed as 1.0.0)
- don't install drupal/core 8.7.x-dev|remove drupal/drupal No version set (parsed as 1.0.0)
- don't install drupal/core 8.6.3|remove drupal/drupal No version set (parsed as 1.0.0)
- Installation request for drupal/drupal No version set (parsed as 1.0.0) -> satisfiable by drupal/drupal[No version set (parsed as 1.0.0)].
- Installation request for drupal/core ^8.6.2 -> satisfiable by drupal/core[8.6.2, 8.6.3, 8.6.x-dev, 8.7.x-dev]

i have tried the composer install by removing composer.lock, vendor and core. Still getting same error.

Updated with my composer.json

{
"name": "drupal/drupal",
"description": "Drupal is an open source content management platform powering millions of websites and applications.",
"type": "project",
"license": "GPL-2.0+",
"require": {
    "composer/installers": "^1.0.24",
    "wikimedia/composer-merge-plugin": "^1.4",
    "drupal/core": "^8.6.2",
    "drush/drush": "^9.2",
    "drupal/s3fs": "^3.0",
    "drupal/csv_serialization": "^1.4"
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
    "preferred-install": "dist",
    "autoloader-suffix": "Drupal8"
},
"extra": {
    "_readme": [
        "By default Drupal loads the autoloader from ./vendor/autoload.php.",
        "To change the autoloader you can edit ./autoload.php.",
        "This file specifies the packages.drupal.org repository.",
        "You can read more about this composer repository at:",
        "https://www.drupal.org/node/2718229"
    ],
    "merge-plugin": {
        "include": [
            "core/composer.json"
        ],
        "recurse": false,
        "replace": false,
        "merge-extra": false
    },
    "installer-paths": {
        "core": ["type:drupal-core"],
        "modules/contrib/{$name}": ["type:drupal-module"],
        "profiles/contrib/{$name}": ["type:drupal-profile"],
        "themes/contrib/{$name}": ["type:drupal-theme"],
        "drush/contrib/{$name}": ["type:drupal-drush"],
        "modules/custom/{$name}": ["type:drupal-custom-module"],
        "themes/custom/{$name}": ["type:drupal-custom-theme"]
    }
},
"autoload": {
    "psr-4": {
        "Drupal\\Core\\Composer\\": "core/lib/Drupal/Core/Composer"
    }
},
"scripts": {
    "pre-autoload-dump": "Drupal\\Core\\Composer\\Composer::preAutoloadDump",
    "post-autoload-dump": [
      "Drupal\\Core\\Composer\\Composer::ensureHtaccess"
    ],
    "post-package-install": "Drupal\\Core\\Composer\\Composer::vendorTestCodeCleanup",
    "post-package-update": "Drupal\\Core\\Composer\\Composer::vendorTestCodeCleanup"
},
"repositories": [
    {
        "type": "composer",
        "url": "https://packages.drupal.org/8"
    }
]

}

I think the composer error messages are really opaque: Took me the whole day to figure this one out. And stil am not sure how to debug the composer related problems (and I have read all the drupal documentation, lots of composer documentation, so maybe I am just losing IQ points lately...)

Error 1: composer install

I had the same problem on composer install (Clive removed my earlier remark) and thought the culprit was

remove drupal/drupal No version set (parsed as 1.0.0)

Couldn't figure out why that would happen: Added all modules neatly with require bladiebla and had no problem updating core to 8.6.4

Site was running smoothly

Error 2: install module

Trying to install backup_migrate resulted in the error

The package is not available in a stable-enough version according to your minimum-stability setting

Which I also did not understand because my minimum stability was dev and the backup_migrate version was a stable one

Trying different things to find out where the problem originates did not bring any solution

composer install
composer update
composer diagnose
composer why
composer give me a break
etc

Is supposed that one of the modules I required conflicted with another one, but how to find out which one..... (any hints on how to debug these composer message are welcome)

SOLUTION (in my case)

In the end I simply did this

starting point

drupal 8.6.4

minimum stability dev

php 7.0.3

actions

remove core, modules/contrib, vendor, composer.lock
in composer.json:

2.1 start with (in my case)

    "drupal/core": "~8.6.0",
    "composer/installers": "^1.0.24",
    "wikimedia/composer-merge-plugin": "^1.4",

2.2 in the following require part require all advised highest version for all modules you use (so go to the drupal mordules site en copy the advised composer require statements)

   "drush/drush": "~9",
    "drupal/backup_migrate": " ^4.0",
    "drupal/backup_db": " ^1.1",
    "drupal/draggableviews": " ^1.0",
    "drupal/pathauto": " ^1.0",
    "drupal/token": " ^1.0",
    "drupal/anonymous_redirect": "^2.2",
    "drupal/ctools": " ^3.0",
    "drupal/calendar": " ^1.0",
    "drupal/geolocation": "^2.0",
    "drupal/views_taxonomy_term_name_depth": "6.x-dev",
    "drupal/views_templates": "^1.0",
    "drupal/paragraphs": " ^1.5",
    "drupal/devel": "^1.2",
    "drupal/webform": " ^5.0",
    "drupal/social_login": " ^2.83",
    "drupal/disqus": " ^1.0",
    "drupal/address": " ^1.4",
    "drupal/leaflet": " ^1.0",
    "drupal/geofield": "^1.0",
    "drupal/geophp": "^1.0",
    "drupal/geocoder": "^2.0",
    "drupal/geofield_map": "^2.20",
    "drupal/google_analytics": "^3.0",
    "drupal/video_embed_field": "^2.0",
    "drupal/better_exposed_filters": "^3.0",
    "drupal/addtoany": "^1.10",
    "drupal/typed_data": "^1.0",
    "drupal/rules": "^3.0",
    "drupal/honeypot": "^1.29",
    "drupal/field_group": " ^3.0"

run
composer install
go to your site and run www.domain.ext/update.php

That resolved my problem


dev-test-prod staging workflow for drupal with transport of database changes Hi I am looking for a best practice staging workflow for a four level staging environement for drupal:

dev->test->pre-prod->prod

I found this quite informative thread already Applying Updates to Multiple Drupal Sites

As the Teams will change especially on the test upwards it has to be pretty straight forward.

I guess we will move everting as far as posible through git or would rsync be better choice?
Is there some way to maintain some kind of central stage configuration where you just maintain the server adresses e.g. in on central place
How to move database changes without conflicting with productive content

Would be great if someone could share hints to some documentation of such a workflow.

Thanks in advance

Regarding #2, I would recommend using drush site aliases.  See also the sync_enable example in Drush, which demonstrates how you can get Drush to automatically adjust your database settings when you move your db from prod towards dev.  For moving configuration from dev to production, many folks use features; you might also want to look at ctools export bonus, which is built on much of the same technology.


Block caching not working for anonymous users despite setting cache contexts I have a block plugin that displays different dynamic content depending on whether you're logged in or not. I attempted enabling this by setting the max-age setting in the #cache attribute of my render array to 0 like so

    if ($user->hasRole('anonymous')) {
            if ($loginrequired) {
                $content = [
                    '#markup' => '
 Login required. Click Here to Login
',
                ];
                return $content;
            }
    }
    $content = [
        'header'   => [
            '#markup' => $header_text,
        ],
        '#cache'   => [
            'max-age' => 0,
        ],
        $webform,
    ];
    return $content;

The dynamic content updates for logged in users, but for anonymous users it just displays exactly what the logged in user saw, instead of showing the login required message.

After doing some research it seems that drupal ignores max-cache for anonymous visitors and cache contexts would be required, according to this page

Disable form or block cache for anonymous users?

So I changed my code to reflect this

        '#cache'    => [
            'max-age'  => 0,
            'contexts' => ['user.roles']
        ],

I used user.roles since the content depended on whether the user was logged in or not. This had no effect. I then tried.

        '#cache'    => [
            'max-age'  => 0,
            'contexts' => ['user.roles:anonymous']
        ],

This also had no effect. Why does my method not work? What cache settings are required in order for the cache to be disabled even for anonymous users? Or is there a completely different method I should be using?

Note: I do not want to disable caching site wide. I would like to be able to disable caching on a plugin to plugin basis.

UPDATE: Looking at examples I also tried

   '#cache' => [
            'max-age'  => 0,
            'contexts' => ['url.path', 'url.query_args']
    ],

but that didn't work either.

The issue was that I had different render arrays set depending on whether the user was logged in or not, but the cache context only applied to one of the render arrays but not the other. If I have different possible render arrays being returned every single one needs to have the cache settings added.

I resolved the issue by changing my code to

if ($user->hasRole('anonymous')) {
        if ($loginrequired) {
            $content = [
                '#markup' => '
 Login required. Click Here to Login
',
                '#cache'   => [
                     'max-age' => 0,
                     'contexts' => ['url.path']
                 ],
            ];
            return $content;
        }
}
$content = [
    'header'   => [
        '#markup' => $header_text,
    ],
    '#cache'   => [
        'max-age' => 0,
        'contexts' => ['url.path']
    ],
    $webform,
];
return $content;


XML to node in Drupal 6 I am using the Services module, through which I have created XML.

But i want to import this XML data into another drupal website. It contains images too.

I also installed feeds module but don't have idea how to use this.

You need to get an XML parser module that interacts with node inserts, similar to feeds xml I would assume. This should allow you to insert the data into your db.


hide titles based on page type? I want to disable titles from showing on main content pages, but have them show still on blog post/article pages.  I was using a CSS rule #page-title to hide them, and was thinking of working from that, but it doesn't work as well in dynamically generated pages. Comparing a post page to a main content page, I don't see any difference in the preceding css classes and ids.

How could I quickly change this behaviour?

I'm working on a self-built custom theme that doesn't have a lot of editing done to it.

If these are different content types, you could create a separate node-[type].tpl.php file for each, leaving out the title in one of them.

http://drupal.org/node/1089642


How do I populate an exposed filter with titles of user's content? I have a view that displays all reviews written by a user. One piece of information that is included in these reviews is the band that the user was playing in at the venue that the review is for. So, I have an exposed filter on the view that allows people to filter reviews by band name.

 http://www.gigindie.com/users/jhegg23

However, the exposed filter renders as a text field. I'd like to change this into a select list containing the currently viewed user's bands. So, instead of the user typing in the name of the band that they want to filter the reviews by, they can instead select a band from the list. I know that I can alter the form type within a custom module, so that it renders instead as a select box. However, I also need to populate the options of the filter with the names of the bands that the user is in.

Bands are a content type of their own. Is there a way to do this, with maybe a view or something?

EDIT - As requested in the below comment:  It's D7, and it's a view of content (filtered by content type: review). The view is a block appearing in the user's profile, with a contextual filter for author UID from the page url. And yes, there is an entity reference. The user creates their bands, and then when they write a review, they select a band, which creates a reference in the review to the band.

Views Reference Filter can be helpful. I you have to create a ER view of node title and then you can use this ER view in your main view exposed filter of type reference.


How to place multiple blocks in one column in bootstrap theme I am using bootstrap theme. I have 4 blocks: block1, block2, block3, block4. Bootstrap has 12 columns grid. I would like to place block 1 in first 7 columns(using bootstrap class "col-md-7"). I would like to place block 2,3,and 4 to the right of the block 1. Can you please advise how to achieve it?

This approach might suit your case.

Create 2 new regions in your template info file and render them in your page.tpl.php

  If you are using a bootstrap subtheme, this file will be located in
  siites/all/themes/bootstrap/templates/system so you will have to copy
  it and put in your templates folder under you subtheme folder.
  Remember to clear the Theme Registry cache after this.

So I would do this like below

info file

regions[main_block] = 'Main Block Region'
regions[side_block] = 'Side Block Region'

page.tpl.php file

    <?php print render($page['main_block']); ?>

    <?php print render($page['side_block']); ?>

After go to the blocks admin interface and select the blocks to show on the correct region. Also for the Side Blocks render all three blocks you need in the Side Block Region and use the correct weights to sort them as you like.


How to best handle "sudo: no tty present and no askpass program specified"? I have custom Drush commands that contain shell commands with 'sudo' included. This results in an error when calling with remote alias to execute on remote instance:

drush @remote-alias custom-command-with-sudo

From research in google.com, I understand there is not tty session loaded when doing ssh user@ssh-server causing the error:

sudo: no tty present and no askpass program specified

https://unix.stackexchange.com/questions/48554/sudo-over-ssh-no-tty-present-and-no-askpass-program-specified
https://askubuntu.com/questions/271186/how-do-i-resolve-the-tty-problem

Can I configure drush to include -t flag when its doing ssh -t user@ssh-server. I understand this will load tty session and solve problem, am i wrong?...in short, how do you best overcame this issue? Thank you

UPDATE:
I followed instructions from similar question referred by Clive

Added following line in .drush/drushrc.php:

$options['ssh-options'] = '-o PasswordAuthentication=no -i $HOME/.ssh/id_rsa/lamp_vbox';

Then I run in debug mode by adding --debug and this is what it shows:

  Calling proc_open(ssh -o PasswordAuthentication=no -i /Users/owner/.ssh/id_rsa/lamp_vbox margots@lamp-vbox 'COLUMNS=179 drush  --debug --uri=dev-metronic --root=/home/websites/dev/metronic --verbose  deploy-asset '\''@dev-metronic'\''   --ver=0.3 --asset=metronic --env=dev 2>&1' 2>&1);
          Starting Drush preflight. [0.06 sec, 1.51 MB]

From the log, I conclude that the settings are being passed, however. I still get the error, so I wonder what could be the problem and how to solve it.

I'm using: Mac 10.9, Drush Version   :  7.0-dev

This may not be solution for everyone, but it worked in my situation because i could change settings at the remote instance. I followed the following instruction and turned on NOPASSWORD, which is adding the following line into sudoers file:

# Members of the admin group may gain root privileges
%admin  ALL=(ALL) ALL

Afterwards, my custom drush commands with sudo works on the remote instance


How do I theme a link from a template file? A twig template is rendering a list of links that come with classes. The basic:

{{ mylink }}

twig code will output something like

the text

Not all links have classes. I want to write a twig template that will instead output something like this:

  the text

What I've tried:

I looked for the twig template to override. Unfortunately it seems that links are not rendered by a twig template.
I tried updating the twig variable like

set mylink['#title'] = "..." ~ mylink['#title']

But it won't let  me do that.

Here's a twig only solution for a particular field that needs this treatment;
it's not a generic solution for all links everywhere.

some-template.twig:

  {% for item in content.field_links %}
  {% if item['#title'] %}

        {% if item['#options']['attributes']['class'] %}

        {% endif %}
        {{ item['#title'] }}

  {% endif %}
  {% endfor %}


Taxonomy view page for double nested terms I have a content type that has an entity reference to a taxonomy term. The referenced taxonomy term has furthermore taxonomy terms referenced to it.

On the taxonomy term view page, I would like the content appear, that refers to the terms nested inside first term reference.

The idea of double nested content and display on the taxonomy view page worked for me well, when I used for the first level nesting another content type instead of a taxonomy term. That way I could successfully apply following relationship and contextual filter on the view. I added a relationship to the entity reference field’s content and applied it to the contextual filter.

Now, wanting to use a taxonomy term as first level reference, I am not able to get it work. I thought the following should work, but it does not:

What relationship do I have to apply, to get the desired result?

(I hope I was able explain my problem comprehensibly)

Edit:

The schema is following:

NODE 1 > TERM 1 > TERM 3

NODE 2 > TERM 2 > TERM 3

TERM PAGE (taxonomy/term/3)
SHOW: NODE 1 + 2

The nodes have the reference field "field_key_data" that references
the vocabulary "architecture". The terms in the vocabulary
"architecture" have a term reference field "field_style" (TERM 1 or
TERM 2) of another vocabulary.
The term in "architecture" may be different, but can reference to the same value in "field_style" (TERM 3).
If this is the case, the TERM PAGE for term 3 should show as
result NODE 1 and NODE 2.
Futhermore the result should be displayed with depth.

Show only grandchild nodes on Taxonomy term pages

In more words: Add nodes to Taxonomy term pages that are tagged with terms that reference the term shown on that page. This means that nodes that directly reference the TID will not be shown. Instead, we show nodes that have an additional Taxonomy link in between, a sort of grandchild connection.

We first introduce the "parent" connection (in your case it's "Architecture" from field_key_data). Then through it we bring in grandparent "Style" information from field_style. Since we want to show nodes that relate to that TID through that "lineage" we simply use Term ID Contextual filter with the "grandparent" Relationship.

Clone (Duplicate) the default Taxonomy term View (which is of Content type). It already has one Contextual filter (Has Taxonomy Term ID) that is responsible for showing all nodes tagged with that term. Remove it, we don't want parents, we're only interested in grandparent.
Add a Relationship Taxonomy term referenced from field_key_data.
Add another Relationship Taxonomy term referenced from field_style, it will use the first Relationship.
Add a new Contextual Filter Term ID, make it use the second Relationship, and configure it:
When the filter value is NOT available
Provide default value
Taxonomy term ID from URL
Load default filter from term page
When the filter value IS available or a default is provided
Specify validation criteria
Taxonomy term ID
Style (or whatever in your case)
Under Query settings choose Distinct because you'll see duplicated results because Relationships introduce many connections so to prevent it Distinct only shows each node once.

No need for Contextual OR BTW, we only have one Contextual filter anyway :)

BTW you can "require" both Relationships since this entire scheme relies on existence of grandchildren.


How do I place content in a user-profile.tpl.php, based on whether a boolean field is true? I am trying to display certain content in the user profile pages of a site based on whether my boolean field 'member' is true. I am currently trying to solve this with an if statement like so.

    if ($user_profile['field_member']['und']['0']['value'] == '1') {

        print ('
This is working
');

    }

However this is returning an

'Undefined index: und in include()'

error on the if statement line. I'm not very well versed in working with drupal template files and would appreciate any help.

EDIT: The syntax was incorrect I should of written '#items' instead of 'und'. I discovered this with advisement, through the use of the devel kpr() function which allowed me to view the array contents more easily than a var dump.

You shouldn't access data that way, especially in template files as it's the raw data.

You should use the functions field_get_items & field_view_value


Can you modify the settings.php file using drush? I am trying to create multisites and the first one is up fine and running.  I am trying to use drush to install a 2nd site but I need the settings.php file to point to a different db.  Can I modify my drush command to do that or am I going to have to modify the settings.php by hand each time?

sudo drush -y site-install standard --db-url=mysql://$username:$pass@127.0.0.1:3306/$dbname --site-name="$sitename" --sites-subdir="$sitename"

What you really need here is different settings.php files for your production and development environments.

There are multiple ways of achieving this, some examples:

Setting various environments (development, production) based on the URL
Environment Specific settings.php Overrides

I usually include the following lines at the end of the settings.php file (in all instances):

// Override settings in this file.
if (file_exists('./' . conf_path() . '/local_settings.php')) {
  include_once './' . conf_path() . '/local_settings.php';
}

And then change the $databases array there, and any other specific environment settings.

You may also find useful the following links:

Defining variables in a site's settings.php $conf array
Set Environment module, that helps maintaining multiple environments with drush.


Flexslider with Link - using Flexslider Field Collection I am using Flexslider with Flexslider Field Collection.

This is working.

But now I need to include Links for each slide. And only found help when using Views.

Is there a way to include links to each slide without Views?

Just found it:

my Slider-Field-Collection ("field_slide") has:

[Label] -[Field Type] - [Widget]
Title- Text - Text field
Body - Long text - Text area
Image - Image - Media file selector
link - Link - Link

Display settings:

[Field] - [Format]
Image - Image Link Formater - Settings: Link image to: link (field_link)

in my content type I use that "field_slide" (embedded) and on display settings: Flexslider

This makes it easy to create content and add unlimited images (as slides) without creating each slide as a node.


Use sites.php to point https and http to diffent sites I've got several Drupal sites on different domains running on the same code using sites.php.

What I want to do is point the same domain to different sites depending on whether it's accessed via http or https.

For example, in sites.php
$sites['http://www.example.com']='site1';
$sites['https://www.example.com']='site2';

However, the above doesn't work. It looks like you can't specify protocol in sites.php.

Thanks,

Robin

Please read through the default example.sites.php file again. A protocol is the same thing as a port (they have a 1-to-1 relationship when we talk about a webserver).

http is implied by default in the rule describing www.example.com. http is also implied to be Port 80, otherwise known as :80 in a URI-scheme.

Your format is completely wrong for any subsite defined in $sites. From the documentation it would be:

$sites['www.example.com']='site1';   // Normal HTTP www.foo.com
$sites['443.www.example.com']='site2';  // SSL version (port 443 by default for www.foo.com)


drupal store and retrieve variable from $_POST array This is really simple question for the user who are using DRUPAL for many years.But for me it is creating a big issue.

I already made a form using the drupal form api.But after submit the form I want to store form data in the "$_POST" and print the data to another module's page.I get the data on the 2nd page(module's page where I want to show the form data)when I store the data in $_SESSION or in $_GET array but not get result when I store data in $_POST.What is the proper way to store data in $_POST array and fetch the data in another page?

my submit code is as follows:

function create_kavings_create_form_submit($form, &$form_state) {
    //print_r($_POST);die();
    //$_POST['first_name'] = $form_state['values']['first'];
    //$_POST['last_name'] = $form_state['values']['last'];
    //$arr[]=$_POST;
      $options = array(
      'query' => array(
         'first' => $_POST['first'],
         'last' => $_POST['last'],
        )
      );
      $form_state['redirect'] = array('coupon_preview',$options);
}

On 2nd page I simplly write the following to print the post array:
print_r($_POST);
But is showing blank.

you should use print_r($_POST['variable_name']); to get the post values you sent form the form.

and add

if(isset($_POST['variable_name']) && !empty($_POST['variable_name'])){
    $values_post = $_POST['variable_name'];
}

to avoid unwanted notices.


View PDF as "node"/content I'm working on updating our current intranet to Drupal.

What I need to be able to do is take a PDF and load it in an iframe/node via Adobe Reader (or similar).

I can get something similar using (I think) CCK and FileViewer, but I'd like to remove the fileviewer wrapper and just have a standard PDF in browser.

Assume IE7/8 and Adobe Reader are installed.

Update:
Custom Formatter Module: Custom Module
Result of Module: enter image description here

Update 2

Using an Object per these instructions gives a more controlled block to build on. Ultimately I'll add a "You need Adobe installed from HERE to view THIS PDF" for the small chance of no pdf-viewer installed.

You can do this using an <iframe> element within a custom formatter for a file field.

Field formatters control the output of a field: it's what lets you choose whether to display a generic link, the file name, etc. What you can do is create one that displays the PDF within an <iframe> element.

To do this, you need to (at a minimum) implement two hooks: hook_field_formatter_info() and hook_field_formatter_view():

/**
 * Implements hook_field_formatter_info().
 */
function sandbox_field_formatter_info() {
  $info = array();
  $info['sandbox_formatter'] = array(
    'label' => t('Inline file'),
    'description' => t('Display the file within an iframe.'),
    'field types' => array('file'),
  );
  return $info;
}

/**
 * Implements hook_field_formatter_view().
 */
function sandbox_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();

  // Create the proper markup for each item within the field instance
  foreach ($items as $delta => $item) {
    $path = file_create_url($item['uri']);
    $element[$delta] = array(
      '#markup' => '<iframe src="' . $path . '"></iframe>',
    );
  }
  return $element;
}

Then you can create a file field, set it to only allow PDF, and choose Inline file as the display format. When you view a node with a PDF, you'll see the PDF within an <iframe> element.

The above is a very basic, minimal example: for an intermediate example that shows how to implement formatter settings, check out Dan Linn's tutorial. Also be sure to check out the relevant API pages, which includes sample implementations even more advanced than Linn's:

File Types API
hook_field_formatter_info()
hook_field_formatter_view()
hook_field_formatter_settings_form()
hook_field_formatter_settings_summary()

As an aside, it should be noted that there are a couple of related modules:

Iframe: creates an <iframe> element formatter, but it hasn't been ported to Drupal 7 yet.
Custom formatters: claims to allow the creation of custom formatters without needing to create a custom module


Webserver authentication I was looking a module that implements single sign on for MS Windows networks. I found Webserver Authentication (https://www.drupal.org/project/webserver_auth). But I activated the module before configure it and now I can't access as ADMIN, or as any other developer user to keep working on the configuration of my project.

Does anyone had this problem before and can guide me to deactivate or uninstall that module??

Drush may be the best option. You have a command to uninstall a module :
drush pm-uninstall module-name

Otherwise there is a really tricky and dangerous way to do it :
Go on your database on the "system" table. And search for the line with your module and set the status to 0. After that you may need to clear your cache with the function : drupal_flush_all_caches() (add it to a index.php and remove it after).

The second method is tricky and you should prefer the one with drush. I just explain it if you don't manage to install drush on windows.


Recipes for most compatible slideshows and/or carousels? I'm getting ready to implement a carousel for client in Drupal 7. I've been searching for information about how to implement carousels and slideshows for maximum compatibility. I've installed several modules in my search and I realize that there is not an out of the box complete solution.

Most of the modules I've tried will make a mess of the page when js is disabled, some of them are buggy on mobile devices etc. I've seen some CSS3 solutions but haven't tried them yet by reason of not knowing the classes employed by them and the level of support they have in browsers/devices. I'd like to ask the community for what solutions exist aside from not using carousels and slideshows to accomplish this. A reasonably compatible solution that looks and functions ok, even on non js enabled browsers.

The most common formula I implement can work for just about any JS library.

Assuming you are attaching slides to a content type, here is how I go about it.

First, you will need File Entity, for the ability to add fields to file types.

You can use the default Image type, or, create a special one like 'Slide', if you'd like to isolate field and behavior.

Add an image field to a content type. Set the widget to 'Media' embed.
Set cardinality
Hide field display from all view modes
Create a new view mode, called 'Slideshow' or 'Carousel' whatever you desire
In the new view mode, set the image reference field to render the image in a view mode from the file entity configuration.
In Image (or your new) file type, add some fields like Title, Text, and Link. Configure the chosen file display to set those fields however you like.
Create a template representing that file display with the markup you desire and placement of fields.
Create a View, add a Block display, and add a contextual filter of node nid, based on url value (when on node pages).
Set the view to only output the Rendered Entity: Slideshow mode. No fields.
Put the block in your designated slideshow region.

When adding images on the content type(s), you should have a ctools window after uploading that presents the fields you added in step 6 - that is for setting headers, text, and 'read more' link on each image.

This will output the markup you provided in those templates on nodes who have one or more files attached. From here, you would want to tweak markup to match whatever slide JS library you select and some CSS tweaking as well. Then, you can hook up an initializer in a JS file in your theme, to call as you need.

This might take 30-60 minutes to setup, but it has been the most bulletproof way for me to allow someone to add a slideshow or hero (just 1 image) to a content page while being open and flexible to whatever slide/carousel library may be required.

My favorite plugins/libraries for slide functionality are Zurb Orbit and slick.js. I don't usually need or implement any modules to do these anymore, for the smallest possible implementation without a ton of overhead.

That said, if you are perhaps using a Foundation based theme, you might find it worthwhile to leverage Field Orbit. It is built a little like the steps above, but uses a field formatter to simplify the implementation part. Disclaimer, I built that many moons ago - but I have not made any changes to it lately. I believe it works with Foundation 5.x as well.


Display alternate content after webform submission Is there a way to display an alternate content once user submits a webform?

For example user submits "Email Sign Up" form on the homepage, and the next time they visit the page containing that form they would see a different message.

Thanks!

You'll notice that for anonymous visitors, webform does store a cookie so that it knows if you've submitted a particular form (assuming a default webform configuration). So in theory, you could hook into that with some custom code to display and/or hide content.


echo() doesn't output anything for anonymous users I am working on my own form module for Drupal 7.

I tried to set some default text depending on a cookie was set or not. It works perfectly as long as your are logged in; once you are an anonymous user, it doesn't read/write the cookie.

I tried to debug this by putting in a few calls to echo(), and drupal_set_message(), but they are only shown when I'm logged in; they don't show for anonymous users. I can't figure out why.

Can anyone help me with this?

This is the code I am using.

$serviceType = "";
$serviceName = "";
if (isset($_COOKIE["kms_hoststring_name"])) {
  $serviceName = $_COOKIE["kms_hoststring_name"];
  $serviceType = $_COOKIE["kms_hoststring_type"];
}
drupal_set_message("test");
echo "TEST";
$form['serviceType'] = array(
  '#type' => 'textfield',
  '#title' => t('Service Type:'),
  '#default_value' => t($serviceType),
);

$form['serviceName'] = array(
  '#type' => 'textfield',
  '#title' => t('Service Name'),
  '#default_value' => t($serviceName),
);

//Deletes cookies after use.
echo "TEST1";
if (isset($_COOKIE["kms_hoststring_name"])){
  setcookie("kms_hoststring_name", "", time()-60000, "/");
  setcookie("kms_hoststring_type", "", time()-60000, "/");
  echo "TEST2".$_COOKIE["kms_hoststring_name"];
}

None of the echo() or drupal_set_message() calls output anything for anonymous users.
When I log in, I see the output of those function calls.

Drupal have much better tools for debugging than echo. You can sent a message to the watchdog log with the watchdog function. And if you install the devel module you get a few more funcions like dpm() to easily send messages or dd() to write onto the drupal debug log.


Login by email instead of username I can't find if it is possible or not to change the log in system by using the couple (email, password) instead of (username, password).

I think people never remember their usernames when not available as they wanted and so had to add a number at the end of it ...

Both the Login Toboggan and Email Registration modules allow your users to use their email when logging in.


Cannot get values in 3rd level SubFormState I have a block that embeds another plugins into itself and this includes configuration form. I can properly handle the form structure but when it comes to validation I am not able to access the values in the embedded plugin form validation handler. I was looking at the SubFormState and I tried to adjust the #parents of the provided form element but it didn't help. I know SubFormState is far from perfect but this should not be an issue.

This is my form:

// ...
$carousel_ajax = [
      'wrapper' => 'carousel-settings-ajax-wrapper',
      'callback' => [get_called_class(), 'selectCarouselAjaxFormRebuild']
    ];

    // No need for "#tree" option here since this form is already embedded.
    $form['carousel'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Carousel'),
      '#prefix' => '
',
      '#suffix' => '
'
    ];

    $form['carousel']['plugin'] = [
      '#type' => 'select',
      '#title' => $this->t('Use carousel'),
      '#options' => ['' => '- ' . $this->t('None') . ' -'] + $this->carouselManager->getList(),
      '#default_value' => $configuration['carousel']['plugin'],
      '#ajax' => $carousel_ajax + ['trigger_as' => ['name' => 'select_carousel_submit']],
    ];

    $form['carousel']['select_carousel_submit'] = [
      '#type' => 'submit',
      '#name' => 'select_carousel_submit',
      '#value' => $this->t('Select carousel'),
      '#submit' => [[$this, 'selectCarouselFormSubmit']],
      '#limit_validation_errors' => [['settings', 'carousel']],
      '#ajax' => $carousel_ajax,
      '#attributes' => [
        'class' => ['js-hide']
      ]
    ];

    $form['carousel']['settings'] = [];
    if (!empty($configuration['carousel']['plugin']) && $this->carouselManager->hasDefinition($configuration['carousel']['plugin'])) {
      $carousel_plugin = $this->carouselManager->createInstance($configuration['carousel']['plugin'], $configuration['carousel']['settings']);
      $form['carousel']['settings'] = $carousel_plugin->buildConfigurationForm(
        $form['carousel']['settings'],
        SubformState::createForSubform($form['carousel']['settings'], $form, $form_state)
      );
    } else {
      $form['carousel']['settings'] = [
        '#type' => 'value',
        '#value' => []
      ];
    }

    return $form;

This is the block form validation handler(I am experimenting with various structures and whatnot):

public function blockValidate($form, FormStateInterface $form_state) {
    if ($form_state->hasValue(['carousel', 'plugin'])) {
      $carousel_plugin = $this->carouselManager->createInstance(
        $form_state->getValue(['carousel', 'plugin']),
        $form_state->getValue(['carousel', 'settings'])
      );
      //array_shift($form['settings']['carousel']['settings']['#parents']);
      $carousel_plugin->validateConfigurationForm(
        $form['settings']['carousel']['settings'],
        SubformState::createForSubform($form['settings']['carousel']['settings'], $form, $form_state)
      );
    }
  }

3rd level because the block itself is 2nd level being embedded in the \Drupal\block\BlockForm::form

After quite some experimenting I came to a working solution.

  /**
   * {@inheritdoc}
   */
  public function blockValidate($form, FormStateInterface $form_state) {
    if ($form_state->hasValue(['carousel', 'plugin'])) {
      $carousel_plugin = $this->carouselManager->createInstance(
        $form_state->getValue(['carousel', 'plugin']),
        $form_state->getValue(['carousel', 'settings'])
      );

      // We have to do some manual adjustments here since the SubFormState
      // is far from perfect.
      $element = $form['settings']['carousel']['settings'];
      array_shift($element['#parents']);

      $carousel_plugin->validateConfigurationForm(
        $element,
        SubformState::createForSubform($element, $form, $form_state)
      );
    }

So the embedded validation handler has to receive altered form element and the subformstate has to receive the original, intact, form.


Multisite Drupal 7 sharing same code base I have existing Drupal 7 site and I want to create a sub-domain using the multisite feature of drupal.

I followed all the steps required for drupal multisite as below.

Suppose my existing site url is www.abc.com and I want to make a sub-domain as www.jobs.abc.com

Steps I followed.

Under sites folder I created a new folder jobs.abc.com and copied the default.settings.php file renamed it as settings.php

sites/jobs.abc.com/settings.php

2.My existing domain settings.php file is under default folder sites/default/settings.php

3.I Renamed the example.sites.php to sites.php and added the following two lines.

$sites['www.abc.com'] = 'default';
$sites['www.jobs.abc.com'] = 'jobs.abc.com';

Finally I installed the Multisite wizard module http://ftp.drupal.org/files/projects/multisite_wizard-7.x-1.3.tar.gz

I configured the module it is showing me the message

"Hint: the folders names should be the same as values of domain-folder array in the site.php file
Folders to be created: default,job.abc.com" please find the screenshot.

I have already created these folders there. I am not sure why its showing this message again.

Having the folders that the message states in your sites/ directory involves two basic steps:

Creating the directories
Making the directories visible to the web server

In a typical Ubuntu installation with Apache as your server the first step is accomplished by executing the mkdir command in your sites directory:

Example

cd /var/www/my_drupal_site/sites
mkdir jobs.abc.com

and for the second step using the chown command.

chown -R www-data:www-data default
chown -R www-data:www-data jobs.abc.com

The chown command changes the ownership of the directory and with the -R flag it does the same thing recursively for every contained subdirectory and file. The www-data is the default user and group that Apache runs as (so if you have an nginx setup, you will probably have to change this).


Enable CKeditor on Webform's textarea I'm trying to create a contact form supporting HTML formatting with Webform and CKEditor. So I created a new webform with a single field of type Textarea and now I have a simple webform with the basic textarea.

How can I enable rich text formatting on this form? It doesn't work by default and I cannot find any option to enable it neither in Webform nor CKeditor settings.


Encoding and decoding in Views I have a view that accepts a contexual filter.When I pass a value through contextual filter like view/sometext ,it is passed directly without encoding.I need to encode it in the url and decode it before processing it in the view.How can I achieve this?

In the view's contextual filter, you would need to select 'PHP Code' in the 'Provide a default value'. Then in code you can specify something like:

// get current path
$path = explode('/', current_path());
// make sure the path component exists (replace 1)
if (empty($path[1])) return;
// decode the component (use any function you fancy; replace 1)
return base64_decode($path[1]);

The encoding would happen wherever the link exists. If it is a view, you might need to use a module such as Views PHP in order to rewrite your link.


How to add  to the header I'm attempting to figure out a way to add

<meta http-equiv="X-UA-Compatible" content="IE=edge">

to the header of my pages. I've heard that you could add it in your theme settings but I could not find where that would be located. I also heard you can resolve the issue using template.php in your theme. I've added

<?php
function retheme_alpha_0_2_preprocess_html(&$head_elements) {
    $element = array(
        '#type' => 'html_tag',
        '#tag' => 'meta',
        '#attributes' => array('http-equiv' => 'X-UA-Compatible', 'content' => 'IE=edge,chrome=1'),
        );
    drupal_add_html_head($element, 'chrome_frame');
}

to mytheme/templates/template.php

However it seems to have no effect.

Try this, it works for me, I just tested. I don't think you need #type and http-equiv needs to match in the html head call.

/**
 * Implements template_preprocess_html().
 *
 */
function mytheme_preprocess_html(&$vars) {

    $element = array(
        '#tag' => 'meta',
        '#attributes' => array(
          'http-equiv' => 'X-UA-Compatible',
          'content' => 'IE=edge,chrome=1'
        ),
      );
      drupal_add_html_head($element, 'http_equiv');

}

Beyond that, if it does not work, then you have some other issue. Be sure to clear all caches.


Ensure atomicity of user_save within hook_node_delete In my system, a user has a number of bookings (nodes of content type 'booking') associated. Each of these bookings has a 'field_price' field and a 'field_customer_user' field (for which I am using the Entity Reference module) that links the booking to its customer. The user also has a 'field_bill' field containing the sum of all his bookings' prices.
Each time a booking gets deleted, I want to subtract its price from its user's bill. I'm doing it the following way, using hook_node_delete:
function mysite_node_delete($node) {
   if ($node->type == 'booking') {
     if ($account = user_load($node->field_customer_user[LANGUAGE_NONE][0]['target_id'])) {
       $bill = $account->field_bill[LANGUAGE_NONE][0]['value'];
       $bill -= $node->field_price[LANGUAGE_NONE][0]['value'];
       $account->field_bill[LANGUAGE_NONE][0]['value'] = $bill;
       user_save($account);
     }
   }
}

However, sometimes this does not work as expected. Given the following case:

User booking #1: 100$
User booking #2: 200$
User booking #3: 50$
Total bill: 350$

An administrator logs in and deletes all three bookings for this user sequentially, starting from booking #1 and finishing with booking #3. The user's total bill should be 0 now, but it ends up being

Total bill: 300$.

I guess that this means that when user_save($account) was called for booking #3, the user bill had not been properly updated by the first two calls to hook_node_delete. Therefore, the old value (350$) gets fetched and subtracted the price of booking #3, and end ups being 300$, which is not correct.
Is there anyway of making it work?

user_save() itself is likely to be guaranteed atomic. You're running innodb or equivalent, right?

However, you have no guarantees that the user isn't altered between your user_load() and user_save(), which can cause a race condition. There lock.inc for that.

  A database-mediated implementation of a locking mechanism.

This is very unlikely though, and if this happens to you often and regularly, you likely have a problem elsewhere in your code.

However, not even that can protect you from other parts of the code, in a parallel request, loading up the user, modifying it, and saving it back, in between your calls. For better or worse, you can't reasonably guarantee that no other piece of code, such as contributed modules, modifies your users.

Suggested options:

Modify the field value directly like UPDATE [table] SET [field] = [field] +/- [value]. Then you can rely on the DB's underlying mechanisms for atomicity.
Accept a small risk of failure. Run a hourly cron job to recalculate values, correcting for mistakes.
Don't use a user field for this data. Either use a custom entity, or directly manage a custom table. Force all updates through a lock mechanism.


When the "Body" field is required, how can I force users to input, say, at least 400 characters? For example, this site (Drupal Answers) has this feature-- if you input too little text in the text box, the interface prompts you to write more.  Is there a module to do this?  I tried various searches but I haven't been able to find anything.

You should be able to just use the Field validation module to set a minimum length on the body field.

  This module adds an extra tab to each field instance, allowing you to
  specify validation rules for your field instances.

  By using the hooks provided by this module, you can also define your
  own validation rules in your own modules.


How do I limit the maximum height of an image in signatures? Is there a way to automatically set the maximum allowed height of images in the Signatures for Forums module for Drupal 6? This will greatly help to have a tidy forum.

Under
Home >> Administration >> Site Configuration
Go to Signatures for Forums
Inside template for signature you can set the height inside the div as follows :

%s

Home >> Administer >> User Management

Go to Picture Support option and enable it

After that you will find a field Picture maximum dimensions: where you can set your image maximum height and width
 check the image link


How to limit preprocess functions base on a theme? I'm working on a theme that using hook_preprocess_node and hook_preprocess_page and everything is working fine. However, whenever I go to any admin pages, it's throwing me some errors because the array changes. So what I'm trying to achieve is to add a condition only to run this preprocess function if using my theme.

How can I limit the preprocess function base on my theme?

You can check theme active with function:

<?php

$active = \Drupal::theme()->getActiveTheme()->getName();

Get list all themes with:

<?php

$themes = \Drupal::service('theme_handler')->listInfo()


In Drupal 7 Views what is the php code to validate a field against a contextual filter argument? Currently I am using the path url to pass in arguments:

path: /%/%/%

On the 3rd argument I am loading a Taxonomy term. I also have a field loaded called: field: device type

What do I have to put in my contextual filter validation PHP code? I did a dsm($view), but my device type shows recursion. I'm not sure how to reference the field properly to create a conditional to compare it to the contextual argument.

Below is a code sample of my contextual filter validation code for drupal 7 views 3 validation.

My view contains a page display with the following path set: blog/%/%/%

Here is a sample path argument of what I'm trying to accomplish:
Path URL: blog/7/node-title/taxonomy-name

if ( is_numeric(arg(1)) && is_string(arg(3)) ) {
//check to make sure arg 1 is text and arg 2 is a string

  $node = node_load(arg(1));
//load the node

  $terms = taxonomy_get_term_by_name(arg(3));
//get the terms array and TID from arg 3.

  if (!empty($terms)) {
    $first_term = array_shift($terms);
    foreach($node->field_repair_states_region['und'] as $x => $y) {
      if( $y['tid'] == $first_term->tid ) { return TRUE; }
//make sure the TID matches the TID to the node.

    }
  }
}

Screenshot of Validation Page: http://prntscr.com/1dcl4v

Screenshot of View: http://prntscr.com/1dclly


How can I setup automatic subpages for existing pages using a view with a contextual filter that uses the URL to determine the filter value? I have two content types that are being linked via entity references.

Area of Expertise [Existing URL: /expertise/specific-area-here]
Employee [Desired URL: /expertise/specific-area-here/staff/specific-employee-here]

Employee has an entity reference field that contains all of the areas of expertise and only one value is allowed to be selected.
For example:
I have an area of expertise called "Pathology" and an employee named "John Doe". In John Doe, I select that the area of expertise is "Pathology".
When I'm on the area of expertise page for a particular area of expertise, I am showing all of the employees that specialize in that area of expertise in the sidebar second region. To do that I'm using a view that generates a block. Within the view I have a contextual filter using the following chunk of PHP code to provide the default filter value:
$filterValue = -1;

$node = menu_get_object();

if(!empty($node))
{
    switch($node->type)
    {
        case 'area_of_expertise':
            $filterValue = $node->nid;
            break;
    }
}

return $filterValue;

All of that is working properly.
What I want to do now is have a staff page that shows all of the staff associated with a particular area of expertise. I want the URL to be /expertise/specific-area-here/staff.
For example, if I want to see all of the staff that are associated with the area of expertise called "Pathology" (located at /expertise/pathology) then I would want the staff page to be available at /expertise/pathology/staff.
The issue I'm having is figuring out how to set up the contextual filter such that the "/expertise/pathology" piece of the URL of /expertise/pathology/staff can be processed so that Drupal knows which area of expertise to use to filter.
Also, the breadcrumbs should work as follows:
If I'm on the Pathology area of expertise page, the breadcrumbs should show:
Home > Pathology

If I'm on the Pathology staff page, the breadcrumbs should show:
Home > Pathology > Staff

If I've drilled down into John Doe's page, the breadcrumbs should show:
Home > Pathology > Staff > John Doe

How should I setup the contextual filter to allow this behavior and how should I configure the "Path" under "Page Settings" in the view?

After much trial and error, I found a solution that seems to work for me.

The first thing I had to do was switch from using a "provide default filter value" to specifying custom validation criteria via PHP:

$normalPath = drupal_get_normal_path('expertise/' . $argument);
$urlPieces = explode('/', $normalPath);

if(!isset($urlPieces[1]))
{
    return false;
}

$nodeId = $urlPieces[1];
$node = node_load($nodeId);

if(!empty($node))
{
    switch($node->type)
    {
        case 'area_of_expertise':
            $handler->argument = $node->nid;
            return true;
    }
}

return false;

Thanks to Cameron for the bits about $argument and $handler->argument.

Once I figured out how to use argument to generate the URL which then allowed me to look-up the node ID, I was able to reuse most of the code that I had before in the "Provide Default Value" section.

The next issue was the breadcrumbs. Before I did anything extra, the breadcrumbs were showing as Home >   > Staff. I ended up having to create a new menu item called Staff in the main menu that was a child of Pathology. So then the breadcrumbs showed as Home > Pathology > Staff > Staff which is still not what I wanted.

I found out that views likes to add each contextual filter as a breadcrumb so that you can navigate up and get less and less granular. Normally this would be a nice feature, but I couldn't see any way to turn it off.

So I found a post that detailed how to remove the breadcrumbs which I tried to implement via hook_preprocess_page. This ended up not affecting the breadcrumbs at all because the views module was altering the breadcrumbs after that hook was being run.

Then I found another post that detailed how to affect the breadcrumbs after the view was ready to be rendered using hook_views_pre_render.

So I have the following code as my hook:

function MODULE_views_pre_render(&$vars)
{
    $page = menu_get_item();

    if(($page['page_callback'] == 'views_page') && ($page['page_arguments'][0] == 'staff_cross_reference'))
    {
        $breadcrumbs = drupal_get_breadcrumb();
        array_pop($breadcrumbs);
        drupal_set_breadcrumb($breadcrumbs);
    }
}

And now my breadcrumbs look like Home > Pathology > Staff which is exactly what I want!


Disable emails turned into links but keep urls turned into links Some users on social sites still enter their email addresses on comment fields.
I'm trying to prevent spammers from harvesting them by replacing the @ character with a graphic. That's really easy to do using the smiley module.

However, I use the text filter option "Convert URLs into links" which turns the email into a mailto link. The smiley filter now breaks the HTML.

I would like to not turn emails into links but keep turning urls into links.
How could I do that?

The easiest way is to creat your own input filter. Do a PREG and obfuscate the email address.  Assign this filter to your input formats, and make sure it runs before the URL-to-link one.


How to make a content type a Ubercart product Basically I want to add the "add to cart" button to a content type.
I've got Ubercart installed and enabled.
Normally whilst editing a content type there should be a section
"ubercart product settings" where I can check "products... are shippable"

But there's no such section to make it a ubercart product.

Go to admin/store/products/classes.

From there you'll be able to assign a product class to an existing content type, after which you should see the Ubercart-specific settings on the content type edit form.


How can I Hide in Drupal 7 the bottom blocks in Add and Edit button for my content I made a new content type in Drupal 7 without problems, but now I want to hide the bottom block in the content Add and Edit fonctions
This block as some url's parameters, comments parameters ...I don(t want to show to the users or registered users

I cant't find where and how I mask this blocks,
Thanks for your help

Sorry I have found the answer myself

If I use another login than admin the blocks are not shown,

Sorry


Paragraphs not displaying on front-end I've created some paragraph types and added them to the "basic page" content type. I've filled in some data, but nothing shows up on the front-end. Only the content of ckeditor does. Any idea why this is?

Okay, it can be a few things...

If that twig template is the node, you would not use {{ page.content }}, but rather just {{ content }}. {{ content }} is the entire render array for the node.

If you wanted to split the fields up within the node twig template, you can use the format {{ content.field_foo }}.

It is already set to render the paragraph entity - so this should be all that is needed.

Another thing to check, if {{ page.content }} is totally blank, ensure that the Main page content block is set to output in the Main Content region of your theme.


Including JS files in template.php to control weight/order/group I'm looking to include a few JS files (some libraries, others are custom modules with dependencies on libraries). Originally I had all JS files added through our .info file, and while I could control the order of the files manually my moving them up and down, that would result in all the JS files loading on every page.

Is it a better idea to add JS files through template.php in the template_preprocess_html function? For each JS file I can attach a group property (one of the constants of JS_Library, JS_DEFAULT, or JS_THEME) to control the ordering, and also control which pages need to load which files.

Thoughts?

You can try JS injector module which provides an UI for that


Don't know where 404 error is coming from Don't know where this 404 error "sites/all/modules/lightbox2/images/blank.gif" is coming from. It's on everypage on www.lostinthesmoke.com. Can't find the reference to it in the page source. I don't know if its Drupal or CloudFlare. CloudFlare says its Drupal or my server. I cleared caches everywhere. I had lightbox2 installed a couple months ago but not on this fresh install. I use this domain to learn and test on. It started showing last night.

If you go into inspector, you can see:

<object data="http://www.lostinthesmoke.com/sites/all/modules/lightbox2/images/blank.gif" width="0" style="position: absolute; left: -9999px; "></object>

is being added at the very bottom of your page.  Why?  I dunno, but it's there :)  The fact that it doesn't show up in "view source" suggests it's being added via javascript on page load.

Why isn't it finding blank.gif?  Again, I dunno.  It's here in my lightbox2 directory, so, perhaps your installation has been corrupted and thinks it is still installed.


Is it possible to convert separate (matching) managed files to a single shared file? I'm finishing up a Commerce store that has tens of thousands of imported products. In a slightly simplified form, here's my problem: Each has a unique primary image and a common secondary image. The import has created a separate secondary image of the exact same file for each product, which obviously creates enormous redundancy and uses much disk space unnecessarily.

Is there a safe way to convert all of the secondary images into a single, shared image in the database and filesystem? (I'm envisioning some kind of database SQL to make multiple products reference the same image, and then hoping that Drupal will clean up the orphan files automatically -- am I looking in the right direction?)

(Drupal 7)

For small scale issues of this nature, the Duplicate Images module may be exactly what you need to step through the process of identifying and removing duplicates. (At the moment it bogs down and fails with huge numbers of duplicate images).

  What does this module do?

  In a multi step form (like update.php) this module executes the
  following steps:

  1) Search for duplicates

  Searches are done on the public and/or private file system
  It searches for file names ('filename' as used by pathinfo) that end with _{n} and whose part before that also exists as separate file
  name.
  It compares file size and md5 hash (see md5_file) to determine if these are real duplicates or possible duplicates.
  The results are presented as a list whereby for the possible duplicates clickable thumbnails are shown so you can visually compare
  them. For documents just a clickable icon is shown.

  2) Search for usages

  Look if a managed file record is defined for the duplicate (and the original).
  Searches for references to the managed file in user pictures, all image and file fields, all fields that according to their field schema
  have a foreign key to the file_managed table.
  Searches for URI references to the file or a(n image style) derivative in selected text and link fields.

  3) Update usages

  Found references to the managed file record are updated to refer to the managed file record of the original (or if that does not yet
  exist, the uri field is simply updated).
  Found textual usages are changed to refer to the URI of the original document.
  Note 1: this phase uses the entity_save() function of the entity api (contrib and thus a dependency) to ensure that caches are cleared,
  hooks are called, file_usage is update, rules are executed, etc.
  Note 2: this phase does keep track of failed updates so that the next phase can skip managed file records or files that are still being
  referred to.

  4) Delete duplicates

  All managed file records that are no longer referred to are deleted.
  All duplicate files that ar no longer referred to are deleted.


How do I avoid editing Drupal core? I was building an exchange with a partners XML service, and I couldn't get the XML right, but as with all things Drupal, the xmlrpc error and action logging is less than robust.

So I did this in includes/xmlrpc.inc.

function xmlrpc_request($method, $args) {
  $xmlrpc_request = new stdClass();
  $xmlrpc_request->method = $method;
  $xmlrpc_request->args = $args;
  $xmlrpc_request->xml = <<<EOD
<?xml version="1.0"?>
<methodCall>
<methodName>{$xmlrpc_request->method}</methodName>
<params>
EOD;
  foreach ($xmlrpc_request->args as $arg) {
    $xmlrpc_request->xml .= '<param><value>';
    $v = xmlrpc_value($arg);
    $xmlrpc_request->xml .= xmlrpc_value_get_xml($v);
    $xmlrpc_request->xml .= "</value></param>\n";
  }
  $xmlrpc_request->xml .= '</params></methodCall>';

  /* This part here */
  watchdog('xmlrpc',$xmlrpc_request->xml);
  /* End ridiculously tiny hack */

  return $xmlrpc_request;
}

I got the data I needed and in 10 minutes had the partner interface responding appropriately to my request because (shocking I know) logs are good.

I like the extra logging, and I want to keep it. What is the clean, straightforward, and most importantly, Drupal-approved way of doing that?

Hacking core is strongly discouraged for the uninitiated because it effectively reduces the support community of thousands to a support community of one (or whatever your team size is). Without this best practice, helping those new to Drupal would be nigh impossible. It also hinders modularity and, in some cases, security.

This having been said, hacking core is not always as evil as we like to make it out to be. Without modifying core, we wouldn't have distributions like Pressflow and the like that augment core in interesting ways. It's just vitally important that you know exactly what you're doing, that you're distributing your patches with your distribution (preferably in a way that allows you to apply them again automatically post-upgrade), and that you're keeping detailed documentation of what you've changed and why you've changed it.

Depending on how you have things structured, you could certainly make the above change to xmlrpc_request(), create a patch, and then use something like Drush Make to automate applying it (note that Drush Make is moving  into the Drush project itself for the 5.x release), while supplying additional documentation in the makefile and elsewhere as to what the change does and why it's necessary/desired.

Another common pattern to enhance core functions is to create a wrapper that adds a tiny bit of functionality to a core function, and call the wrapper in lieu of core's implementation. When feasible, this makes things much more modular. Consider the following:

/**
 * Wrapper function for xmlrpc_request() to provide logging.
 */
function mymodule_xmlrpc_request($method, $args) {
  $xrr = xmlrpc_request($method, $args);
  watchdog('xmlrpc', $xrr->xml);
  return $xrr;
}

Again, depending on what you're doing this may or may not be feasible, but when it is you've saved yourself a few headaches in trying to make sure that core stays patched and documented. Though in this case, a one-off function like this seems like a perfect candidate for such a wrapper. If your implementation is captured in a module, you could even expand on it to control the log level of your entire solution, disabling this functionality on production sites:

/**
 * Wrapper function for xmlrpc_request() to provide logging (if enabled).
 */
function mymodule_xmlrpc_request($method, $args) {
  $xrr = xmlrpc_request($method, $args);
  if (variable_get('mymodule_log_level', 0) > 0) {
    watchdog('xmlrpc', $xrr->xml);
  }
}

In short, you want to maximize what you can do with modules (and you can do a lot), but there are legitimate reasons for altering core. It should be done with care, that's all.


Is it possible to have a dynamic route as configure module page? I installed the SEO Checklist module and when I go the search in the Extend (admin/modules) page the module Configure page I don't see it, so I go the the module issue an create a new issue Add link to configure page to solve the problem, I thought at the end this will be very easy, the page exists (admin/config/search/seo-checklist) so, is just search the route and add it to the .info.yml file.

But when I start to check the module files I see that the .info.yml file have the configure page defined with the same route that have as url admin/config/search/seo-checklist

configure: checklistapi.checklists.seo_checklist

So I start to dig a little in the code and I found that this route checklistapi.checklists.seo_checklist is defined dynamically in the Checklist API module

  $routes["checklistapi.checklists.{$id}"] = new Route($definition['#path'], [
    '_title' => (string) $definition['#title'],
    '_form' => '\Drupal\checklistapi\Form\ChecklistapiChecklistForm',
    'checklist_id' => $id,
    'op' => 'any',
  ], $requirements);

I'm missing something here or is not possible to have a dynamic route as configure module page?

It is possible to use any route for the configure link, as long as all route parameters are satisfied (parameters can be specified via configure_parameters).

In the case of the above bug, the access check was failing, preventing the link from displaying.

The problem was solved in: ChecklistapiAccessCheck looks in the wrong place for 'checklist_id' and 'op'


Media 7.0-2.x and Plupload Is there any combination of Media module in version 2.x for Drupal 7 which works with Plupload Integration of any version?

I installed the newest dev versions of File entity, Media and Plupload but they don't work togheter.

Is there any other Bulk upload for Media which already works with version 2.x?

Are there any patches I can apply to get Media togheter with Plupload working?

It's been a little while for me and it was tricky at the time, but enabling these modules should help:

Multiple Forms
Media Multiselect (provides a "Media Multiselect" widget instead of the standard Media Browser)

There was an additional patch to Media and a plethora of other issues (mostly related to permissions and editing files) that I noted as resolved as of 2014-Sep.

As you point out in the comments, a patch to the Media Multiselect module was still required to get the most recent dev versions of Plupload and Media 2.x working together by changing the widget type to that provided by Media Multiselect:

Patch (required for now but under review): Issue #2216273: Latest media changes break the multiselect (Comment #52)

Cheers -


field_deleted_date_N and field_deleted_revision_N not removed on cron run or field_purge_batch() I am running a site on D7. I noticed a no. of field_deleted_data_N and field_deleted_revision_N tables in my database. Through a lot of googling I found people saying that these tables will eventually be cleared on cron run. They also said you could run field_purge_batch().

However neither of there suggestions worked. Could somebody please help me solve this problem? Why are these fields never removed? Is there something wrong with my database? How can I remove them in a drupallish manner?

Thanks.

If drush doesn't help and running cron doesn't help, that might mean that the field data can't be purged because the module providing the field type has been disabled and / or uninstalled.
In that case just drop the tables manually.


Node paths with custom prefix based on taxonomy I have a "category" field attached to the "article" content type that is a taxonomy term reference. I want to setup path auto to create a path wich is prefixed based on the category. My problem is that i.e.: I have a category called "Interesting facts", path auto will create a path /interesting-facts/node-title but I want to have /facts/node-title And I could change the taxonomy term to "Facts", but the taxonomy term index page would show "Facts" too, but I want it to remain "Interesting facts".

So basically I want to customize prefixes, without changing the taxonomy terms. Is that possible?

Create a new field on the Category Taxonomy called something like "Title Prefix" and then use this Field to create a custom path for the article


How do I redirect back to the source page after the user submits a comment? How can I access the nid of the current page so that a user can submit their comment and be returned back to the page they just commented from. Here's what I am proposing...

function mymodule_form_comment_form_alter(&$form, &$form_state) {
  $nid = arg(2);
  $form_state['redirect'] = 'mymodule/' . $nid;
}

...to be placed in template.php. However using $node -> nid (referenced in comment.module) or $nid (referenced in my custom module) throws an undefined error. How can I access the nid to complete my redirecting URL? Or is there a better way of acheiving this?

I believe this is the part of comment.module that I need to hook into and modify - so in a wider sense my question is about hooking into a core module and modifying its function:

/**
 * Process comment form submissions; prepare the comment, store it, and set a redirection target.
 */
function comment_form_submit($form, &$form_state) {
  $node = node_load($form_state['values']['nid']);
  $comment = comment_form_submit_build_comment($form, $form_state);
  if (user_access('post comments') && (user_access('administer comments') || $node->comment == COMMENT_NODE_OPEN)) {
    // Save the anonymous user information to a cookie for reuse.
    if (user_is_anonymous()) {
      user_cookie_save(array_intersect_key($form_state['values'], array_flip(array('name', 'mail', 'homepage'))));
    }

    comment_save($comment);
    $form_state['values']['cid'] = $comment->cid;

    // Add an entry to the watchdog log.
    watchdog('content', 'Comment posted: %subject.', array('%subject' => $comment->subject), WATCHDOG_NOTICE, l(t('view'), 'comment/' . $comment->cid, array('fragment' => 'comment-' . $comment->cid)));

    // Explain the approval queue if necessary.
    if ($comment->status == COMMENT_NOT_PUBLISHED) {
      if (!user_access('administer comments')) {
        drupal_set_message(t('Your comment has been queued for review by site administrators and will be published after approval.'));
      }
    }
    else {
      drupal_set_message(t('Your comment has been posted.'));
    }
    $query = array();
    // Find the current display page for this comment.
    $page = comment_get_display_page($comment->cid, $node->type);
    if ($page > 0) {
      $query['page'] = $page;
    }
    // Redirect to the newly posted comment.
    $redirect = array('node/' . $node->nid, array('query' => $query, 'fragment' => 'comment-' . $comment->cid));
  }
  else {
    watchdog('content', 'Comment: unauthorized comment submitted or comment submitted to a closed post %subject.', array('%subject' => $comment->subject), WATCHDOG_WARNING);
    drupal_set_message(t('Comment: unauthorized comment submitted or comment submitted to a closed post %subject.', array('%subject' => $comment->subject)), 'error');
    // Redirect the user to the node they are commenting on.
    $redirect = 'node/' . $node->nid;
  }
  $form_state['redirect'] = $redirect;
  // Clear the block and page caches so that anonymous users see the comment
  // they have posted.
  cache_clear_all();
}

Thanks.

To redirect a form after submission you would do this:

/**
 * Implements hook_form_FORM_ID_alter().
 */
function MYMODULE_form_comment_form_alter(&$form, &$form_state) {
  // Add a custom submit handler to act when the form submits.
  $form['#submit'][] = 'MYMODULE_custom_comment_submit_handler';
}

/**
 * Custom submit handler for the comment form.
 */
function MYMODULE_custom_comment_submit_handler($form, &$form_state) {
  // Redirect the user after submission
  $nid = arg(2);
  $form_state['redirect'] = 'mymodule/' . $nid;
}


How do I automatically approve a user account in Drupal 7 based on a rule I would have thought that I could find the answer to this by just googling but here I am...

In Drupal 6 it appears that you could setup user access rules in core to do this.  So for example approve accounts that match the rule: %@email.com, which would approve any email.com address.
http://drupal.org/getting-started/6/admin/user/rules

Does anyone know how to do this in Drupal 7.  I would also like to be able to automatically assign a role to the account.

Thanks for your help!

I'm pretty sure you can do that with rules in D7:

Event: "After saving a new user account".

Condition: "data comparison" on "account:mail" contains "@email.com".

Actions: "Unblock a user" and "add user role"

I personally like this tutorial by node.se.


Is a block changed programmaticaly with hook_block_view_alter cached? I have a lateral section which will be different for every page in my site, but the content is practically unaltered for every single page.

I had the intention of using hook_block_view_alter. I would create an empty block in the region, and would fill the content dinamically with PHP in a hook in a custom module.

Will the content be cached or should I better create different blocks for every single page and change the content only if the content changes?

hook_block_view_alter() isn't going to affect the cache settings for the block automatically, though you can find a way if you really want to as Molot points out below; typically you use hook_block_info_alter() to change the cache settings for a block:

function mymodule_block_info_alter(&$blocks, $theme, $code_blocks) {
  $blocks['block']['my_block_id']['cache'] = DRUPAL_CACHE_PER_PAGE;
}

Here, DRUPAL_CACHE_PER_PAGE will cache your block for each page, which could be quite a bit better than not caching at all and creating the content dynamically for each page. If you need dynamic content every time, choose DRUPAL_NO_CACHE. Clear the block cache to make Drupal aware of your new settings.

But! If you are prepared to have a custom module to run alter hooks, consider writing a block from scratch. If you are going to have a custom block, I feel that it helps if it is impossible to accidentally delete in the Drupal UI.

To implement a basic block you need hook_block_info and hook_block_view.

hook_block_info is where you tell Drupal that the block exists and how to cache it:

function mymodule_block_info() {
  $blocks['myblock'] = array(
    'info' => t('My Awesome Block'),
    'cache' => DRUPAL_CACHE_PER_PAGE,
  );
  return $blocks;
}

Next, hook_block_view does the work of generating the content. I find that assigning the content to a callback makes my code easier to read, but do what works for you. Using switch() makes it easy to add more blocks to your module later on.

function mymodule_block_view($delta='') {
  $block = array();

  switch ($delta) {

    case 'myblock':
      $block['subject'] = t('My awesome block');
      $block['content'] = mymodule_some_function_to_build_the_block_content();
      break;

  }

  return $block;
}


show/hide a menu item based on specific user role I have a certain number of main menus which need to showcased based on logged in user role.
for example user with the role, A can sees few menus and user with the role B, sees another set of few menus.

All you gotta do is configure your menu block

Then under Visibility > Roles, check mark ☑ the roles that you want to be able to view this block menu.


Views slideshow won't show "slideshow" display format (commerce kickstart) My Views slideshow won't give me the option to show my content as a slideshow (when creating block or page).

I have Libraries, Views 3.X, Views Slideshow, Ctools, ... all the requirements and both Views Slideshow and Views Slideshow Cycle is enabled. Still it isn't giving me the option.

Anyone who has any idea why?

Fixed this myself.

I am working with commerce kickstart and instead of adding it to the regular modules, added it to the kickstart ones (contrib). Also added the jquery.cycle library there (in libraries though) and then cleared the cache just to be sure.


Avoid caching a JavaScript file when the page cache is on So I have a custom block that shows a div and a JavaScript (tried inline and file), while page cache is on.
JavaScript loads a uncacheable token got generated through a php function called within block view.
I tried using drupal_add_js to pass parameter to setting and on second drupal_add_js to load file and set cache to false. But setting get cached and provide cached parameter to JavaScript which i dont want.

drupal_add_js('var videoPlayer = Player.create("' . $container_id . '",' . '"' . $embed_code . '", ' . $params . ');',
        array(
          'type' => 'inline',
          'async' => TRUE,
          'scope' => 'footer',
          'cache' => FALSE
        )
      );

drupal_page_is_cacheable(FALSE);

Is what you're looking for.


Can I make Drush use a pattern to name sql-sync dump files? I'm using Drush to sync up my dev, staging and live sites using rsync and sql-sync. I want sql-sync to create a dump file named using a pattern. For example, I want the dump file to be named site_database_name__date_time. Looking in example.drushrc.php I saw you can use @DATABASE and @DATE for the --result-file option in sql-dump. I tried using the same pattern in my site alias definition but it didn't quite work. The dump file is created properly, using the replacement pattern. But when it tries to restore the database to the target site it throws an error saying there's no such file as "@DATABASE_@DATE.sql". So it's not making the replacement when it does the restore phase of sql-sync. Is there a way to get this to work? Or am I taking the wrong approach here?

I realize the sql-sync documentation references a "temp" directory for these dump files, implying they aren't meant to be kept around. My thought is to keep them around for a record of what was used for each sync in case something goes wrong.

Below is an example of the site alias I'm using, which specifies the %dump path alias used by sql-sync.

$aliases['dev'] = array(
  'uri' => 'dev.example.com',
  'root' => '/home/websites/dev.example.com',
  'path-aliases' => array(
    '%files' => 'sites/files',
    '%dump' => '/home/username/tmp/drush/@DATABASE_@DATE',
  ),
  'command-specific' => array (
    'sql-sync' => array (
      'simulate' => '1',
      'structure-tables' => array(
        'custom' => array('cache', 'cache_filter', 'cache_menu',
          'cache_page', 'history', 'sessions', 'watchdog'),
      ),
    ),
  ),
);

If you use the '%dump-dir' directive, then drush will create a name for your dump file based on the name of the remote host and the name of the database.  It is best to not include the date in the database name for remote sql-syncs, because the rsync operation will be faster if it can update only the incremental changes in the database dump, and this of course would not be possible if the filename changed on every operation.

If you want the date to appear in the database dump's filename so that it can also serve as a backup of your drupal site, you must also be careful to back up the files at the Drupal root as well.  It is common for Drupal to simply fail (with errors or even a WSOD) if you try to use an sql database with a different version of the code (core or contrib) than was used to create the database.

An easy way to backup your database and files together is with the drush archive-dump command, which also has a convenient archive-restore command to go the other way.

Some combination of the above is probably a better solution than what you are trying to do in your question above.  The exact feature you are looking for is not currently supported in drush.  We could certainly consider feature requests to add that capability (ideally posted to the drush issue queue with a proposed patch already attached -- see function drush_sql_dump_file in commands/sql/sql.drush.inc), but there may be some reluctance to accept it, since the alternatives already described are probably better in most instances.


Manual ajax callback on saved dropdown value Normally the #ajax property of a form item launches a ajax callback. So when you select an item of a drop-down menu it will be triggered.

In this case I use variable_get() to see if the drop-down menu value has already been saved on that admin page. If it is I use it as the default value. But in that case what does not happen is the ajax call that is associated with that value.

So this is what I would like to have:

if(isset(variable_get('dropdown_value'))) {
  // Manually call ajax callback function, just like the one in $form[item][#ajax][callback].
}

Does anybody know how to do this? I would prefer to use php instead of JavaScript.

If I understand correctly, anything that can query a URL would do, for example Curl.


Help creating action Here is the code I currently have:

function mymodule_action_info() {
  return array(
  'mymodule_send_mail_admin_action' => array(
  'type' => 'node',
  'label' => t('Send a mail to administration warning insertion and deletion of nodes.'),
  'configurable' => FALSE,
  'triggers' => array('node_insert', 'node_delete'),
  ),
);
}

function mymodule_send_mail_admin_action($object, $context) {

if ($context['hook'] == 'node_insert') {}

//if ($context['hook'] == 'node_delete') {}
    }

What should I put inside the mymodule_send_mail_admin_action function? How should I complete it?

Note: I need to write a function for this (not use rules).

You don't need to create this action programmatically. You can simply use the Rules UI.  I'm pasting an export of a sample Rule that does this. You can import it using the Rules UI import link.

{ "rules_email_administrators_when_new_node" : {
    "LABEL" : "Email administrators when new node",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "ON" : { "node_insert" : [], "node_delete" : [] },
    "DO" : [
      { "mail_to_users_of_role" : {
          "roles" : { "value" : { "3" : "3" } },
          "subject" : "Node added or modified.",
          "message" : "Hi, administrator(s),\r\n\r\nA node has been added or deleted.\r\n\r\nNode ID: [node:nid]\r\nNode title: [node:title]\r\n\r\n"
        }
      }
    ]
  }
}

EDIT: Now, if you MUST do this programmatically, I would first look at the Examples for Developers project (it contains an action example). In a nutshell:

First, I would use dpm($context); and 'dpm($object); to see what parameters are being passed to the function. You can probably use some of the information there to include in the email, like the node ID and the author ID.
Then I would load an array of administrator users, maybe using EntityFieldQuery or a db_query.
Then I would use drupal_mail() to send the email. It shouldn't be hard to do.


Running a Script with Job Scheduler API I am trying to use the Job Scheduler Module's API to automatically run a script every 6 hours but I'm having problems getting it working.

This is the code:

function jobbank_cron_job_scheduler_info() {
  $schedulers = array();
  $schedulers['custom'] = array(
    'worker callback' => 'custom_job',
    'jobs' => array(
       array('crontab' => '6 * * * *', 'periodic' => TRUE),
    )
  );
  return $schedulers;
}

function get_job_bank() {
  //Save the (long) job bank URL
  $jobBankURL = "https://www.jobbank.gc.ca/xmllite/en/?q=city_id:33821";
  $jobURL = "https://www.jobbank.gc.ca/xmllite/en/";
  $jobs = [];
  $jobInfo = null;

  //Get the XML data into an object
  $jobsInfo = simplexml_load_file($jobBankURL);

  //Send a message and exit if it fails getting the XML
  if($jobsInfo === false) {
    mail ('webmastercolin@gmail.com',
          'Job Central SM Job Bank CRONjob issue',
          'Getting the $jobsInfo XML data failed (line 9) at '.date('H:i:s \o\n F j, Y'));
    exit();
  }

  //Iterate through the objects
  foreach($jobsInfo->Documents->Document as $job) {
    //Get the job data from Job Bank
    $jobInfo = simplexml_load_file($jobURL.$job->jobs_id.".xml");

    //Grab just the information for the job and put it in the array
    $jobs[] = $jobInfo->Documents->Document;
  }

  //Encode the array as JSON
  $json = json_encode($jobs);

  //Send a message and exit if it fails encoding the JSON
  if($json === false) {
    mail ('webmastercolin@gmail.com',
          'Job Central SM Job Bank CRONjob issue',
          'JSON encoding the array failed (line 23) at '.date('H:i:s \o\n F j, Y'));
    exit();
  }

  //Save new data to json file, overwriting existing
  $writeResult = file_put_contents($base_path . 'sites/default/files/jobbank/job-bank-data.json',$json,LOCK_EX);

  //Send a message and exit if overwriting the file failed
  if($writeResult === false) {
    mail ('webmastercolin@gmail.com',
          'Job Central SM Job Bank CRONjob issue',
          'Writing to the JSON file failed (line 31) at '.date('H:i:s \o\n F j, Y'));
    exit();
  }

  //Send a message on success, we are done
  mail ('webmastercolin@gmail.com',
        'Job Central SM Job Bank CRONjob Success!',
        'JSON creation succeeded at '.date('H:i:s \o\n F j, Y'));
  exit();
}

I appreciate the help.

If you want to schedule it every 6 hours, then it's 'crontab' => '0 /6 * * *'
The README.txt contains examples:

 /* Declare scheduler. */

  function example_cron_job_scheduler_info() {
    $schedulers = array();
    $schedulers['example_unpublish'] = array(
      'worker callback' => 'example_unpublish_nodes',
    );
    return $schedulers;
  }

 /* Add a job. */

  $job = array(
    'type' => 'story',
    'id' => 12,
    'crontab' => '0 /6 * * *', // I changed this line.
    'periodic' => TRUE,
  );
  JobScheduler::get('example_unpublish')->set($job);

 /* Work off a job. */

  function example_unpublish_nodes($job) {
    // Do stuff.
  }

 /* Remove a job. */

  $job = array(
    'type' => 'story',
    'id' => 12,
  );
  JobScheduler::get('example_unpublish')->remove($job);

'worker callback' => 'custom_job' it's bad practice to not include the name of your module in your callback. This is to prevent collisions. You should name it module_name_custom_callback. In your case it would be 'callback' => 'jobbank_custom_job'

The Job Scheduler is only going to schedule it, not run it. It will get run whenever cron runs. So if you have cron run set to once a day, it will only run your scheduled task once a day. Therefore, you will have to set cron to run every 6 hours or fewer.

Alternatively, I suggest you use a module like Ultimate   Cron which allows you to schedule different cron run times for different cron tasks. So you can set it to every 6 hours here.

This is the proper Drupal way to programmatically send e-mails How to programmatically send an email?