Add webform field programmatically In older versions of Webform (Drupal 7), the function webform_component_insert() can be used to add fields to a webform, for example inside a hook_node_insert() implementation, so they are added when the webform is created.
Does anyone know how to do that in Webform 6.x? I would like to add fields to webforms automatically after they are created.

You can alter a webform by modifying the YAML content of the config field elements:
use Drupal\webform\Entity\Webform;
use Drupal\Core\Serialization\Yaml;

  $webform = Webform::load('contact');
  $elements = Yaml::decode($webform->get('elements'));

  // add a field
  $elements['additional_field'] = [
    '#type' => 'textfield',
    '#title' => 'Additional field',
  ];

  $webform->set('elements', Yaml::encode($elements));
  $webform->save();


Get tag(term) name for multiple nodes without a performance hit I want to get a list of nodes and return them as JSON along with their tags (names included). After a lot of research, I've only come up with this solution:

I have an array of Nodes (\Drupal\Core\Entity\EntityInterface) loaded with Node::loadMultiple().

Iterating over the array of nodes, and getting their tags using $node->field_tags (or whatever the machine name of the tags is) which yields an array of \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem

Getting all the terms of the node using Term::loadMultiple() and then iterating over them and getting the name using $term->name[0]->value.

The problem is that there's an extra database read for every node, and I guess that the underlying query for this read is a JOIN :|.

Question: Is there an efficient way to load the tag (term) names along with target_id, target_type, target_uuid, etc? If no, is the current loop on each node the way to go???

More Info:

I'm paginating the results
The client can set the number of results per page, but there's a 50 nodes per page limit

Thanks

P.S.: I have two more types of tags so I have to do this two more times. Bright side is, the other two tags are 1to1.

If you're already looping over an array of nodes, have you considered collecting the term IDs before loading them in one query? That should save a lot of the overhead of running multiple queries:

$map = [];
$tids = [];

// Collect IDs for each node:
/** @var \Drupal\node\Entity\NodeInterface[] $nodes */
foreach ($nodes as $nid => $node) {
  /** @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $item */
  foreach ($node->field_tags as $item) {
    $tid = $item->target_id;
    $map[$nid][$tid] = $tid;
    $tids[$tid] = $tid;
  }
}

// Load terms and collect their labels:
$term_labels = [];
/** @var \Drupal\taxonomy\Entity\TermInterface $term */
foreach (Term::loadMultiple($tids) as $tid => $term) {
  $term_labels[$tid] = $term->label();
}

// Assign the term labels to each node.
foreach ($map as $nid => $node_tids) {
  foreach ($node_tids as $tid) {
    $map[$nid][$tid] = $term_labels[$tid];
  }
}


How do I set permission for a custom page to be based on node access? I have added pages using hook_menu like so:

function dynamic_entries_menu() {
    $items = array();
    $items['entries/get'] = array(
            'title' => 'Dynamic Entries',
            'page callback' => 'dynamic_entries_get_entry',
            'type' => MENU_CALLBACK
    );
    return $items;
}

A node ID is added to the end of the URL. For example, /entries/get/10. I want to allow access to this page to anyone who has access to the requested node. How do I do that?

Use entries/get/%node as path and node_access() as access callback. Also, you might want to consider setting page arguments. It's not a good idea for the page callback to fetch the node id from the URL or using the  arg() function.

$items['entries/get/%node'] = array(
  'title' => 'Dynamic Entries',
  'page callback' => 'dynamic_entries_get_entry',
  'page arguments' => array(2),
  'access callback' => 'node_access',
  'access arguments' => array('view', 2),
  'type' => MENU_CALLBACK,
);

BTW the function node_menu() is the hook_menu implementation of the node module. Looking up how the Drupal core modules implement certain hooks often helps.


How can I display the last modified date on my site? I am using Drupal 7, and I would like to include a PHP snippet on my home page that displays the date the site was last updated (i.e., had content added or modified).

How can I go about doing this?

Assuming you just want to check nodes (and not other content, like users), you'll want to check the node table and find the row with the latest changed timestamp. This function should do the trick:

/**
 * Get the last updated date for nodes.
 *
 * @return
 *   A formatted date for the last updated time if there are published nodes,
 *   FALSE otherwise.
 */
function _mymodule_last_updated() {
  // Pull from cache if available
  if($cache = cache_get('mymodule_last_updated')) {
    $last_updated = $cache->data;
  }
  else {
    // Otherwise, find the timestamp for the latest node record
    $last_updated = db_select('node', 'n')
      ->fields('n', array('changed'))
      ->condition('status', 0, '>') // only published nodes count
      ->orderBy('changed', 'DESC')
      ->range(0, 1)
      ->execute()
      ->fetchField();

    // If nothing found, return FALSE.
    if (!$last_updated) {
      return FALSE;
    }

    // Otherwise, save the data to cache for one hour.
    cache_set('mymodule_last_updated', $last_updated, 'cache', time() + 3600);
  }

  return format_date($last_updated);
}

Now, wherever you wanted to put the information, just call _mymodule_last_updated():

if ($last_update = _mymodule_last_updated()) {
  $last_update_text = t('Last updated: @name', array('@date' => $last_update));
}
else {
  $last_update_text = t('There have been no updates lately.');
}

However, I'd suggest creating custom module and defining a block. This would allow you to avoid having to mess with the PHP code any time you wanted to move the information around, and expose it to others who don't have access to the source code.

Once you've created your custom module, you want to implement the hook_block_info() and hook_block_view() hooks:

/**
 * Implements hook_block_info().
 */
