drupal 7 calculated field returns undefined index - drupal-7

Ok, struggling now after two hours - and I still cant get it.
I'm trying to average all of the fivestar ratings I have for a node using a computed field. But i'm struggling to simply access the other fields using entity!
In the body of the node, this works fine:
$test1 = $node->field_ae_stimclasswrk[und][0]['average'];
but in the computed field area, this doesn't work:
$entity_field[0]['value'] = $entity->field_ae_stimclasswrk[$entity->language] [und][0]['average'];
Instead, when I save the node, I get this index error:
Notice: Undefined index: und in eval() (line 2 of...
It must be something syntax, but i'm completely out of ideas.
here is the field info:
[field_ae_stimclasswrk] => Array
(
[und] => Array
(
[0] => Array
(
[user] => 80
[average] => 80
[count] => 1
)
)
)

Just a tiny error in your code:
$entity->field_ae_stimclasswrk[$entity->language][und][0]['average'];
If you look at that closely you're actually trying to access the language element of the field twice, once with $entity->language and once with und.
It would probably be best to keep the code contextual so I would remove the [und] item in the code:
$entity->field_ae_stimclasswrk[$entity->language][0]['average'];

I've had the same issue. It was actually caused by a non-existent index inside $entity->field_ref[$entity->language].
For me, $entity->field_ref[$entity->language] existed for all nodes but when you add an index inside that it causes a problem for any nodes that don't use the field.
$entity->field_ref[$entity->language][0] caused the issue (note the addition of the [0] index).
To solve your problem you could try:
$test1 = (isset($node->field_ae_stimclasswrk[$node->language][0]['average']))? $node->field_ae_stimclasswrk[$node->language][0]['average'] : NULL;
Or a little easier to read:
if (isset($node->field_ae_stimclasswrk[$node->language][0]['average'])){
$test1 = $node->field_ae_stimclasswrk[$node->language][0]['average'];
} else {
$test1 = NULL;
}
This way it will bypass any nodes that don't make use of the field.

Related

Why is removing an item from a list with the key as index working as expected?

I have a component in which you can add or remove an option item. When I remove an option item, it is simply removed from an options list stored in state using the index value.
I would have thought that because I am using an index as the key, whenever I deleted an option item, the last element would incorrectly be removed however it seems to be working as expected.
displayedOptions = options.map((option, optionIndex) => (
<DropdownOption
option={option}
onRemoveOption={() => onRemoveOption(optionIndex)}
onChange={onChangeOption(optionIndex)}
key={optionIndex}
/>
));
const onRemoveOption = (taskIndex: number) => (optionIndex: number) => {
const newTaskFields = [...taskFields];
newTaskFields[taskIndex].options = newTaskFields[taskIndex].options.filter(
(_option, index) => {
return optionIndex !== index;
}
);
setTaskFields(newTaskFields);
};
Are there any risks to doing it this way?
Would anyone know why this is working as expected?
I thought the behaviour in my app would have been similar to what was reported here: React - Deleting from middle of list removes last element instead
That is, if I had an list that used indexes as keys containing the following values:
[a, b, c]
and I removed index 0 ('a'), I thought the diff would have been between:
Original:
[0:a, 1:b, 2:c]
and
Updated:
[0:b, 1:c]
In this case, React would see that keys 0 and 1 still exist and would continue to render a and b as it would assume these haven't changed. This would result in c disappearing (not a).
Thank you.
Your onRemoveOption is partially correct. You should shallowly copy all elements of the array/object you intend to update (mutate/remove/etc...).
Your onRemoveOption handler would then become something like:
const onRemoveOption = (taskIndex: number) => (optionIndex: number) => {
setTaskFields((tasks) =>
tasks.map((task, index) =>
index === taskIndex
? {
...task,
options: task.options.filter((_, index) => index !== optionIndex)
}
: task
)
);
};
Uses a functional state update
Maps the tasks to a new array object
If the task index matches the one you need to delete an option from, shallow copy to new object and update the options property, otherwise return the task object
If deleting an option, filter the options by index
Issue will raise while implementing sorting and Removing based on map index.
for example
let Options = [d,a,e,y];
right now Options and index looks like this way.
d 0
a 1
e 2
y 3
Removing item always apply changes from last item. Because you are not passing unique key to the item. Read diff algorithm.
But if you implement sorting and removing - it will failed in removing specific element
after sorting index will change
a 0
d 1
e 2
y 3
You can send option name instead of index.

Angular 2 / Typescript - how to check an array of objects to see if a property has the same value?

This question does it in Javascript, but I would have thought in Typescript I could do some kind of map/filter operation to do the same thing.
I have an array of objects called Room. Each Room has a property called Width (which is actually a string, eg '4m', '5m', '6.5m').
I need to check the entire array to see if all the widths are the same.
Based on that question I have this, but I was wondering if TypeScript has something better:
let areWidthsTheSame = true;
this.qp.rooms.forEach(function(room, index, rooms) {
if (rooms[index] != rooms[index+1]) areWidthsTheSame = false;
});
Any ideas?
FYI the linked question has a comment that links to these performance tests, which are interesting in the context of this question:
This can be done in the following way:
const widthArr = rooms.map(r => r.width);
const isSameWidth = widthArr.length === 0 ? true :
widthArr.every(val => val === widthArr[0]);
We first convert the rooms array to an array of widths and then we check if all values in widths arrays are equal.

Laravel 4 updating all records with array gives me parameter mismatch error

Trying to update each row of a table with a multidimensional array created from querying another database.
The array:
Array
(
[0] => Array
(
[community_id] => ap
[floorplan_code] => ap1-1a
[name] => 33flat
[hidden] => 0
)
[1] => Array
(
[community_id] => ap...
Here is the code I'm using in an attempt to update:
$floorPlan = new Floorplan; //create new instance
$floorPlan->get(); //get all rows
$floorPlan->update($floorplanMappedArray); //map db columns to array and update
Error message: preg_replace(): Parameter mismatch, pattern is a string while replacement is an array.
The parameter mismatch came from the fact that I was trying to shove a multidimensional array into a single row. Therefore, I needed a foreach loop to index through the multidimensional array.
I thought that there was a magical way to use the update() method in the same way that the insert() method is used. Apparently, there is not.
Here is the code that solved the parameter mismatch error:
foreach ($floorplanMappedArray as $floorPlan) {
Floorplan::where('floorplan_code', $floorPlan['floorplan_code'])->update($floorPlan);
}

what it the find list error

I tyed get with the method $this>model->find() an array with ids of my model that have this form:
Array ( [0] => 2, [1] => 3) (value are the IDs)
and I try $this->model->find('list') I thought that would work too but for some strange reason I have done:
$this->model->find('list',array('recursive' => -1 ,'fields' => array('model.type_id'),'conditions'=>$cond));
and the query result is:
SELECT `model`.`round_id`, `model`.`type_id` FROM `database`.`model` AS `X` WHERE `X`.`Round_id` = '1'
If I make this query to the database returns two values ​​but cakephp returns only one:
Array ( [1] => 2 )
i do not know that may be going
I would use
$ids = $this->Model->find('list', array('fields' => array('id')));
if you really need the 0 based integer keys, you can still do:
$ids = array_values($ids);
but that is not necessary IMO.
Update:
After your question update the whole meaning of your question itself changed:
If you specify only id, they keys and values will both be filled with it.
Using 'fields' => array('round_id', 'type_id') you have round_id filling the keys, and type_id filling the values for find(list).
find(list) returns always a list (key + value row). If you don't want that use find(all) then.

Unsetting elements of a cakephp generated array

I have an array called $all_countries following this structure:
Array
(
[0] => Array
(
[countries] => Array
(
[id] => 1
[countryName] => Afghanistan
)
)
[1] => Array
(
[countries] => Array
(
[id] => 2
[countryName] => Andorra
)
)
)
I want to loop through an array called prohibited_countries and unset the entire [countries] element that has a countryName matching.
foreach($prohibited_countries as $country){
//search the $all_countries array for the prohibited country and remove it...
}
Basically I've tried using an array_search() but I can't get my head around it, and I'm pretty sure I could simplify this array beforehand using Set::extract or something?
I'd be really grateful if someone could suggest the best way of doing this, thanks.
Here's an example using array_filter:
$all_countries = ...
$prohibited_countries = array('USA', 'England'); // As an example
$new_countries = array_filter($all_countries, create_function('$record', 'global $prohibited_countries; return !in_array($record["countries"]["countryName"], $prohibited_countries);'));
$new_countries now contains the filtered array
Well first of all id e teh array in the format:
Array(
'Andorra' => 2,
'Afghanistan' => 1
);
Or if you need to have the named keys then i would do:
Array(
'Andorra' => array('countryName'=> 'Andorra', 'id'=>2),
'Afghanistan' => array('countryName'=> 'Afghanistan', 'id'=>1)
);
then i would jsut use an array_diff_keys:
// assuming the restricted and full list are in the same
// array format as outlined above:
$allowedCountries = array_diff_keys($allCountries, $restrictedCountries);
If your restricted countries are just an array of names or ids then you can use array_flip, array_keys, and/or array_fill as necessary to get the values to be the keys for the array_diff_keys operation.
You could also use array_map to do it.
Try something like this (it's probably not the most efficient way, but it should work):
for ($i = count($all_countries) - 1; $i >= 0; $i--) {
if (in_array($all_countries[$i]['countries']['countryName'], $prohibited_countries) {
unset($all_countries[$i]);
}
}
If you wanted to use the Set class included in CakePHP, you could definitely reduce the simplicity of your country array with Set::combine( array(), key, value ). This will reduce the dimensionality (however, you could do this differently as well. It looks like your country array is being created by a Cake model; you could use Model::find( 'list' ) if you don't want the multiple-dimension resultant array... but YMMV).
Anyway, to solve your core problem you should use PHP's built-in array_filter(...) function. Manual page: http://us3.php.net/manual/en/function.array-filter.php
Iterates over each value in the input
array passing them to the callback
function. If the callback function
returns true, the current value from
input is returned into the result
array. Array keys are preserved.
Basically, pass it your country array. Define a callback function that will return true if the argument passed to the callback is not on the list of banned countries.
Note: array_filter will iterate over your array, and is going to be much faster (execution time-wise) than using a for loop, as array_filter is a wrapper to an underlying C function. Most of the time in PHP, you can find a built-in to massage arrays for what you need; and it's usually a good idea to use them, just because of the speed boost.
HTH,
Travis

Resources