Drupal taxonomy with special characters in a term - drupal

I sync data from external source to my Drupal installation. I have problem when i'm adding taxonomy term relation to my newly created node.
I'm syncing cars and if manufacturer name ($name in code) is not in vocabulary, it will get added to it. If it already exists, tid attached to node.
This works perfectly with terms like Ferrari or Volkswagen. But then there is Mercedes-Bentz. For some reason EntityFieldQuery doesn't seem to find it from vocabulary, because this code, when run in loop, creates Mercedes-Bentz terms over and over again.
I guess the problem is that dash between words. I'd like to see SQL clause behind EntityFieldQuery, but i don't have entire drupal setup up when i'm running this, so modules like Devel are not loaded. And I don't have a clue how to inspect SQL otherwise.
I'm more than grateful of suggestions how to debug or how to solve this. Every link is appreciated.
Here is my code:
$query = new EntityFieldQuery();
$result = $query
->entityCondition('entity_type', 'taxonomy_term')
->propertyCondition('name', $name) // $name = manufacturer, like "Ferrari"
->propertyCondition('vid', 2)
->execute();
if(!empty($result))
{
$tmp = array_pop($result['taxonomy_term']);
$node->field_brand[LANGUAGE_NONE][0]['tid'] = $tmp->tid;
}
else
{
$term = new stdClass();
$term->vid = 2;
$term->name = $name
taxonomy_term_save($term);
$node->field_brand[LANGUAGE_NONE][0]['tid'] = $term->tid;
}

There is a way to do the same with taxonomy_get_term_by_name(), but i guess it is not preferred way and the solution explained in question should be right for this.
I think we are seeing Drupal bug here. But for others trying to do that, here is the solution:
$test = taxonomy_get_term_by_name($name);
// It should be full of unique names, so no need to go through all of them
if(!empty($test))
{
$tmp = array_pop($test);
$node->field_brand[LANGUAGE_NONE][0]['tid'] = $tmp->tid;
}
else
{
$term = new stdClass();
$term->vid = 2;
$term->name = $name;
taxonomy_term_save($term);
$node->field_brand[LANGUAGE_NONE][0]['tid'] = $term->tid;
}

Related

Limiting fields to certain users

