Alter views search api solr result - drupal

I am using search api and Solr, When I echo the result variable , it gave me the following results
stdClass Object
(
[entity] => 442415
[_entity_properties] => Array
(
[search_api_relevance] => 1
[search_api_excerpt] =>
[search_api_item_id] => 442415
)
)
In views i added ( custom text field, that is global variable), With this nid 442415, i will do certain node load operation and finally,
i will get price for the specific product. This code block will execute inside the foreach.
_views_pre_render
Please guideme,
which hook i should use , _views_post_execute or _views_pre_render ?
How to assign new value in to which variable and how to print that in tpl
Finally, i want to display the price on each item

This link resolved my problem.
Solution approach
function mymodule_views_pre_render(&$view) {
if($view->name == 'my_view') {
foreach($view->result as &$row) {
$row->_entity_properties['nothing'] = 'new value';
}
}
}
views-view-field--view-name--display-name--nothing.tpl.php
print $row->_entity_properties['nothing'];

Related

How to reliably retrieve product attribute data?

On a site where I started with WooCommerce version 2.. and then upgraded through newer releases (3.0.0, 3.0.1, ... 3.0.4), I'm noticing an inconsistency in how the order item meta data is stored for product attributes.
When using an attribute "Class Date" for variations, when an order is placed for some products in the store, the meta data for Class Date is stored using the key "pa_class-date". But for other products, the data for that same attribute is stored using the key "class-date".
My code for fetching attribute data looks like this:
$items = $order->get_items();
if ( isset($item['item_meta']['class-date']) ) {
$class_date = $item['item_meta']['class-date'];
} elseif ( isset($item['item_meta']['pa_class-date']) ) {
$class_date = $item['item_meta']['pa_class-date'];
} else {
error_log("Missing class date. We tried pa_class-date and class-date, but both are empty");
}
I would like to be able to simplify this to just look in one key or the other (pa_class-date or class-date, not both). Is that possible?
Here is what a dump of the order meta data looks like for the purchase of two different products. This one uses pa_class-date.
[467] => stdClass Object
(
[key] => pa_class-date
[value] => 2017-09-01
[display_key] => Class Date
[display_value] => <p>2017-09-01</p>
)
But for a different product, the data stored using the key "class-date":
26-Apr-2017 16:26:06 UTC] Array
(
[480] => stdClass Object
(
[key] => class-date
[value] => 2017-05-18
[display_key] => Class Date
[display_value] => <p>2017-05-18</p>
)
What causes the inconsistency in which key is used to store the data?
What is the most reliable (futureproof) way to retrieve the data?
This inconsistency is possible. But its inconsistent data entry rather. When you add attribute to Products >> Attributes, they become part of woocommerce system. Then you can map them to variation by just selecting on product details page.
However, when you add "Custom Attribute" directly from product details page, that data will be specific for that product and can cause inconsistency.

How to add / update a field collection without updating parent node/entity drupal 7

I needed to to add / update field collections to node entities without updating the node entities. I tried two ways listed in https://www.drupal.org/node/1842304 and http://alexrayu.com/blog/saveupdate-field-collection-without-nodesave but none of them seems to be working exactly the way I want.
I tried as follows:
$node = node_load($nid);
$field_collection_item = entity_create('field_collection_item', array('field_name' => 'field_college_rating_data'));
$field_collection_item->setHostEntity('node', $node);
$field_collection_item->field_text1['und'][0]['tid'] = $form_state['input']['field_text1']['und'];
$field_collection_item->field_text2['und'][0]['value'] = $form_state['input']['field_text2']['und'];
$field_collection_item->save();
It added a field collection but it updates the node.
I also tried to alter the field collection form submit and used custom submit handler as follows:
function own_custom_field_collection_submit($form,$form_state) {
$field_collection_item = field_collection_item_form_submit_build_field_collection($form, $form_state);
$field_collection_item->save(TRUE);
drupal_set_message(t('The changes have been saved.'));
$form_state['redirect'] = $field_collection_item->path();
}
I have copied this code from core field collection module to change the default argument to "TRUE" in the save function. It added the field collection but didn't associated with the parent node.
I need to save the field collection separately since my node entity form is very large with 50 to 60 fields and field collections and I don't want to update it as many times as I add / update any field collections to the node.
Any help will be much appreciated.
Thanks
You have to pragmatically relate your field collection to the host entity by the following code.
$field_collection_item = field_collection_item_form_submit_build_field_collection($form, $form_state);
$field_collection_item->save(TRUE);
$host_entity = $field_collection_item->hostEntity();
$lang = 'und';
if (isset($host_entity->nid) && isset($host_entity->vid) && isset($lang) && isset($field_collection_item->item_id) && isset($field_collection_item->revision_id)) {
$query = db_select('field_data_field_text1', 'fd');
$query->addExpression('max(fd.delta)', 'total_row');
$query->condition('fd.entity_id', $host_entity->nid);
$max_delta = $query->execute()->fetchField();
if (isset($max_delta)) {
$max_delta = $max_delta + 1;
} else {
$max_delta = 0;
}
db_insert('field_data_{field_collection}')->fields(array(
'entity_type' => 'node',
'bundle' => '{node_type}',
'entity_id' => $host_entity->nid,
'revision_id' => $host_entity->vid,
'language' => $lang,
'delta' => $max_delta,
'field_text' => $field_collection_item->item_id,
'field_text_revision_id' => $field_collection_item->revision_id
))
->execute();
}
Replace your content type and field type in { } and then you just have your field collection relate to your host entity.
Thanks

Wordpress Pod Relationshop field

Is it possible to display a template for a related pod?
$mypod = pods('custompage', 'page-slug');
$related_pod = $mypod->field('top_feature');
Now I want to call something like
$related_pod->template('FeatureTemplate');
I can't seem to find a solid answer in this docs, is this possible?
What you are trying to do will not work. The problem is that $related_pod is not an object of the Pods class, and therefore you can not call the method template() on it.
It is possible to use the ID of the related item to build a second Pods object for the related post, which we can then call the method template() on. Normally we wouldn't do this because we don't need to and its not the most performant way of working.
Here is how you can do this. IMPORTANT: this assumes that "top_feature" is a single select field, as it is in OP's case. This will not work for a multi-select field.
```
$mypod = pods( 'custompage', 'page-slug' );
$relationship_field = $mypod->field( 'top_feature' );
if ( $relationship_field ) {
//get ID of related item
//Depending on content type you may need to use, 'id', instead of 'ID'
$related_item_id = pods_v( 'ID', $relationship_field );
$related_pod = pods( 'name_of_related_pod', $related_item_id, true );
if ( is_a( $related_pod, 'Pods' && $related_pod->id() === $id ) ) {
$related_pod->template( 'FeatureTemplate' );
}
}
```

Modifying a field collection programmatically missing hostEntity fields

I am trying to modify a field collection in a node that already exists so I can change an image on the first element in an array of 3. The problem is, the hostEntity info is not set when I do a entity_load or entity_load_single so when I do a:
$field_collection_item->save(true); // with or without the true
// OR
$fc_wrapper->save(true); // with or without the true
I get the following error:
Exception: Unable to save a field collection item without a valid reference to a host entity. in FieldCollectionItemEntity->save()
When i print_r the field collection entity the hostEntity:protected fields are indeed empty. My field collection is setup as follows:
field_home_experts
Expert Image <--- Want to change this data only and keep the rest below
field_expert_image
Image
Expert Name
field_expert_name
Text
Expert Title
field_expert_title
Text
Here is the code I am trying to use to modify the existing nodes field collection:
$node = getNode(1352); // Get the node I want to modify
// There can be up to 3 experts, and I want to modify the image of the first expert
$updateItem = $node->field_home_experts[LANGUAGE_NONE][0];
if ($updateItem) { // Updating
// Grab the field collection that currently exists in the 0 spot
$fc_item = reset(entity_load('field_collection_item', array($updateItem)));
// Wrap the field collection entity in the field API wrapper
$fc_wrapper = entity_metadata_wrapper('field_collection_item', $fc_item);
// Set the new image in place of the current
$fc_wrapper->field_expert_image->set((array)file_load(4316));
// Save the field collection
$fc_wrapper->save(true);
// Save the node with the new field collection (not sure this is needed)
node_save($node);
}
Any help would be greatly appreciated, I am still quite new to Drupal as a whole (end-user or developer)
Alright so I think I have figured this out, I wrote up a function that will set a field collection values:
// $node: (obj) node object returned from node_load()
// $collection: (string) can be found in drupal admin interface:
// structure > field collections > field name
// $fields: (array) see usage below
// $index: (int) the index to the element you wish to edit
function updateFieldCollection($node, $collection, $fields = Array(), $index = 0) {
if ($node && $collection && !empty($fields)) {
// Get the field collection ID
$eid = $node->{$collection}[LANGUAGE_NONE][$index]['value'];
// Load the field collection with the ID from above
$entity = entity_load_single('field_collection_item', array($eid));
// Wrap the loaded field collection which makes setting/getting much easier
$node_wrapper = entity_metadata_wrapper('field_collection_item', $entity);
// Loop through our fields and set the values
foreach ($fields as $field => $data) {
$node_wrapper->{$field}->set($data);
}
// Once we have added all the values we wish to change then we need to
// save. This will modify the node and does not require node_save() so
// at this point be sure it is all correct as this will save directly
// to a published node
$node_wrapper->save(true);
}
}
USAGE:
// id of the node you wish to modify
$node = node_load(123);
// Call our function with the node to modify, the field collection machine name
// and an array setup as collection_field_name => value_you_want_to_set
// collection_field_name can be found in the admin interface:
// structure > field collections > manage fields
updateFieldCollection(
$node,
'field_home_experts',
array (
'field_expert_image' => (array)file_load(582), // Loads up an existing image
'field_expert_name' => 'Some Guy',
'field_expert_title' => 'Some Title',
)
);
Hope this helps someone else as I spent a whole day trying to get this to work (hopefully I won't be a noob forever in Drupal7). There may be an issue getting formatted text to set() properly but I am not sure what that is at this time, so just keep that in mind (if you have a field that has a format of filtered_html for example, not sure that will set correctly without doing something else).
Good luck!
Jake
I was still getting the error, mentioned in the question, after using the above function.
This is what worked for me:
function updateFieldCollection($node, $collection, $fields = Array(), $index = 0) {
$eid = $node->{$collection}[LANGUAGE_NONE][$index]['value'];
$fc_item = entity_load('field_collection_item', array($eid));
foreach ($fields as $field => $data) {
$fc_item[$eid]->{$field}[LANGUAGE_NONE][0]['value'] = $data;
}
$fc_item[$eid]->save(TRUE);
}
I hope this helps someone as it took me quite some time to get this working.

how to populate text area with database value before form load in drupal 7?

I have used hook_form_FORM_ID_alter( ) function to alter a menu_edit_menu form to add few fields. I ve stored the values from those fields in a table when submit action is performed. what I need now is when the particular form entry is loaded again for editing. The fields should be populated with the data in the database before form loads. Can anyone tell me how this could be done.
I have tried using hook_validate ( ) function but the function is called when the submit action is performed which is of no use in this regard. I have to perform the database query before the form gets rendered to populate the text fields with data from tables. Kindly provide me some insight into how this could be accomplished.
I have a problem with the sql select query as well/
$query = db_select('menu_custom');
$query
->fields(array('menu_name','role1','role2','role3'))
->condition('check',1,'=')
->conditon('title',$form_state['values']['title'])
->execute();
foreach($query as $record)
{
$mname = $result ->menu_name;
$rl1 = $result -> role1;
$rl2 = $result -> role2;
$rl3 = $result -> role3;
dpm($mname." ".$rl1);
}
I am getting error that my field specification is wrong but I cant figure out the problem there.
This is a bit too long for a comment so I'll put it here:
The only error you've got in your query is that the first argument passed to the fields() function needs to be the name/alias of the table from which the fields are coming. So your query should probably look something like this:
$query = db_select('menu_custom')
->fields('menu_custom', array('menu_name','role1','role2','role3'))
->condition('check',1,'=')
->conditon('title',$form_state['values']['title'])
->execute();
You get the data from your database in your form function, and put them as default_value
$name = db_query(YOUR_SQL);
$form['first_name'] = array(
'#title' => t('First Name'),
'#type' => 'textfield',
'#default_value' => $name,
);
is this what you meant?

Resources