Drupal node creation - back to origin after creation - drupal

I have organic groups setup and within those group users are allowed to post certain content.
What I woulkd like to do is, when you create a node inside an organic group, it automatically defaults back to frontpage of the group, or the same page that I used to create the node.
At present it defaults to the node view page.I assume there must be a way to add some kind of code so that after the node creation it defauls back to its origin. I.E. the page from where the node was created from.
thanks :)
UPDATE: Got the below, but not entirly sure how to ensure that it redirects back to the GROUP node, from where it was created,
<?php
/**
* Grabs current node ID
*/
$node_nid = nid;
/**
* Implements hook_form_alter().
*/
function mod_form_alter(&$form, $form_state) {
$form['buttons']['submit']['#submit'][] = 'mod_form_finish_redirect';
unset($form['buttons']['preview']);
}
/**
* Custom submit handler. Overwrites the form redirection variable.
*/
function mod_form_finish_redirect($form, &$form_state) {
$form_state['redirect'] = '/content/<?php print $node_nid; ?>';
}
?>

I would recommend the rules module. Rules is a great module that allows you to do many kinds of workflow and it is perfect for this. You can write a rule that triggers when a specified node type is created (and include any other conditions you require as well). After the node is created you can specify a redirect action rule to the home page. This can all be done without any code.

Rules (as 'We Love Drupal' says) is a possibility, but also quite a big module for such a small change in behavior. Another option is to write a custom module implementing hook_form_alter setting the #redirect value of the form.
Keep in mind that of seeing the node you have just created is important feedback for a user. When you perform an action, you want confirmation that you have achieved your task. While it's technically possible to do what you ask, it may be bad for usability.

I had the same requirment. Rules worked for me.

Related

Symfony2 best way of removing business logic from controller and correct usage of model

I'm in searching of the best way of removing business logic from controller and correct usage of model(and maybe services).
Some details below.
Actually, my project is more complicated, but as example I will use Simple Blog application.
I have created my application (Simple Blog) in next steps:
created bundle
generated entities(Topic, Post, Comment)
generated controller for each entity, using doctrine:generate:crud
installed FOSUserBundle and generated User entity
So, I have all needed methods and forms in my controllers. But now I have some troubles:
Admin need to be able see all topics and posts, when simple User can only see
topic and posts where he is owner.
Currently there are indexAction, that return findAll common for any user. As solution, I can check in action, if ROLE_USER or ADMIN and return find result for each condition. But this variant keep some logic at action.
I also can generate action for each role, but what happened if roles amount will increase?
What is the best way to solve this problem with result for each role?
I need to edit some parameters before saving.
For example, I have some scheduler, where I create date in some steps, using features of DateTime.
Before saving I need to do some calculations with date.
I can do it in controller using service or simple $request->params edit.
What is the best way to edit some $request parameters before saving?
My questions I have marked with bold.
Thanks a lot for any help!
What I would do is to create a query which fetches the topics. Afterwards I would have a method argument which specifies if the query should select only the topics for a certain user or all topics. Something like this should do the work in your TopicRepository:
public function findTopics($userId = false)
{
$query = $this->createQueryBuilder('topic');
if($userId) {
$query->join('topic.user', 'user')
->where('user.id = :user_id')
->setParameter(':user_id', $userId)
;
}
return $query->getQuery()->getResult();
}
So, whenever you need to get the topics only by a user, you would pass a $userId to the method and it would return the results only for that user. In your controller you'd have something similar to this code (Symfony 2.6+):
$authorizationChecker = $this->get('security.authorization_checker');
if($authorizationChecker->isGranted('ROLE_ADMIN')){
$results = $this->get('doctrine.orm.entity_manager')->getRepository('TopicRepository')->findTopics();
} else {
$results = $this->get('doctrine.orm.entity_manager')->getRepository('TopicRepository')->findTopics($this->getUser()->getId());
}
You can try using Doctrine Events and create a PreUpdate depending on your case. See the documentation for more information. If you have a TopicFormType, you could also try the form events.
You are not supposed to "edit" a $request, which is why you can't directly do that. You can, however, retrieve a value, save it as a $variable and then do whatever you want with it. You can always create a new Request if you really need it. Could you be more specific what you want to do here and why is this necessary?

