How can I remove a message shown from a different module? - drupal

In Drupal 7, I could use the following code.
if ($_SESSION['messages']['status'][0] == t('Registration successful. You are now logged in.')) {
unset($_SESSION['messages']['status']);
}
What is the equivalent code for Drupal 8?

First of all, in Drupal 8, messages are stored in the same $_SESSION['messages'] variable as before. However, using it directly is not a good way, as there exist drupal_set_message and drupal_get_messages functions, which you may freely use.
Then, status messages are shown using status-messages theme. This means that you can write preprocess function for it and make your alteration there:
function mymodule_preprocess_status_messages(&$variables) {
$status_messages = $variables['message_list']['status'];
// Search for your message in $status_messages array and remove it.
}
The main difference with Drupal 7, however, is that now status messages are not always strings, they may be objects of Markup class. They are wrappers around strings and may be cast to underlying string using magic method __toString. This means that they can be compared with and as strings:
function mymodule_preprocess_status_messages(&$variables) {
if(isset($variables['message_list']['status'])){
$status_messages = $variables['message_list']['status'];
foreach($status_messages as $delta => $message) {
if ($message instanceof \Drupal\Component\Render\MarkupInterface) {
if ((string) $message == (string) t("Searched text")) {
unset($status_messages[$delta]);
break;
}
}
}
}
}

Upon reading the related change record, I have discovered \Drupal::messenger()->deleteAll(). I hope this is useful to someone. UPDATE: You should NOT do this, as it removes all subsequent messages as well. Instead, do unset(['_symfony_flashes']['status'][0]).

You can install the module Disable Messages and filter out messages by pattern in the configuration of the module.
For this particular case, you can filter out the message using the following pattern in the module configuration
Registration successful.*
Although the question is asked around Drupal 8 which is no longer supported, the module works for Drupal 7, 8, 9.

You can solve your problem in more than one way.
First way:
You can make minor change in core user module.
Go on:
\core\modules\user\src\RegisterForm.php
In that file you have line you can change:
drupal_set_message($this->t('Registration successful. You are now logged in.'));
NOTE: This is easiest way but in this case way you will edit Drupal core module and that is generally bad practice. In further development you could have problems like overwrite your changes when you do update.
Second way:
You can disable end user message using module. Disable message module have option you need. In module configuration you have text box where you can filter out messages shown to the end users.
Third way:
Messages in Drupal 8 are stored in a session variable and displayed in the page template via the $messages theme variable. When you want to modify the variables that are passed to the template before it's invoked you should use preprocess function. In your case here you can just search string in session variable and alert/remove it before it's displayed.
function yourmodule_preprocess_status_messages(&$variables) {
$message = 'Registration successful. You are now logged in.';
if (isset($_SESSION['messages'])) {
foreach ($_SESSION['messages'] as $type => $messages) {
if ($type == 'status') {
$key = array_search($message, $messages);
if ($key !== FALSE) {
unset($_SESSION['messages'][$type][$key]);
}
}
}
}
}
(Note:Untested code, beware of typos)
Hope this helps!

Related

Send Gravity Forms data to redirection page