Using SilverStripe 2.4.7.
I've done some searching but I can't seem to be able to find an answer to this. I want to include a checkbox on a popup window in dataobjectmanager but not for every user.
I have two separate pages, one for one user and another for the other, and I only want the checkbox on one. I thought an if statement would suffice, quick and simple right?
public function getCMSFields()
{
$categories = array("Morning","Afternoon", "Evening", "Night");
return new FieldSet(
new TextField('Title'),
new DatePickerField('Date', 'Date'),
new ImageField('Photo', 'Photo'),
new MoneyField('AdultPrice', 'Adult Price'),
new MoneyField('ChildPrice', 'Child Price'),
new DropdownField('Category', 'Choose a Category', $categories)
);
This is my attempt at the if statement approach
if($this->ClassName == 'Movie'){
$films= DataObject::get('Films');
if (!empty($films)) {
// create an array('ID'=>'Name')
$map = $films->toDropdownMap('ID', 'Name');
$fieldset->push(new CheckboxSetField(
$name = "Films",
$title = "Select Films",
$source = $map
));
}
}
Basically this works if I use it within getCMSFields_forPopup, but not in just getCMSFields, but changes my checkboxsetfield to a dropdown.
Edit
I have found that my approach would not work due to the fact that the DOM Popup cannot have the classname of the page which contains the DOM (DataObjectManager). This is a simple inheritance issue and I can't believe I didn't see it before. See the answer below for details of how I solved my original query.
In the end the answer was quite simple. I did the following and I hope someone finds this useful.
Create the checkboxset on the page as normal
if(Permission::check("ADMIN")){
if (! empty($values))
{
$checkBox = new CheckboxSetField(
$name = "Values",
$title = "Select Value",
$source = $values
);
$fieldset->push($checkBox);
}
}
The if statement with Permission::check("ADMIN") checks if the admin is logged in and only shows the checkboxset if they are.
You will also need to include the $fieldset->push within this method to add it to the cms. The ADMIN can be changed to any of your user groups which you created in the security panel so this is an adaptable approach.
I found this the best way for me but if someone can improve on it/offer a better solution I'd love to hear about it.

Drupal Bulk Update Url Alias

I have a set of nodes (about 200) that need to have their url alias updated since we changed the setup; from "site.com/things-to-do/title" to "site.com/guides/title"
I tried using VBO, but when I select the nodes, click Update Url Alias, and then execute, nothing happens.
Although I'd rather not do a straight DB update, I also tried:
"UPDATE url_alias set dst = replace(dst, 'things-to-do', 'guides') WHERE url_alias LIKE 'things-to-do/%';
Thanks
Path auto should fix your problem:
http://drupal.org/project/pathauto
It will give you the option to delete existing aliases and regenerate them.
Apart from using the pathauto module stated above, you should also use path redirect module - http://drupal.org/project/path_redirect - so that you can redirect your old links to the newly created ones, else your old links will die out.
You can also use Global redirect - http://drupal.org/project/globalredirect
Here's a quick script I wrote that solves the problem. It does a simple find and replace on the alias and then creates a redirect.
You need the url_alias and path_redirect modules installed, this is for Drupal 6. This isn't the cleanest syntax (it was written quickly) but it works.
$string_to_replace = "foo";
$replacement_string = "bar";
//Get an array containing all aliases that need to be updated
$query = "SELECT * from url_alias where dst like '%$string_to_replace%'";
$result = db_query($query);
$paths = array();
while ($row = db_fetch_array($result)){
$paths[] = $row;
}
foreach($paths as $path){
//Determine the new path
$path['new_dst'] = str_replace($string_to_replace,$replacement_string,$path['dst']);
//Update the existing url_alias
$query = "UPDATE url_alias SET dst = '".$path['new_dst']."' WHERE pid = " . $path['pid'];
$result = db_query($query);
//Create and save a redirect
$redirect = array(
'source' => $path['dst'],
'redirect' => $path['src'],
);
path_redirect_save($redirect);
}
$nids = Drupal::entityQuery('node')
->condition('type', 'CONTENT_TYPE')
->execute();
$nodes = Node::loadMultiple($nids);
foreach($nodes as $node) {
$node->path->pathauto = 1;
$node->save();
}
I hope above code will solve the issue.

Zend_Search_Lucene implementation with Symfony2 returning empty result

I have an implementation of Zend_Search_Lucene within a Symfony2 application. I am using Zend 1.11. The index seems to be being created, I have several files including:
_0.cfs
optimization.lock.file
read-lock-processing.lock.file
read.lock.file
segments_2
segments.gen
write.lock.file
here is the php code which I have inside a controller
$index = \Zend_Search_Lucene::create(__DIR__.'/../../../../data/index');
$doc = new \Zend_Search_Lucene_Document();
$doc->addField(\Zend_Search_Lucene_Field::unIndexed('title', 'Symfony2') );
$doc->addField(\Zend_Search_Lucene_Field::text('contents', 'cat dog') );
$index->addDocument($doc);
$index = \Zend_Search_Lucene::open(__DIR__.'/../../../../data/index');
$term = new \Zend_Search_Lucene_Index_Term("dog");
$query = new \Zend_Search_Lucene_Search_Query_Term($term);
$results = $index->find($query);
try {
$results = $index->find($query);
}
catch (\Zend_Search_Lucene_Exception $ex) {
$results = array();
var_dump($ex);
}
foreach ( $results as $result ) {
echo $result->score, ' :: ', $result->title, "n";
}
var_dump($results);
exit;
When I run the script the index files are created but only an empty array gets returned and is printed out with the last var_dump as
array(0) { }
Firstly does anyone know how I can check the index is being written correctly?
Secondly does anyone know why my query is not returning any results?
Has anyone successfully implemented Zend_Search_Lucene with Symfony2? I have tried both Lidaa Search and EWZ bundles but neither seems to work.
I worked all day yesterday trying to resolve this problem with no joy, so any help would be very greatly appreciated.
ok, so I've managed to write to the index file now by encoding as utf-8 like this
$doc->addField(\Zend_Search_Lucene_Field::text('contents', 'dog', 'utf-8') );
However, I can still not retrieve any results. I think it might have something to do with the locale settings but I have explicitly set this like so:
setlocale(LC_ALL, 'en_UK.utf-8');
ini_set('intl.default_locale', 'en-UK');
Also if I try and parse the query string as utf-8 the script hangs and timesout
$queryStr = $_GET['query'];
$query = \Zend_Search_Lucene_Search_QueryParser::parse($queryStr, 'utf-8');
Anyone know why this won't work on my Mac?
Yeehaa! I reinstalled MAMP to version 2.0.3 and Boom! it works. I have a feeling this was something to do with either the default locale or encoding but not sure what. If anyone know why version 2.0 MAMP had a bug please let us know.
Cheers
Patrick
You seem to be missing a commit.
$doc->addField(\Zend_Search_Lucene_Field::text('contents', 'cat dog') );
$index->addDocument($doc);
$index->commit(); //Try adding this line
$index = \Zend_Search_Lucene::open(__DIR__.'/../../../../data/index');

Setting location data programmatically

I'm stuck on a problem that I've researched for several days with no luck and the answers here are usually spot on.
I have custom module code that adds a node from form supplied data:
$edit = array();
$edit['uid'] = $user->id;
$edit['name'] = $user->name;
$edit['status'] = 1;
$edit['taxonomy'] = array($term_id);
$edit['title'] = $Title;
$edit['body'] = $body;
etc...
and then saved with:
node_invoke_nodeapi($edit, $nType);
node_validate($edit);
if ($errors = form_get_errors()) {
print_r($errors);
}
$node = node_submit($edit);
node_save($node);
This all works perfectly. But I'm trying to add location data to each node based on a supplied (sanitized) zip field.
I have gmap and location modules installed and working. When I add the zip directly using the drupal content editor it all works. Even the views gmap. So i know versions and mods are all correct.
I've used this:
$location = array(
'country' => 'US',
'postal_code' => $zip,
);
$locationID = location_save($location);
and this:
$location['country'] = "US";
$location['postal_code'] = $zip;
$locationID = location_save($location);
with and without the country element.
And then in the node data init section (above) this:
$edit->locations[0]['lid'] = $locationID;
or
if($locationID) $edit['field_location'][0]['lid'] = $locationID;
or
if($locationID) $edit['location'][0]['lid'] = $locationID;
But none of this works. The submit will go through ok actually but no location data is saved. And no errors thrown.
Any help with this would be greatly appreciated.
I did get this to work, (in case anyone is having the same issue and stumbles upon this), by creating the node first and then adding the location data to the node with:
$locations = array();
$locations[0]['postal_code'] = $zip;
$criteria = array();
$criteria['nid'] = $node->nid;
$criteria['vid'] = $node->vid;
$criteria['genid'] = 'NAME OF NODE TYPE HERE';
location_save_locations( $locations, $criteria );
I guess location_save_locations is the correct way of doing it, not location_save.
Following your approach, as exposed by the wider location_save_locations() at line 4, you can update a location with location_save($locations[$key], TRUE, $criteria).
A few notes:
location_save return the lid of the saved location, or FALSE if the location is considered "empty."
Clean your cache or query the database ( mysql> SELECT * FROM location ORDER BY lid DESC limit 6 ) for a fresh view of the new entity location (ie: node_load data may be cached).
Alternatively, if you are handling an entity with a location field, you may try something cleaner like:
// Updated the location.
$node->field_location['und'][0] = $location;
// Save the node.
node_save ($node);

Theme CCK fieldset

I am attempting to use the CCK theme_fieldgroup_fieldset($elements) hook to convert the fieldset to a two column layout.
I thought that this shouldn't be to hard because the individual fields are in the $elements variable so all I have to do is iterate over them and print them individually. the problem is that I have no way to tell if they have been excluded from display on the "Display Fields" tab of the content type.
Does anyone have any ideas for me? Am I trying to do this the hard way or what am I missing?
Following is the solution that I came up with. The biggest problem is that it requires a database query for every field. These isn't the greatest, but it works so what can you say?
function _brioratheme_include_cck($field) {
$query = "SELECT display_settings AS ds FROM {content_node_field_instance} WHERE field_name = '%s' LIMIT 1";
$result = db_query($query, $field);
if ($result) {
$row = db_fetch_object($result);
$display_settings = unserialize($row->ds);
return !$display_settings['full']['exclude'];
}
}

Resources