Multiple conditions for db_update - drupal-7

In Drupal 7 simple updates work like this:
$num_updated = db_update('joke')
->fields(array(
'punchline' => 'Take my wife please!',
))
->condition('nid', 3, '>=')
->execute();
But what if I have multiple conditions( say nid >=3 and uid >=2). Writing something like:
$num_updated = db_update('joke')
->fields(array(
'punchline' => 'Take my wife please!',
))
->condition('nid', 3, '>=')
->condition('uid', 2, '>=')
->execute();
does not seem to work. Any ideas?

What you have written will do the equivalent of:
'...WHERE (NID >= 3 AND UID >= 2)"
If you wanted an OR conditional you need to nest the statements as such (no, it's not very intuitive):
->condition(db_or()->condition('NID'', 3, '>=')->condition('UID', 2, '>='))
There is also db_and() [default for chaining multiple condition methods] and db_xor() that you can use when nesting.

Related

Laravel 5.4 skip first value in Pluck array

I have this query
$orderStates = OrderState::listsTranslations( 'states' )->pluck( 'states', 'id' )->toArray();
which will output something like
array:3 [▼
1 => "waiting"
2 => "agreed"
3 => "canceled"
]
I need to skip the first one to be something like
array:3 [▼
2 => "agreed"
3 => "canceled"
]
How this can be done please?
There is multiple ways you can achieve this. One that doesn't seem very consistent to me would be to use skip(1) (this expects the query to sort by id and that always the entry with id = 1 needs to be skipped):
$orderStates = OrderState::listsTranslations( 'states' )
->skip(1)
->pluck( 'states', 'id' )
->toArray();
An alternative might be to use whereNotIn() to exclude specific ids:
$orderStates = OrderState::listsTranslations( 'states' )
->whereNotIn('id', [1])
->pluck( 'states', 'id' )
->toArray();
You could also use where('id', '!=', 1) instead of whereNotIn('id', [1]) or skip(1), but personally I think that whereNotIn offers the most extensibility for the future.
First thanks for Namoshek guide but skip(1) didn't work with this but slice(1) did
Here is the last query
$orderStates = OrderState::listsTranslations( 'states' )
->pluck( 'states', 'id' )
->slice( 1 )
->toArray();
Worked fine.

Booleans, arrays, and not typing 256 possible scenarios

I'm trying to make a program based around 8 boolean statements.
I build the array = [0,0,0,0,0,0,0,0];.
For each possible combination I need to make the program output a different text.
To make things simpler, I can remove any possibilities that contain less than 3 true statements.
For example: if (array === [1,1,1,0,0,0,0,0]){console.log('Targets: 4, 5, 6, 7')};
Is it possible to have it set so that if the value is false it's added to then end of "Targets: "? I'm very new to coding as a hobby and have only made 1 extensive program. I feel like {console.log("Targets: " + if(array[0]===0){console.log(" 1,")} + if(array[2]===0)...}would portay what I'm looking for but it's terrible as a code.
I'm sure that someone has had this issue before but I don't think I'm experienced enough to be searching with the correct keywords.
PS: I'd greatly appreciate it if we can stick to the very basics as I haven't had any luck with installing new elements other than discord.js.
This does what you need:
const values = [1,1,1,0,0,0,0,0];
const positions = values.map((v, i) => !v ? i : null).filter(v => v != null);
console.log('Target: ' + positions.join(', '));
In essence:
Map each value to its respective index if the value is falsy (0 is considered falsy), otherwise map it to null.
Filter out all null values.
Join all remaining indexes to a string.
To address your additional requirements:
const locations = ['Trees', 'Rocks', 'L1', 'R1', 'L2', 'R2', 'L3', 'R3'];
const values = [1,1,1,0,0,0,0,0];
const result = values.map((v, i) => !v ? locations[i] : null).filter(v => v != null);
console.log('Target: ' + result.join(', '));

Yii2 Array sorting

In my Yii2 Project I have an array for example
$array = [];
$array [] = 8 , 3, 6
So when I print out the array is
[8,3,6]
So when I use the same in a where statement it jumbles up.
$class = ModelClass::find()->where(['array_no' => $array])->all
So when I print out class I get the output in asc order sorted..
I get the information of
3 in the first
6 in the second place
8 in the third place.
How can i stop this from happening. I want them to return my output in the same order as array
You should use ORDER BY FIELD(), e.g. :
$models = ModelClass::find()
->where(['array_no' => $array])
->orderBy(new \yii\db\Expression('FIELD (array_no, '.implode(',', $array).')'))
->all();

drupal 7 db_select with OR statement

I am trying to execute the following code:
$state = db_select('webform_email_confirm', 'wec')
->fields('wec')
->condition('nid', $form['nid']['#value'], '=')
->condition('cid1', $form['cid']['#value'], '=')
->or('cid2', $form['cid']['#value'], '=')
->execute()
->fetchAssoc();
The third statement, ->or('cid2', $form['cid']['#value'], '='), does not work.
I need to match records in my database in either cid1 or cid2.
You would have to use the db_or(), or the $query->where constructs.
Please have a look at this page for more information.
So basically, try:
$or = db_or()
->condition('cid1', $form['cid']['#value'])
->condition('cid2', $form['cid']['#value']);
$state = db_select('webform_email_confirm', 'wec')
->fields('wec')
->condition('nid', $form['nid']['#value'], '=')
->condition($or)
->execute()
->fetchAssoc();
The examples on the drupal website may be useful too:
$query
->condition('field1', array(1, 2), 'IN')
->condition(db_or()->condition('field2', 5)->condition('field3', 6))
// Results in:
// (field1 IN (:db_placeholder_1, :db_placeholder_2) AND (field2 = :db_placeholder3 OR field3 = :db_placeholder_4))

Array of sorted key/value pairs to sorted array of keys and hash

I am developing a Catalyst app which uses Template::Toolkit as template engine. One page needs a list of equal input elements. They can be taken from an array but I need both sort order and a descriptive label for the element.
For having a sort order I would use an array. For storing an additional value per key a hash is perfect. How to combine both in TT? I could use both things but that seems ugly and can cause mistakes when changing the fields.
However, I prefer doing this in TT because both the descriptions and the order of form elements is a front-end thing.
This is how I would do it in pure Perl:
#!/usr/bin/perl -w
use 5.10.0;
# definition of description and order in 1 step
my #fields = (
property_foo => "Some property",
property_bar => "Important field",
property_baz => "Something else",
);
# extract information
my %descriptions = #fields;
my #order = #fields[grep {($_ + 1) % 2} 0..(scalar #fields - 1)];
say "=== natural perl sort order ===";
foreach (keys %descriptions) {say $_};
say "=== wanted output ===";
foreach (#order) {
say $descriptions{$_} . ": [label for $_]";
}
Outputs:
=== natural perl sort order ===
property_baz
property_foo
property_bar
=== wanted output ===
Some property: [label for property_foo]
Important field: [label for property_bar]
Something else: [label for property_baz]
This is what I write in my template:
[%
order = (
property_foo,
property_bar,
property_baz,
);
descriptions = {
property_foo => "Some property",
property_bar => "Important field",
property_baz => "Something else",
}
FOREACH property IN order %]
[% descriptions.$property %]: <input name="[% property %]" />
[% END %]
However, it is really ugly to have the same information (list of fields) twice. I want to avoid editing the list twice and with a longer list of fields it gets really annoying (about 20 items, not long enough to do some database stuff).
It's amazing how people complicate easy stuff!
You don't need the #fields array. Please read the perldoc about keys, values and sort.
# untested sketch
my %description = ( prop23 => "foo", prop24 => "bar" );
foreach my $key(sort (keys %description)) {
print $key, " is: ", $description{$key}, "\n"; # or whatever
}
Addendum: Regarding the order of keys, just do the following:
my #arbitraryOrder = qw(prop42 prop35 prop1 ...); # allows to map number to key
my %keytoNumber = (); # will map keys to numbers
foreach my $i(0..$#arbitraryOrder) $keyToNumber{$arbitraryOrder[$i]} = $i;
Writing the comparison function for sort is left as an exercise :)
You might be interested in Tie::IxHash
It is a "hash" that keeps the order in which you add keys (value updates do not affect sorting).
EDIT: A brief example:
use warnings;
use strict;
use Tie::IxHash;
tie my %H, "Tie::IxHash";
$H{foo} = 1;
$H{bar} = 2;
# order of keys is now always 'foo', 'bar'
print keys %H;
EDIT2: I've tried it out, and it actually works:
#!/usr/bin/perl -w
use strict;
use Template;
use Tie::IxHash;
# my %h; # this breaks ordering
tie my %H, "Tie::IxHash"; # this keeps ordering
#H{qw/f oo b a r/} = 1..100;
# don't define $H{'keys'} or you'll get disappointed
my $tpl = Template->new();
$tpl->process(\*DATA, {hash=>\%H});
__DATA__
[% FOREACH k IN hash.keys %]
[% k %] => [% hash.$k %]
[% END %]
If you need ordering and multiple pieces of information then you should consider an array of hash references.
my #fields = (
{ id => 'property_foo',
label => 'Some property' },
{ id => 'property_bar',
label => 'Important field' },
{ id => 'property_baz',
label => 'Something else' },
);
foreach (#fields) {
print "ID: $_->{id}, Label: $_->{label}\n";
}
If the complexity increases much beyond this, you might consider replacing the hashrefs with real objects.
And, in TT, it looks like this:
[%-
properties = [
{id => 'property_foo',
label => 'Some property'},
{id => 'property_bar',
label => 'Important field'},
{id => 'property_baz',
label => 'Something else'},
];
-%]
[%- FOREACH property IN properties %]
[% property.label %]: <input name="[% property.id %]" />
[% END %]
Actually if you want your hash alphabetically sorted by key, Template::Toolkit does that for you.
test.pl
use strict;
use warnings;
use Template;
my %hash = qw' a 1 b 2 c 3 ';
my $config = {
INCLUDE_PATH => '/search/path',
};
my $input = 'test.tt2';
my $template = Template->new( $config );
$template->process( $input, {
hash => \%hash,
})
test.tt2
[% FOREACH hash -%]
[% key %] => [% value %]
[% END %]
output
a => 1
b => 2
c => 3

Resources