Theming Node Edit Forms I'm having an issue with theming our node edit forms. We are converting a Drupal 6 theme to Drupal 7 and its causing a lot of problems.

In our template.php we have

function dupublic_theme($existing, $type, $theme, $path) {
    return array(
            'page_node_form' => array(
                    'arguments' => array('form' => NULL),
                    'template' => 'page-node-form',
                    'render_element' => 'form',
            ),
    );
}

This successfully points Drupal at 'page-node-form.tpl.php'

Our goal is to pull out some fields into labeled areas to make our editor's job easier. We had a more complex layout, but I've simplified it for the following example.
In page-node-form.tpl.php I have the following:

    <?php print drupal_render($form['title']);?>

    <?php print drupal_render_children($form); ?>

This, however, does not work. $form does not appear to exist, and dpm($form); displays as an empty array. We do not get any form fields at all - unless I remove everything from the tpl file, then I get some sort of default form display, which doesn't make sense. If the tpl file is empty no form should be displayed, but everything I am reading states that drupal_render($form['field']) and drupal_render_children($form) should work! They aren't!

This is what is rendered on page load:

<form class="node-form node-page-form" action="/node/5/edit" method="post" id="page-node-form" accept-charset="UTF-8" data-thmr="thmr_33">

</form>

As you can see, no form fields!

In your template.php the hook_theme implementation should look like that:

function dupublic_theme($existing, $type, $theme, $path) {
  return array(
    'page_node_form' => array(
      'template' => 'page-node-form',
      'render element' => 'form',
    ),
  );
}

Notice that in the return array 'render element' key is without underscore, and there is no 'arguments' key in Drupal 7 version of hook_theme(). It is replaced by 'variables' key, but the documentation states that:

  Each information array must contain either a 'variables' element or a
  'render element' element, but not both. Use 'render element' if you
  are theming a single element or element tree composed of elements,
  such as a form array, a page array, or a single checkbox element.

Another point that I notice is, that you used in your page-node-form.tpl.php file statements like:

<?php print drupal_render($form['title']);?>

I prefer to print the elements like that, and recommend you to do so:

<?php print render($form['title']);?>

It's a new function in Drupal 7 and it calls drupal_render() but first checks if the passed element is an array and also calls show() function if the element is set hidden.


Change workflow default state with hook_form_alter() How can I programmatically access and alter the Workflow module settings with hook_form_alter() on a node edit form?

I can see the Workflow] module settings in its own field-set on the node edit form, but I cannot find any mention of it when I look at the output of dd($form), dd($form_state), or dpm($form).

I would have expected to find it somewhere similar to the following.

$form['edit_workflow']['value'];

It seems your implementation of hook_form_alter() runs before the one provided by the Workflow module. Implement hook_module_implements_alter() to change the order in which implementations of hook_form_alter() are executed. Alternatively, give your module a higher weight than the Workflow has.

Beware that this approach does not work for changing the order of implementations of hook_form_FORM_ID_alter() specifically. Implementations of hook_form_FORM_ID_alter() are always executed in the same order as those of hook_form_alter(). This is due to the way how drupal_prepare_form() calls drupal_alter().


Creating redirects for files (images) on Pantheon What is the best way to create 301 redirects on Pantheon for file?  I can create redirects for paths by placing rules in my settings.php:

switch ($_SERVER['REQUEST_URI']) {
  case '/my-path':
    header('HTTP/1.1 301 Moved Permanently');
    header('Location: http://mydoamin/my-new-path');
   exit();
}

This is the redirect I want to create:

a/b/c/document.pdf and e/f/g/document2.pdfboth should be redirected to /new/folder/document3.pdf.

Unfortunately, this won't work with files.

Here is how I test:

Create file test.txt in sites/default/files
Access sites/default/files/test.txt and verify it works
Update settings.php and add die($_SERVER['REQUEST_URI']); and verify you the get uri.

Instead of getting URI I get 404.

Thanks to Sarah at Pantheon for walking me through this.

File redirects aren't really possible using the same logic used to do PHP redirects for URLs.  Requests to files are managed by the server and don't run through settings.php (Drupal) or wp-config.php (WP).  It is not possible to intercept those like a URL served by the application.

If you were running your own nginx server you could manage this in a .conf file, but on Pantheon the nginx.conf isn't editable on a per-site basis since it's set platform-wide (https://pantheon.io/docs/platform-considerations/#nginxconf)

A workaround could be to utilize a third-party CDN like Cloudflare to create nginx-like redirects before you hit the server.


How to hide exposed sort if view return empty result? I have a view with an exposed filters and sorting. They are displayed as a separate block.

I want to hide only sorting widget if view return empty result (filters must left)

How to achieve this?

The problem is that when exposed form is rendered its view isn't executed yet - so i can't determine if view has any result.

In views-view.tpl.php, just replace this code

<?php if ($exposed): ?>

      <?php print $exposed; ?>

  <?php endif; ?>

with

<?php if ($exposed && $rows): ?>

      <?php print $exposed; ?>

  <?php endif; ?>

Cheers


Change the warning message how to change the message "you must be logged in to place an order." I can not find in the rules and in the translation? thank you

In that case, what you'll want to do is set this variable: commerce_checkout_redirect_message. This variable is used by the module to populate the message.

For example:

variable_set('commerce_checkout_redirect_message', 'You must log in to continue.');


How to download webform data to an Excel file? I'm using the Webform module (version 7.x-4.8), which I only enabled (I didn't change any configuration). I have 10 records in the database.

I want to download the data from Webform to an Excel file, using the typical screen to do so, as in this screenprint:

I tried using these Export Formats:

Microsoft Excel: I can't open the download with with Microsoft Excel 2007.
Delimited text: No data in the file.