Buddypress plugin Group Hierarchy

Buddypress has a group functionality in which I combined with the plugin BP Group Hierarchy so that I can create an hierarchy of groups based on user role.
However, the plugin used an method as taught by Buddpress in group-extension-api> link.
The group steps are registered using the function bp_register_group_extension and add_action are called. I tried to remove the action by with no success. Because I not really understand how the array works i.e. array( &$extension, \'_register\' ), so I go search out and found this post.
There's a line stating that
The new format for the above object referenced method callbacks are always: class name, followed immediately by the method name, followed by the amount of previously added (classname+methodname). For classes, this allows you to add as many object referenced classes and add methods which don’t override each other.
However I can't seems to be able to remove the action.
I tried to remove the action by putting following lines of code in function.php
function remove_bp_hierarchy(){
if (has_action('bp_actions')) {
echo $extension = new BP_Groups_Hierarchy_Extension;
remove_action('bp_actions', array( &$extension, '_register' ), 999);
} else {
}
add_action('bp_init','remove_bp_hierarchy', 999);
Is it something wrong with my remove_action or I use wrong method? Thanks and regards.
## Update
Found a page in which let we see a list of hooks and also hooked function in the page. I see that there's a function with the name _register which is the function I'm looking for. However, class address always change. I was thinking using the function found to do a preg_match on it and remove it when it found. this is super heavy. So is there other way of removing it? Thanks and Regards.
CodingBabyDotCom -
Long story short: you will have to traverse the $wp_filter array to remove the action.
You need a reference to the SAME instance that was used to create the action in order to remove it with the remove_action function. So the function you posted doesn't work because it is using a new instance.
Unfortunately bp_register_group_extension() creates only a temporary instance, so it can't be referenced by later functions.
The code in your comment will remove ALL actions at level 8, which means all group extensions. To remove only the one you want, iterate over each filter and check its type with:
is_a( $wp_filter['bp_actions'][8][$key], 'BP_Groups_Hierarchy_Extension' )

How to update the value of a single field invoking appropriate validation

I'm making a module to allow users to update single fields on in this case, their user entity.
The code below is an example of the method I have initially been using to get it working and test other elements of the module
global $user;
$account = user_load($user->uid);
$edit = (array) $account;
$edit['field_lastname']['und'][0]['value'] = 'test';
user_save($account, $edit);
However this bypasses any field validation defined elsewhere in Drupal. I don't want to reproduce any validation written elsewhere - it's not the Drupal way!
My question is: Is there a function in Drupal 7 that can be called to update the value of a single field. I imagine such a function would clear the appropriate caches, invoke the fields validation etc.
I am aware the solution will be totally different to my current user object based one. I just can't for the life of me find the appropriate function in the API. I wander whether the fact I am looking for a save function alone is the problem - and that there are some other necessary steps that come before.
Any help gratefully appreciated.
Check out the drupal_form_submit function. It lets you submit forms from code. In this case, you could use it to the user edit form, which would then fire the appropriate validation.

How to create custom access function for editing a node type in Drupal?

I have a node type that should only be edited by users under certain circumstances that go beyond the permissions their role has. I am doing this in a custom module.
I would like to remove the ability to even see the edit tab, and not just add a validation function to the form that will alert the user after the form is submitted.
I need to add some sort of access function. Anyone know how to do this?
Thanks in advance.
--Update--
I now have 2 ways that should work.
1) Using hook_nodeapi:
function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch($op) {
case 'prepare':
if(!mymodule_access_function($node)) {
$_REQUEST['destination'] = 'my_access_denied_page';
// rest of function
2) I can insert a access callback function into the menu item using hook_menu_alter.
For my purposes, 2 makes more sense. I thought I would spell out the code for (1) though since that was the answer given on this page and it works.
For the tabs visibility you can alter the themed output anywhere from a module hook to a theme template or css patch. Depending on the requirements for data visibility and performance issues some solutions are better than others. We need more details on what kind of processing you need.
For access, hook_nodeapi(), $op is 'prepare', run your custom code against $node at this point, and decide what you want to do (like redirect to another form if a requirement is not present, or to an access denied page).
Edit: Redirecting is usually done with $_REQUEST['destination'] = 'destination/alias' (does not break execution), sometimes drupal_goto('destination/alias') (breaks execution) is suitable but often it doesn't work. Please keep redirects tracked on your project, as with multiple logic conditions you may end up with unwanted and hard to debug behavior.
Every content type has default permission settings in admin/user/permissions for creating,editing ,deleting node . You may assign to anonymous or authenticated users. If you want assign to group then create another role and assign permission as mentioned above.

Disable Drupal content creation message?

Whenever a content item is created, a message is displayed like this:
[Content Type] [Name] has been created.
Is there any way to disable this message for specific users? Or for all users would be fine too.
I think the best practice would be to use hook_nodeapi() and drupal_get_messages('status'). The $op for hook_nodeapi() would be insert. Ex:
mymodule_nodeapi(&$node, $op) {
if ($node->type == 'content_type_to_check_for' && $op == 'insert') {
drupal_get_messages('status');
}
}
It's node_form_submit that is creating those messages. You could pretty easily use hook_form_alter on the node form and use your own version of node_form_submit instead. All you would need to do, would be to copy the function and add an user_access('whatever') check before that message is created.
Alternatively, you could in preprocess_page function, check which messages is being served, and remove unwanted ones, but that would be a bit more tricky. Should be possible with some regex. On the other hand, this method would be a bit more upgrade friendly, since you could remain using the node_form_submit function and would get future changes if any.
Best way would be to user Disable Messages module.
There are many kind of messages that can be disabled by this module:
Filter out messages that match a full text string exactly.
Filter out messages that match a regular expression.
Permissions to specifically hide all messages of a given type from any role.
Disable all filtering for specific users.
Disable all filtering for specific paths.
Apply filtering only for specific paths.
Debug system to get messages in the HTML without showing it to the end users.
Here is the way I discovered to hide such messages for specific content types (the node type is 'request'):
// specific node type form alteration hook (implements [hook_form_FORM_ID_alter][1]())
function MYCUSTOMMODULE_form_request_node_form_alter(&$form, &$form_state) {
// ...
// custom validation function
$form['#validate'][] = '_custom_request_node_form_validate';
// ...
}
function _custom_request_node_form_validate($form, &$form_state) {
//...
// here we can set a submit handler that is executed before
// node_form_submit which sets the messages we are trying to hide
$form_state['submit_handlers'][] = '_custom_request_node_disable_msg';
//...
}
function _custom_request_node_disable_msg($form, &$form_state) {
//...
// clear status messages
drupal_get_messages('status');
}
If you want to use the Rules module, then you can use the new module I created called "Better Rules Message".
By using this you can setup a rule that will delete all of the messages after a node is being created...
Hopefully this will be added to the main Rules module in the near future.
googletorp is right (about the submit function). But unfortunately you can't decouple the message from the node submit function and duplicating the functionality (without the message) is going to mean your site might break when a security release is issued. You'd have to maintain your own version of that function. It's probably not a big deal but it's a good idea to follow best practice.
You'll need to write your own submit hook either before or after node_form_submit gets called.
With a submit hook after the node save, you could remove the message from $_SESSION['messages'] if the messages array was easy enough to work with. I imagine that would be simple enough. See drupal_set_message
OR
You could write some class in CSS in your body tag and set the display to none when status messages are returned on the page that the node form submits to. But that might put your business logic in your theme layer which should be avoided.
You can use stringoverrides module in drupal ! :)
You could try using the following module to disable specific messages in Drupal - http://drupal.org/project/disable_messages

Resources