function mymodule_block_info() {
  $blocks['mymodule_last_updated'] = array(
    'info' => t('Last updated block'),
  );
  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function mymodule_block_view($delta = '') {
  $block = array();

  // Only act if it's our block
  if ($delta == 'mymodule_last_updated') {
    $block['subject'] = t('Last updated');

    if ($last_update = _mymodule_last_updated()) {
      $block['content'] = t('The site was last updated on @date.', array('@date' => $last_update));
    }
    else {
      $block['content'] = t('There have been no updates.');
    }
  }

  return $block;
}

Once defined, your new block would show up in Structure → Blocks.

Note: in all of these snippets, you'll want to replace mymodule with your custom module's name.


What determines what "view" gets displayed first on a page? Lets say I have 2 views, that both need to be displayed on the same page and in the same content region. What determines which one gets displayed first over the other? I have looked around in the settings, but I can't seem to find them. I want to switch/flip my views around, but there doesn't seem to be a option to do this.

If you refer this Question on stackoverflow: How does Drupal Views decide between multiple displays with the same path, I think he has described both situations of views in his answer as separate paragraph and second paragraph is your answer.

I am pasting the entire answer here of @Andrew Aledge,

  If you're referring to the display within the views: each view display
  has a position and the displays are loaded according to that position
  in an ascending sort. So if you create a page display (which may get a
  position of 2 since the Default display typically has a position of 1)
  and then create another page display after that, the next page display
  may get a position of 3. The customer will be exposed to the position
  it reaches first (2, provided that they have met the criteria).

  If you're referring to the views themselves: views are loaded in order
  of their view id (vid). The customer will be exposed to the first one
  loaded.

If you see the LAST TWO Lines, he has mentioned on which basic the views decide which view will be displayed and which one not. He means that Provided all conditions same, the view will be shown as per the view id(vid)

Other situation: Apart from above two situation, Which view user will see if they have different Roles. So in that can I think It will be decided based on which user has access to which view(I mean based on thier role access), and if same user has access to multiple views then in this case it will decided again based on vid.

I think, above three discussion have cover all the various situation of visibility of view.


How to completely disable 'further instructions sent to email' message after sign up How to completely turn off/remove message 'Further instructions have been sent to your e-mail address.' that appears after registration? I'm using logintobogan module and I can see some customization than can be made to registration confirmation page, but none of these settings direct this particular message. It appears every time, also if I use redirection to completely custom thank you page?

Any idea?

You can use rules redirect the user to a pre-defined URL upon registration. This should over-ride whatever default behaviors you are seeing now...

Back up your database.
Enable Rules
Navigate to admin/configuration/workflow/rules
Add new Rule

Event: 'After saving a new user account'
Action: 'Page Redirect' (optionally 'force redirect')


How to add captcha to "Printer, e-mail and PDF versions" email form I am using the Printer, e-mail and PDF versions module to enable user to share pages on my d6 website.
Now I  have recently noticed that some robots make thousands of requests on this form a nd I need a captcha to prevent it. How can I do that?

Thanks

I just added my send form ID to the CAPTCHA form list, and it worked fine.


JSON:API error unprocessable entity status 422 entity_id this value should not be null I'm trying to post a flag with JSON:API but I'm getting the following error:
"errors": [
    {
        "title": "Unprocessable Entity",
        "status": "422",
        "detail": "entity_id: This value should not be null.",
        "source": {
            "pointer": "/data/attributes/entity_id"
        }
    }

I'm very confused because in the data I'm posting, the entity_id is definitely included...

Check if you have the JSON:API Extras module enabled.
If you do, you or someone else may have disabled the field for the resource you are trying to POST to at /admin/config/services/jsonapi/resource_types.
In this case, I had disabled the entity_id field for my flag resource, causing the "null" error even when I posted a value with axios.


Is custom token module sustainable for masive use? Is the Custom Token module sustainable for massive use or should I create custom module?

Custom Token will be used for generating URL path, "massive use" means hundreds or thousands of nodes created per day.

In general - no, this shouldn't be a performance issue for your use case. The main problem identified with token module and pathauto is in generating the Token UI screen when dealing with a large number of tokens. There are good discussions on this here on stackexchange but I've also found that using the token tweaks module can resolve most of these.

In your use case case, your using just one token to generate the URL path which is then saved to the path alias table, a table optimized and indexed for performance. The only real demand is on token implementation but this is only done once, when saving the article and you're using objects that are already loaded (ex. $user, $node->nid) to generate it so it won't be a performance issue.


Views listing of nodes and node title as exposed filter When I started this view I thought it would be simple… But it's not.

I've an "Office" content type and a view (block) where are listed my "Office" nodes as teaser.

First of all it could be great if the result should be sorted with AJAX, but it's only an option.
I would like an exposed dropdown list filter with all the nodes title of my "Office" content type. But it seems I could only expose an input search field.

I already looked at BEF and several posts here but I didn't find a clear solution.

Finally found a solution with Views Selective Filters. :)

By added a "Regions" field in my content type I've been able to get only the regions with results exposed as a filter in my views.


How do I get the route name of a view page? In my custom submit handler I want to redirect to a view page Url, let's suppose my view name is team and its path is /admin/team, I find out I should  use $from_state->setRedirect('route'); but when I tried $from_state->setRedirect('/admin/team'); Faced with error, How can I get view route name in?

The correct routename for view is view.VIEW_MACHINE_NAME.PAGE_MACHINENAME(in another word "view.$view_id.$display_id" ) . try something like following

use \Drupal\Core\Url;

$url = Url::fromRoute('view.VIEW_MACHINE_NAME.PAGE_MACHINENAME');
$form_state->setRedirectUrl($url);

and for your case

$url = Url::fromRoute('view.team.page_1'); // page_1 is my guess as to your page name, please replace it with your page machine_name

Lean more : How to formulate the route name

after @4k4 comment, Also you can redirect form to custom router with URL

just need use $form_state->setRedirectUrl($url)


How to get the value of a node field? In node.tpl.php I am trying to get the raw value but the problem is that when I use render:

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

it does not just return field_image value but formats and outputs the whole image.

I need a way to get only the field's raw value. How can I achieve this?

To get the real value and not  a themed one...

You can use http://api.drupal.org/api/drupal/modules!field!field.module/function/field_get_items/7

 $my_field_items = field_get_items('node', $node, 'field_my_field');

Or use Entity API module and entity_metadata_wrapper

 $node_wrapper = entity_metadata_wrapper('node', $node);
 $field_val = $node_wrapper->field_test->value();

Take a loot also at http://www.computerminds.co.uk/articles/rendering-drupal-7-fields-right-way


Can use taxonomies to I build a list of "conditions" that can be added to and referenced from different nodes? I need to build a list of "conditions" that can be added to and references from different nodes. "Conditions" have a title and body. This screamed taxonomy but what's stopping me is that the "conditions" need the ability to modify the body field on a node-by-node basis.

It's a bit difficult to explain but I need:

A library of content that can be referenced and can grow, like taxonomy.
When referenced, the content has to be able to be modified but only that instance (don't modify the referenced entity site-wide). This will will be like an override for the reference.

I can to the first part with taxonomies but don't know how to override on a node-by-node basis as it's just a reference. It seems as if the referenced entity needs to populate a field on the node, and there it can be overwritten.

EDIT: Found the solution using this: https://www.drupal.org/project/entityreference_autofill. I added a long text field on my taxonomy and my content and mapped them together.

I'm not sure if you can get this done with taxonomies. However I would recommend you to have a look at either of those modules also (or "instead"?):

Entity reference.
Entity connect.

These 2 modules are also recommended in the (illuminating) article "Relativity Model for Drupal", for which this is an introduction to it (quoted from this linked page):

The Relativity Data Model for Drupal is a zero-custom-code, collection of steps, procedures and methods that strive to help site builders, users and site visitors interact with Drupal in a far easier and more efficient way. This is done by:

Data architecture and data modeling merging as a single step through a documentation procedure.
Customized user interfaces that cater to individual workflows throughout permission roles.
Multi-level relational data structures that relate to other multi-level relational structures.
Mimicking the concept of database joins within Drupal's UI's.
Vastly reducing the size of Drupal sites by a small handful of modules that provide greater power, speed and expansion capabilities.

The small handful of modules (cfr. the last bullet) is detailed on Interface elegance and experience.


How to refer paths relative to the theme directory? I have a theme called Eternal with the following data in it's eternal.info file-

name = Eternal
description = A Customized Drupal 7 Theme
core = 7.x
engine = phptemplate

In the template folder lies the page.tpl.php. Under the /themes/ folder, the address becomes -

/eternal/templates/page.tpl.php

There are several lines inside the page.tpl.php that require I define a path for an image, like so-

The /images/ folder is located inside the /eternal/ folder, so to access it from /templates/ one would need to travel one level up and then access the /images/ folder. That would look like this - /../images/.

The problem is, I cannot define a link that works in Drupal. And I'm sure the images exist in that directory.

I've tried these-

<img src="<?php drupal_get_path('theme', 'eternal'); ?>/images/facebook_icon.png" alt="image comes here">

It just shows the alt text in every case. No image. How to accomplish this and what is the recommended and proper way to do this?

<?php print drupal_get_path('theme', 'eternal'); ?>

as you've already tried, is the correct way to solve your problem. Notice though that you have to print it out as well, as drupal_get_path will only return the path, not print it for you.

I can't immediately think of any reason why it would not work in your case. Some potential suggestions to try could be

Double-check your spelling of the theme name in the code.
Clear caches.
Try disabling the theme/module and re-enable it.

Failing everything else, you'll need to debug drupal_get_filename() directly.


Button that changes form field value based on other field values (D8) I made a simple form with two input fields and a button. The button is supposed to enter the sum of the two input fields in a third field. I want the value in the third field to be editable by the user.
I've tried to change the default_value with an ajax callback, but that doesn't work. I can change all other field properties though (description, placeholder, title, ...), but not default_value.
I also tried changing the value through form_state -> setValue() in a custom validate function that I attached to the button. But form_state seems to be reset to the initial value upon form rebuild.

This is my code:

  class calculatorForm extends FormBase {

  public function getFormId() {
    return 'calculator_example';
  }

  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['#prefix'] = '
';
    $form['#suffix'] = '
';

    $form['number1'] = array(
      '#type' => 'textfield',
      '#weight' => 0,
      '#title' => $this->t('number 1'),
    );

    $form['number2'] = array(
      '#type' => 'textfield',
      '#weight' => 1,
      '#title' => $this->t('number 2'),
    );

    $form['button_sum'] = array(
      '#type' => 'button',
      '#name' => 'sum',
      '#value' => t('+'),
      '#weight' => 2,
    );

    $form['sum'] = array(
      '#title' => $this->t('sum'),
      '#type' => 'textfield',
      '#weight' => 3,
    );

    // attempt with validation function
    $form['button_sum']['#element_validate'] = array([$this,'calculator_example_custom_validate']);

    // attempt with ajax callback
    $form['button_sum']['#ajax'] = array(
      'callback' => [$this,'sumValues_ajax_callback'], //'sumValues_ajax_callback',
      'event' => 'click',
      'wrapper' => 'calculator-form-wrapper',
      );

    $form['sum']['#description'] = t('calculated sum');
    return $form;
  }

  function sumValues_ajax_callback(array &$form, FormStateInterface $form_state)  {
    $n1 = $form_state->getValue('number1');
    $n2 = $form_state->getValue('number2');
    $sum = $n1 + $n2;
    $form['sum']['#placeholder'] = $sum;
    $form['sum']['#default_value'] = $sum;
    return $form;
  }

  function calculator_example_custom_validate($element, &$form_state, $form) {
    $n1 = $form_state->getValue('number1');
    $n2 = $form_state->getValue('number2');
    $sum = $n1 + $n2;
    $form_state->setValue('sum' , $sum);
    drupal_set_message($this-> t('sum is '). $sum);
    $form_state->setRebuild('true');
  }

  public function validateForm(array &$form, FormStateInterface $form_state) {  }

  public function submitForm(array &$form, FormStateInterface $form_state) {  }

}

Does anyone know why $sum doesn't appear as a value in the 'sum' field? What am I doing wrong?

Thanks a lot!!

I found the solution myself. In case someone else stumbles upon this: In the ajax callback you need to change #value instead of #default_value.

So this callback works:

function sumValues_ajax_callback(array &$form, FormStateInterface $form_state)  {
   $n1 = $form_state->getValue('number1');
   $n2 = $form_state->getValue('number2');
   $sum = $n1 + $n2;
   $form['sum']['#placeholder'] = $sum;
   $form['sum']['#value'] = $sum;
   return $form;
}


Inherit areas of parent or ancestor page I have a website built with Drupal 7. Each page on the site can have an infinite number of child pages. Each page has "areas"; an area can be a thing such as left or right side bars that contain blocks, views or attributes/fields of the page content type (e.g., page.sponsor_ad_1, page.sponsor_ad_2).

I want the child pages inherit the areas of its closest ancestor page by default. A content editor can override it afterwards.

What's the best way to achieve this? What module does, completely or partially, what I need?

It depends how arbitrarily flexible the layouts need to be but:

For the layout switching you could probably use Omega and Delta http://drupal.org/project/delta

Then write your own custom context condition that says "does this page have a parent with the layout X?" then use the reactions provided by Delta to switch to layout X for the closest parent.

For the defining/storing what layout is associated with each "page" you could just use the Field API. If each "page" is a node then it will be easier for you, otherwise you might have to also define a new type of Entity for your site.


Drush Make and the Windows maximum path length When building Commerce Kickstart on Windows, using Drush Make, a customer has this problem:

copy(C:\Users\User\AppData\Local\Temp\make_tmp_1449319094_5662dab66a8f0
\__build__\profiles\commerce_kickstart\modules\contrib/commerce_discoun
t/modules/commerce_discount_usage/includes/views/handlers/commerce_disc
ount_usage_handler_field_commerce_discount_analytics.inc): failed to
open stream: Invalid argument filesystem.inc:267

It results in the Drush error "Project commerce_discount (7.x-1.0-alpha6) could not be downloaded".

The build works on non-Windows platforms.

I notice that the file path is 264 characters long, and I suspect this is a problem of the Windows MAX_PATH constant (variously quoted on the web as being 255, 256, or 260 characters).

Is there a way to get around this?

I should note: I have read the drupal.org issue about Kickstart on Windows (https://www.drupal.org/node/1648992)

The Drush temporary directory can be set manually in the environment variable TEMP. So something like:

mkdir -p /c/drushtmp
TEMP=/c/drushtmp drush make [...]

can neatly solve the MAX_PATH problem for the temporary directory.


How to make a Role label display? Is there an easy way to list someone's "role" sort of like a badge, next to their username?

I dont want any point system or anything like that

I'd use Views to create a View of Users, and then you can add fields as you like.


How to add new reference in entity reference field in node edit form keeping old references intact and hidden? In my project, there is a content type 'song' containing an entity reference field to reference content type 'playlist'. More than one user can edit a 'song' to add it to their own 'playlist's.

Now, when one user updates a 'song' node creating his/her references in the node edit form, the previous references made by another user are deleted. In the node edit form, the field is formatted through an entity reference view showing a list of 'playlist's only created by the current user. The number of values for the entity reference field is set to unlimited.

What would be a good and server-friendly approach to solve this problem keeping in mind that there can be an unlimited number of previous references made by other users?

Edit the field and set number of values to be unlimited. If you want more control and flexibility you could put the entity reference within a field collection.


Mark New Nodes in Views via Template I have a portfolio view that displays all items in the portfolio. The fields are set via template so I do not have access to the fields area in views to select the parameter there, I have to do it within my node template.

The issue is I can't figure out what code to stick in there to display the "New" tag if the visitor has not yet viewed the node.

This is the code I have in the template:

<a href="<?php print $node_url?>"><?php print $title;?>

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

I have googled and found the info here (https://api.drupal.org/api/drupal/includes!theme.inc/function/theme_mark/7) but I just can't figure out how to translate it to what code I put in my actual template file to make it happen.

Thank you so much for your help.

Thank you for your answer!  I am primarily a themer and php just is not my strong suit.

I have changed my code to be:

<a href="<?php print $node_url?>"><?php print $title;?>

  <?php print strip_tags(render($content['field_portfolio_categories'])); ?>
  <?php
    if (node_last_viewed($node->nid) > 0) {
       print '' .  theme('mark', array('type' => MARK_NEW)) . '';
    }
  ?>

This code displays the "new" text, but only if I am logged in as the administrator and it displays on all items, not just ones I have not visited yet.  Any ideas?

<?php print theme('mark', array('type' => node_mark($node->nid, $node->changed))); ?>

this is how it is done on the content overview page. give it a try, it will display read for anonymous users' - probably ..,

here's the code from node_mark, where node_last_viewed is used:

function node_mark($nid, $timestamp) {
  global $user;
  $cache = &drupal_static(__FUNCTION__, array());

  if (!$user->uid) {
    return MARK_READ;
  }
  if (!isset($cache[$nid])) {
    $cache[$nid] = node_last_viewed($nid);
  }
  if ($cache[$nid] == 0 && $timestamp > NODE_NEW_LIMIT) {
    return MARK_NEW;
  }
  elseif ($timestamp > $cache[$nid] && $timestamp > NODE_NEW_LIMIT) {
    return MARK_UPDATED;
  }
  return MARK_READ;
}

so for you maybe this could be used (statistics module needs to be enabled)

 <?php
      if (node_last_viewed($node->nid) == 0) {
        print '<span>' .  theme('mark', array('type' => MARK_NEW)) . '</span>';
      }

best to call this theme function (and any logic) in the preprocess method, and use a variable in the template ..


Related nodes displaying same related data drupal 7, using views and eva.

So i have restaurant nodes and menu nodes, and all menus nodes relate to a restaurant node, now i have a duplicate restaurant node which is just showing an alternative location for the same franchise, how can i reference the menu nodes related to the first restaurant node into the 2nd duplicate one? (which has a seperate nid)

So end result i am looking for, is if node-rest1 is called, it displays the node-rest1 output, followed by the related nodes (currently using eva), and if i open node-rest2 it shows node-rest2 output followed by the related menu nodes from node-rest1.

is this possible and if so how?

The duplicate node with different locations is in question. I would do it using the Location module which can add multiple locations to a single node.

  Location Add Another: Allows you to quickly add new locations to a
  node.

In your case, you can even add many locations to a restaurant node without creating duplicates. The menus nodes can be entity reference to each restaurant node.


Publish Blog Post command line I've been looking around the Internet trying to investigate how to publish a blog post via either rest APIs or other command line tools. However, I have not found a way to do this. How can I publish a blog post (or node) either through a command line, rest APIs, or another way programmatically?

Drupal 6 has a module to publish to a site via external GUI applications. It supports different XML-RPC based blogging APIs, such as the Blogger API, the new Blogger Data API, the MetaWeblog API, and most of the Movable Type API.

In Drupal 7, the module has been removed from core, and it is now a third-party module.

Reference

BlogAPI: post from blog tools


How to correct my rule to update user info on login using HybridAuth? I'm using Drupal 7.5x and the HybridAuth Social Login module.

I am aware a lot of users have done this using Rules and Rules Event HybridAuth login, combined with Set a data value. However no one explains what comes after, it seems the Hybridauth tokens are either not editable or just invalid.

So I am using the the Rules Event User logged in through HybridAuth, and I want to set a data value. Here is an export of the rule I have so far:

{ "rules_updateinfo" : {
    "LABEL" : "updateinfo",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "TAGS" : [ "login" ],
    "REQUIRES" : [ "hybridauth" ],
    "ON" : { "hybridauth_user_login" : [] },
    "DO" : []
  }
}

I want to update the token user:hybridauth:profileURL with the new data provided by the API (= hybridauth:profileURL). However when trying to input any of these tokens into the data selector, either of the following errors show up:

If I use Data selector: hybridauth:profileURL, the error is:

  "The selected data property doesn't support writing."

If I use Data selector: user:hybridauth:profileURL, the error is:

  "Data selector user:hybridauth:profileURL for parameter data is invalid."

I'm sure I'm doing something wrong, can someone help me to get such rule to work? Is it even possible?

Some more details about the errors you encountered:

Data selector user:hybridauth:profileURL for parameter data is invalid.

Using the Rules Event like you're using, there doesn't seem to be something like user:hybridauth:profileURL, which I believe explains this error.
The selected data property doesn't support writing.

To understand the reason for this error, have a look at:

The question about "How to fix entity property X doesn't support writing, when setting content type field values?".
The Rules issue titled "The selected data property doesn't support writing." when Action: Set a data value is applied to a taxonomy field:tid.

With that, I'm fairly sure that the answer to the "Is it even possible"-part of your question is:

  I'm afraid it is NOT ... Though I'd love to see anybody tell me I'm wrong.


How can I add paragraphs to a translated node? I have a problem with the Paragraphs module and translation. I'm using Drupal 8.7.7 and Paragraphs 8.x-1.9.

When I add a translation to a node with a paragraphs field (unlimited), I can only translate existing fields in this paragraph, but I cannot add new values on the translation node.

I followed the instructions given in the docs on  https://www.drupal.org/docs/8/modules/paragraphs/multilingual-paragraphs-configuration and in fact, if I didn't I wouldn't have been able to even see the fields in the translation edit form.

I have no idea, how to set this up correctly.

I installed the Paragraphs Asymmetric Translation Widgets module which somehow says, it deals with it, but it does not. I used the Widget 'Paragraphs Classic Asymmetric' in the form display, but to no avail.

I'm really desperate now.

If I remember this right this is by design (or maybe more a technical necessity). And you can only circumvent this by having multi-value fields inside a paragraph type. Like a node reference field for example. This then can have a different number of items per language and even in a different order.

You could also add a new untranslatable "Visibility" field to each paragraph type, like Paragraphs Collection is offering it, see 2846682#comment-11887724 for example. Then you add different paragraphs in the original language but set them to be displayed only in selected languages.

And regarding Paragraphs Asymmetric Translation Widgets you may file a bug report in its issue queue.


How can I change the node path shown to the user? How can I change the path part of the node URL from ?q=node/2 into something more meaningsful. I want, for instance, to display it like this: ?q=Services.

Assuming you're using Drupal 7, to manually set a name for a module, all you need to do is to login as admin and navigate to Configuration → URL aliases.  There you can create string aliases for nodes, so that node/2 is aliased to Services.

For the nicest URLs, you should also enable Clean URLs on you site.

If you do not want to do this yourself, but instead want want names to be assigned to node paths automatically (based on some set of rules), then you can install and enable the PathAuto module.


Extend a modules database table I would like to extend the schema of another module's ("Rooms") database table.

I have my own module for alterations of that module (specifically the Rooms-module)

Rooms has "Options" with Name, Value..etc...

I want to add "Description" to Options.

My question:

is it possible to alter the database-table of another module..??

How would I start to change this?

I'm a litle confused about your goal, but taking your question literally as I would like to extend the schema of another module, and assuming by extend you mean alter and not inherit from, then yes, it's pretty straightforward.

First of all, implement hook_schema_alter() so that Drupal knows about the change you're going to make to the table:

function MYMODULE_schema_alter(&$schema) {
  $schema['rooms']['foo_table']['new_column'] = array(
    // ...
  );
}

Then add an update hook to your module's install file to physically add the field to the table, e.g.

function MYMODULE_update_7100() {
  $schema = drupal_get_schema_unprocessed('rooms', 'foo_table');
  db_add_field('foo_table', 'new_column', $schema['new_column']);
}

It would also be advisable to implement hook_uninstall()/hook_disable() to remove that column from the table when your module is no longer active. Leaving it there probably won't hurt anything, but for the sake of cleanliness it's a good idea.


Alter Multiple Field Values by Testing "Field Type" Drupal 8.x

I would like to alter the value of all/any ckeditor/text fields on a node.

Currently working with HOOK_node_presave().

Ideally, I'd like an agnostic approach that doesn't mind where the field is coming from, e.g. paragraph, node, taxonomy, etc.

How can I loop through all fields, check the field type, get and replace the value?

MYMODULE.module

Working with the below code gets me close I think:

use Drupal\Core\Entity\EntityInterface;

function MYMODULE_node_presave(EntityInterface $entity) {
  $fieldsArray = \Drupal::service('entity_field.manager')->getFieldMapByFieldType('text_long');

  foreach($fieldsArray as $longTextName=>$key) {

    kpr($key); // This returns an array of the values I need.
    if ($entity->hasField($key)) {
      $entity->get($result)->value = preg_replace(
        $toReplace,
        $replaceWith,
        $entity->get($result)->value
      );
    }
  }

}

Try #2;

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;

function MYMODULE_presave(EntityInterface $entity) {
  // Get form config.
  // Get config Node field names.
  // Get config Paragraph names.
  // Get config Paraghraph field names.

  // Loop through our Node field names.
  foreach($nodeFieldNames as $fieldName) {
    // Check if the entity has field.
    if ($entity->hasField($fieldName)) {
      // Get the field.
      $entity->get($fieldName)->value = $newValue;
    }
  }

  // Loop through our Paragraph names.
  foreach($paragraphNames as $paragraphName) {
  // Check if the entity has field.
  if ($entity->hasField($paragraphName)) {
    $paragraphs = $entity->$paragraphName->getValue();
    foreach ($paragraphs as $paragraphItem) {
      $p = \Drupal\paragraphs\Entity\Paragraph::load( $paragraphItem['target_id'] );
      foreach($paragraphFieldNames as $paragraphFieldNamesitem) {
        if ($p->get($paragraphFieldNamesitem)->value) {
          // kpr($p->get($paragraphFieldNamesitem)->value);
          $p->get($paragraphFieldNamesitem)->value = $newvalue;
          // kpr($p->get($paragraphFieldNamesitem)->value);
          // This does alter the value, just does not get saved.
        }
      }
    }
  }
}

You can use FieldConfigInterface to get fields info.
Try the following:

use Drupal\Core\Field\FieldConfigInterface;

function MYMODULE_node_presave($node) {
  //- Call helper function to get all the fields
  $fieldsArray = getContentTypeFields($node->bundle());
  //- Loop through fields
  foreach ($fieldsArray as $fieldName => $fieldConfig) {
    ///- Example to check if type is text_with_summary
    if ($fieldConfig->getType() == 'text_with_summary') {
      /**
       * @TODO : Something here for field of type text_with_summary
       */
    }
  }
}

/**
 * Helper function to Get all fields of content type:
 *
 * @param $contentType
 *
 * @return array
 */
function getContentTypeFields($contentType) {
  $entityManager = Drupal::service('entity.manager');
  $fields = [];
  if (!empty($contentType)) {
    $fields = array_filter(
      $entityManager->getFieldDefinitions('node', $contentType), function ($field_definition) {
      return $field_definition instanceof FieldConfigInterface;
    }
    );
  }

  return $fields;
}


How to compare the already saved value of node and updated value? I want to programmatically compare a field value of a node in hook_node_update(). How can I get the already saved and the updated values?

node_save(), which invokes hook_node_update(), contains the following code.

// Load the stored entity, if any.
if (!empty($node->nid) && !isset($node->original)) {
  $node->original = entity_load_unchanged('node', $node->nid);
}

So, every time a node is updated, $node->original will contain the node object before it is updated.

To get, for example, the value the field_example field had before the update, you use the following code.

$old_value = field_get_items('node', $node->original, 'field_example');

To get the updated value for the same field, you use the following code.

$new_value = field_get_items('node', $node, 'field_example');


Hide Workflow Tab For Given State I am developing moderation workflow using Workflow modeule. I have created different states for that. And using rules module I am putting node into one of the state based on certain event. It is working fine.

Now to emulate the Moderation process, I wanted to hide workflow tab (that appears on node page) when node is in certain state, and to display tab only when node is in one of the given states.

Is there any way I can achieve this?

-- Many thanks for your time.

Solved it using hook_menu_alter and adding custom module. I have modified the access callback function to suit my needs.

Here is my code, may help user having same task:

    function mymodule_tab_menu_alter(&$items) {
        $items['node/%node/workflow']['access callback'] =
        'custom_workflow_tab_node_access';
    }

    function custom_workflow_tab_node_access($node = NULL) {

    global $user;

    if ($workflow = workflow_get_workflow_type_map_by_type($node->type)) {
        if ($workflow = workflow_get_workflows_by_wid($workflow->wid)) {
            $roles = array_keys($user->roles);
            if ($node->uid == $user->uid) {
                $roles = array_merge(array('author'), $roles);
            }
            $allowed_roles = $workflow->tab_roles ?
            explode(',', $workflow->tab_roles) : array();

          if (user_access('administer nodes') || array_intersect($roles, $allowed_roles)) {

      /* This is additional Condition*/

      if ($node->type == "article") {
     $current_state = workflow_get_workflow_states_by_sid(workflow_node_current_state($node));
                    if ($current_state->state == "State_name") {
                        return FALSE;
                    } else {
                        return TRUE;
                    }
                } else /*End Additional Condition */{
                    return TRUE;
                }
            } else {
                return FALSE;
            }
        }
    }
    return FALSE;
}

As above in custom access callback, I have used the same code, just added the additional condition and it solved my issue. :)

-- Thanks


Access denied to file in sites/all/default/files I am getting:

access denied   04/30/2013 - 16:56  sites/default/files/styles/thumbnail/public/KRIS... admin

in my error message log when trying to do some file updating. I am guessing this is a permissions problem, but i am running on a local server. How do I change permissions in drupal for access to read/write to the files folder on a mac in terminal?

Drupal.org has a great guide on permissions.

The TLDR; version.

You can change permissions by opening up your terminal and perform the following commmand:

(sudo) chmod <mode> <path>.

For more information about chmod, check the manpage. Or just perform:

chmod --help


AJAX dependent select I know this has been asked before and I'm trying to use the example at Dynamic select list in the form (dependent dropdown) but I am struggling to get the desired results.

The goal:
Have a form that presents the user with a Platform select field. Once selected take the value from that field pass it to the a SQL statement to render an additional select field with a list of results from the query. Right now the following code displays both select fields when the form renders. I would like only the platform select field to be rendered until the user chooses an option.

I'm a little bit confused about the AJAX function and how you wrap another select item to be marked for replacement when the page is called again so any explanations or pointers would be great.

Per @Clive I've adjusted the code below. However I'm fighting with pulling the selected value into the model lookup query statement. Right now as is the form doesn't even render.

Update 2

I've been cleaning up my code and catching small stupid errors. Which have yielded: 1)AJAX call back working. 2)Hiding the model select field when the platform select hasn't changed.

However I can't seem to make the model field appear when an option is selected in the Platform field. I suspect it's a problem with if (isset($form_state['values']['platform'])) {. Updated full code below. I feel close to completing this just need some guidance.

Full Code

function iosupload_menu() {
$items = array();
$items['ios_upload/form'] = array(
  'title' => t('IOS Upload'),
  'page callback' => 'iosupload_form',
  'access arguments' => array('access content'),
  'description' => t('IOS Upload'),
  'type' => MENU_CALLBACK,
);
return $items;
}

function iosupload_form() {
return drupal_get_form('main_iosupload_form');
}

function main_iosupload_form($form, &$form_state) {
//Define SQL Lookup Query
$sqlplatform = "SELECT vid, name FROM {taxonomy_vocabulary} WHERE vid >= 4";

$result = db_query($sqlplatform);
$options = array();
  foreach ($result as $row) {
    $options[$row->vid] = t($row->name);
  }

$form['platform'] = array(
  '#type' => 'select',
  '#title' => t('Select a Platform'),
  '#options' => array(
    0 => t('- Select -')) + $options,
  '#default_value' =>  0,
  '#required' => TRUE,
  '#ajax' => array(
    'callback' => 'ajax_select_callback',
    'wrapper' => 'replace_model_div',
    'effect' => 'slide',
   ),
);
if (isset($form_state['values']['platform'])) {
 $platform_value = $form_state['values']['platform'];
 $sqlmodel = "SELECT tid, name FROM {taxonomy_term_data} WHERE vid = $platform_value";
 $result = db_query($sqlmodel);
 $options = array();
   foreach ($result as $row) {
     $model_options[$row->vid] = t($row->name);
    }

$form['model_wrapper'] = array(
  '#type' => 'select',
  '#title' => t('Select a Model'),
  '#options' => $model_options,
  '#options' => t('$platform_value'),
  '#prefix' => '
',
  '#suffix' => '
',
);
}
return $form;
}
function ajax_select_callback($form, $form_state) {
  return $form['model_wrapper'];
}

A few problems I can see:

The $model_options variable is used both in the form and AJAX callback function, but isn't defined anywhere. Same thing with the $platform variable in the AJAX callback.
You're putting a wrapper around a particular element, but instead of returning that element you're returning the entire form.
It looks like you're attempting to put form-altering logic into the AJAX callback function - it should be used only to return the updated element, the actual building of it should be done in the form function.
You're defining the AJAX callback wrapper as 'replace_model_div', and implementing it as a class name instead of an ID, and with a complete different name (model-wrapper).
The function signature for your form is wrong (in Drupal 7 it's:

function form_name($form, &$form_state)

You should get some joy with code a bit more like this:

function main_iosupload_form($form, &$form_state) {
  //Define SQL Lookup Query

  $sqlplatform = "SELECT vid, name FROM {taxonomy_vocabulary} WHERE vid >= 4";
  $sqlmodel = "SELECT tid, name FROM {taxonomy_term_data}";

  $result = db_query($sqlplatform);
  $options = array();
  foreach ($result as $row) {
    $options[$row->vid] = t($row->name);
  }

  $form['platform'] = array(
    '#type' => 'select',
    '#title' => t('Select a Platform'),
    '#options' => array(
      0 => t('- Select -')) + $options,
    '#default_value' => isset($form_state['values']['platform']) ? $form_state['values']['platform'] : 0,
    '#required' => TRUE,
    '#ajax' => array(
      'event' => 'change',
      'callback' => 'ajax_select_callback',
      'wrapper' => 'replace_model_div',
      'method' => 'replace',
     ),
  );

  if (isset($form_state['values']['platform'])) {
    $model_options = function_to_get_model_options_by_platform($form_state['values']['platform']);

    $form['model_wrapper'] = array(
      '#prefix' => '
',
      '#suffix' => '
',
    );

    $form['model_wrapper']['model'] = array(
      '#type' => 'select',
      '#title' => t('Select a Model'),
      '#options' => $model_options,
    );
  }

  return $form;
}

function ajax_select_callback($form, $form_state) {
  return $form['model_wrapper'];
}


The requested page "/mywebsite/?q=admin%2Fcontent%2Fnode&render=overlay" could not be found When I am logged as an administrator and try to access Content from the administrator menu, the corresponding window pops up, with the add content link, but just below, I get the following error message:

The requested page "/mywebsite/?q=admin%2Fcontent%2Fnode&render=overlay" could not be found.

although content already exists. What is causing this and how can I get rid of it? I am on Drupal 7 release 12. Thanks.

Update

If anyone has ideas, tips, suggestions about what is causing (or could cause) this issue, it is welcome. Could I have modified the config by accident (if yes, which)? Is there a tool (other than FireBug) to debug this issue? I plan to re-install a system from scratch and check whether the error happens too. Thanks.

Update II

Here is what I get when requesting Content from the Administrator menu:

When I click on Amdinistration, I get the following:

First, I notice something strange: an empty entry in the provided list. Why? I don't know.

Second, when I click on Content from this page, I am not facing the issue I reported above. I noticed a difference in the URLs between both methods:

http://www.mysite.com/#overlay=%3Fq%3Dadmin%252Fcontent%252Fnode <- NOT OK
http://www.mysite.com/#overlay=%3Fq%3Dadmin%252Fcontent <- OK

The url you have posted translates to

admin/content/node?render=overlay

This is how the overlay works, which displays a regular page, but adds a param to tell drupal it should be rendered as the overlay (no header, footer etc is rendered).

The problem could be that overlay is disabled, or that the url isn't encoded as it should.

If you use clean urls, you shouldn't see the ?q=...


Render a node field inside page.html.twig I have an image field on my content type (field_hero_image).

I don't want it to render in the node.html.twig file. However, I DO want to render it in the page.html.twig file. Specifically, I want to render it alongside the page title.

What code would I use in my page.html.twig file to access node level fields and render them?

(There is a similar question posted, but I was unable to use the answer provided there to solve my problem.)

This for Drupal 8 theming.

After doing quite a bit more research, I was able to find enough pieces in other questions and on drupal.org to achieve what I wanted to do.

No pre-processing is needed for this answer, so no code needs to be added to your mytheme.theme file.
All of these variables are already accessible in page.html.twig by default.

To render a field's default value inside page.html.twig, you would typically use a Twig variable as in {{ node.field_some_name.value }}.

If you have an image field, and want to render the URL to the image stored in that field inside the page.html.twig template, you would use {{ file_url(node.field_some_image.entity.fileuri) }}.

Finally, if you want to render the title of a node inside the page.html.twig template, you would use {{ node.label }}.

I also learned how to use some Twig conditionals for my particular issue, but that is beyond the scope of this question/answer.


Commerce Kickstart 2 - Disable ajax in seach products backend How can I disable ajax in admin/commerce/products (Commerce Kickstart 2 menu)? I've searched  in Search API settings but found nothing.

Edit: I found that the View Commerce Backoffice: Products (Content) control the search of products in admin/commerce/products. In section Advanced > OTHER there is field Use AJAX. You can set to Yes or No this field. But even if you set to No, when you search for a product the query is made before you press Enter, what is exactly my client want.

So the question persists, is there a way to change this behavior, to be able to search only when you press Enter?

You can install (if it's not installed yet) Better Exposed Filters. If you edit the View in admin/commerce/products/list (or any of them) and you select BEF for displaying your exposed filters (using defaults) then the autosubmit feature will no longer work.

On the other hand, see https://www.drupal.org/node/1735254 for an explanation on how to disable the autosubmit feature. It's just adding a CSS class to your filter. You have to find out how to add classes to exposed filters in Views, though. Some dirty jQuery can help, I guess.


Webform save draft after each field update I need to save a draft of the webform after each field change. I know that you can save a draft by clicking a button (or between pages in multi-page forms) and my initial tough was to do a form_alter, add an ajax callback to fields and call the submit handler for save_draft. Had anyone tried something like this?

Some conditions:

If there is an existing draft for the current user, it needs to update that one (not create a new one);
it needs to work for anonymous users as well.

Drupal 7 + Webform 7.x-3.x

I'll post the answer here if I manage to do it, but any feedback would be appreciated if there are people who've done this before.

Ok, I've found this http://drupal.org/node/1319926 and based on it I've managed to make it work. This is my ajax callback (it can be attached using hook_form_alter(), based on your needs):

function _my_module_js_draft($form, &$form_state) {
  global $user;
  $draft_sid = _webform_fetch_draft_sid($form['#node']->nid, $user->uid);

  $form_state['values']['details']['sid'] = $draft_sid;
  $form_state['values']['op'] = !empty($form['actions']['draft']['#value']) ? $form['actions']['draft']['#value'] : t('Save Draft');

  $form_state['save_draft'] = TRUE;
  webform_client_form_pages($form, $form_state);
  webform_client_form_submit($form, $form_state);

  return $form;
}

For having the save draft functionality available for Anonymous I've used this patch: http://drupal.org/node/1932560#comment-7185674


How do I count the number of Facebook likes in articles? I am working on a Drupal 8 site. I added fblikebutton to my articles to enable users to like content.

Is it possible to get the number of likes for each article as field? I am using the Views module to show the latest 3 articles, as in the following screenshot.

Probably setting the layout to button_count will do all the magic ;)
This should be available in settings, or can be changed in MYTHEME_preprocess_fblikebutton.

Or use modules which provide this functionality, like:

social_counters and shariff have D8 versions.
views_fb_like counts your likes. (D7 only yet)
facebookshare implements this in combination with social_stats. (D7 only yet)


Views entity reference based on passed in value I have a set of taxonomies that are related to a role- each member of the role gets their own set of values, plus a default value that is common to everyone. For example:
uid | tid | taxname
20 | 200 | name1
20 | 201 | name2
20 | 202 | name3
21 | 203 | name4
22 | 204 | name5
0  | 205 | default
So users 21 & 22 each have 1 term plus the default term, user 20 has 3 terms plus the default term.

I am trying to figure out how to setup an entity reference View that would display the terms available to each user. I know how to setup the entity reference View based on the uid as a contextual filter, but can't figure out how to bring in the default value as well.

Ended up doing a somewhat convoluted hack with a custom module.

1) Used 2 Conditional Filters in the View (A- uid of logged in user, b- uid=0)

2) Used regular filter of the taxonomy type (C).
Since Conditional Filters are ANDed together as well as ANDed with any normal filters, the derived WHERE logic of View is (A AND B) AND C (which would never return results unless the logged in user was user 0, but the query isn't available to anonymous users).

3) Created a custom module and used the following in hook_views_query_alter:
$query->where[0]['type']='OR'
So the WHERE logic of the altered view becomes (A OR B) AND C, which gives me the results I wanted.


field_widget_form get value I am creating a custom field and I am looking to get the value of a textfield during node creation. In the callback I need to get the value of the textfield, how do I do this?

function field_zoekproduct_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
      switch ($instance['widget']['type']) {
        case 'field_zoekproduct_field' :

          $element['searchfield'] = array(
            '#title' => t('Zoek naar een product'),
            '#type' => 'textfield',
            '#required' => TRUE,
            '#maxlength' => 115,
            '#size' => 55,
            '#weight' => 0,
            '#default_value' => 'zoek...',
            "#executes_submit_callback" => FALSE,
            '#attributes' => array('onfocus' => "this.value = '';"),  //when textbox gets focus the default value will be removed
            '#ajax' => array(
                  'event' => 'change',
                  'callback' => 'zoekproduct_zoek_getypte_text',
                  'keypress' => true,
                  'wrapper' => 'dropdown-second-replace',
                ),
        );

  return $element;
}

Your callback must look like this
zoekproduct_zoek_getypte_text($form, &$form_state){}

check what values you receive in $form_state or $form


How to redirect programatically using a route with parameters? I am trying to use the Passwordless module API to redirect the user on login.

I want to redirect the user to a specific node edit page (node/12/edit).

In hook_passwordless_login_redirect(), the module redirects the user with this code:

return $this->redirect($redirect);

So here is my implementation:

function MYMODULE_passwordless_login_redirect_alter(&$redirect) {
  // You can use hasPermission() with currentUser, but need to load for hasRole()
  $account = \Drupal\user\Entity\user::load(\Drupal::currentUser()->id());
  $test = \Drupal::service('path.validator')->getUrlIfValid('node/12/edit');
  if (!($account->hasRole('admin'))) {
    $redirect= $test->getRouteName();
  }

The problem is that I get this error:

  Some mandatory parameters are missing ("node") to generate a URL for
  route "entity.node.edit_form".

The missing route parameter is the node id, which I can get with $test->getRouteParameters().  But how do I pass this to the redirect?  (How do I call the redirect and give it both the route name and the route parameters?)

As pointed out by @4k4, the problem is that the module did not ask for the route parameters, so I patched it.

Then you can call the redirect like this:

  if (!($account->hasRole('admin'))) {
    $routename = $test->getRouteName();
    $routeparameters= $test->getRouteParameters();
  }


Change the way "add content" and "node's" are displayed I was wondering how one would go about changing the layout of the nodes when you are adding content, as well as when you view the full story.

I want certain text to be bigger, some fields to be placed side by side, some vertically. I want full control over the layout. I tried editing the CSS to change fonts and colors but it all changes fonts for the enitre website and not just in the node view. any thoughts?

page--node--[content-type].tpl.php = node template for a specific content type (no square brackets)

page--node--add--[content-type].tpl.php = node/add template for specific content type.

Copy/paste the code you have in node.tpl.php and clear your server cache. Now you can add custom classes everywhere or even create a custom HTML structure to render your fields. See the node.tpl.php documentation and Drupal 7 template suggestions.

Hope this helps!


How to get the number of items in a user's cart from commerce? I've been looking into the drupal 8 commerce module, I want to take the variable $count that is generated within

  ../commerce/modules/cart/src/plugin/block/CartBlock.php

and place it into a custom block in my own theme. I see that the build() function returns the count variable through #count which can then be accessed via twig. Just for reference Drupal commerce currently uses the template:

  ../commerce/modules/cart/templates/commerce-cart-block.html.twig

to output the variables and markup:

      {{ icon }}
      {{ count_text }}

  {% if content %}

        {{ content }}

        {{ links }}

  {% endif %}

My question is, how I can I make that variable global, are there any implications to just making it global, like what if the user updates the basket?

How do I go about achieving this? Does anyone have a possible solution?

you will have to use hook_preprocess_hook to achieve this by passing the variable to the template.

function template_preprocess_TEMPLATE_NAME(&$variables) {
    $variables['YOUR_VAR_NAME'] = $YOUR_VAR;
}

Then you can access your var in the template like so:

{{ YOUR_VAR_NAME }}


Render view for specific user, drupal_mail Is it possible to generate the content of the view as a specific user. So only the content the user has access to is rendered.

//Get view
$view = views_get_view("list_nodes");
//Pass arguments
$view->args = $locatie;
//Generate content
$content = $view->execute_display("block");

I got a custom module wich gets a list of users, to all those users the content of this view need to be send. But only the content the use has access to.

To render a view programmatically as a specific user, you need to adjust the global $user variable.

//Run script as a sepcific user
global $user;
$original_user = $user;
drupal_save_session(FALSE);
$user = user_load($uid);

//Your code goes here
....

//Return global variable to its orignal value
$user = $original_user;
drupal_save_session(TRUE);


Unable to remove label field from the registration form I am unable to remove the label from a form element of the registration form.

I have:

Enabled the kint module for debugging
Implemented hook_form_alter() and tried to change the form variables

function drupalfresh_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  kint($form);
  $form['field_company_name']['#attributes']['widget'][0]['#title'] = t('');
}

This doesn't change the form.

This is how the form element appears.

Actually the can be changed using this code:

$form['field_company_name']['widget'][0]['value']['#title'] = $this->t('WHATEVER');


Linking in views with multiple fields displayed I am making a view in Drupal 7 to display grants: the name, the description, the amount of the grant, and the due date for submission.

It's easy to make a view that displays the name, the amount and the date in each row of a table, with the name linking to the full node display.

I've also learned how to display the description below the title, using the rewrite rules for the title, like:

[title]

[body]

What I want is having only the title as link to the full node, not all the text. Can I do this?

Try this:

Format

Format: table
Show: fields

Fields

Content: Title

under "settings" check "exclude from display"

Content: Path

under "settings" check "exclude from display"

Content: Grant Amt
Content: Due date
Content: Body

under "settings" choose to rewrite output as follows:

[title]

[body]

... and then add filter and sort criteria as desired.


Dynamically Alter Node Edit Tab Link I would like to all the href of the edit tab link on several nodes.

IOW: instead of

example.com/node/%/edit

I would like to substitute my dynamically created link

example.com/products/$myproductid/edit

My first stab at this (just to see if I understood the wild cards):

function jch_utilities_menu_alter(&$items) {
  $items['node/%node/edit']['title'] = '1234';
}

...and this fires, BUT I don't understand how to pass the URL I want dynamically to it.

What I want to do is pass a variable from the node (a field variable) to that link.

I see that there is a page callback member of the array but that seems to call the node_edit page... which is over my head. I can't find a simple clear example of how to do this without a -lot- of study.

Is there no way to simply -force- a link href as one could do with jQuery?

TIA.

You can use a module call Sub Path Auto

here is a help video with an example that should work for you.

Module description :

  For example, if user/1 is aliased to users/admin, this module rewrites
  the link to the user contact page user/1/contact to use the aliased
  URL users/admin/contact instead. This also includes Views URLs taking
  a node as argument (e.g. node/%/yourview), in short, every URL that is
  based on, or extends, an existing alias. In combination with the
  Pathauto module it is possible to get rid of all remaining exposed
  internal non-administrative URLs.


Configuring Drupal 7 settings.php with both Memcache and Varnish I am noob to using both Varnish and Memcached. I have been following some copy and paste install guides.

I have both servers installed and running. Memcached seems to be working fine. Varnish is serving pages but there are a lot of cache misses. I am trying to enable the Drupal module to make Varnish aware to cache the pages, the css etc.

However, when I copy the settings.php snippet from the README.txt file in the Varnish module to my own settings.php I get a white page and this message in the Apache error log:

PHP Fatal error:  Class 'MemCacheDrupal' not found in /var/www/myhost/includes/cache.inc on line 31

Here is the cache section added to my settings.php. The Varnish part is commented out because it causes the above error with MemCached.

# Memcache
$conf['cache_backends'][] = 'sites/all/modules/contrib/memcache/memcache.inc';
// The 'cache_form' bin must be assigned no non-volatile storage.
$conf['cache_class_cache_form'] = 'DrupalDatabaseCache';
$conf['cache_default_class'] = 'MemCacheDrupal';
$conf['memcache_key_prefix'] = 'myhost';
# Varnish
// Add Varnish as the page cache handler.
#$conf['cache_backends'][] = array('sites/all/modules/contrib/varnish/varnish.cache.inc');
#$conf['cache_class_cache_page'] = 'VarnishCache';
// Drupal 7 does not cache pages when we invoke hooks during bootstrap.
// This needs to be disabled.
#$conf['page_cache_invoke_hooks'] = FALSE;

What is wrong with the Varnish snippet or with my setup in general?

I tried re-ordering to put the Varnish lines before the Memcached lines and I got this error:

PHP Fatal error:  require_once(): Failed opening required '/var/www/myhost/Array' (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/myhost/includes/bootstrap.inc on line 2308

I got it a little bit later. It was just the array format being different in the two sources I copies and pasted from. The problem line was:

#$conf['cache_backends'][] = array('sites/all/modules/contrib/varnish/varnish.cache.inc');

It should be:

#$conf['cache_backends'][] = 'sites/all/modules/contrib/varnish/varnish.cache.inc';


How can I verify email addresses? Here is the workflow

Users register with a valid email and a password
Drupal automatically sends an email to the new registered user
The email contains a link to verify the email
The email verification is performed

This is similar to email addition and verification of http://drupal.org. I can't find any module for that purpose. Some patches are available on https://www.drupal.org/node/115801. Any way?

That sounds like the core behaviour to: "Require email verification when a visitor creates an account"

However, the password will be selected after clicking the email verification link, to activate the account.


How do I set a Boolean field with "yes" and "no" values? I have a content type, I'm trying to add a field that's a boolean. I want the options to be yes or no. This is something I thought would be relatively simple however, I keep getting an error message. I've attached 2 screenshots. 1 is the configuration for my boolean. The other is the error message my site gets. Can someone help me. What am I doing wrong?

The Boolean field accept only 0 and 1 as value.
if you want to add allowed values by PHP Code should be:

0|No
1|Yes

I create a Boolean field on Content type and i set the On value to Yes and
 off Value to No.
As you see In the below screenshot the value of input is 0 for NO and 1 for Yes.


How can I build my own jquery ui theme and select it? I started using the datepicker from jquery. I noticed that by default it uses the provided theme in /core/assets/vendor/jquery.ui/themes/base/theme.css and /core/assets/vendor/jquery.ui/themes/base/datepicker.css.

There seems to be only the base theme available.

How can I create my own theme and tell drupal to use my jquery ui theme?

Ideally I would like to be able to select the jquery ui theme from a custom Drupal theme. This way I would be able to change automatically the jquery ui theme from the Appearance menu by changing the theme and use the existing overriding system if I have a sub theme inheriting from that theme.

Use libraries-override in mytheme.info.yml.

These are examples from test_theme.info.yml:

libraries-override:
  # Replace an entire library.
  core/drupal.collapse: test_theme/collapse
  # Remove an entire library.
  core/drupal.progress: false
  # Replace particular library assets.
  classy/base:
    css:
      component:
        css/components/button.css: css/my-button.css
        css/components/collapse-processed.css: css/my-collapse-processed.css
        css/components/container-inline.css: /themes/my_theme/css/my-container-inline.css
        css/components/details.css: /themes/my_theme/css/my-details.css
  # Remove particular library assets.
  classy/dialog:
    css:
      component:
        css/components/dialog.css: false
  # It works for JS as well.
  core/jquery:
    js:
      assets/vendor/jquery/jquery.min.js: js/collapse.js
  # Use Drupal-relative paths.
  core/drupal.dropbutton:
    css:
      component:
        /core/themes/stable/css/core/dropbutton/dropbutton.css: /themes/my_theme/css/dropbutton.css
  # Use stream wrappers.
  core/drupal.vertical-tabs:
    css:
      component:
        /core/themes/stable/css/core/vertical-tabs.css: public://my_css/vertical-tabs.css
  # Use a protocol-relative URI.
  core/jquery.ui:
    css:
      component:
        assets/vendor/jquery.ui/themes/base/core.css: //my-server/my_theme/css/jquery_ui.css
  # Use an absolute URI.
  core/jquery.farbtastic:
    css:
      component:
        assets/vendor/farbtastic/farbtastic.css: http://example.com/my_theme/css/farbtastic.css

Reference: https://www.drupal.org/docs/8/theming-drupal-8/adding-stylesheets-css-and-javascript-js-to-a-drupal-8-theme See subsection Overriding and extending libraries


How can I replace the Forum's vocabulary 'Forums' with my existing vocabulary 'tags'? I use a "tags" taxonomy for most content on my site. The "Forum" (core) module insists on using its own vocabulary ("Forums") and also seems to have automatically created a vocabulary for itself.

Is there a way to have the forum module use my existing "tags" vocabulary? I'd imagine forum topics tags with a tagged term to be listed in a teaser kind of preview when browsing that tags' vocabulary's matching term (alongside other content with that tag).

Edit: See below screenshot where I try to change the vocabulary in the forum content type field. The vocabulary choice is disabled.

After you enable the D7 core Forum module, you'll also have a "Forum topic" content type (and a "Forums" vocabulary as shown via admin/structure/taxonomy/forums).

Using the "Manage fields" tab of this content type (located at /admin/structure/types/manage/forum/fields), you can see the various fields for this content type. One of its fields is the "Forums" field (with machine name "taxonomy_forums"), with "Term Reference" as Field type.

Click the "Term Reference" link of the "Forums" field there, which brings you to /admin/structure/types/manage/forum/fields/taxonomy_forums/field-settings, where you can change its "Field settings".

There you will be able to change the (default) "Forums" vocabulary to (e.g) your existing "Tags" vocabulary (or any other vocabulary you have defined).

Attention: if on the "Field settings" screen the Vocabulary drop down is disabled (= you cannot select another vocabulary, as in the screenprint in the "PS" of the question), and you get an error message like "There is data for this field in the database. The field settings can no longer be changed.", then you'll have to think of a way to get around it somehow. A few more links that provide some more details on this (and possibly other alternatives):

Support issue ( = Error on changing field type: "There is data for this field in the database. The field settings can no longer be changed.").
Support request nr 1378894 ( = modifying "Field settings" with data in database).

Be careful when trying to get this fixed! Because things may get worse ...
You might consider a possible approach like this:

Create a new term reference Field for the Forum topic content type, and for which you then select the desired taxonomy.
After that, it should be OK to "delete" the original taxonomy_forums (machine name) field.

However, in doing so, the new term reference Field will have a machine name starting with a prefix field_. But if you then try to use that field (as part of the Forum module functionality), the Forum module might not use such  field_ prefix (you might get errors about that mismatch).

An alternative approach might be to uninstall/reinstall the Forum module, and then check if after enable you can change the taxonomy term field. However, in doing so, be aware that the taxonomy term "General discussion" of the taxonomy "Forums" (used by the module) is NOT deleted as part of the uninstall of the module. So before re-install (enable), you may want to try to manually delete that term and taxonomy first. If you don't do that, then you might end up with a taxonomy term like "General discussion" multiple times.


Fatal error: Call to undefined function media_filter I've upgraded Media module from 2.0-alpha2+6-dev and 2.0-beta1, however now I've the following error on some random pages:

( ! ) Fatal error: Call to undefined function `media_filter()` in my_module.module on line 224

My code in hook_field_formatter_view in my module is:

$element[0]['#markup']
  = '

'
  . media_filter($text_summary)
  . '' . $read_more_text . ''
  . '

';

The code of that media_filter function was:

function media_filter($text) {
  $text = preg_replace_callback(MEDIA_TOKEN_REGEX, 'media_token_to_markup', $text);
  return $text;
}

What is the current replacement for that function which I can use instead?

Prior to newer version of Media, media_wysiwyg_filter should be used instead which will perform media markup filter. This can be found in modules/media_wysiwyg/includes/media_wysiwyg.filter.inc.

The code is:

/**
 * Filter callback for media markup filter.
 */
function media_wysiwyg_filter($text) {
  $text = preg_replace_callback(MEDIA_WYSIWYG_TOKEN_REGEX, 'media_wysiwyg_token_to_markup', $text);
  return $text;
}


Drupal 7, Faceted results from Search Form I hope this is not a duplicate of something as I've been searching for hours and I'm pretty confused.

So what I need to do is to have a Search Form/Block like the one the core uses (I've already themed it so if I can use the same one would be splendid, if not, no problem), who's results will be organized in a faceted sort of way kinda like this:

Results:
All(100)
Cakes(43)
Wrappings(12)
Random Stuff(25)
Misc(25)

Cakes, Wrappings, Random Stuff and Misc would be Content Types, and clicking on them (links) should display in a view next to them the appropriate results (as thumbnails).

Since my Content isn't that much I'd like to avoid Solr if possible.

Any hints?

EDIT: In case this wasn't clear, the results are yielded according to given keywords, I don't want a simple sitemap.

Check out these tutorials for faceted / "drill-down" / filtering searching and browsing navigation without the need for solr.

http://envisioninteractive.com/drupal/drupal-7-views-with-faceted-filters-without-apachesolr/ (really good tutorial and this worked for me but for me the URLs need to be made more user friendly, not covered by this tutorial admittedly)

http://webwash.net/tutorials/intro-search-api-part-1-how-create-search-pages and http://webwash.net/tutorials/intro-search-api-part-2-faceted-search (similar to the first tutorial)

They use the Database Search module: https://drupal.org/project/search_api_db but the settings can be modified later to use SOLR for when your site hits the big time and needs the sophistication and scalability that SOLR provides. But for now, database search gets you going without needing SOLR.

For pretty URLs check out module: https://drupal.org/project/facetapi_pretty_paths - this module aims to make your URLs generated by the faceted filtering and search pretty.

The drupal recruiter distribution is an example of using facetapi_pretty_paths : https://drupal.org/project/recruiter
- on this page you'll find more information including how to run a demo via simplytest.me with just a few clicks!

Myself I will be working out how to use facetapi_pretty_paths in my project and any steps I that work I will follow up on here (not an empty promise as I do write up my findings whenever I can)


Render image that is linked I am loading an unmananged image file and would like to render it in a block, but it should be linked.
I have an uri (public://...) and I am able to render the image using

$build['my_image'] = [
          '#theme' => 'image_style',
          '#style_name' => 'large',
          '#uri' => $uri,
];

This works, but how can I render it beeing linked to some url?

image_formatter is to render an entity field, you can't use that without having that.

Try using a render array for the link, like this:

$type_link_nested_array = [
  '#type' => 'link',
  '#title' => ['#theme' => 'image_style', '#style_name' => 'large', '#uri' => $uri, ],
  '#url' => Url::fromUri('https://www.drupal.org'),
];


How to convert subset of users into a content type? I have a Google Map set on view of the node type. I am mapping several piece pieces of content on that map (group meeting locations, organization meeting places, etc). I would also like to be able to add my users to this map but I'm not given "users" as a content type in my list of options.

For this reason I want to take a subset of my users and create a new content type to add to the map. I know I could map a view the users, so it looks like users are a special content type.

So, it seem like the best approach is to create a content type based on a subset of my users (users that aren't admins, or who register under member, chapter head, etc roles).

I realize I could do this manually, and then have the admin add the users that match the criteria, but that seems like a work around, and fairly tedious.

With new users, I could probably hack together a rule that populates the content type from the profile fields, but I have a substantial amount of registered users already.

So, is there some way to populate a content type with user fields? Such that the content type was populated with the fields from every user of a particular role.

Content types are not optimal for this use case. Use entities instead.

Create an appropriate user entity to map. You can have several bundles within it to represent any relevant different types of users.

Then you will need to relate the user entities to the actual users. It's up to you how you do the relating. You can use entity references or the relation module.


Managed file validation on first upload only In D7,I have new_form with a managed_file field to allow my user to upload documents to public://. I'm trying to prevent my user from uploading a document if the file name they are trying to upload already exists in the system. So far I've been successful using this:

function mymodule_file_validate($file) {
  $filename = $file->filename;
  $errors = array();
  if (file_exists('public://' . $filename)) {
    $errors[] = t("File exists already!.");
  }
  return $errors;
}

This displays an error if the user browses for the file and presses upload, even before the file submission, which is exactly what I need.

However, I also have another form modify_form in this module that allows users to modify the document and in that case it's okay to upload the document with the same name even though the file name exists already. BUT... the function above blocks my modify_form too.

Any suggestions how to make the function apply only to my new_form? Or another way to prevent upload if file exists already only on new_form? Thanks!

I ended up adding a custom validator only to the new_form file upload field:

'#type' => 'managed_file',
'#upload_validators' => array(
      'file_validate_unique' => array($file),
)

and then added a function:

function file_validate_unique($file) {
   $errors = array();
   $filename = $file->filename;
   if (file_exists('public://' . $filename)) {
         $errors[] = t('The file could not be uploaded because a file by that name already exists in the destination directory.');
   }
   return $errors;
}

now it only validates the new_form and outputs an error right when the user tries to upload the managed_file, before the form is even submitted.


How to create a Views custom exposed filter with predefined range of date values (today, next 15 days, next month) I have a content type "event" with start_date and end_date (fields by date module).

A View lists this events and I need a custom exposed filter with a SELECT with 3 options:

-All-
Today
In the next 15 day
Next month

With the following comparison:

Today
(start_date <= NOW && end_date >= NOW)

In the next 15 days
(start_date <= NOW+15day && end_date >= NOW)

Next month
(start_date <= $next_month_last_day && end_date >= $next_month_first_day)

What is the best way to go to create the above custom filter?

I have to create a Views custom filter handler that does everything, in this case I can generate html select directly in the handler and expose it by default without pass trough views interface to check "expose this.."?
Or is best to FIRST create the above separate filters trough Views interface and then ALTER the form to combine all filters in a unique SELECT and then ALTER the query?

I've already take a look to Easy date selector for Views Exposed Date Filter but grouped filters are not a solution for me because I have to manage 2 dates, and not a single one (post date) as in that example.

I also look at How to customize exposed filter for date field? but I'm not sure if using templates like suggested is a good solution for me or there is a more elegant way to reach the goal.

Also found this module: https://www.drupal.org/project/views_between_dates_filter but doesn't provide the select I need.

Thank you very much for any help.

I've written a custom module exactly for this purpose but haven't released it as it ended up being a little less abstracted than I'd like.

The way you do it is by writing a Views filter handler (which is surprisingly easy). Without giving the whole game away and leaving a little homework for you: please read on. Let me know how you go.

You'll need a line in your .info file.

files[] = inc/views_relative_date_filters.inc

Register it with the Views API in the .module file.

/**
 * Implements hook_veiws_api().
 */
function views_relative_date_filters_views_api() {
  return array(
    'api' => 2,
    'path' => drupal_get_path('module', 'views_relative_date_filters') . '/inc'
  );
}

Register the Views handlers inc/views_relative_date_filters.views.inc

function views_relative_date_filters_views_handlers() {
  return array(
  // ...
  );
}

function views_relative_date_filters_views_data() {
  $data = array();
  // ...
  return $data;
}

And finally write the filter itself in inc/views_relative_date_filters.inc

class views_relative_date_filters extends views_handler_filter {
  // You'll need an options form (just use the parent)
  function options_form(&$form, &$form_state) {
    parent::options_form($form, $form_state);
  }

  // You can use a views_form or an
  function exposed_form(&$form, &$form_state) {
    // Return a Form API select element
    // ... all, this-day, this-fornight, this-month
  }

  // The query to get your results based on your time period
  function query() {
    $this->ensure_my_table();

    // Get the value of the submitted filter
    if (isset($this->value[0])) {
      $value = $this->value[0];
    } else {
      $value = 'all';
    }

    // A switch on the $value
    switch( $value ) {
      case 'all';
        return;
      case 'this-month':
        // Modify your query with where conditions, groups, joins, whatever
        // ...
        break;
      case 'this-fortnight':
        // Modify your query with where conditions, groups, joins, whatever
        // ...
        break;
      case 'this-day':
        // ...
        break;
      case default;
        break;
    }
  }
}


How to display a video file without using the video hosting websides? I need to display video file without using youtube, vimeo etc.
I am using the bootstrap theme. I've tried to using some modules with no luck:

Module: MediaFront, Field type: File, Display mode: MediaFront Player
File is not rendering at all.
Module: Video, Field type: Video On Chrome looks fine, but there is a
problem on Safari (can't debug it – tested on iPad).

I'm looking for some module/way that enables me to embed a responsive video.

The Media project (https://www.drupal.org/project/media) has support for displaying uploaded video files using native HTML5.


Can I refresh parent window through drupal_goto? I am working within iframe but hoping to refresh whole page through drupal_goto. Is it possible to do it ?

Thansk

drupal_goto will can be used to reload the same window. if you are in iframe, then it will reload the iframe, if you want to refresh the whole page you need javascript and you can add it inline using drupal_add_js

  drupal_add_js('parent.location.reload();',array('type' => 'inline'));


How to delete a node/nodes created by a user with rules? How would I delete a users content automatically when a certain rule triggers?

The content is of a certain content type.

Add an action for "Fetch by Property" > Node
Property > Author
Value > The user
Add a Loop
Add an action for "Delete an entity > List Item" inside the Loop (on the right)


Why does node_access_view_all_nodes() return true for anonymous users? On a Vanilla Drupal install (tested on D8 and D9), this will print "1":

drush eval 'echo node_access_view_all_nodes() . PHP_EOL;'

Stepping through the code reveals that it happens because there is a default grant for ALL nodes (nid = 0) for anonymous users in the node_access table (as far as I can see).

My question is about the rationale of behind this. The function description states:

  Determines whether the user has a global viewing grant for all nodes.

Why would the anonymous user have the permission to view all nodes by default? Why does this not correspond to what I see when trying to access various nodes as the anonymous user? Some nodes (e.g. unpublished nodes or anything blocked by a node_access hook) do return 403 when trying to load them as the anonymous user, so it obviously does not have access to all nodes. Is there another level of access checking hidden somewhere?

whenever drupal needs to check if a current user has the right or not to see a specific node it passes through this process :
1. check if current user bypass node access
In determining access rights for a node, \Drupal\node\NodeAccessControlHandler first checks whether the user has the "bypass node access" permission. Such users have unrestricted access to all nodes. user 1 (administrator) will always pass this check.

2.check Hook_node_access implementations
Next, all implementations of hook_node_access() will be called. Each implementation may explicitly allow, explicitly forbid, or ignore the access request. If at least one module says to forbid the request, it will be rejected. If no modules deny the request and at least one says to allow it, the request will be permitted,
in the Example bellow whenever any user(except admin) tries to view a node we will check if field_prevent_webmaster is checked the user will get access forbidden message.
/**
 * Implements hook_ENTITY_TYPE_access
 */
function modul_name_node_access(\Drupal\node\NodeInterface $node, $operation, AccountInterface $account) {

  // 1.limit the action according to the  operation performed on the requested entity
  switch($operation){
    case 'view': // when a user visit a node page ex : /node/52

      // 2.limit the current operation according to the current account information
      if( in_array('webmaster',$account->getRoles()) ){
        //3. then further limit the current operation according to the current requested node entity field
        // ex : if field_prevent_webmaster is checked prevent a user form
        // viewing the node through the /node/{id}
        if($node->hasField('field_prevent_webmaster') ) {
          if ($node->field_prevent_webmaster->value == TRUE) {
            return AccessResult::forbidden(); // send Access denied message to the client
          }
        }

        if($node->hasField('field_allow_webmaster') ) {
          if ($node->field_allow_webmaster->value == TRUE) {
            return AccessResult::allowed(); // send Access denied message to the client
          }
        }

      }
      break;

    case 'delete':// in /admin/content page u won't find the 'delete' button
      if( in_array('webmaster',$account->getRoles()) ){

        if($node->hasField('field_prevent_webmaster') ){
          if(  $node->field_prevent_webmaster->value == true){
            return AccessResult::forbidden();
          }
        }

        if($node->hasField('field_allow_webmaster') ) {
          if ($node->field_allow_webmaster->value == TRUE) {
            return AccessResult::allowed(); // send Access denied message to the client
          }
        }

      }
      break;

    case 'update': // in /admin/content page u won't find the 'update' button
      if( in_array('webmaster',$account->getRoles()) ){

        if( $node->hasField('field_prevent_webmaster')){
          if(  $node->field_prevent_webmaster->value == true){
            return AccessResult::forbidden();
          }
        }

        if($node->hasField('field_allow_webmaster') ) {
          if ($node->field_allow_webmaster->value == TRUE) {
            return AccessResult::allowed();
          }
        }

      }
      break;
  }
}

3.Getting permissions from node_access table
If all modules ignore the access request, then the node_access table is used to determine access and this more complicated then the previous 2 so we need to understand :
the node access table

nid: The node id that will be affected by this permission line.
gid(like user): the grant id, is simply a way to associate a user with a node.
realm(like user type): It can be pretty much anything you want to consider it as a user type that groups a set of grant ids (gid).
grant_view: Boolean indicating whether a user with the realm/grant pair can view this node.
grant_update: Boolean indicating whether a user with the realm/grant pair can edit this node.
grant_delete: Boolean indicating whether a user with the realm/grant pair can delete this node.

Example according to the node_access table bellow:

the user that have gid=2 and realm=node_atuthor, he can view and update the node 52.
the user that have gid=2 but a realm=node_super_user, he can view , update and delete the node 52.

Hook_node_access_records()
when a node is saved this hook will be executed, which enables us to fill the node_access table with the permission privileges that have already explore in the previous step.
/**
 * Implements HOOK_node_access_records
 **/
function entity_access_node_access_records(\Drupal\node\NodeInterface $node) {
   $grants = [];
   if( $node->isPublished() == TRUE) {
     $grants = [
       [
         'realm' => 'node_author',
         'gid' => $node->getOwnerId(),
         'grant_view' => 1,
         'grant_update' => 1,
         'grant_delete' => 0,
         'priority' => 0,
       ],
       [
         'realm' => 'node_viewer',
         'gid' => $node->getOwnerId(),
         'grant_view' => 1,
         'grant_update' => 0,
         'grant_delete' => 0,
         'priority' => 0,
       ],
       [
         'realm' => 'node_super_user',
         'gid' => $node->getOwnerId(),
         'grant_view' => 1,
         'grant_update' => 1,
         'grant_delete' => 1,
         'priority' => 0,
       ]
     ];
   }
  return $grants;
}

Hook_node_grants()
is called every time access to a node is requested to determine access and this is what is used to check the node_access table and decide who what nodes the current user can see:
/**
 * Implements Implements HOOK_node_grants
 */
function entity_access_node_grants(AccountInterface $account, $op) {

  // Allow the user that have 'see_omar_is_nodes' permission and that is also not omar :
  if ($account->hasPermission('see_omar_is_nodes') && $account->id() != 3){
      // to get This gid realm grants ( to see his content + Omar is content)
      $grants = [
        'node_super_user' => [$account->id()],
        'node_viewer' => [3]
      ] ;
  }

 // else if the user acount id =3 (omar)
  else if ($account->id() == 3){
    // get This gid realm grants of current user
    $grants =[
      'node_author' => [3]
    ] ;
  }


How to set and use direct files folder path in a multisite installation Drupal 8 multisite install where

First site is on a subdomain one.example.com
Second site is in a subfolder one.example.com/two

How can files folder for both sites to be accessible via URL/files and not URL/sites/domain/files

current: one.example.com/sites/one.example.com/files
desired: one.example.com/files
current: one.example.com/two/sites/two/files
desired: one.example.com/two/files

I tried several variants listed here https://www.drupal.org/node/53705 and put them at following locations, but nothing worked.

Drupal8/.htaccess
Drupal8/files/.htaccess
Drupal8/sites/two/files/.htaccess

Setup information is provided below

Filesystem setup

--Drupal8
  --index.php
  --one.example.com (sym link ln -s . one.example.com)
  --two (sym link ln -s . two) Not required in D8, but could not get the subfolder site to work without it.
  --sites
    --default (sym links to one.example.com)
    --one.example.com
      --settings.php, services.yml
      --files, modules,etc
    --two
      --settings.php, services.yml
      --files, modules,etc

Sites.php

$sites = [];
$sites['one.example.com'] = 'one.example.com';
$sites['one.example.com.two'] = 'two';

Apache setup : One virtual host for one.example.com

In /.htaccess, above other rewrite rules, use something like this example for foo.bar.com:

RewriteCond %{HTTP_HOST} ^foo\.bar\.com
RewriteRule ^files/(.*)$ sites/foo.bar.com/files/$1 [NC,L]


How to prevent a node from being saved/updated by using the Rules module? I've created a content type 'H'. The following rule (using the Rules module) has been built to prevent the node from being saved/updated if the field 'a' is larger than 5.

Event: Before saving content of type 'H'.

Condition: Data Comparison - Node field 'a' is larger than 5.

Action: Show a message on the site - Message type: Error.

Action: Go back to the front page.

It will show the error message if the condition is TRUE. However, the node is still being saved/updated.

Is it possible to control this without programming?

I'm not aware of a way to do what you're asking for by only using the Rules module ... And the (old) issue about "Prevent Node from being saved" (with confusing status "Closed (fixed)" ...) somehow seems to confirm you'd need "a bit more" ...

You can try to make it work by ALSO using the Conditional Rules module for this. Some more details about this module (from its project page):

  ... provides Rules plugins for conditionally altering execution flow directly inside a group of actions.

Here is a screenprint of a rule with an action that uses Conditional Rules (though only with an "if"-part here, no "else"):


Attaching Callbacks to Standard Drush Commands I would like to add a callback to fire after anyone runsdrush cc all. Ideally this behaviour would be enabled in a drush alias file. Is this possible?

By way of example, in this particular instance I am managing multiple developers across several environments. Each environment is capable of flushing one or more CDN caches, and will do so during various system routines.

I don't want dev, qa, or local environments flushing production caches. Given that drush cc all is an integral part of the deploy and local build processes, which runs right at the beginning no less, I would like to have calls to cc all (other than those against @prod) call a method to disable any CDN modules before exit.

Additionally, I may wish to run patch files or other bash scripts to ensure certain environments are up to date in situations where a developer may not be able to merge a dev branch but has resources accessible online which must be updated against security vulnerabilities. And so on.

Take a look at the sync_enable.drush.inc example file.  If you configure this example as it describes, then your alias file can be configured to disable any modules that you do not want to have enabled on staging or dev sites.  This is presuming that you are copying your database from @prod down to @stage or @dev.  Disabling as sql-sync time is probably best, as this will protect you if, for example, someone clears the caches through the admin interface on a dev machine.

If you do need to run code prior to the cache-clear command, you can easily do so, as Drush does provide a general callback mechanism that can be used to hook any Drush command.  sync_enable is just one example of this; a policy file is another example of the same thing.

To get started, first you will need a Drush commandfile.  We'll call it mycf.drush.inc in this example.  Drush will tell you what hooks are available for a command if you specify the --show-invoke global option.  There are many many possible hook functions, so you'll probably want to pipe the output through grep, and filter on your commandfile name.

$ drush cc all --show-invoke 2>&1 | grep mycf

drush_mycf_cache_clear_pre_validate
drush_mycf_cache_clear_validate
drush_mycf_pre_cache_clear
drush_mycf_cache_clear
drush_mycf_post_cache_clear

In your case, you would want to implement the function drush_mycf_pre_cache_clear(), and put whatever guard function you wanted in there.

I'm not sure what you are asking vis-a-vis patch files and bash scripts & c.; perhaps ask this part in another question with more specific details, if the Drush pre-and-post command hooks do not solve the problem for you.