I also tried using these Download Range Options (which didn't help either):

Set All submissions (10 total).
Set Submissions by number from '1' and optionally to:(blank).

Any suggestions about what the problem might be?

Above the Download button,you can select range option from here.


drupal_get_path() not working in subdirectories of my site So I'm using drupal_get_path() within a block to reference an image in my themes//images directory.

And this works. At the root and all first level pages. example.com, example.com/about, etc.

However, if I am on a page such as example.com/about/csa:

Instead of continuing to output the filepath as /sites/all/... it outputs the file as //sites/all/...

This only happens when I'm in a subdirectory of the site.

Does anyone know why this might happen?

EDIT:

<?php $src = drupal_get_path('theme', $GLOBALS['theme']) . '/images/carrots.png';
echo '<img src=' . $src . ' alt="carrot background image" >'
?>

Its because drupal_get_path returns relative path.

Try this:

<?php
  global $base_path;
  $src = $base_path . drupal_get_path('theme', $GLOBALS['theme']) . '/imag/carrots.png';
  echo ''
?>

Edit with url function:

<?php
  $src = url(drupal_get_path('theme', $GLOBALS['theme']) . '/imag/carrots.png');
  echo ''
?>


How can I use Drush to sanitize a database on a remote server? I'm on Pantheon and I want to run some custom SQL queries to sanitize my dev server.

I have the queries in a file, custom_sanitize.sqlqueries.

It looks something like this:

UPDATE user__field_useragent SET field_useragent_value = 'Sputnik';
UPDATE node__field_useragent SET field_useragent_value = 'Sputnik';
UPDATE node_revision__field_useragent SET field_useragent_value = 'Sputnik';

TRUNCATE TABLE watchdog;

Goal

I want to run these queries on a remote server with a single Drush command.

My Current Workaround

I connect to the database with Sequel Pro, cut and paste the queries in, and run them.

What I tried

Based on the Drush 8 sql-query documentation, I tried to execute my file like this:

drush @alias.dev sql-query --file=custom_sanitize.sqlqueries

This fails:

failed to open stream: No     [warning]
such file or directory drush.inc:904

I assume this is because my local drush calls the remote drush on the server, and the file path is different.

So then I tried to input the content of the file this way:

`drush @alias.dev sql-connect` < custom_sanitize.sqlqueries

This fails with the following message:

-bash: PTY: command not found

So then I tried inputting the queries in at the command line:

drush @alias.dev sql-query "UPDATE node_revision__field_useragent SET field_useragent_value = 'Sputnik';TRUNCATE TABLE watchdog;"

This also fails:

PTY allocation request failed on channel 0
Command not supported as typed.

I also tried using hook_drush_sql_sync_sanitize(), but I couldn't get my hook picked up by the drush on Pantheon.

You can use sql-cli command for that:

  drush @alias.dev sql-cli < custom_sanitize.sql


Views Custom Contextual filter How to create custom contextual filter for views using views api.

I have a custom table which is having some statistics data about the user. The user id is also stored in the table.

I managed to get the results using views api, Now I would like to use the contextual filter on the logged-in user, this is where I got interrupted. The contextual links are empty, its not showing any filters I can use of. How do I get contextual filters working using views api?

did you implement hook_views_data and then defined you table there? if yes then did you define relation for uid?
you can copy code from views/modules/node.views.inc

  // uid field
  $data['node']['uid'] = array(
    'title' => t('Author uid'),
    'help' => t('The user authoring the content. If you need more fields than the uid add the content: author relationship'),
    'relationship' => array(
      'title' => t('Author'),
      'help' => t('Relate content to the user who created it.'),
      'handler' => 'views_handler_relationship',
      'base' => 'users',
      'field' => 'uid',
      'label' => t('author'),
    ),
    'filter' => array(
      'handler' => 'views_handler_filter_user_name',
    ),
    'argument' => array(
      'handler' => 'views_handler_argument_numeric',
    ),
    'field' => array(
      'handler' => 'views_handler_field_user',
    ),
  );


What would make all content of a certain type return a 404 on the node page? When trying to view/edit nodes of Content Type X, drupal returns a 404 - Not Found. All other content on the site (content of other node types) seems unaffected.

To eliminate other issues with clean URLs, path or path auto, I'm using the q param to access the nodes (example.com?q=node/123, example.com?q=node/123/edit), so it's not something silly like that (not likely anyway since all of the other site content renders fine at the expected URLS).

To be clear, drupal seems completely unaware of these nodes. Filtering by this content type on the admin/content/node page returns "No posts available". However, I happen to have a Views Bulk Operation view that modifies a CCK field for these nodes and that page does show all of them with the proper titles and everything. Trying to modify that CCK field with the VBO has no effect though (the field is not updated).

What I was doing before this happened:
I recently installed a new theme. Unfortunately, I can't confirm or deny that this started happening as a direct result of the theme. I would expect any error caused by this to result in 500 errors anyway. Or possibly 403 errors because I do use drupal_access_denied() in some custom modules - but not drupal_not_found().

What I have looked into while troubleshooting:

The node table looks fine. The rows referring to these nodes remain and appear unchanged.
All of the CCK tables (content_type_x, content_node_field, content_field_abc, etc) look fine.
The menu_router table rows for node/%, and node/%/edit are fine (but like I said, this is just one content type and I would think that something wrong with those rows would break all content types). (All of these database checks seem unlikely anyway since I haven't touched the DB directly or modified much of anything recently.)
I have rebuilt the permissions on site content (/admin/content/node-settings/rebuild).
The watchdog table records the 404, but nothing else.
The Status Report page is all green.

I realize that this is a pretty esoteric question, but I'm hoping something in the above rings a bell with someone.

This site is (still) running on Drupal 6.

The author of the nodes in question (just happened to be the same author for all of the nodes in this content type) was missing from the user table. To be clear, the user was not properly deleted - the row was simply removed from the database.

I'm guessing that this caused the db_fetch_object() function to fail within node_load() when it tried to JOIN the user table on the nonexistant uid:

$node = db_fetch_object(db_query('SELECT ' . $fields . ' FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid WHERE ' . $cond, $arguments));

But it failed completely silently - I that's guess because this scenario would never happen if the user had been deleted properly (Drupal 6 automatically sets the Author of all content created by a deleted user to Anonymous (uid == 0).

Lot's of red herrings while troubleshooting, but maybe this will help someone in the future that doesn't realize they're using a half-sanitized database.


Using computer's proxy settings Currently I'm manually putting my local environment proxy settings in my settings.php file like so:

 $conf['proxy_server'] = '192....';
 $conf['proxy_port'] = ####;
 $conf['proxy_username'] = 'myusername';
 $conf['proxy_password'] = 'mypassword';
 $conf['proxy_user_agent'] = '';
 $conf['proxy_exceptions'] = array('127.0.0.1', 'localhost');

This works, but I work with a team, and the others on my team can see my login info when they enter the settings.php file. Plus when I change my password, I need to remember to change it here.

We're using Windows 7 machines. How could I make it so that Drupal automatically uses the logged-in user's credentials (like the way browsers seem to do) instead of hard-coding them into the settings.php file?

Sharing settings.php isn't good practice at the best of times.

Instead, it would be better to make that file specific to your own machine, and exclude it from version control. Have the rest of your dev team do the same. Then the problem is mostly solved, and you'll find it impossible to accidentally overwrite a production site's settings.php as a bonus.

Regarding automatically updating when you change your password - I think you're out of luck.

The way drupal_http_request() uses the proxy vars means you need to provide URL, username and password in plaintext as variables (i.e. the $conf array). I may be wrong, but I don't think you can get at those system credentials through PHP. Perhaps there's an extension that provides it, but I haven't come across one before. I'm almost positive core PHP doesn't have anything useful anyway.


Automatically adding paid membership products based on field values with Ubercart and Content Profile I'm in the early stages of building a client site that is heavily centred around paid membership. Depending on a fairly complex set of rules, members will join the site and be charged different amounts for their annual membership based on fields they fill in on the signup form.

I am using Ubercart and Content Field Profile to create a custom membership form. The membership boils down to having 1-many products added during the sign up, based on the values entered in the form.

Is there a way I can do this without coding it all myself using submit or validate hooks and uc_add_product or similar?

I would look into Rules (may require some patches and the Ubercart Rules module, as I don't know if it can add products to the cart by default).

That said, a Google search (which I'm sure you've also done) doesn't hint at much. If you have time, I would suggest doing it the way you're planning (validate and submit hooks and uc_add_item). It will work well. Then contribute back what you've done either to an existing, similar module or as a new uc_ module.

Before doing so, you could ask in #drupal or, more specifically, #drupal-ubercart on IRC.


Contact form redirects to homepage without showing submission information I am using default contact form available in D7 under module section. The problem is that contact form redirects to the homepage. It doesn't show any information about submission, such as "Your message has been sent" etc etc. Instead it redirects to home page immediately.

I don't want the contact form to redirect. It should stay here and should show the submission information/message.

You can use hook_form_alter to hook into the contact form and change the default submit behaviour. So instead of redirecting when the form submits, you can just omit that part and display the status message.

function mymodule_form_alter($form, &$form_state, $form_id ) {
  if ($form_id == 'contact_site_form') {
    // Use our own custom submit function for the contact form.
    $form['#submit'] = array('my_custom_submit');
  }
}

function my_custom_submit($form, &$form_state) {
  drupal_set_message(t('Success.'));
}


How to SAVE a webform in Simpletest? I am able to save a sample webform in Simpletest if I only use title and body:

  $edit = array();
  $edit['title'] = 'Sample webform';
  $edit["body[$langcode][0][value]"] = $this->randomName();
  $this->drupalPost('node/add/webform', $edit, t('Save'));

But when it comes to add the additional fields,

$edit['customfield_xxx'] = '0053416';

the test fails:

Failed to set field customfield_xxx to 0053416

Is any nesting necessary to make it work?

UPDATE
It seems like after submitting the form as describe above I need to access the components page:
$this->drupalGet('node/1/webform/components');
where I build an array with all components. However I have been able to fill in the specific component form with 1 single field.

You need to mimics the user's behaviour.

You need to submit individually each form in multiple steps.

You must write correctly the field names (look for input names in the DOM with Firebug or Developer Tools)

  $edit = array();
  $edit['title'] = 'Sample webform';
  $edit["body[$langcode][0][value]"] = $this->randomName();
  $this->drupalPost('node/add/webform', $edit, t('Save'));

then submit the fields individually:

  $edit = array();
  $edit['add[name]'] = 'Sample webform';
  $edit['add[type]'] = 'textfield';//or whatever, optional
  $this->drupalPost('node/webforms/components', $edit, t('Add'));

Rinse and repeat.

You can create a custom function to perform that.


How do I change jquery_update version for a custom theme? There are two options in jquery_update module's configuration: Jquery to be used in frontend theme, and Jquery to be used in admin themes. I set another theme to be used by a specific role (say, manager).
How do I change jquery_update version of that theme that is used by manager role.
Is it possible to do this with template.php, if yes, how so?

I already followed a patch here, but I am not sure if I should apply that old patch.

No need for a patch, jquery_update 7.x-3.0-alpha5 works great and it already includes functionality to specify jquery version per theme (as per this issue) on configuration page admin/config/development/jquery_update

For specifying a theme per role you can try any of the following modules role_theme_switcher Themes By Role (TBR)


Updating a module via backend or manually didn't work. No drush available. What else can I try? I have to administrate a site I didn't build. An older version (7.x-3.0-beta4) of http://drupal.org/project/context (7.x-3.0-beta6) gives me security alerts and suggests to update immeditaley(!).

The automated update process works fine until it comes to the point where the database should is updated. I just says: No pending updates. Back in the modules overview it still is the old version (7.x-3.0-beta4) and message prompts again: update immediately.

So I tried updating manually. Deleted the context module folder in sites/all/module. And uploaded the freshly unpacked new version (7.x-3.0-beta6). Then I ran updated.php and: same again. Drupal still says old version and tells me to update immediately.

Then I tried to uninstall the complete module through the 'uninstall module' dialogue, though I don't know if uninstalling it completely is a good idea (Is it? Or will data get lost?). But even that didn't work. I deactivated all the three parts of that module (context, context ui, context layouts), then went to the uninstall site but there I wasn't given the chance to check the main part (context).

Even when deleting the whole module folder, the module still appears in every list and the alert message still prompts me to update.

So, what can I do to force the database to update and finally recognize the new files? Or what else would be a point I maybe missed to try?

Have you flushed your caches? Sometimes you will see old data, even in regard to modules because of cache issues.


autolink body content to node I want to do this: If I enter a body in content type, on save the content type body searched and  automatically link to exists node title.

As example :
body:   The drupal is one of best CMS systems,

If I have a node with title "drupal" I want  the drupal link to it automatically on save,
is there any module to do this? If not appreciate any idea help me to implement it.

I found Alinks module, it similar to what I want but It not link to existing nodes, it just link to some user defined word and links.

The main problem is searching for existing node title not linking to them,
we have body with many word,I want if a word equal node title that exist , it link to it

You may consider the FreeLinking module.

The Freelinking module adds a text filter for using Wiki-style markup for creating links automatically, by searching the node body for markup.  It supports a number of methods for creating the link, including Nodetitle (which sounds like the one you're looking for). You may even add methods by adding your own link plugin.

However, you need to indicate the text you want to be considered as a candidate for automatic linking by markup: i.e. by surrounding it with double square brackets.  This is how your example will look like:

The [[drupal]] is one of best CMS systems

It even lets you create placeholder links to pages that has not been created yet. Both internal and external links are supported by the module.

There tutorial is about using the Freelinking module, with a little help from the companion WikiTools module, here.

If the way Freelinking does this is not good enough for you, here are a couple of alternative solutions:

Alternative solution #1: You can write your own custom text filter for this.  I suspect that to create something that works during node saves without freezing or killing your site will be very hard to do.

Alternative solution #2: If you can accept a solution that delays the creation of links, you can place new and altered links in a queue, and then use a cron job  to parse them for links.  This allows you to space out the parsing of node bodies over time and will avoid the performance problems a real-time text filter would create.  For the record: There exists no module that does the parsing of node bodies and add links like this.  You'll need to write it yourself.


Help link doesn't appear in module page What do I have to do to show help link in module menu?

My code looks like:

/**
 * Implements hook_help().
 */
function mymodule_help($path, $arg) {
  if ($path == 'admin/help#mymodule') {
    $output = '
' . t('About') . '
';
    $output .= '
' . t('descripton.') . '
';
    return $output;
  }
}

In order to the help link appear on the module page (admin/modules), you should have both the core Help module and your module enabled.


Correct way for a db_query for nodes between two timestamps I have a very simple db_query.  I want to look for any node created between two timestamps.

This query works fine in MySQL shell

SELECT nid as id,created as start,title FROM node WHERE created BETWEEN '1403564400' AND '1403650800';

This works fine in Drupal

$data = db_query("SELECT nid as id,created as start,title FROM node")->fetchAll();
echo json_encode($data);

As soon as I add in the BETWEEN conditions below I get an Internal Server Error.

$data = db_query("SELECT nid as id,created as start,title FROM node WHERE created BETWEEN '1403564400' AND '1403650800'")->fetchAll();

I am unsure what I am doing wrong here, perhaps someone can point me in the right direction please!

You can try using db_select instead wich is a better way to create query with Drupal (assuming you are using Drupal 7).

$start_time = '1403564400';
$end_time = '1403650800';
$query = db_select('node', 'n')
  ->fields('n', array('nid', 'created', 'title'))
  ->condition('created', array($start_time, $end_time), 'BETWEEN');
$result = $query->execute();
$record = $result->fetchAll();


Drupal 7: Using Views to display articles with a taxonomy that is also selected for the current user I'm trying to make a View that displays all articles having the same value in an taxonomy field as the current user has in its taxonomy field (taxonomy is "Work Location" and I want to display the work location news)

For that I created the taxonomy and added several locations. Then I added a field based on this taxonomy to the user and to the article content type.

Now I'm trying to create the View but I just can't figure it out.

Found my own solution:
See this link: http://blog.ampli.fi/filtering-a-drupal-7-view-based-on-a-user-profile-field/


text overlay image views I want to show images on my website. website example

When I hover over the images, the page title shows up. But when you move with your cursor over the text it won't link to my colorbox popup.
How can I solve this problem. I've been looking for a long time.

I've used the rewrite results to get the title on hover.

There are 2 solutions:

use title as the text and it will automatically redirects you to the content page when you click on it.
in your views add the path field to your fields,

apply it and now check the exclude from display checkbox in its setting. go to Rewrite Results and set these settings:

click ok and move the path field at the top of the fields.

Now click on the field that displays your text on the image and set these settings:

Now that field will be a link to your content.


Functional tests report constants are undefined, even if the constant is set in the test or phpunit.xml I have unit and kernel tests that check for the existence of secrets (via define) in a settings.secrets.php file in my local site (Acquia Cloud convention). This file is not committed to the repo, stored in the database or exported.

When writing a functional test, I ran into an issue (which sounds similar to this one). If I tried to put define in my test file, I would just get an error and test failure saying the constant is undefined.

I came up with this, overriding prepareSettings() to write to the settings file generated for functional tests:

  /**
   * {@inheritdoc}
   */
  protected function prepareSettings() {
    parent::prepareSettings();
    $directory = DRUPAL_ROOT . '/' . $this->siteDirectory;
    copy(DRUPAL_ROOT . '/sites/example.secrets.settings.php', $directory . '/secrets.settings.php');
    $append_line = 'include_once dirname(__FILE__) . \'/secrets.settings.php\';';
    file_put_contents($directory . '/settings.php', $append_line, FILE_APPEND);
  }

The file that is copied just contains define statements with fake values.

Is this a valid approach to fixing this problem in a functional test, or did I miss something else and don't need the above code?

Update:

The code in the question only works for Functional tests as they have that method. Lower level kernel and unit tests have no access to that.

Instead, I found that you can add constants to phpunit.xml and then the tests have them defined:

    <php>
        <const name="MYMODULE_API_URL" value="https://api.myproject.localhost"/>
        <const name="MYMODULE_API_KEY" value="123456789"/>
        <!-- Set error reporting to E_ALL. -->
        <ini name="error_reporting" value="32767"/>

There appears to be one exception though - BrowserTests that have calls to drupalGet can still throw Use of undefined constant exception and fail the test. I can't figure that part out. I also tried using a testing profile that does not enable page or dynamic cache - same result. For now I had to comment out the drupalGet calls until I figure it out later.

However by adding it to phpunit.xml, you cannot do it in prepareSettings or you get a 'constant already defined'. So it appears that it is aware of the existing of this value.

Why do non BrowserTests not adhere to constants that are set either in code or in phpunit.xml, but any other tests do?

Update 2:

Here is the code in the test. The lines in the first loop for drupalGet will fail with the error, but curiously, the last block passes just fine:

    foreach ($permitted as $account) {
      $this->drupalLogin($account);

      foreach ($this->entity_types as $entity_type) {
        $this->drupalGet('node/' . $entity_type['nid'] . '/edit');

        if ($entity_type['response'] === 200) {
          $this->assertLinkByHref('/node/' . $entity_type['nid'] . '/update');
          $this->assertLinkByHref('/node/' . $entity_type['nid'] . '/data');
        } else {
          $this->assertNoLinkByHref('/node/' . $entity_type['nid'] . '/update');
          $this->assertNoLinkByHref('/node/' . $entity_type['nid'] . '/data');
        }

        $this->drupalGet('/node/' . $entity_type['nid'] . '/update');
        $this->assertResponse($entity_type['response']);

        $this->drupalGet('/node/' . $entity_type['nid'] . '/data');
        $this->assertResponse($entity_type['response']);
      }

      $this->drupalLogout();
    }

    // As someone without the specific permission
    $this->drupalLogin($this->staff);

    foreach ($this->entity_types as $entity_type) {
      $this->drupalGet('node/' . $entity_type['nid'] . '/edit');
      $this->assertNoLinkByHref('/node/' . $entity_type['nid'] . '/update');
      $this->assertNoLinkByHref('/node/' . $entity_type['nid'] . '/data');
      $this->drupalGet('/node/' . $entity_type['nid'] . '/update');
      $this->assertResponse(403);
      $this->drupalGet('/node/' . $entity_type['nid'] . '/data');
      $this->assertResponse(403);
    }

The code in the question only works for Functional tests as they have that method. Lower level kernel and unit tests have no access to that, and thus, they would fail.

Instead, I found that you can add constants to phpunit.xml and then the tests have them defined:

    <php>
        <const name="MYMODULE_API_URL" value="https://api.myproject.localhost"/>
        <const name="MYMODULE_API_KEY" value="123456789"/>
        <!-- Set error reporting to E_ALL. -->
        <ini name="error_reporting" value="32767"/>

Then you can remove the prepareSettings method from functional tests. However, there seems to be another bug (that I can't track down) where tests that use drupalGet can sometimes fail with an undefined constant error, even though it is defined in the configuration file (you can do it in code too, and will still fail).

My only guess here is that its an issue with a new process spawn not getting the defined configuration from phpunit.xml, or files are loaded out of order (test file constants aren't seen?).

I settled on the following. I left the constants defined in phpunit.xml so my unit/kernel tests did not need them littered in the tests. For functional tests, I put prepareSettings back in with some changes:

  protected function prepareSettings() {
    parent::prepareSettings();
    $directory = DRUPAL_ROOT . '/' . $this->siteDirectory;
    copy(DRUPAL_ROOT . '/sites/functional.settings.php', $directory . '/functional.settings.php');
    $append = 'include dirname(__FILE__) . \'/functional.settings.php\';';
    file_put_contents($directory . '/settings.php', $append, FILE_APPEND | LOCK_EX);
  }

The contents of the file:

/**
 * @file
 * Functional tests settings file.
 *
 * There is a weird bug where constants are not recognized in certain cases
 * in functional tests, despite them being defined in phpunit.xml.dist.
 *
 * Functional tests should include any required constants here to avoid this
 * bug.
 *
 * @see https://drupal.stackexchange.com/questions/292713/functional-tests-report-constants-are-undefined-even-if-the-constant-is-set-in
 */

if (!defined('MYMODULE_API_URL')) {
  define('MYMODULE_API_URL', 'https://api.docker.localhost');
}

if (!defined('MYMODULE_API_key')) {
  define('MYMODULE_API_key', 'foobar');
}

Now, with the functional test uncommenting all the calls to drupalGet, all tests are passing with no errors about undefined constants.


Is drush.wrapper used anymore for Drush 8? How to use for Windows? We have 3 devs working on a Drupal 7 site. Drush 8 is provided via a local composer file drush/drush:~8.0. A drush.wrapper exists in the project root containing:

cd "`dirname $0`"
DRUSH_ALIAS_FILE="./drush/MYPROJECT.aliases.drushrc.php"
DRUSH_LAUNCHER="./vendor/bin/drush.launcher"

if [ ! -f $DRUSH_ALIAS_FILE ]; then
  echo "No Drush alias file was found at ./drush/MYPROJECT.aliases.drushrc.php"
  exit;
fi

if [ ! -f $DRUSH_LAUNCHER ]; then
  echo "Drush Launcher was not found at ./vendor/bin/drush.launcher. Have you ran 'composer install' from the project root?"
  exit;
fi

$DRUSH_LAUNCHER --local --alias-path=./drush "$@"

This works for everyone; except the one user on Windows. They get an error along the lines of "drush.php was not found". If he removes the file, drush works (but then it is using the globally installed drush). This of course would break it for everyone else.

I am confused by the docs. How does one properly supply Drush 8 with a Drupal 7 project via Composer and have 'drush' work as a command from the project? I see issues saying the wrapper file is not needed anymore and other posts saying you need one.

edit: We started over and installed drush launcher per the documentation with the Windows .bat file. It still gives the error:

"Could not open input file /usr/local/bin/drush"

No, don't use drush.wrapper. There is a new tool in town - Drush Launcher. It works on Windows too since it's PHP based - just follow step 4 in the installation instructions. (Step 2 and 3 aren't relevant on Windows, and step 1 is just a normal file download on Windows.)

Added: You should remove/rename the global Drush if you have any. If you need it, check out the fallback option for Drush Launcher.

PS! Also the Linux/Mac people should use Drush Launcher.


User restrictions- field comparision In my site, I have various fields for user registration along with image captcha. Though I get fake registrations at least 3 per day. I found that "username" and "address" fields are identical by value in all those registrations. Is there any way to deny access to those registrations?.

Use Botcha. This will effectively prevent bot submissions. Don't use short term adjustments for Drupal defaults unless you've used your site for long time.


Emailing a bunch of users selected from a user reference field I have a node that lets me select multiple users in a user reference field. I also have a rules setup to email the author when someone makes a comment on that node.

Now, how do I also email the users I selected in the user reference field when someone makes a comment? Would rules work in this scenario or something else?

You should be able to add another "Send email" action to your rule, but place it inside a Rules loop so it can iterate over the multiple values in the user reference field. You may need to first add an "Entity has field" condition to get access to these values.


Loading nodes from a specific user and a specific node type I have written this function to do so, but it behave strangly, i am wondering if i have the correct approach

function getNodes($type,$userID){
        $where = array();
        $nodes = array();
        $where[':type'] = $type;
        $where[':uid'] = $userID;
        $result = db_query('SELECT nid FROM {node} WHERE uid = :uid AND type = :type', $where);
        if($result){
            foreach($result as $o){
                $nodes = node_load($o->nid);
            }
        }
    return $nodes;
}

Isn't there a drupal API that loads node from the DB by passing it a UID and Node type ?

In D6 you could pass criteria to node_load(), so you could do

 $criteria = array(
   'uid' => $userID,
   'type' => $type,
 );

 $nodes = node_load($criteria);

would do the job.

In D7, you don't have this option with node_load as it is just a wrapper for entity_load. This has a depricated argument which allows you to load nodes in the same way

 $criteria = array(
   'uid' => $userID,
   'type' => $type,
 );

 $nodes = entity_load('node',FALSE,$criteria);

note untested

This may work, but is not guaranteed to.

The approved way to do this in D7 is to use EntityFieldQuery

  $query = new EntityFieldQuery();
  $entities = $query->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', $type)
    ->propertyCondition('uid', $userID)
    ->execute();
  $nodes = node_load_multiple(array_keys($entities['node']));

note also untested


How to format the display of a node? I have contributors who have a vast range of skills and experience, who will have permission to post on my site. I want them their content to be displayed in the same way.

I want the user to be able to upload a single image and write some text in WYSIWYG and for it to publish with the picture at a pre-formatted width (let's say 40%) and for the text to wrap around it, like you would expect on a web page.

I imagine that I might not be able to create this as a content type and will have to use a webform, but I am still not convinced.

Yes, that is how I envisage the end result, but I am looking for a
  solution to allow the node author to drop the picture into an input
  field and let Drupal deal with the float.

All you have to do is create a template file for your content type. Then add a class or an id for your image field. (copy the node.tpl.php file and paste, rename the copy to node--[your content type name].tpl.php such as node--articles.tpl.php) Then add this line, you will also need to print all the other fields you want to see.

Example
<?php print render($content['field_image_example']); ?>

So when someone view's the page, your image will automatically be wrapped inside floated.

(above answer assumes you're using Drupal 7)

Template file

<?php print render($content['field_image_example']); ?>

  <?php print render($content['body']); ?>

CSS

#example{
    width: 400px;
    background: yellow;
}
#floated img{
    float: left;
    width: 150px;
    background: red;
}

If you want an easier solution, less advanced knowledge needed, then use Panels which will let you add a class to your image.

  The Panels module allows a site administrator to create customized
  layouts for multiple uses. At its core it is a drag and drop content
  manager that lets you visually design a layout and place content
  within that layout. Integration with other systems allows you to
  create nodes that use this, landing pages that use this, and even
  override system pages such as taxonomy and the node page so that you
  can customize the layout of your site with very fine grained
  permissions.

Panels Tutorials


How to attach a css style with a node in the node-edit form I don't want to save the style in a file. What I want is to store the css code in a field while editing node and use the id or class within the node content.

take a look at css_injector, it allows to add css only on specific pages, like 'node/add'.


Views count grandchildren with specific value I have a Organic Groups structure of:

Organsiation

-Property

--Claim

I can use views to show all of the properties within an organisation by setting a contextual filters with OG membership: Group ID.

What I want to be able to do is count the number of open claims (a claim where a feild 'status' is set to 'open') within a property. For example:

Is this possible using views? It seems to ask a lot of views as I guess I need a subquery or second query to get the claims of each property.

Each claim references a property in its group audience feild. Each property references an organisation in its group audience feild.

EDITED

The end result of this will be a view using the organisation NID showing property with the number of claims.

ie. on an organisation's node, this would be the block.

Property 1 -  18 (open claims)

Property 2 -  13 (open claims)

Step 1: Grandchildren.

Add your regular group ID contextual filter.
Add the relationship, OG membership: Group Node from OG membership.
Add it to your contextual filter as its relationship. This gives grandchildren.
Filter out Property content type.
Add property entity reference as a field.

You now have a all properties with all claims.

Step 2: Counting

Try Views Aggregation in Advanced. It will probably cause an OG error.
Instead, install Views Merge Rows. https://www.drupal.org/project/views_merge_rows
It will add a new option under Advanced in your view.
For title, Count merged unique values.
For property entity ref field, Use values as a filter.

Now you should have something similar to my example above.

Step 3: Filtering to OPEN

Add a relationship for that field. I just tried it with a taxonomy field but a Boolean should be similar.
Add a filter, eg. (term from field_hello) Taxonomy term: Term ID (= 90210)

Adapt the filter to what you need or use the general idea to create your own solution.


Drupal downloads the module update but need FTP As the above screen shots, from Drupal 7 shows, the updates are downloaded! However, it still says Updating modules and themes requires FTP access to your server.
I have tried the ownership of sites directory as whole sudo chown www-data sites. I also tried chmod -R 777 sites. Is there any other way beside having to configure an FTP server, and if it must need a FTP, what is the directory I should set it to files?

I sometimes have seen that message with Drupal 7, and I always got confused about why Drupal was asking for FTP access to save files in the same server it was running, and why I didn't get that message in some Drupal 7 installations.
Looking at the code used from Drupal to updates the modules, I then discovered Drupal first checks if local file transfers are allowed. If they aren't allowed, that message will be shown.
In particular, this is the code Drupal uses. (See update_manager_local_transfers_allowed().)
  // Compare the owner of a webserver-created temporary file to the owner of
  // the configuration directory to determine if local transfers will be
  // allowed.
  $temporary_file = drupal_tempnam('temporary://', 'update_');
  $local_transfers_allowed = fileowner($temporary_file) === fileowner(conf_path());

In other words, if the account owning a temporary file created in the temporary directory set up for the site isn't the account owning the directory containing the settings.php file used for the site, Drupal will show the message you saw.
Setting the temporary directory and the directory containing the settings.php file to be owned from the same account will make updates from the user interface possible via local file transfers. In this case, Drupal won't show any message about the FTP access being required.
update_manager_local_transfers_allowed() is called from _update_manager_check_backends(), which contains the following code. (The comments explain what is happening and why.)
  // If file transfers will be performed locally, we do not need to display any
  // warnings or notices to the user and should automatically continue the
  // workflow, since we won't be using a FileTransfer backend that requires
  // user input or a specific server configuration.
  if (update_manager_local_transfers_allowed()) {
    return TRUE;
  }

  // Otherwise, show the available backends.
  $form['available_backends'] = array(
    '#prefix' => '
',
    '#suffix' => '
',
  );
  $available_backends = drupal_get_filetransfer_info();
  if (empty($available_backends)) {
    if ($operation == 'update') {
      $form['available_backends']['#markup'] = t('Your server does not support updating modules and themes from this interface. Instead, update modules and themes by uploading the new versions directly to the server, as described in the handbook.', array(
        '@handbook_url' => 'http://drupal.org/getting-started/install-contrib',
      ));
    }
    else {
      $form['available_backends']['#markup'] = t('Your server does not support installing modules and themes from this interface. Instead, install modules and themes by uploading them directly to the server, as described in the handbook.', array(
        '@handbook_url' => 'http://drupal.org/getting-started/install-contrib',
      ));
    }
    return FALSE;
  }
  $backend_names = array();
  foreach ($available_backends as $backend) {
    $backend_names[] = $backend['title'];
  }
  if ($operation == 'update') {
    $form['available_backends']['#markup'] = format_plural(count($available_backends), 'Updating modules and themes requires @backends access to your server. See the handbook for other update methods.', 'Updating modules and themes requires access to your server via one of the following methods: @backends. See the handbook for other update methods.', array(
      '@backends' => implode(', ', $backend_names),
      '@handbook_url' => 'http://drupal.org/getting-started/install-contrib',
    ));
  }
  else {
    $form['available_backends']['#markup'] = format_plural(count($available_backends), 'Installing modules and themes requires @backends access to your server. See the handbook for other installation methods.', 'Installing modules and themes requires access to your server via one of the following methods: @backends. See the handbook for other installation methods.', array(
      '@backends' => implode(', ', $backend_names),
      '@handbook_url' => 'http://drupal.org/getting-started/install-contrib',
    ));
  }
  return TRUE;

As side note, the temporary directory is the one set on admin/config/media/file-system, which by default is set to /tmp.

Note also that, as 4k4 said in a comment, updating modules or themes from the user interface is a security risk. In fact, it requires the system account used to run PHP to be able to write files in the directory containing the modules. For example, with that permission, a malicious script could alter the submission callback used for the user login form, and add code that sends the login credentials to a remote server.
For a general discussion see Should PHP run as www-data or as the user who owns the website? where one of the comments says:

PHP should NEVER have write access to or ownership of the files it executes, or the directories they reside in. I cannot emphasize this strongly enough. It just takes one security vulnerability, and now you're phishing, hosting a reverse shell, spamming, participating in an outbound DoS, or otherwise compromised, because an attacker used PHP to write a malicious script into a place where it could be executed. #3 is the best solution, best implemented by changing the group of the upload directory to www-data and giving group write access. Also ensure that nginx will not ask PHP to execute scripts stored in that directory.


How do i deactivate "Your comment has been posted." after user posted a comment How do I deactivate -Your comment has been posted- after user posted a comment.

Is it possible to deactivate the message above with out touching the core?

you can add a custom submit handler to the comment form using hook_form_alter():

function yourmodule_form_alter(&$form, &$form_state, $form_id){
  if( $form_id == 'comment_form' ) { // find and use the actual form ID
    $form['#submit'][] = 'yourmodule_your_custom_comment_submit_function';
  }
}

Then in that submit function check to see if the message exists using drupal_get_messages():

function yourmodule_your_custom_comment_submit_function(){
  $message = drupal_get_messages('status', false);
  if( $message['status'] == 'Your comment has been posted' ) { // Or what is the actual message
    drupal_get_messages('status');
  }
}

This is for Drupal 7 but these functions exists in older drupal versions. Check api.drupal.org for details.


How to implement something like OG which the groups can manage on their own? I'm building a learning tracking site for a community where Mentors will match up with Mentees. I'd like them to create either an organic group or a paired relationship to share content (seen only by the two of them plus a supervisor, observer, or instructor).

The catch is I'd like to let them do it on their own. In other words, I'd like to "get out of the way" and not maintain the actual groupings.

Does this sound like a job more for Organic groups (OG) or User Relationships? Is there another technique that could get the job done more smoothly?

And, how can they share content only amongst those with in that group or relationship?

If I use OG, how can I best let users create and invite others without my intervention?

You could, for sure, use the Group module for this. Group allows for creating arbitrary collections of your content and users on your site, and grant access control permissions on those collections. It is available as of D7, and has a D8 version also. It is designed to be an alternative to Organic Groups. The Group module creates groups as entities, making them fully fieldable, extensible and exportable.

For more details about how Group compares to Organic Groups, refer to my answer to "What are the features of the Group module versus Organic Group module?". And for more details about the various roles and permissions, refer to my answer to "What are the various roles supported by the Group module?".

Resources

Community documentation for the Group module.
Video tutorial "How to use the Group module in Drupal 8 to manage editorial access control to different areas of a web site".


How to copy blocks placement and settings between themes? How can I copy blocks placement and settings between themes?

I've found this module: https://drupal.org/project/blockregion and this code to do it in the database. But both are for D6. How can I do this for D7

First, clear the existing block information for the new theme:

DELETE FROM blocks WHERE theme = 'NEW_THEME_NAME'

Now, copy all the block information from the old theme:

INSERT INTO blocks (module, delta, theme, status, weight, region, custom, throttle, visibility, pages, title, cache) (SELECT module, delta, 'NEW_THEME_NAME', status, weight, region, custom, throttle, visibility, pages, title, cache FROM blocks WHERE theme = 'OLD_THEME_NAME')

Also found this, but for D5: http://pierrerebours.com/blog/duplicating-block-settings-across-themes-drupal

I changed a little bit the code and it worked:

Before running this code you should be sure that both themes have the same regions and, if needed you will have to create the missing regionsin the new theme.

DELETE FROM block WHERE theme = 'NEW-THEME'

INSERT INTO block (module, delta, theme, status, weight, region, custom, visibility, pages, title, cache, i18n_mode) (SELECT module, delta, 'NEW-THEME', status, weight, region, custom, visibility, pages, title, cache, i18n_mode FROM block WHERE theme = 'OLD-THEME')


drush appears to not be respecting --no-backup My server has a great backup system in place.  I do not need additional backups dropped into my home directory.

Reading the drush docs gave me the impression that the --no-backup option, would instruct drush to not make a backup.

$ drush --version
drush version 4.5

When I update a module with the --no-backup option it seems to be ignored.

$ ls ~/
creds
$ drush dl drush --no-backup --yes
Would you like to back up your current drush version 4.5 to /home/username/drush-backups/unknown/20110823223228 and replace it with drush 4.5? (y/n): y
drush backed up to /home/username/drush-backups/unknown/20110823223228/drush  [ok]
Project drush (7.x-4.5) downloaded to                                [success]
/srv/www/_drupal_.example.org/drush.
Drush successfully updated to version 7.x-4.5.                       [success]
$ ls ~/
creds  drush-backups

Am I missing something obvious here?  I have tried changing the order of the parameters, but that doesn't seem to make any difference.

This is a Drush bug, and would best be raised in the issue queue.  By coincidence, someone recently posted this: http://drupal.org/node/1741108


Image style is not rendering My field_image is not rendering on user-profile.tpl. I have the following code (two different ways to render for testing):

    $image = field_get_items('user', $user, 'field_image');
    $output = field_view_value('user', $user, 'field_image', $image[0], array(
      'type' => 'image',
      'settings' => array(
        'image_style' => 'header_image_160x160',
      ),
    ));
    print render($output);

This produces the following in html:

<img src="https://coinme.io/sites/default/files/styles/header_image_160x160/public?itok=f31sbmSd" width="160" height="160" alt="">

I get the dead image logo. It is missing the final part of the file structure. And this is how I normally render:

$to_render = field_view_field('user', $user, 'field_image', array('settings' => array('image_style' => 'header_image_160x160'))); print render($to_render);

This is showing the default image, even though the image does exist:

https://coinme.io/sites/default/files/styles/header_image_160x160/public/images/profile/profile-large.png?itok=rb-2qFOw

I have the same field in a content type which is rendering correctly (only difference being the $user user -> $node node.

<?php $to_render = field_view_field('node', $node, 'field_image', array('settings' => array('image_style' => 'header_image_160x160'))); print render($to_render);?>

So it appears that when using user-profile specifically is the issue. I have also tried adding a new field type and same effect. Any suggestions?

Thanks,
Paul.

The answer was simple, $user is the user logged in. As my logged in user didn't have a profile image, all I kept seeing was the default. Unfortunately, elsewhere on the page I am not using $user but just $field_*, so it looked like I was using the right variable. This fixed it:

<?php $account = $elements['#account'];?>

And then updated $user to $account.

<?php $to_render = field_view_field('user', $account, 'field_image', array('settings' => array('image_style' => 'header_image_160x160'))); print render($to_render);?>

You cannot believe how much time and searching I did to fix this, and it turned out I was looking at the wrong variable the whole time.

Thank you,
Paul.


Resolve CORS issue without changing services.yml file I have below in routing.yml

sample.post:
  path: '/sample/post'
  defaults:
    _controller: '\Drupal\sample\Controller\SampleController::postData'
  methods: [POST]
  requirements:
    _access: 'TRUE'
    _format: 'json'

In services.yml no change it will be same as default. I don't want to change in service.yml by enabling cors config.

When I call using jQuery.

  jQuery.ajax({
      url: 'http://localhost/sample/post',
      contentType: "application/json",
      type: 'POST',
      complete: function (data) {
        console.log(data);
      }
  });

It gives

  Failed to load http://localhost/sample/post: Response to preflight
  request doesn't pass access control check: No
  'Access-Control-Allow-Origin' header is present on the requested
  resource. Origin 'http://localhost' is therefore not allowed access.

Can I achieve w/o enabling cors config? If I enable cors then it works fine.

Can I achieve w/o enabling cors config?

No. Without CORS configured, the server and browser will correctly conspire to reject the request.

You could implement it yourself, rather than using services.yml, but something needs to set the headers. And at the point where all you need to do is make a few simple edits to a configuration file, I'd question why you would want to write all that extra code yourself.


Required autocomplete field I have an 'Entity Reference' autocomplete field populated by a view that returns all authenticated user email addresses.  I have set the field to 'Required' but when I enter an email address not in the list and save the node, it doesn't trigger an error.  It just makes the field blank.  Is there anything I can do to force the node not to save if a valid email address has not been entered?

You should try changing the no results message in the view, maybe have return an invalid address like a@a@a.c or something.


How to change the path when cloning the Taxonomy term view? I am trying to clone the default Taxonomy Term view to a new view.

I have a Block with the list of contents when I was clicking one of the content inside the Block, it goes to this path: taxonomy/term/%.

But I want to change the path to blog/%

I have changed the Path in the view's settings to (blog/%) from (taxonomy/term/%),But when I will click the content in the block goes to the same Taxonomy/term/% not to new wanted path.

How to change the taxonomy/term/% path to blog/% ?

To change the path that user's will see, you don't actually want to update the view path (which is not obvious), you need to change the path of the taxonomy vocabulary and its terms.  The Pathauto module makes this easy by creating a pattern for your blog taxonomy at: /admin/config/search/path/patterns (once pathauto is installed and working)


Editor adds &nbsp on every enter I've got a problem with CKEditor in Drupal 8. I've searched related questions like CKeditor adds extra <p> tags, but almost all questions are related to Drupal 7.

So, my CKEditor automatically applies a <p>&nbsp</p> when I hit enter and don't type anything.

How can I disable this? I don't want to remove the padding or anything of a <p> tag. I need something that checks if the paragraph is empty and then don't display it.

have you tried toggling off the "Convert line breaks into HTML (i.e. <br> and <p>)" setting on the text input format?


Am I able to remove unneeded field/migration tables from the database manually? I have been working on my site for three months now and I have noticed that the number of empty tables in my database has grown considerably.  Upon closer inspection, I saw that these tables were use by fields belonging to content types that have been removed from the site.  Apparently Drupal does a bad job of removing field tables when you simply delete a content type.  Is it OK for me to delete these tables manually, or will doing this break code (I have been seeing plenty of mysterious, field related errors lately.)  If so, is there anything else besides the field table that I can remove?

The same question is also asked about the migration tables.  Can I get rid of them if they don't go away?

Yes, use

drush migrate-deregister --orphans

This should get rid of all migration tracking tables that are not longer being referred to.


REST API Guzzle POST gives timeout but the same call works if I run it on the server cli I have Drupal running in a docker container and nginx running in another container.

When I do the login call through postman or directly on the webserver cli it works perfectly.
But when I do call from within my application I get a timeout after 30 seconds.

From server:

  wodby@php.container:/var/www/html $ curl -X POST \
    'http://api.swappr.localhost/user/login?_format=json' \
    -H 'Postman-Token: a9c80844-ed69-4d24-b205-6475b7e469dc' \
    -H 'cache-control: no-cache' \
    -d '{"name":"logintest2@gmail.com", "pass":"password"}'
  {"current_user":{"uid":"21","name":"logintest2@gmail.com"},"csrf_token":"yf5YBYyY4YvXCcufLyTWeKnvbhq5sdcZHpgmsVDeSRY","logout_token":"PEarVS7vPi5idARarGQzrrXAYcJL9YkiXmoHw_a7yJE"}

In code:

$response = \Drupal::httpClient()->post(
            'http://api.swappr.localhost/user/login?_format=hal_json',
            ['name' => 'logintest2@gmail.com', 'pass' => 'password']
        );

cURL error 28: Operation timed out after 30001 milliseconds with 0 bytes received (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

Anyone knows what could cause this problem?

Okay turns out it was xdebug. I had to allow more simultaneous connections in the PHP Debug settings of PHP Storm.


How to resolve my error when uploading files? In our Drupal site when we try to upload .zip file having 210MB size, we are getting an error saying:

The file NewEdition105.zip could not be saved. An unknown error has occurred.
The file in the Sai Rel File field was unable to be uploaded.

If I try with a 100mb .zip file I am able to upload. My maximum upload file size is 1800MB, upload_max_filesize=1600MB and post_max_size=1600 MB.
Did anybody face a situation like this? Any solution for this?

You can try the Pack & Upload module for this. This module can be used to upload the zip file.


Possible to use drush to list overrides for all features? I believe that drush features-diff will list the overrides for a specific feature and that drush features-list will list all features. Is it possible to list all of the overrides for all features, perhaps by piping the results of drush fl to drush fd?

If so, how would one pick up the second field from drush fl to pipe to drush fd? Or, is there a better way to do this?

In the current version of Drush, you can show a list of all features and their override state with (both short and long versions of commands shown, with and without the "-y" flag to skip confirmation questions):
$ drush features-list
$ drush fl

If you want to show only the overridden features:
$ drush features-list | grep -E "Overridden|Needs"
$ drush fl | grep -E "Overridden|Needs"

To show everything that has been overridden for all features:
$ drush features-diff-all
$ drush fda -y

To update all features to their currently overridden state:
$ drush features-update-all
$ drush fua -y

To revert all features to their default state:
$ drush features-revert-all
$ drush fra -y


Programatically save comma-separated string as value of taxonomy field I have a comma-separated string $string of the form "term1,term2,term3" and I would like to save it as the value of a taxonomy term field that is attached to my node. I have tried
$node->field_taxonomy[LANGUAGE_NONE][0]['value'] = $string;
node_save($node); but this throws me an error "Warning: Illegal string offset 'tid' in taxonomy_field_presave()" coming from Taxonomy module.

What is the correct way to set the value of $node->field_taxonomy?

I also need that when node_save($node); is executed, taxonomy terms that had not been taxonomy terms before are created, just like it would happen when I set the value of $node->field_taxonomy via the user interface. I was expecting this to happen automatically when I set and save the taxonomy field value.

Edit: Actually, I am trying to attach taxonomy terms to files, but I thought that the analogous setup of nodes would be more familiar to most people.

I have attached a description field (field_description) and a taxonomy field (field_hashtags) to files via the user interface, using File Entity Module. I now want to upload files and fill in their attached fields using a custom file upload form, but on the custom file upload form there is only

a field for the file itself ($form['file'] of type managed_file) and
a field for the description that the file should be given ($form['description'] of type textarea).

My CUSTOMMODDULE_form_submit() function now defines $submitted_file = file_load($form_state['values']['file']);, i.e. as the submitted file, and $submitted_description = $form_state['values']['description'];, i.e. as the submitted description.

It then sets $submitted_file->field_description[LANGUAGE_NONE][0]['value'] = $submitted_description; and, as expected, when saving the file via file_save($submitted_file); the description field of the file is saved being populated with the submitted values.

However, before saving the file I run a custom function that returns a comma-separated string of hashtags (all words from the submitted description that start with '#') that were used in the description. I now want to set $submitted_file->field_hashtags as exactly those terms from the string that my custom function returns, just like I would enter a comma-separated string into a taxonomy field by hand from the user interface.

Edit 2: I further tried the following code from taxonomy.module

$terms = explode(',', $string);
$voc = taxonomy_vocabulary_machine_name_load('vocabulary_name');
$vid = $voc->vid;

foreach ($terms as $key => $term) {
  if ($possibilities = taxonomy_term_load_multiple(array(), array('name' => trim($term), 'vid' => $vid))) {
            $term = array_pop($possibilities);
        }
        else {
        $term = array(
          'tid' => 'autocreate',
          'vid' => $vid,
          'name' => $term,
          'vocabulary_machine_name' => 'vocabulary_name',
        );
        }

        $term_array = (array) $term;
        $node->field_taxonomy[LANGUAGE_NONE]['$key'] = $term_array;
    }

but this gives me "Error
Error message
PDOException: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '$key' for column 'delta' at row 1:"

try that:

$terms = explode(',', $string);
foreach ($terms as $key => $term) {
  $node->field_taxonomy[LANGUAGE_NONE][$key]['value'] = $term;
}


Unable to load css files using ['#attached'] or drupal_add_css I'm attempting to attach several css files to a Drupal 7 module. All files have identical read/write/execute and owner permissions. I haven't had trouble with one of the three files but I can't get the other two added (checked the loaded stylesheets in developer tools). Here's what I've tried:

<?php
function usspd_search_main_form($form, $form_state) {
  $form['#attached']['css']['css1'] = '/sites/all/libraries/data_search/bootstrap_tagsinput/bootstrap_tagsinput.css'; //failed
  $form['#attached']['css']['css2'] = '/sites/all/libraries/data_search/tagme/tagme_jquery-ui.css'; //failed
  drupal_add_css('/sites/all/libraries/data_search/bootstrap_tagsinput/bootstrap_tagsinput.css'); //failed
  drupal_add_css('/sites/all/libraries/data_search/tagme/tagme_jquery-ui.css'); //failed

  $form['#attached']['css']['css3'] = drupal_get_path('module', 'usspd_search') . '/theme/usspd_search.css'; //works
  return $form;
}

My best guess is that there's a class conflict and instead of overriding, the attachment just fails. Is there any way to declare priority? Otherwise I'll have to add the css from both files inline.

Additionally, I'm able to call everything fine when added as raw HTML to a basic page. It shouldn't be a pathing issue.

<link rel="stylesheet" href="/sites/all/libraries/data_search/bootstrap_tagsinput/bootstrap_tagsinput.css">
<link rel="stylesheet" href="/sites/all/libraries/data_search/tagme/tagme_jquery-ui.css">

The pathing was wrong after all. The preceding "/" was messing things up. Strangely, this was not an issue for javascript attachments. For example:

$form['#attached']['css']['css2'] = '/sites/all/libraries/data_search/tagme/tagme_jquery-ui.css'; //fails
$form['#attached']['js']['js2'] = '/sites/all/libraries/data_search/tagme/tagme_jquery-ui.min.js'; //works
$form['#attached']['css']['css2'] = 'sites/all/libraries/data_search/tagme/tagme_jquery-ui.css'; //works


Zen theme: understanding the zen grids design in _responsive.scss? Below is some of the code from _responsive.scss from the latest release of the Zen theme. It controls the layout of the page. Does anyone know what I have marked 'FROM HERE' to 'TO HERE' is for? I was following the Zen grids method fine until I came across this section of Sass. It doesn't appear in the five column layout, just the three column layout. Thanks

/**
* The layout when there are two sidebars.
*/
.two-sidebars {
  /* Span 2 columns, starting in 2nd column from left. */
  #content {
    @include zen-grid-item(2, 2);
  }

  /* Span 1 column, starting in 1st column from left. */
  .region-sidebar-first {
    @include zen-grid-item(1, 1);
  }

  /* Start a new row and span all 3 columns. */
  .region-sidebar-second {
    @include zen-grid-item(3, 1);

    --- FROM HERE ---

    @include zen-nested-container(); // Since we're making every block in this region be      a grid item.
    @include zen-clear();

    /* Apply the shared properties of grid items in a single, efficient ruleset. */
    .block {
      @include zen-grid-item-base();
    }
    /* Span 1 column, starting in the 1st column from left. */
    .block:nth-child(3n+1) {
      @include zen-grid-item(1, 1);
      @include zen-clear();
    }
    /* Span 1 column, starting in the 2nd column from left. */
    .block:nth-child(3n+2) {
      @include zen-grid-item(1, 2);
    }
    /* Span 1 column, starting in the 3rd column from left. */
    .block:nth-child(3n) {
      @include zen-grid-item(1, 3);
    }

    --- TO HERE ---

  }

}

*Note that this is also inside the .region-sidebar-second container

Also of note, is that zen-grids actually has nothing to do with Drupal apart from being created by John Albin. The documentation can be found here.

Quick and dirty explanation:

--FROM HERE--

@include zen-nested-container(); // Since we're making every block in this region be      a grid item.

Ensures that the element (in this case, .region-sidebar-second) does not have any guttering (margins outside of the declared columns).

@include zen-clear();

This means that the sidebar region will have a clearfix applied

/* Apply the shared properties of grid items in a single, efficient ruleset. */
.block {
  @include zen-grid-item-base();
}

This applies a set of base styles to all blocks that will be in the sidebar. Things such as gutter width and box sizing. It takes something of an OOCSS approach in that it encourages DRY CSS (i.e. you don't need to apply the same CS to each block individually).

/* Span 1 column, starting in the 1st column from left. */
.block:nth-child(3n+1) {
  @include zen-grid-item(1, 1);
  @include zen-clear();
}

For 1st block in a group of three (3n+1), make the block 1 column wide, and place it in the first "column". Then assign a clearfix. I tend to read @include zen-clear() as new line.

/* Span 1 column, starting in the 2nd column from left. */
.block:nth-child(3n+2) {
  @include zen-grid-item(1, 2);
}

For 2nd block in a group of three (3n+1), make the block 1 column wide, and put it in the second "column"

/* Span 1 column, starting in the 3rd column from left. */
.block:nth-child(3n) {
  @include zen-grid-item(1, 3);
}

For every third block, make it 1 grid item wide, and put it in the 3rd "column"

--- TO HERE ---

Useful links:

Note: As of August 13th 2013 these all work fine, but they might go over the next few years. If they do go and you notice, please be a darling and remove/update them from this answer ;-)

CSS Tricks nth-child tester
Zen grids documentation
Nicole Sullivan's OOCSS code standards (trust me, if you're using SASS then you're going to want to read this).
Harry Robert's fantastic CSS guidelines.
The obligatory link to CSSWizardy that I attach to almost every SASS/CSS question I answer.


How can I use Rules to send an e-mail to the author of a node linked by an entity reference field? I have a content type called Help Wanted.  I have another content type called Reply to Help Wanted.  The reply content type includes an entity reference field that contains a node reference to the original help wanted ad being replied to.

I am trying to use Rules to send an e-mail when a reply is posted to the author of the original Help Wanted post.

However, I don't know what to put in the To field of the Send mail action.  I tried the following:

[node:field_my_entityreference:author:mail]

But this token didn't work.  I also tried several other variations to no effect.  Is it possible to use tokens to get the author's e-mail of a node linked by entity reference?  If not, how do I get the author's e-mail via the entity reference?

Here's how I got mine to work:

Switch to 'Data selection mode' which is not how the mail action launches by default:

Select through the field sequence just like you already had with tokens!

I noticed that the tokens are otherwise not available if you just use the direct input mode.  Weird!


Targeting a Specific Contact Form for Altering I'm writing a custom module to format the email I receive from a user who fills out a contact form. I've created two contact forms and I want a separate email format for each form.

Code

I'm using this code as the basis of my module

But, I'm having trouble targeting a particular form. This is the code I'm trying to use, but it doesn't seem to be working:

    // further restrict mail_alter to machine name of a particular contact form
    if ($message['params']['contact_form']->id() ==
    'contact_message_contact_technical_support_form') {
    ...code to format message... (from linked article)
}
elseif ($message['params']['contact_form']->id() ==
'contact_message_feedback_form_form') {
    ...code to format message... (from linked article)
}

Question

Would someone please tell me how to properly id my forms so I can target them?

Thanks for your help everyone. The comments were helpful. I ended up using the var_dump($message) as suggested and then whittled that down to what I needed. As one of you suggested the form name wasn't as long as I originally thought (and it WAS NOT the ID for the form). I think one ended up being 'feedback' and the other was, as you suggested 'contact_technical_support' or something like that.

The other issue I was having was that I was ignorantly naming my module with the word 'alter' in it which was overriding, or being overridden, by the alter hook it was using, I think.

At any rate, short answer is, my code basically works, but use var_dump($message) to find the correct ID of the forms and don't use 'alter' in the module name.


CKEditor links wrap the contents of a container individually instead of a container I'm in a situation where I want to use WYSIWYG with CKEditor because of the easy Media integration. However, I'm building a page with some interactive tabs that have markup something like this:

(#1)

            [[Media markup to insert an image]]

Some text.

            [[Media markup to insert an image]]

Some text.

I want to wrap each of these tabs with a link, this being the desired end result:

(#2)

                [[Media markup to insert an image]]

Some text.

                [[Media markup to insert an image]]

Some text.

If I try to do this in CKEditor, however, I get this:

(#3)

            [[Media markup to insert an image]]

Some text.

            [[Media markup to insert an image]]

Some text.

This creates problems with styling and, more importantly, makes some regions of the tab unclickable. What's even more maddening is that even if I disable rich text and edit the HTML directly to #3, if I switch back to CKEditor it "corrects" the markup to #2.

Is there any way to change or otherwise prevent this behavior? I still want to use the Media module integration to insert and modify images, so I'm hesitant to simply disable CKEditor and leave it off. I can insert my images, then edit the HTML to insert my link tags properly, then save the page, but it can still break again if I go back to make changes.

I'm currently running CKEditor version 3.6.6.7689, WYSIWYG module 7.x-2.2, Media 7.x-2.0-alpha3, and the latest Drupal 7 core.

The CKEDitor by default restricts the HTML you can use to what it considers safe by means of something called the advanced content filter (ACF). It is this feature of CKeditor that rejects your HTML-construct.

To change or otherwise prevent this behavior, you must describe the construct you want to allow by using the syntax described in the allowed content rules and assigned the JavaScript variable config.extraAllowedContent.

PS: If you Google this, you'll often see the following JavaScript suggested to "fix" to CKEDitor removing "unsafe" HTML:

config.allowedContent = true;

What the above line does it to turn ACF of completely.  It will allow any valid HTML to be inserted.  It is OK to do this for testing and debugging, but it is not recommended that you do this on a production site.


How to get access all images of custom directory in twig template? I intend to create a slideshow in front page of my theme to show all images in custom directory, I try to use file_scan_directory and drupal_get_path in below codes to get any non static images path and display that images automatically without any need to calling each one of them separately:
Theme Name.theme:

function MyThemeName_preprocess_page(&$variables) {
$mask = '/\.(?:jp[e]?g|gif|png)$/i';
$files = file_scan_directory(drupal_get_path('theme', 'Theme Name') . '/assets/img/orbit', $mask);
ksort($files);
$variables['files'] = $files;
}

page.html.twig:

{% for file in files %}
<img src="{{ file.uri }}" width="100%" height="100%" alt="{{ file.name }}"/>
{% endfor %}

I would be happy to hear what is the problem with the codes and what is the right way to load that slideshowe pictures?

The path will be wrong, file_scan_directory() will return a relative path, you need to add the base_path(), you can set a variable in preprocess:

$variables['base_path'] = base_path();

So...

<img src="{{ base_path }}{{ file.uri }}" width="100%" height="100%" alt="{{ file.name }}"/>


Why we go for template files and why we go for theme function? Possible Duplicate:
  When should I add a new tpl.php file, and when should I implement a theme function?

To theme a form: There are two ways.

using function theme_themename_form($form)
Assigning to a variable in preprocess and printing it in the template files.

My question is:

Why two ways?
Which way is best for which case ?

That is for which type of cases we should go for function theme and for which cases we should go for template files.
What is all time best way?

I always think of it like this:

If you need to write a fair bit of HTML for your theme then you want a template file. This way you can maintain as much separation HTML and PHP as you'd like.

If you theme is just accepting data and putting that data through (say) another theme function, then you're not going to be writing any/much HTML. In this case a theme_* function is more appropriate in my opinion.

I don't think there really is an "all time best way", both methods are appropriate for different situations.


If field date is 15 days away from today, change another field value OK, this is specific:

I have a content type with two fields:

First is a expiration date field (d-m-y format);
Second is a select list field: "green, red, yellow, empty"

WHAT I NEED:

When there is 15 days left for the expiration date of a specific node, the select list field from that node should automatically change to "yellow".

Is this possible using, for example, rules module? Is there any other option?

Thank you!

Hmm.. This sounds like it could be done with Rules and VBO.

Create a VBO view of nodes that match your date requirement using filter date field > relative date. You might also want to filter out nodes that have already been changed.
Create a rule:

Event: Cron or maybe the Rules Once per Day module
Action: Load a list of entity IDs from a VBO view
Action: Loop list
Action: Change / Add field using Set a data value if it's a single value field or Add item to list if it's a multi-value field.

EDIT: As of November 2017, this feature whereby VBO supplies Rules has been a bit broken and requires a patch to work.


Update CCK fields on a User I'm working on a Drupal 6 project and we've added some fields to a user profile via CCK. What's the best way to update this information programmatically? When the user logs in I'm gathering some data from a 3rd party API that I need to update their user with. I've got the data, but the global $user object doesn't seem to have the extra fields.

OK, the information is stored in the node associated with the user, and not the user itself.

You essentially need to query the database to find the node for the user, load it, edit the fields, and then save out the node.

It would roughly look  like

$sql = "
  SELECT nid FROM {node}
  WHERE type = '%s' AND uid = %d AND status = %d
";

$nid = (int) db_result(db_query($sql, "profile", $user->uid, 1));

$node = node_load($nid);

$node->field_foo[0]["value"] = "foo";

node_save($node);

This is a copy/edit/paste from a project of mine, so error checking and other steps have been omitted, and the code may not run as-is.


Strange sorting in one facet of Apache Solr Search results We're using the Apache Solr Search module to allow users to filter search results; for example, if a user searches for Pepsi, they get all results, but along the left of our screen they get facets allowing them to filter by Post Date, Article Type, Trend, etc. (Ignore the HTML under Trends/Seasonal; we have the Themer module turned on.)

We haven't done anything custom to this search that I know of, but there's something strange: all the facets EXCEPT post date sort descending by number of results. Filter by post date actually sorts by post date. We want that one to also filter by number of results. (It's not visible in the screenshot, but 2010, for example, has over 500 posts so we'd definitely like that one to be at the top.)

Is sorting a module setting somewhere? (There are blocks for each filter-by facet, but sort order is not one of the config settings.) I tried looking around in the code, and I found the spot in our search results page template where the entire left filter bar is printed out, but cannot for the life of me find (even with a full-site grep) where the variable it's printing is actually being set.

Don't know exact path for D6, but you can got to facet configuration, configure display - and there will be sort options with ability to enable/disable sorts and reorder sorting.


How do I programmatically load an order by its properties? I know how to load an order by its ID using \Drupal\commerce_order\Entity\Order::load($order_id). I added a custom field (Token ID) to the orders.

How can I load the orders knowing the value of that field? If I want to get the state of the order, how can I achieve it?

The best way to do this is by using by loadByProperties based on Token field:

$orders = \Drupal::entityTypeManager()
  ->getStorage('commerce_order')
  ->loadByProperties(['field_token_id' => 'TOKEN VALUE']);
$order = reset($orders);
$state = $order->get('state')->value;
$total_price = $order->getTotalprice()->getNumber();
$currency = $order->getTotalprice()->getCurrencyCode();

Here assuming token as a unique value.


Customize "view modes" and "form modes" based on role Drupal 8 has extended the View Modes concept to Form modes

Is it possible to assign a role to both "View Modes" and "Form Modes"?
How does one assign a mode both view mode or form mode to be shown at a particular place ? Say I wish to Full content view mode shown at certain page and Teaser view mode show in a block at another location. Similarly I want form mode A show during create and form B during edit.

For example there is a content type with following Fields

Title : displayed publicly, editable by author
Body : displayed publicly, editable by author
Project code : Not displayed publicly, displayed and editable by author
System code : only visible/editable by admin

Essentially this could be an interesting and performant way to implement field permissions. The field permissions module has no port for Drupal 8 yet.

Nothing in core uses form modes - it's an API waiting for contrib to make use of.
This, and the question of when to manipulate form fields and when form modes, is discussed at:
https://www.drupal.org/node/2530086.

There Berdir says "Showing/Hiding fields but keep them otherwise the same is IMHO a perfect use case for hook_entity_field_access() not switching out the form display. I'd only try to do something like [switching form  mode] when you want to show different widgets based on the user roles."

In general, managing display differently for different roles is easy, managing forms differently is more difficult.

Alternatives to the field permissions module for managing display (NOT forms):

The classic answer might be that this is a job for the Panels family, but it's mostly not quite ready for D8.  Page manager is however quite usable and does much of what you want. For specifically created pages, it can control the content based on role. What it won't do is take over the rendering of all nodes of a certain content type.

Display suite is D8 ready, and allows you to show fields based on permissions by using token fields. See https://swsblog.stanford.edu/blog/using-display-suite-provide-field-level-permissions for a description of the procedure in D7, which is only cosmetically changed for D8.


how to change taxonomy term fields before being created first time I'm trying to copy parent's image field to a "goint to be created" taxonomy term using this code but it isn't working:

function my_module_taxonomy_term_insert($term) {
    if ($term->vid == 29) {

        //if any of parents have logo then copy it
            foreach ($term->parent as $p) {

            if (isset($p->field_image[LANGUAGE_NONE][0]['fid'])) {
                //copy the image
                $filepath = drupal_realpath($p->field_image[LANGUAGE_NONE][0]['uri']);

                // Create managed File object and associate with Image field.
                $file = (object) array(
                            'uid' => 1,
                            'uri' => $filepath,
                            'filemime' => file_get_mimetype($filepath),
                            'status' => 1,
                );

                $term->field_image[LANGUAGE_NONE][0] = (array) $file;
            }
        }
    }
}

How to do this?

In Drupal 7, you can achieve this by using the following taxonomy APIs

hook_taxonomy_term_insert : Act on taxonomy terms when inserted.
taxonomy_term_load : To load the taxonomy by using term ID
taxonomy_term_save : To update the taxonomy by using term ID

/**
 * Implementing hook_taxonomy_term_insert
 */
function hook_taxonomy_term_insert($term) {
  $vid = 2; //User your vid
  if (is_object($term) && $term->vid == $vid && isset($term->parent)) {
    //get parent tid using $term->parent array
    foreach ($term->parent as $ptid) {//check image for each parent, if image exist assign and exit
      if ($ptid > 0) {//except root
        //get parent image WHERE field_data_field_image_vocab_image is the parent image field
        $pfid = db_select('field_data_field_image_vocab_image', 'pimg')//change field_data_field_image_vocab_image with your field name
            ->condition('pimg.entity_id', $ptid, '=')
            ->fields('pimg', array('field_image_vocab_image_fid'))//change field_image_vocab_image_fid with your image fid name
            ->execute()->fetchField();
        $update_taxo = taxonomy_term_load($term->tid); //load created taxonomy
        if ($pfid > 0 && empty($update_taxo->field_image_vocab_image)) {//image exist for this parent $ptid and image is not assigned yet
          $update_taxo->field_image_vocab_image[LANGUAGE_NONE][0]['fid'] = $pfid;
          taxonomy_term_save($update_taxo); //update taxonomy after assigning image
          break; //break after saving the image
        }
      }
    }
  }
}

Note :

Change the field names
Go through the comments for explanation.


Language switcher links are hidden for anonymous users I'm trying to add a language switcher to a Drupal 8 site menu (it's switching between English and Spanish). I have the links working when logged in as admin but they're not shown for anonymous users, even though the language switcher block displays fine, as well as adding a language switcher through twig. However, I'd really like to get this working and be able to add it to menus through a custom module.

As an anonymous user I am able to view the translated content (by clicking the Default Drupal language switcher options) but these links that are created are not rendered.

Here's my code for the custom module:

MYMODULE.links.menu.yml

MYMODULE.switch:
  class: Drupal\MYMODULE\Plugin\Menu\MenuLanguageLink
  menu_name: MENUNAME
  route_name: '<current>'
  options:
    attributes:
      hreflang: 'en'
MYMODULE.switch_2:
  class: Drupal\MYMODULE\Plugin\Menu\MenuLanguageLink
  menu_name: MENU2NAME
  route_name: '<current>'
  options:
    attributes:
      hreflang: 'es'

/src/Plugin/Menu/MenuLanguageLink.php:

<?php
/**
 * @file
 * Contains \Drupal\MYMODULE\Plugin\Menu\LanguageSwitchController.
 */
namespace Drupal\MYMODULE\Plugin\Menu;

use Drupal\Core\Menu\MenuLinkBase;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class MenuLanguageLink extends MenuLinkBase implements ContainerFactoryPluginInterface {

  /** @var array Available languages */
  protected $languages = [];

  /**
   * {@inheritdoc}
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    LanguageManagerInterface $language_manager
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->languages = $language_manager->getLanguages();
  }

  /**
   * Dependency injection.
   */
  public static function create(
    ContainerInterface $container,
    array $configuration,
    $plugin_id,
    $plugin_definition
  ) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('language_manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function updateLink(array $new_definition_values, $persist) {
    return $this->pluginDefinition;
  }

  /**
   * {@inheritdoc}
   */
  public function getOptions() {
    $options = parent::getOptions();
    $langcode = $options['attributes']['hreflang'];

    if (isset($this->languages[$langcode])) {
      $options += ['language' => $this->languages[$langcode]];
    }

    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function getTitle() {
    $langcode = $this->getOptions()['attributes']['hreflang'];
    if ($langcode == 'es') {
      return 'Español';
    } else {
      return $this->languages[$langcode]->getName();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getDescription() {
    return $this->t('Switch Language');
  }

}

After installing your module, I can confirm the behavior that you're seeing.

When I change the route to <front> I am able to see the links as anonymous.

What I know is that the menu system automatically checks if the user has access or permission before it displays the links.

So my first thought is there must be a Core bug with this <current> route.

When I check /core/modules/system/system.routing.yml all I see is:

'<current>':
  path: '<current>'

Which is interesting that this route doesn't have an access nor a permission key.

In /admin/people/permissions if I check this permission:

  Link to any page

  Warning: Give to trusted roles only; this permission has security implications. This allows to bypass access checking when linking to
  internal paths.

I can see the links as anonymous, but obivously we do not want to this.

When I try to add <current> via the UI, I cannot; even though, <front> is acceptable.

Therefore, my best educated guess, seems to me that the <current> route is not designed to be used in Menu links because it doesn't have an access key nor permission key. Also, this might explain why the language switcher is a block and not a menu link.

However, there is work around for this if you pro-grammatically print the menu and not perform an access check, but there is a caveat. You would have to make sure there is no link in this menu that anonymous is not suppose to see.

As per code provided in Menu system, "Rendering" section, comment out the access check part.

Example:

    $menu_tree = \Drupal::menuTree();
    $menu_name = 'MENUNAME';

    // Build the typical default set of menu tree parameters.
    $parameters = $menu_tree
      ->getCurrentRouteMenuTreeParameters($menu_name);

    // Load the tree based on this set of parameters.
    $tree = $menu_tree
      ->load($menu_name, $parameters);

    // Transform the tree using the manipulators you want.
    $manipulators = array(
//    // Only show links that are accessible for the current user.
//    array(
//      'callable' => 'menu.default_tree_manipulators:checkAccess',
//    ),
      // Use the default sorting of menu links.
      array(
        'callable' => 'menu.default_tree_manipulators:generateIndexAndSort',
      ),
    );
    $tree = $menu_tree
      ->transform($tree, $manipulators);

    // Finally, build a renderable array from the transformed tree.
    $menu = $menu_tree
      ->build($tree);
    $menu_html = drupal_render($menu);

    print $menu_html; // print the menu

If the above does not suffice, because of the caveat, you might want to look into

  Potentially write a custom menu tree manipulator, see
  \Drupal\Core\Menu\DefaultMenuLinkTreeManipulators for examples. This
  is only necessary if you want to do things like adding extra metadata
  to rendered links to display icons next to them.

  source: Menu System

I believe here you will be able to target specifically the language menu links and make Drupal skip the access check only on those specific language links which would be the best solution.


Can db_select cope with mysql "case when" structures? I have a complex mysql query with "case when" to combine values across multiple rows in columns. I'm currenty using db_query, but I would like to use the TableSort and Pager extenders. But (correct me if I'm wrong) those only work with db_select.

This is the query:

SELECT gsid, created_by_uid, difficulty, gametime, max(submitted_on), score, mission, name,
 ifnull(max(case when mission = 1 then score end),0) as mission_1,
 ifnull(max(case when mission = 2 then score end),0) as mission_2,
 ifnull(max(case when mission = 3 then score end),0) as mission_3,
 ifnull(max(case when mission = 4 then score end),0) as mission_4,
 ifnull(max(case when mission = 5 then score end),0) as mission_5,
 ifnull(max(case when mission = 6 then score end),0) as mission_6
FROM `game_sessions` m
INNER JOIN `users` u ON m.created_by_uid = u.uid
GROUP BY created_by_uid

The game_sessions table contains a row for each game mission that a user played. The game mission can be 1-6. This query gives me an overview with the maximum score for each mission per user (each row is a user).

Is it possible to rewrite this query using db_select? I'm using Drupal 7.

SelectQuery has the addExpression() method for adding arbitrary expressions. e.g.

$query = db_select('game_sessions', 'm')->fields('m');
$query->addExpression('ifnull(max(case when mission = 1 then score end),0)', 'mission_1');

Yields:

SELECT m.*, ifnull(max(case when mission = 1 then score end),0) AS mission_1
FROM {game_sessions} m


.htaccess 301 redirects breaking clean URLs I am trying to make a couple of (I think) very basic rewrite condition / rules in .htaccess.

I placed them as the first rule after RewriteEngine on. Things seemed fine locally, and the rules appeared to work in .htaccess tester under each scenario.

However, when I pushed the code live, clean urls stopped working. Everything was only accessible as its route, i.e. /node/1234 instead of /foo/page.

Here are the rules I added:

<IfModule mod_rewrite.c>
  RewriteEngine on

  # Custom redirects
  RewriteRule ^ptistore/control/interviews(.*) http%{ENV:protossl}://%{HTTP_HOST}/nurse-interviews [NC,L,R=301]
  RewriteRule ^ptistore/control/news(.*) http%{ENV:protossl}://%{HTTP_HOST}/cpn-numbers [NC,L,R=301]

So, any hit on either URL should 301 to the provided URL. I tested them locally and they appeared to work (and not break clean URLs), but when I pushed it up to our Acquia environments, URLs were no longer rewritten.

I wound up implementing a RouteSubscriber to get around this for the moment:

/**
 * Class RedirectSubscriber
 * @package Drupal\mymodule_redirects\EventSubscriber
 */
class RedirectSubscriber implements EventSubscriberInterface {

  public function redirectIndexPHP(GetResponseEvent $event) {
    $request = $event->getRequest();
    $uri = $request->getRequestUri();

    if (preg_match('/ptistore\/control\/interviews\/.*/i', $uri)) {
      $response = new TrustedRedirectResponse('/nurse-interviews', 301);
      $event->setResponse($response);
    }

    if (preg_match('/ptistore\/control\/news\/.*/i', $uri)) {
      $response = new TrustedRedirectResponse('/news', 301);
      $event->setResponse($response);
    }
  }

  static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = array('redirectIndexPHP', 39);
    return $events;
  }
}

Which works... but I really would rather it live in .htaccess.

Did I just place my rules too early in the file? How can I correct this?

No idea how acquia hosting works, but I doubt they respect your .htaccess and possibly don't even use Apache.

Maybe they have their own configuration settings for that, I know that platform.sh (which uses nginx) does.

If not, then you don't really have a choice but to do it in Drupal.

You could also try the latest redirect release which has a new submodule that supports domain and wildcard based redirects.