Anonymous users getting same product items in cart - drupal-7

I am using drupal commerce module, i have an issue with anonymous users, when users click on add to cart button, cart is showing extra items which are added by other anonymous users.
I am using custom code for add to cart using ajax. following is the code.
// Add a product to cart on ajax call.
function mymodule_custom_add_to_cart($product_id,$uid){
$line_item = commerce_product_line_item_new(commerce_product_load($product_id));
commerce_cart_product_add($uid, $line_item);
$order = commerce_cart_order_load($uid);
commerce_cart_order_refresh($order);
// loads data array from order object
$data = mymoudle_custom_cart_load_all_variables($order->order_id);
$jsonencoded = json_encode($data);
print $jsonencoded;
}
I dont know why all anonymous users are getting same products in there cart.
Please help me to find out the issue.
UPDATE 1:
I have changed the code for anonymous user as following, then i am getting an error: EntityMetadataWrapperException: Unable to get the data property data as the parent data structure is not set. in EntityStructureWrapper->getPropertyValue() (line 451 of /entity.wrapper.inc
CHANGED CODE
// Add a product to cart on ajax call.
function mymodule_custom_add_to_cart($product_id,$uid){
if($uid == 0){
$order_id = commerce_cart_order_id($uid);
if($order_id == false){
$order = commerce_cart_order_new(0, 'checkout_checkout');
} else {
$order = commerce_order_load($order_id);
}
// Load whatever product represents the item the customer will be
// paying for and create a line item for it.
$product = commerce_product_load($product_id);
$line_item = commerce_product_line_item_new($product, 1, $order->order_id);
commerce_line_item_save($line_item);
// Add the line item to the order using fago's rockin' wrapper.
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$order_wrapper->commerce_line_items[] = $line_item;
// Save the order again to update its line item reference field.
commerce_order_save($order);
// loads data array from order object
$data = mymoudle_custom_cart_load_all_variables($order->order_id);
$jsonencoded = json_encode($data);
print $jsonencoded;
}else{
$line_item = commerce_product_line_item_new(commerce_product_load($product_id));
commerce_cart_product_add($uid, $line_item);
$order = commerce_cart_order_load($uid);
commerce_cart_order_refresh($order);
// loads data array from order object
$data = mymoudle_custom_cart_load_all_variables($order->order_id);
$jsonencoded = json_encode($data);
print $jsonencoded;
}
}
UPDATE 2: ISSUE RESOLVED.
Site is crawling by googlebot, which is clicking addtocart link and its adding an product to anonymous user account automatically, so i removed link for addtocart button and used commerce addtocart form.

All anonymous users have uid zero (see documentation). That is the reason why all the items added by different anonymous users are being added to the same shopping cart.

Related

Drupal pagination count issue while i try to filter the data

$table_sort = $query->extend('TableSort')->orderByHeader($header);
$pager = $table_sort->extend('PagerDefault')->limit($pagerLimit);
$result = $pager->execute();
I use this code for pagination,everything is fine until i'm using filter option.
Page navigation link is visible even i have only one records which has come from filter by id.
For example:
By default i have 100 records in table,so we can see page navigation link,its good.
The problem is when i try to filter the records by id alone.
I got only one record which is matched for given id but still now the pagination link is visible.
$countQuery = $query;
$result = $query->execute();
$Totalcount = $result->rowCount();
$page = pager_default_initialize($Totalcount,$pagerLimit);

How can I programmatically set the value for a field in a Commerce Product custom Line Item Type?

I've set up a product which uses a custom line item type called "Custom Notes" (created through the UI at Configuration > Line Item Types). One of the fields in "Custom Notes", that is exposed at checkout, is a "field_notes" textarea field. It works as intended... in a product display I can add some custom text, click ORDER and the note carries through to checkout.
However, I need to create these orders programmatically. I've gotten to the point where i'm using a hook_menu to submit an order and it works great. The only problem is that I can't seem to set the value for the "field_notes".
// Load whatever product represents the item the customer will be
// paying for and create a line item for it.
$line_item = commerce_product_line_item_new($product, $quantity, $order->order_id);
// Save the line item to get its ID.
commerce_line_item_save($line_item);
//***this is the part that's not working. trying to set the field_notes field***
$line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
$line_item_wrapper->field_notes->set("Does this work??");
// Save the line item to get its ID.
commerce_line_item_save($line_item);
// Add the line item to the order using fago's rockin' wrapper.
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$order_wrapper->commerce_line_items[] = $line_item;
// Save the order again to update its line item reference field.
commerce_order_save($order);
What am i doing wrong? Thanks!
I think it could be because you are not passing the correct line item type to commerce_product_line_item_new. For example, this is how I would do it:
$line_item = commerce_product_line_item_new(
$product,
$quantity = 1,
$order_id = 0,
$data = array(),
$line_item_type = 'my_custom_line_item_type'
);

Display module form on admin pages. Drupal 7. Commerce.

I've created a small module that I would like to link account notes with users.
I have written the beginnings of the module that includes a form for adding notes and date created. This works when I access mydomain.com/admin/user_notes.
My question is, how do I get this form to display in the admin section of the site on a users orders history page. eg mydomain.com/users/1245/order-history
I would like our admins who have a specific role to be able to add notes when they view a users order history page.
Thanks in advance for any advice.
you could use a block, create one with the hook_block_info and hook_block_view function.
Like this:
function tips_block_info() {
$block['yourBlockName'] = array(
'info' => t('This my created block'),
'cache' => DRUPAL_NO_CACHE, // Disable caching if you need/want to
);
return $block;
}
Thisby will create an empty block, to fill it with content use hook_block_view:
function moduleName_block_view($delta = '') {
$block = array();
switch($delta) {
// The delta of your block will be the key from the $block array we set in hook_block_info
case 'yourBlockName':
// Set the block title
$block['subject'] = 'Hey I\'m your block title';
$block['content'] = 'Block content goes here can also be the output of any function';
break;
}
return $block;
}
Don't forget to set access permission for your block if you need any, you can do that by editing the block on the block admin page.
Relevant Drupal API links:
hook_block_info
hook_block_view

Creating muliple users in a loop from array

How does one go about creating multiple new users, say in a loop, from an array in a different controller?
I have an issue where attempting to create multiple users in a form submit fails, but creating a single new user works as designed. It appears the issue may be when saving the new user and then bringing the new user_id back in the return statement. Although the new id comes back, subsequent users (2nd, 3rd, etc) all get the same id value, and it appears that the subsequent $this->save calls modify the first created user rather than create add'l ones. Any none of the new users appear in the database. (again, the problem only happens when more than one new users will be created.)
My one small clue is that if I var_dump($user) in my importPublicLDAPUser() function (user.php) just after the $user = $this->save(array('User' => array( ... ))); then for the first element I see both 'modified' and 'created', whereas I see only 'modified' for the rest. This leads me to believe there's a step missing, like the user needs to be saved or commit (??) before the next user can be be created.
I tried changing this to $user = $this->User->save(array('group_id' => 3, ... and adding a 'create' before: $this->User->create(); but these produce errors 'Call to a member function save() on a non-object' and 'Call to a member function create() on a non-object'.
My application manages documents. Each document can have many authors, so it has controllers for: docs, doc-types, users, groups, and authors.
When a new document is entered, the form allows selection of multiple users to create 'Author' records. In addition to the local users table, it also searches our LDAP server (both via auto-sugggest) and also allows input into a text field. So, Authors are selected from
the existing table of users
via the LDAP helper
free text entry.
This result is two arrays: $Authors (from local users tables), and $badAuthors (LDAP and text-input) which the app then tries to add to the local users table when the form is submitted.
The form works just fine if:
one or more authors are added from local users table;
a single author is added from LDAP (succeeds in creating a new entry in users table), and zero or more local users
a single author is added from text input (also succeeds), and zero or more local users
However if two or more non-local users are added ($badAuthors has more than one element) then the form fails. "fails" means that either the Author or User save routine failed, and so it skips the Document commit $this->Docu->commit(); and I spit out an error via ajaxResponse. Thus, the app works as designed, but only with one new User entry at a time, even though the form is designed to allow Authors/badAuthors to be >1.
What I don't understand is why when I loop through bad authors why it doesn't correctly add the users if $badAuthors has more than one element.
As the user enters each name (which is checked against the users table and LDAP via ajax helpers, etc) and then selected, an author_name_list array is built. And then:
foreach($this->params['form']['author_name_list'] as $author_name){
$user_id = $this->Docu->User->field('id',array('User.name' => $author_name));
if($user_id){
$Authors['Author'][]=array(
'docu_id'=>$this->Docu->id
,'user_id'=>$user_id
);
}else{
$badAuthors[] = array('name'=>$author_name);
}
}
So $badAuthors is now those found in LDAP or entered manually.
So now I try to create/save all badAuthors...
docu controller (docu_controller.php):
if(count($badAuthors)){
foreach($badAuthors as $key => $author){
$this->Memo->User->create(); // ** <-- this was missing!! **
if($ldap_author = $this->Docu->User->importPublicLDAPUser($author['name'])){
unset($badAuthors[$key]);
$Authors['Author'] []= array(
'docu_id'=>$this->Docu->id
,'user_id'=>$ldap_author['User']['id']
,'precedence' => $author['precedence']
);
} elseif ($new_author = $this->Docu->User->newReadonlyUser($author['name'])) {
unset($badAuthors[$key]);
$Authors['Author'] []= array(
'docu_id'=>$this->Docu->id
,'user_id'=>$new_author['User']['id']
,'precedence' => $author['precedence']
);
}
}
}
if(!count($badAuthors)){
$authors_saved = true;
foreach($Authors['Author'] as $author_arr){
$this->Docu->Author->create();
if(!$this->Docu->Author->save(array('Author' => $author_arr))){
$authors_saved = false;
break;
}
}
}
user model (user.php)
function afterSave($created) {
if (!$created) {
$parent = $this->parentNode();
$parent = $this->node($parent);
$node = $this->node();
$aro = $node[0];
$aro['Aro']['parent_id'] = $parent[0]['Aro']['id'];
$this->Aro->save($aro);
}
}
function importPublicLDAPUser($cn){
App::import('Vendor','adLDAP',array('file'=>'adLDAP.php'));
$oLDAP = new adLDAP(Configure::read('LDAP_options.email'));
$oLDAP->authenticate(NULL, NULL);
$filter = '(&(cn='.$oLDAP->ldap_escape($cn).'))';
$ldap_res = #$oLDAP->search($filter, array('cn', 'uid','profitcenter'),1);
if(isset($ldap_res['count']) && ($ldap_res['count'] > 0)){//found it
$user = $this->save(array('User' => array(
'group_id' => 3,
'name' => $ldap_res[0]['cn'][0],
'username' => $ldap_res[0]['uid'][0],
'grpnum' => pc2grpnum($ldap_res[0]['profitcenter'][0])
)));
if($user){
$user['User']['id'] = $this->id;
}
return ($user ? $user : false);
}else{
return false;
}
}
Any suggestions? Thanks!!
It turns out that in my docu_controller.php I was missing a create() call. It seems that without a create, an object can still be saved/created when the other controller does a commit(). So before adding the create(), prior to the commit, in later loop iterations I was still modifying the original object, not any new ones. By adding a create in the controller, the save in the method function acts on the new user for each loop iteration.
in controller:
if(count($badAuthors)){
foreach($badAuthors as $key => $author){
$this->Memo->User->create();
if($ldap_author = $this->Memo->User->importPublicLDAPUser($author['name'])){
in method:
function importPublicLDAPUser($cn){
....
$user = $this->save(array('User' => array(...

Receive model data inside a CakePHP model callback function

I try to use existing model data inside a models callback function in CakePHP 2.1 but can't get it working.
What I do is I try to get a users role in the beforeValidate() callback and check if it's empty. If yes, I'll set it. Normally I do it like this, and for the first creation of the record it works pretty well.
if (empty($this->data[$this->alias]['role']))
$this->data[$this->alias]['role'] = 'user';
The problem is, every time an existing record (user) gets updated, the role will be set again.
Question: So, how do I check if the field role is already set in the record data, not the post data (seems like $this->data[$this->alias] only contains POST data)?
There are three solutions to this problem as I can see it.
Set a default value in the database column (easiest, best?)
Add role to your inputs everytime.
Lookup the user and add a role if it's missing
The first two options seem obvious, so I'll just illustrate the last.
public function beforeValidate() {
if (!empty($this->id) {
$this->data[$this->alias][$this->primaryKey] = $this->id;
}
if (!empty($this->data[$this->alias][$this->primaryKey])) {
// user exists, check their data
$id = $this->data[$this->alias][$this->primaryKey];
$user = $this->find('first', array(
'conditions' => array($this->primaryKey => $id)
));
$this->data[$this->alias]['role'] = $user[$this->alias]['role'];
}
if (empty($this->data[$this->alias]['role'])) {
// new user but missing a role
$this->data[$this->alias]['role'] = 'user';
}
return true;
}
This callback will check if an ID was passed, and if so it will look up the user and populate the role field. Then, it checks for an empty role and fills it with the default if necessary. Obviously he more code you have, the more possibilities for bugs, so I suggest the first option for default column values.
try:
if (empty($this->data[$this->alias]['role']) && empty($this->role)) {
$this->data[$this->alias]['role'] = 'user';
}

Resources