I have a very simple form created with Gravity Forms;
It submits two numbers and then redirects to a different result page.
How do I retrieve those two numbers on the result page?
add_filter("gform_confirmation_4", "custom_confirmation", 3, 4 );
function custom_confirmation($confirmation, $form, $lead, $ajax)
Gives a custom confirmation. Each field value can be retrieved by using $lead[{field ID}]
I have a solution for this based on using a combination of form submission hooks and the GForms API. It's a horrible plugin so I apologise for the messiness of the logic flow. It's important to use the framework methods rather than processing the data yourself since there are a good amount of hacks and shonky things going on in there to correctly match field IDs and so forth.
I will provide a solution to pass a submission from one form to pre-populate another. Changing the destination for POST data is pretty straightforward, they have an example for it on their gform_form_tag hook documentation page. Yes, that really is the only way of doing it.
Without further ado here is the code. I've set it up to work off form configuration to make things simpler for the end user, so it works like this:
Select "allow field to be populated dynamically" in your destination form field's advanced settings and choose a parameter name for each.
Add matching CSS classes on the source fields of the other form(s) to setup the associations.
Add a CSS class to the source forms themselves so that we can quickly check if the redirection is necessary.
.
$class = 'GForms_Redirector';
add_filter('gform_pre_submission', array($class, 'checkForSubmissionRedirection'), 10, 1);
add_filter('gform_confirmation', array($class, 'performSubmissionRedirection'), 10, 4);
abstract class GForms_Redirector
{
const SOURCE_FORMS_CLASS_MATCH = 'submission-redirect';
const DEST_PAGE_SLUG = 'submit-page-slug';
const DEST_FORM_ID = 1;
protected static $submissionRedirectUrl;
// first, read sent data and generate redirection URL
function checkForSubmissionRedirection($form)
{
if (false !== preg_match('#\W' . self::SOURCE_FORMS_CLASS_MATCH . '\W#', $form['cssClass'])) {
// load page for base redirect URL
$destPage = get_page_by_path(self::DEST_PAGE_SLUG);
// load form for reading destination form config
$destForm = RGFormsModel::get_form_meta(self::DEST_FORM_ID, true);
$destForm = RGFormsModel::add_default_properties($destForm);
// generate submission data for this form (there seem to be no hooks before gform_confirmation that allow access to this. DUMB.)
$formData = GFFormsModel::create_lead($form);
// create a querystring for the new form based on mapping dynamic population parameters to CSS class names in source form
$queryVars = array();
foreach ($destForm['fields'] as $destField) {
if (empty($destField['inputName'])) {
continue;
}
foreach ($form['fields'] as $field) {
if (preg_match('#(\s|^)' . preg_quote($destField['inputName'], '#') . '(\s|$)#', $field['cssClass'])) {
$queryVars[$destField['inputName']] = $formData[$field['id']];
break;
}
}
}
// set the redirect URL to be used later
self::$submissionRedirectUrl = get_permalink($destPage) . "?" . http_build_query($queryVars);
}
}
// when we get to the confirmation step we set the redirect URL to forward on to
function performSubmissionRedirection($confirmation, $form, $entry, $is_ajax = false)
{
if (self::$submissionRedirectUrl) {
return array('redirect' => self::$submissionRedirectUrl);
}
return $confirmation;
}
}
If you wanted to pass the form values someplace else via the querystring then you'd merely need to cut out my code from the callback and build your own URL to redirect to.
This is a very old question, now you can send it using a Query String on the confirmation settings.
They have the documentation on this link:
How to send data from a form using confirmations
Just follow the first step and it will be clear to you.

drupal7 blocked user show content not anonymous

Does anyone know if it is possible in Drupal 7 to show a piece of content (a Page) to a blocked user that an anonymous user can not access?
If so how to you go about doing it?
Many thanks.
Create a new content type (or a node) for blocked users.
Then you will need to code a custom module for that. Inside this module you'll need to implement hook_node_access, and the code would be similar to this
function [YOUR_MODULE]_node_access($node, $op, $account)
{
if($op == "view" && $node->type == "YOUR_CONTENT_TYPE" && $account->status != 0)
{
return NODE_ACCESS_DENY;
}
}
You can then use these nodes inside a block/view or any way you like.
Kindly note that I haven't tested the code, tell me if you have any problems getting it to work.
Hope this helps... Muhammad.

Drupal user access callback selective response

Please bear with this Drupal API novice whilst I explain some background stuff!
I have been experimenting with the code below to create 2 separate responses when my users click on a custom node creation link. By default, a page opens that allows users to go through the usual steps in creating a node.
What my module does is check if the user has specific permissions and either allow them to proceed in creating the node or throw up an access denied page.
function mymodule_menu_alter(&$items) {
$items["node/add/page/%"]['access callback'] = 'mymodule_access_callback';
}
function mymodule_access_callback(){
if( user_access('open sesame') ){
drupal_set_message("successfully intecepting new node creation");
return true;
}
return false;
}
The node/add/page is blocked successfully but it does so in both cases. The if statement determines if the user has a certain permission and within it I added return true which resulted in the following error:
Fatal error: require_once() [function.require]: Failed opening
required '/node.pages.inc' (include_path='.:') in
/var/www/vhosts/mysite.co.uk/httpdocs/includes/menu.inc on line 347
As a novice, I am not sure what I need to do in order to avoid the access denied page for the right users.
Try this:
function mymodule_menu_alter(&$items) {
$items["node/add/page/%"]['access callback'] = 'mymodule_access_callback';
$items["node/add/page/%"]['file'] = drupal_get_path('module', 'node') . '/node.pages.inc';
}
EDIT
Try changing the second line above to this:
$items["node/add/page"]['file'] = drupal_get_path('module', 'node') . '/node.pages.inc';
It's an attempt to explicitly set the file path for the parent item of the path you're defining.
Also this might be a stupid thing to say but every time you make a change to hook_menu_alter() make sure you clear Drupal's caches so the changes are picked up.

Javascript permission denied error when using Atalasoft DotImage

