Change node author automatically - drupal

Anonymous user is able to post nodes. After posting node, user is redirected to registration. After registration, the previously submitted node should be linked with newly registered user.
I played with rules and entities but I was not able to get it work properly. Any ideas?

I would write a custom module (but that's me). The module needs to implement hook_node_insert and save the nid into SESSION. Then on hook_user_insert it can do the change. Untested code:
function foo_node_insert($node) {
$_SESSION['mynodes'][] = $node->nid;
}
function foo_user_insert($edit, $account) {
if (!empty($_SESSION['mynodes'])) {
foreach ($_SESSION['mynodes'] as $nid) {
$node = node_load($nid);
$node->uid = $account->uid;
// This saves the revision as the current user uid but that's just what we wanted.
node_save($node);
}
}
}
Edit: don't forget unset($_SESSION['mynodes']);

Save the node data until after registration and post it then.

There's the Anonymous Node Create module.
The module allows anonymous users to create nodes. But 'anonymous' is questionable in this module. This module alters the node form for anonymous users by adding two field groups at the end before the save button.
The first field group has fields that allow users to create a new account. This new account is then the author of the new node created.

Related

Get password value in WooCommerce checkout

Is there any way to retrieve the clean unhashed password value in the WooCommerce checkout page with any hook?
What I need to do: I need to create a Firebase Auth user when a new WordPress user is creating. If this is not possible, what would be the best practice to achieve this?
What I tried
First I tried to create a new custom field on checkout and retrieve it with:
function wh_CustomReadOrder($order_id)
{
$order = wc_get_order($order_id);
WC()->session = new WC_Session_Handler;
/*
* Next lets create a customer so we can access checkout fields
* If you will check a constructor for WC_Customer class you will see
* that if you will not provide user to create customer it will use some
* default one. Magic.
*/
WC()->customer = new WC_Customer;
/*
* Done. You can browse all chceckout fields (including custom ones)
*/
?>
<script type="text/javascript">
var order = <?php echo $order ?>;
var checkout_fields = <?php echo json_encode(WC()->checkout->checkout_fields) ?>
var email = order;
console.log(checkout_fields);
</script>
<?php
}
add_action('woocommerce_thankyou', 'wh_CustomReadOrder');
I get an array with all fields, but my custom field is not showing. But even if so, the WordPress password will still be different. The best way would be to simply get the WordPress password and then create the user in Firebase.
Do you have any idea?
As you will see in the wc-user-functions.php file, the function wc_create_new_customer is used when creating a new account.
For checking the checkout page you can use Conditional Tags
is_checkout() Returns true on the checkout page.
So to intercept the unhashed password you could use the woocommerce_created_customer hook. The $unhashed_password variable will contain the unhashed password.
function action_woocommerce_created_customer ( $customer_id, $new_customer_data, $password_generated ) {
// Returns true on the checkout page.
if ( is_checkout() ) {
$unhashed_password = $new_customer_data['user_pass'];
}
}
add_action( 'woocommerce_created_customer', 'action_woocommerce_created_customer', 10, 3 );
One approach I would consider is to build a custom webform for creating the customer's account. That way you can manipulate the data however you want.
For example, when the user submits the form, take the data, register the new user in WC/WP, send the data to firebase, then redirect.
The downside is that you'll have to manage the process a 100% and deal with any possible errors.
Another way:
Use the default WC or WP account creation form, but on submit -> prevent Default with Javascript, take the data (yes you can access the password before it's hashed), send it to Firebase, THEN, submit the form and let WC/WP save it in the database in a normal fashion.
I did it like this when I needed to send that data to an Email Management software. The user enters the values, hits submit: my code blocks the submit event, sends the data where I want it to, then submits the form.
Hope it helps!

How to: Unpublish Nodes by Author when Author is assigned Role

I'm using Drupal 7 + Rules. I would like to create a rule that unpublishes all nodes authored by a user when they have been given a particular role.
EVENT - After updating an existing user account
CONDITION - User has role(s): SelectedRole
ACTION - ???
BONUS: If this could be limited to nodes of a certain type, that would be even better.
If there is a better way outside of Rules to do this, I'm open to other ideas.
Thanks so much!
You can create a custom ruleset to loop through the nodes or a Views Bulk Operation action.
An easiest option is to add a custom PHP function on your rule (PHP > Execute custom PHP code). Of course you have to enable the php filter core module if you didn't already.
In the PHP action you have to get all the nids of the published nodes the current user and loop through them to unpublish them. I will use the EntityFieldQuery API class but you can use the database functions also.
// Get updated user id
$uid = $account -> uid;
// Get all nodes from user that are of NODE_TYPE and are published
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', 'node')
->entityCondition('bundle', 'NODE_TYPE')
->propertyCondition('status', 1)
->propertyCondition('uid', $uid);
$result = $query->execute();
$nids = array_keys($result['node']);
// Load all nodes in one go for better performance.
$nodes = node_load_multiple($nids);
foreach ($nodes as $node) {
// set status property to 0 (unpublished)
$node->status = 0;
// re-save the node
node_save($node);
}
I would also suggest to add one more Condition for the user before the one you are using: User Has Roles: (NOT) SelectedRole so that the action do not run everytime the user profile is updated.
References:
Use Rules to Unpublish content based on Author's role
Publish unpublished node programmatically
Find nodes created by user (more programmatically)

Change current user role with form selection on update (not entry creation)

I'm using Formidable forms in Wordpress and have a form that registers users. I can use a radio button in the registration form to determine what their role will be. I have a hook for that. What I need, however, is a hook that will change the user role based on radio selection on form entry UPDATE. My current code only works on entry creation. Here is the code that assigns roles on registration:
add_filter('frmreg_new_role', 'frmreg_new_role', 10, 2);
function frmreg_new_role($role, $atts){
extract($atts);
if($form->id == 8){
if($_POST['item_meta'][280] == 'Job Applicant')
$role = 'applicant';
}
return $role;
}
"8" is the id of the form itself. "280" is the id of the radio button field where "Job Applicant" is one of the values. And "applicant" is one of our site's user roles.
I need an adaptation of this that will change the role after the entry has already been created, on update. The closest thing I can find is a hook that changes user role after a successful PayPal payment. I tried to combine the two but I couldn't get it to work. Here is the PayPal generated user role changer:
add_action('frm_payment_paypal_ipn', 'change_paid_user_role');
function change_paid_user_role($args){
$new_role = 'contributor'; //change this to the role paid users should have
if(!$args['pay_vars']['completed'])
return; //don't continue if the payment was not completed
if(!$args['entry']->user_id or !is_numeric($args['entry']->user_id))
return; //don't continue if not linked to a user
$user = get_userdata($args['entry']->user_id);
if(!$user)
return; //don't continue if user doesn't exist
$updated_user = (array)$user;
// Get the highest/primary role for this user
$user_roles = $user->roles;
$user_role = array_shift($user_roles);
if ( $user_role == 'administrator' )
return; //make sure we don't downgrade any admins
$updated_user['role'] = $new_role;
wp_update_user($updated_user);
}
UPDATE: the action hook should probably be: frm_after_create_entry according to Formidable forums.
Many times, researching the core files is more productive than any Google or Manual. Dropping the whole plugin directory in a code editor and researching for the string frm_after_create_entry takes us to the create() method where this hook happens.
After that, there's the update() method and it provides the action hook: frm_after_update_entry.
This hook passes two parameters: $id and $new_values['form_id']. I cannot reproduce your setup, so testing the hook is up to you.
Reference: Actions and filters are NOT the same thing…
In this example:
add_action( 'frm_after_update_entry', 'change_role_to_staff', 10, 2);
function change_role_to_staff( $form_id, $values ){
var_dump($values);
die();
}
As this is an action hook, nothing has to be returned.
There's no $roles or $atts, the parameters are the form ID and Values.
What you're looking for is inside $values.
var_dump() and die() are for debugging purposes and must be removed at once after testing.
Do your wp_update_user with this values and adapting your previous code.

Need advice to get my logic correct in d7

Goal: Is to save information of a node which gets updated. We need to gather the node id of the node which is updated and also the user names of people who have bookmarked it.
Implementation:
I have managed to get the both this detail using flags and rules module. I made a custom module which implemented the hook to get this info.
I am getting stuck here:
Now I need to save the user name and the node id. I am still deciding if I want to use fields or the db layer.
One username can have multiple node id saved.
Now the problem is I don't know for sure how many nodes will be enough. It depends on the user. It can be 5 can be 500 or even 5000 node ids that might need to be saved for one user.
So how do I make provision for this ?
So I am stuck with the logic. How should I use the db layer or the fields in custom content type to save this ? and how should I do it ?
Please advice. I am using d7.
custom module code
/*
* Implementation of the hook_rules_action_info()
*
*/
function customvishal_rules_action_info()
{
$actions = array(
'customvishal_action_userdetail' => array(
'label' =>t('Custom function to send notifications'),
'group'=>t('Cusotm Code for sending notifications'),
'parameter'=> array(
'account'=> array(
'type'=>'user',
'label'=>t('Going to get user list'),
),
// for the node
'productdetail'=> array(
'type'=>'node',
'label'=>t('Passding the node data'),
),
)
),
);
return $actions;
}
/*
* The action function for the rules exampled hello world
*
*/
function customvishal_action_userdetail($account,$productdetail)
{
drupal_set_message(t('This user #username! has flagged it',
array('#username' => $account->mail)));
drupal_set_message(t('This node #nid has got updated',
array('#nid' => $productdetail->nid)));
// The above takes care of the node and the user information later I will put
// it in a db or something like that.
// end of the function customvishal_action_userdetail
}
It really seems like you should be using hook_node_update() and hook_node_insert() to for access to nodes that have just been added or updated.
If you wanted access to the node data just before it was saved, then hook_node_presave() would be the one to use.
I don't think you need presave though because you mentioned you needed the node ID, and presave does not have that for new nodes yet.
Here's a way to process new and updated nodes. The first 2 functions just hook into the right place and route the node to the 3rd function.
<?php
// hook into node inserts
function customvishal_node_insert($node) {
if ($node->type == 'mynodetype') {
customvishal_handle_data($node);
}
}
// hook into node updates
function customvishal_node_update($node) {
if ($node->type == 'mynodetype') {
customvishal_handle_data($node);
}
}
// custom handler for the nodes
function customvishal_handle_data($node) {
// load a user object of the node's author
$author = user_load($node->uid);
// now do what we need to do with $node and $user data
}
Remember you need to clear the Drupal cache for new hooks in your module to work in D7.

Adding avatar to $user in Drupal 7

I've created a simple module for displaying a flash game in a custom block by overwriting game_block_view() and game_block_info() in the sites/default/modules/game.module and it works ok.
I need however to pass user avatar and also gender and city (I've added the 2 mandatory fields to the registration form) through the FlashVars-parameter to the flash game in my block.
So I'm trying to overload the hook_user_load, because I suppose that this is the method where you add properties to the $user object after it has been initiated from the database (this probably happens when the user logins or alters his/her profile data?):
function game_user_load($users) {
global $user;
$uid = $user->uid;
$result = db_query('select filename from {file_managed} where uid=:uid', array(':uid' => array($uid)));
$avatar = $result->fetchField();
$users[$uid]->avatar = $avatar;
drupal_set_message("<pre>$uid: $avatar</pre>\n");
print_r($users);
}
Unfortunately I see no output produced by the last 2 lines above in the web page
What am I doing wrong?
Thank you!
Alex
The global user object does not go through hook_user_load(), see http://api.drupal.org/api/drupal/includes--session.inc/function/_drupal_session_read/7. Don't ask me why, that's just the way it is :)
When using user_load(), any added fields will automatically be loaded, you don't need custom code for that. You just need to know how to access them, which is a bit complicated.
Something like this should work:
global $user;
// $account is now a fully loaded user object.
$account = user_load($user->uid);
// Your field name is probably 'field_avatar'.
if ($avatar = field_get_items('user', $account, 'field_avatar')) {
dpm($avatar); // only works with devel.module, strongly suggested!
}

Resources