Have a real puzzler here. I'm using Atalasoft DotImage to allow the user to add some annotations to an image. When I add two annotations of the same type that contain text that have the same name, I get a javascript permission denied error in the Atalasoft's compressed js. The error is accessing the style member of a rule:
In the debugger (Visual Studio 2010 .Net 4.0) I can access
h._rule
but not
h._rule.style
What in javascript would cause permission denied when accessing a membere of an object?
Just wondering if anyone else has encountered this. I see several people using Atalasoft on SO and I even saw a response from someone with Atalasoft. And yes, I'm talking to them, but it never hurts to throw it out to the crowd. This only happens in IE8, not FireFox.
Thanks, Brian
Updates: Yes, using latest version: 9.0.2.43666
By same name (see comment below) I mean, I created default annotations and they are named so they can be added with javascript later.
// create a default annotation
TextData text = new TextData();
text.Name = "DefaultTextAnnotation";
text.Text = "Default Text Annotation:\n double-click to edit";
//text.Font = new AnnotationFont("Arial", 12f);
text.Font = new AnnotationFont(_strAnnotationFontName, _fltAnnotationFontSize);
text.Font.Bold = true;
text.FontBrush = new AnnotationBrush(Color.Black);
text.Fill = new AnnotationBrush(Color.Ivory);
text.Outline = new AnnotationPen(new AnnotationBrush(Color.White), 2);
WebAnnotationViewer1.Annotations.DefaultAnnotations.Add(text);
In javascript:
CreateAnnotation('TextData', 'DefaultTextAnnotation');
function CreateAnnotation(type, name) {
SetAnnotationModified(true);
WebAnnotationViewer1.DeselectAll();
var ann = WebAnnotationViewer1.CreateAnnotation(type, name);
WebThumbnailViewer1.Update();
}
There was a bug in an earlier version that allowed annotations to be saved with the same unique id's. This generally doesn't cause problems for any annotations except for TextAnnotations, since they use the unique id to create a CSS class for the text editor. CSS doesn't like having two or more classes defined by the same name, this is what causes the "Permission denied" error.
You can remove the unique id's from the annotations without it causing problems. I have provided a few code snippets below that demonstrate how this can be done. Calling ResetUniques() after you load the annotation data (on the server side) should make everything run smoothly.
-Dave C. from Atalasoft
protected void ResetUniques()
{
foreach (LayerAnnotation layerAnn in WebAnnotationViewer1.Annotations.Layers)
{
ResetLayer(layerAnn.Data as LayerData);
}
}
protected void ResetLayer(LayerData layer)
{
ResetUniqueID(layer);
foreach (AnnotationData data in layer.Items)
{
LayerData group = data as LayerData;
if (group != null)
{
ResetLayer(data as LayerData);
}
else
{
ResetUniqueID(data);
}
}
}
protected void ResetUniqueID(AnnotationData data)
{
data.SetExtraProperty("_atalaUniqueIndex", null);
}

How can I modify the Book Copy module in Drupal 6 to forward the user to a different starting tab once a copy is made?

Example call to copy a book using the Book Copy module in Drupal 6 (assuming a node exists with book id of 142):
www.examplesite.com/book_copy/copy/142
When the above site is called and node 142 is copied it then notifies the user that the book was copied, but starts the user out on the Outline tab for the book copy. I think it would be more intuitive to start the user out on the Edit tab for the book copy so the user can immediately start to edit the information for the book. The outline is less important than setting up the actual initial details for the book which are in the Edit tab.
Does anyone know how I could modify the module to forward the user to the Edit tab? I looked through the code and it's just not clicking. I'm having problems interpreting exactly how this Book Module is working under the hood. Any suggestions will be greatly appreciated. Thanks!
I have no experience with the book_copy module, but looking at the last lines of the book_copy_copy_book() function:
$book = node_load(array('nid' => $newbid));
$book->bookcopydata = array();
$book->bookcopydata['message'] = t('Successfully cloned "%message", now viewing copy.', array('%message' => $message));
if (_book_outline_access($book)) {
$book->bookcopydata['url'] = 'node/'. $newbid .'/outline';
}
else {
$book->bookcopydata['url'] = 'node/'. $newbid;
}
// The function signature is: hook_book_copy_goto_alter(&$data);
drupal_alter("book_copy_goto", $book);
drupal_set_message($book->bookcopydata['message']);
drupal_goto($book->bookcopydata['url']); // requires user has 'administer book outline' or can access personal books
the user would automatically end on the new book page if he did not have the 'administer book outlines' right. If you want the user to always end on the new book edit page, you could just replace the whole if
if (_book_outline_access($book)) { ... }
clause with the assignment from its else part with an adjusted url:
$book->bookcopydata['url'] = 'node/'. $newbid . '/edit';
However, changing a modules code directly is not recommended (update clashes), especially if the module provides a hook to achieve the change you need 'from outside'. So the 'right' way in your situation would be to implement the offered hook_book_copy_goto_alter(&$data) in a custom module in order to adjust the redirection URL to your liking:
function yourModule_book_copy_goto_alter(&$new_book) {
$new_book->bookcopydata['url'] = 'node/'. $new_book->nid . '/edit';
}

Resources