I have search query where i am using single meta_key with multiple values but its not working . here is the meta query .
[meta_query] => Array
(
[0] => Array
(
[key] => _vital_lighting_color
[value] => Array
(
[0] => red
[1] => green
[2] => blue
)
[type] => char
[compare] => IN
)
)
but its not fetching record i don't what's happening can you please check it .
Thanks
Using proper php syntax would help :
$query_args = array(
'meta_query' => array(
'key' => '_vital_lighting_color' ,
'value' => array
('red' , 'green' ,'blue' ) ,
'compare' => 'IN'
)
) ;
I removed type, because "char' is the default value
If it does not work, then run a query on the database directly to check you have posts
Related
I'm having an issue with comparing values between two arrays in wp_query
I have the two roles administrator and forhandler_salg ($roles returns an array with these two values), but it only queries posts with the "public" key set to true
I got more posts when I changed the "allowed_userroles" key compare value to "LIKE", but those aren't the right posts
$roles = "";
if (is_user_logged_in()) {
$user = wp_get_current_user();
$roles = (array) $user->roles;
}
$args = array(
'post_type' => 'downloads',
'posts_per_page' => '-1',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'public',
'value' => true,
'compare' => '=',
),
# Not working
array(
'key' => 'allowed_userroles',
'value' => $roles,
'compare' => 'IN',
),
),
);
print_r($args) returns
Array
(
[post_type] => downloads
[posts_per_page] => -1
[meta_query] => Array
(
[relation] => OR
[0] => Array
(
[key] => public
[value] => 1
[compare] => =
)
[1] => Array
(
[key] => allowed_userroles
[value] => Array
(
[16] => administrator
[17] => forhandler_salg
)
[compare] => IN
)
)
)
And a post with the "public" custom field as true and some added roles returns this, when I print_r() the allowed_userroles for the post:
Array
(
[0] => role1
[1] => role2
[2] => role3
)
How would I go about checking if allowed_userroles in the query has values that are also present in $roles?
EDIT: "like" works if I put in a role manually
Ok, for these kinds of problems, it's easier to start with your basic array of arguments and then modify it.
Since this question is tagged with ACF, ACF is likely storing this as a single meta entry. Furthermore, if this is an array of values, ACF is very likely storing it as a serialized PHP string in the database (e.g., a:2:{i:0;s:4:"1234";i:1;s:3:"qed";}).
Let's start with the base code:
$roles = [];
if (is_user_logged_in()) {
$user = wp_get_current_user();
$roles = (array) $user->roles;
}
$args = array(
'post_type' => 'downloads',
'posts_per_page' => -1,
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'public',
'value' => "1",
'compare' => '=',
),
),
);
In this case, you'll need to use a LIKE to attempt a sub-string match.
foreach($roles as $role) {
$args['meta_query'][] = [
'key' => 'allowed_userroles',
'value' => $role, // can't remember if wp will wrap value with %
'compare' => 'LIKE',
];
}
Ideally, you'd want to match based on the string length as well, but that might be a bit prohibitive. If you keep running into issues getting the exact results out, you could run two separate queries. The first query would be for all public items, and the second query would be for non-public items. You could then take the results of the second query and then filter out values that do not have the correct meta, since it'll be easier to process using get_field('allowed_userroles').
OK, I've been struggling with this for days now. Hopefully someone can shed some light on this...
Site is on Drupal 9.4.3 (currently the latest) using PHP 8.1.6
I have a content type with a datetime_range field setup to use as time-range (Start time and End Time) formatted for time only input. Field Name: field_friday_hours
The content type also has a computed_field decimal field, where I want to set the total hours calculated from the "Start time and End time" of the date range field. Computed Field Name: field_test_total_hours
The date range field collecting the start and stop time also uses time_range contrib module as well as DateTime Hide Seconds (datetimehideseconds) module - which I don't know if that's been complicating the situation for me or if that doesn't matter.
The computed field gives me this code sample to use in a custom module:
The hook implementation function signature should be
computed_field_field_test_total_hours_compute($entity_type_manager, $entity, $fields, $delta)
and the desired value should be returned.
The variables available to your code include:
$entity_type_manager: The entity type manager.
$entity: The entity the field belongs to.
$fields: The list of fields available in this entity.
$delta: Current index of the field in case of multi-value computed fields (counting from 0).
$value: The resulting value to be set above, or returned in your hook implementation).
Here is what dpm($form); gives me on node/add/...(
[field_friday_hours] => stdClass Object
(
[__CLASS__] => Drupal\field\Entity\FieldConfig
[entityTypeId:protected] => field_config
[enforceIsNew:protected] =>
[typedData:protected] =>
[cacheContexts:protected] => Array(0)
[cacheTags:protected] => Array(0)
[cacheMaxAge:protected] => -1
[_serviceIds:protected] => Array(0)
[_entityStorages:protected] => Array(0)
[originalId:protected] => node.time_sheets.field_friday_hours
[status:protected] => 1
[uuid:protected] => fad1e2cf-9c60-4e4a-b171-33c2579f6712
[isUninstalling:Drupal\Core\Config\Entity\ConfigEntityBase:private] =>
[langcode:protected] => en
[third_party_settings:protected] => Array(0)
[_core:protected] => Array(0)
[trustedData:protected] =>
[dependencies:protected] => Array(2)
[isSyncing:protected] =>
[id:protected] => node.time_sheets.field_friday_hours
[field_name:protected] => field_friday_hours
[field_type:protected] => daterange
[entity_type:protected] => node
[bundle:protected] => time_sheets
[label:protected] => Friday Hours
[description:protected] =>
[settings:protected] => Array(0)
[required:protected] =>
[translatable:protected] =>
[default_value:protected] => Array(0)
[default_value_callback:protected] =>
[fieldStorage:protected] => Drupal\field\Entity\FieldStorageConfig
[itemDefinition:protected] => Drupal\Core\Field\TypedData\FieldItemDataDefinition
[constraints:protected] => Array(0)
[propertyConstraints:protected] => Array(0)
[deleted:protected] =>
)
[field_test_total_hours] => stdClass Object
(
[__CLASS__] => Drupal\field\Entity\FieldConfig
[entityTypeId:protected] => field_config
[enforceIsNew:protected] =>
[typedData:protected] =>
[cacheContexts:protected] => Array(0)
[cacheTags:protected] => Array(0)
[cacheMaxAge:protected] => -1
[_serviceIds:protected] => Array(0)
[_entityStorages:protected] => Array(0)
[originalId:protected] => node.time_sheets.field_test_total_hours
[status:protected] => 1
[uuid:protected] => a7179c06-3ea9-4152-960d-9f82075e7da0
[isUninstalling:Drupal\Core\Config\Entity\ConfigEntityBase:private] =>
[langcode:protected] => en
[third_party_settings:protected] => Array(0)
[_core:protected] => Array(0)
[trustedData:protected] =>
[dependencies:protected] => Array(2)
[isSyncing:protected] =>
[id:protected] => node.time_sheets.field_test_total_hours
[field_name:protected] => field_test_total_hours
[field_type:protected] => computed_decimal
[entity_type:protected] => node
[bundle:protected] => time_sheets
[label:protected] => test total hours
[description:protected] =>
[settings:protected] => Array(2)
[required:protected] =>
[translatable:protected] =>
[default_value:protected] => Array(0)
[default_value_callback:protected] =>
[fieldStorage:protected] => Drupal\field\Entity\FieldStorageConfig
[itemDefinition:protected] => Drupal\Core\Field\TypedData\FieldItemDataDefinition
[constraints:protected] => Array(0)
[propertyConstraints:protected] => Array(0)
[deleted:protected] =>
)
[field_friday_hours] => Array
(
[type] => time_range
[weight] => 26
[region] => content
[settings] => Array(0)
[third_party_settings] => Array(1)
)
[field_test_total_hours] => Array
(
[type] => computed_number_widget
[weight] => 27
[region] => content
[settings] => Array(0)
[third_party_settings] => Array(0)
)
[field_friday_hours] => stdClass Object
(
[__CLASS__] => Drupal\time_range\Plugin\Field\FieldWidget\TimeRangeWidget
[pluginId:protected] => time_range
[pluginDefinition:protected] => Array(6)
[configuration:protected] => Array(0)
[stringTranslation:protected] => Drupal\Core\StringTranslation\TranslationManager
[_serviceIds:protected] => Array(0)
[_entityStorages:protected] => Array(0)
[messenger:protected] =>
[settings:protected] => Array(0)
[thirdPartySettings:protected] => Array(1)
[defaultSettingsMerged:protected] =>
[fieldDefinition:protected] => Drupal\field\Entity\FieldConfig
[dateStorage:protected] => Drupal\Core\Config\Entity\ConfigEntityStorage
)
[field_test_total_hours] => stdClass Object
(
[__CLASS__] => Drupal\computed_field\Plugin\Field\FieldWidget\ComputedNumberWidget
[pluginId:protected] => computed_number_widget
[pluginDefinition:protected] => Array(6)
[configuration:protected] => Array(0)
[stringTranslation:protected] => Drupal\Core\StringTranslation\TranslationManager
[_serviceIds:protected] => Array(0)
[_entityStorages:protected] => Array(0)
[messenger:protected] =>
[settings:protected] => Array(0)
[thirdPartySettings:protected] => Array(0)
[defaultSettingsMerged:protected] =>
[fieldDefinition:protected] => Drupal\field\Entity\FieldConfig
[default_value] =>
)
[field_friday_hours] => Array
(
[#type] => container
[#parents] => Array
(
[0] => field_friday_hours_wrapper
)
[#attributes] => Array
(
[class] => Array
(
[0] => field--type-daterange
[1] => field--name-field-friday-hours
[2] => field--widget-time-range
)
)
[widget] => Array
(
[0] => Array
(
[#title] => Friday Hours
[#title_display] => before
[#description] =>
[#field_parents] => Array
(
)
[#required] =>
[#delta] => 0
[#weight] => 0
[value] => Array
(
[#type] => datetime
[#default_value] =>
[#date_increment] => 1
[#date_timezone] => America/New_York
[#required] =>
[#title] => stdClass Object
(
[__CLASS__] => Drupal\Core\StringTranslation\TranslatableMarkup
[string:protected] => Start time
[arguments:protected] => Array(0)
[translatedMarkup:protected] =>
[options:protected] => Array(0)
[stringTranslation:protected] => Drupal\Core\StringTranslation\TranslationManager
)
[#date_date_format] => none
[#date_date_element] => none
[#date_date_callbacks] => Array
(
)
[#date_time_format] => H:i:s
[#date_time_element] => time
[#date_time_callbacks] => Array
(
)
[#datetimehideseconds] => Array
(
[hide] => 1
)
)
[#theme_wrappers] => Array
(
[0] => fieldset
)
[#element_validate] => Array
(
[0] => Array
(
[0] => Drupal\time_range\Plugin\Field\FieldWidget\TimeRangeWidget
[1] => validateStartEnd
)
[1] => Array
(
[0] => Drupal\time_range\Plugin\Field\FieldWidget\TimeRangeWidget
[1] => validateStartEnd
)
)
[end_value] => Array
(
[#title] => stdClass Object
(
[__CLASS__] => Drupal\Core\StringTranslation\TranslatableMarkup
[string:protected] => End time
[arguments:protected] => Array(0)
[translatedMarkup:protected] =>
[options:protected] => Array(0)
[stringTranslation:protected] => Drupal\Core\StringTranslation\TranslationManager
)
[#type] => datetime
[#default_value] =>
[#date_increment] => 1
[#date_timezone] => America/New_York
[#required] =>
[#date_date_format] => none
[#date_date_element] => none
[#date_date_callbacks] => Array
(
)
[#date_time_format] => H:i:s
[#date_time_element] => time
[#date_time_callbacks] => Array
(
)
[#datetimehideseconds] => Array
(
[hide] => 1
)
)
)
[#theme] => field_multiple_value_form
[#field_name] => field_friday_hours
[#cardinality] => 1
[#cardinality_multiple] =>
[#required] =>
[#title] => Friday Hours
[#description] =>
[#max_delta] => 0
[#after_build] => Array
(
[0] => Array
(
[0] => Drupal\time_range\Plugin\Field\FieldWidget\TimeRangeWidget
[1] => afterBuild
)
)
[#field_parents] => Array
(
)
[#parents] => Array
(
[0] => field_friday_hours
)
[#tree] => 1
)
[#access] => 1
[#weight] => 26
[#cache] => Array
(
[contexts] => Array
(
)
[tags] => Array
(
[0] => config:field.field.node.time_sheets.field_friday_hours
[1] => config:field.storage.node.field_friday_hours
)
[max-age] => -1
)
)
[field_test_total_hours] => Array
(
[#type] => container
[#parents] => Array
(
[0] => field_test_total_hours_wrapper
)
[#attributes] => Array
(
[class] => Array
(
[0] => field--type-computed-decimal
[1] => field--name-field-test-total-hours
[2] => field--widget-computed-number-widget
)
)
[widget] => Array
(
[0] => Array
(
[value] => Array
(
[#title] => field_test_total_hours
[#type] => hidden
[#default_value] => 0
[#disabled] => 1
[#description] => stdClass Object
(
[__CLASS__] => Drupal\Core\StringTranslation\TranslatableMarkup
[string:protected] => Normally this field should not be shown!
[arguments:protected] => Array(0)
[translatedMarkup:protected] =>
[options:protected] => Array(0)
[stringTranslation:protected] => Drupal\Core\StringTranslation\TranslationManager
)
)
)
[#theme] => field_multiple_value_form
[#field_name] => field_test_total_hours
[#cardinality] => 1
[#cardinality_multiple] =>
[#required] =>
[#title] => test total hours
[#description] =>
[#max_delta] => 0
[#after_build] => Array
(
[0] => Array
(
[0] => Drupal\computed_field\Plugin\Field\FieldWidget\ComputedNumberWidget
[1] => afterBuild
)
)
[#field_parents] => Array
(
)
[#parents] => Array
(
[0] => field_test_total_hours
)
[#tree] => 1
)
[#access] => 1
[#weight] => 27
[#cache] => Array
(
[contexts] => Array
(
)
[tags] => Array
(
[0] => config:field.field.node.time_sheets.field_test_total_hours
[1] => config:field.storage.node.field_test_total_hours
)
[max-age] => -1
)
)
In the above I believe the 2nd to last array is the one I'm looking for yet I have no idea what to do with that information in this particular situation.
In my custom module I've tried a bunch of random things found in other posts that yield either no results or produces errors.
I've tried
function computed_field_field_test_total_hours_compute($entity_type_manager, $entity, $fields, $delta) {
$start_time = $entity->field_friday_hours[0]['value'];
$end_time = $entity->field_friday_hours[0]['end_value'];
$total_time = $end_time - $start_time;
$value = $total_time;
}
additionally I've tried to get the time values with: (examples for $start_time...)
$start_time = $fields['field_friday_hours'][0]['value']['time']['#value'];
$start_time = $entity->field_friday_hours[0]['value']['#default_value'];
$start_time = $entity->get('field_friday_hours')->getValue();
$start_time = $field['field_friday_hours'][0]['value']['time']['#value'];
And several variations of the above as well including $start = $start_time->_toString and $start_time = $entity->field_friday_hours[0]['value']->format('H:i'); etc etc etc, nothing is getting me where I need to be!
Further more even trying to just set the value of the computed field using something like $value = 8.5; without trying to get any other field data/values and it won't even set it. So I'm assuming I missed the boat on this completely.
I know with computed field there is also the option to format the computed field via a plugin and doing calculations there - however before I even attempt that approach I'd like to know how to make the hook approach work correctly.
I even tried hook_alter like this:
function custom_module_computed_field_field_test_total_hours_value_alter(&$value, $context) {
}
But nothing there seamed to work either!
At this point my head is pounding from reviewing document after document having searched for an answer extensively with nothing adding up and or working.
If recreating the the computed field in another type would help I'm all for it - or if there is a definite easier way to do this I'm all ears...
Please HELP - Thanks in advance!
So after a lot of trial and error I finally figured things out.
With the use of the provided function displayed on the computed fields edit page in my custom module as follows:
function computed_field_field_test_total_hours_compute($entity_type_manager, $entity, $fields, $delta) {
// Get and set Start time
$get_stime = $entity->field_friday_hours->value;
$start_time = new DrupalDateTime($get_stime);
// Get and set End time
$get_etime = $entity->get('field_friday_hours')->getValue()[0]['end_value'];
$end_time = new DrupalDateTime($get_etime);
// Calculate hours to decimal
$diff = $end_time->getTimestamp() - $start_time->getTimestamp();
$hours = $diff/3600;
$tot_hours = round($hours, 2);
// Set Computed field value
$value = $tot_hours;
return $value;
}
In comparison to what I was originally trying (which was initially based on other posts and answers to similar questions when trying to get field values in a hook or function) I was close. Looks like I didn't have enough information with setting a variable with $entity or it was in the wrong format.
I'm still not 100% clear on what patterns in what types of hooks can be used to get field data especially in Drupal 8 and 9, let alone through the use of a custom module. Most documentation especially for contributed modules for anything Drupal 8 or 9 is incomplete or none existent.
I ended up having to simplifying things first and work through it.
First by just setting a generic value and returning it to make sure the computed field actually populated on node save.
After that I made sure I could do basics to generate a value to return, by creating a date with start and end time from a string without getting it from any fields. I could manage this fine in both the suggested function and hook_value_alter.
Then I created simple text field and tried to get it's field value.
Still for the life of me I couldn't figure out how to get a basic text field value in hook_value_alter, so I switched to the suggested function as the few snippets I found using $entity worked to get the text fields value and on node save it took the value of the text field and placed it in the computed field.
After that it took a little more in trial and error on getting the actual date-range using time-range field values.
At this time what confused me the most was were I could get the start time with this:
$entity->field_friday_hours->value;
To get the end time value I couldn't do this:
$entity->field_friday_hours->end_value;
I had to do this:
$entity->get('field_friday_hours')->getValue()[0]['end_value'];
Which at first struck me as odd; anytime I tried to use get() or getValue() I constantly fatal errored with can't get or getValue of null. So for the longest time I really thought that wouldn't work in either the suggested function or hook_value_alter.
That said using dpm($form) made how it ended up working even a bit more confusing, considering that should have given me the structure to use to get the start and end time values "at least from what I understood" and had read pretty much everywhere.
Yet using the array structure per dpm() the order should have included ['widget'] before [0] which was not the case in the final result.
If I'm understanding correctly now get() gets the field and getValue() starts from whatever part of the object array that follows it - which is still a tad bit confusing (aside from the fact I may be completely wrong on that, as I'm just going by what I can see happening as I worked through everything)
Please feel free to correct me on anything.
Regardless this works in Drupal 9 to get date-range start and end times and then convert them to hours in a decimal format and return them to a computed field.
I am attempting a meta query to get between two prices set as a meta field in my custom post.
However the _ccprop_prop_price query is being ignored. Its still giving results higher than 100000 , I can confirm the id of the meta field is _ccprop_prop_price. It is worth noting however that the field is a text field not a number field.
Am I missing something obvious? I even tried to break it down further by doing two arrays and using < and > instead.
Edit: Just another development, I notice = does in fact work which makes me wonder is it something to do with it being a text field.
Here is the resulting final $args
(
[post_type] => property
[orderby] => meta_value_num
[meta_key] => _ccprop_prop_price
[order] => ASC
[posts_per_page] => 30
[paged] => 1
[tax_query] => Array
(
[0] =>
[1] =>
[2] =>
[3] =>
)
[meta_query] => Array
(
[relation] => AND
[0] => Array
(
[key] => _ccprop_prop_price
[value] => Array
(
[0] => 0
[1] => 100000
)
[compare] => BETWEEN
[type] => NUMERIC
)
)
)
I found the issue, there were commas for some of the prices in that meta field and they were the ones appearing.
I'm comparing the trip_region custom field of my trip CPT to the first element of an array: $filter_region[0].
Howevere I may have more elements in that array and I need to select trips whose trip_region field equals any of these elements. Is it possible, with meta_query, to compare (with an OR, not an AND) a field to several values at once? Because there's nothing quite like that in the doc.
$get_trips_region = get_posts(array(
'post_type' => 'trip',
'meta_query' => array(
array(
'key' => 'trip_region',
'value' => '"' . $filter_region[0] . '"',
'compare' => 'LIKE'
)
)
));
EDIT:
Here's my new code, presumably closer to the solution but doesn't return any result:
$get_trips_region = get_posts(array(
'post_type' => 'trip',
'meta_query' => array(
array(
'key' => 'trip_region',
'value' => $filter_region,
'compare' => 'IN'
)
)
));
EDIT(2):
Replacing get_posts with WP_Query and using WP_Query's request property I see the following SQL query is being executed here:
SELECT SQL_CALC_FOUND_ROWS wp_15_posts.ID FROM wp_15_posts INNER JOIN wp_15_postmeta ON (wp_15_posts.ID = wp_15_postmeta.post_id) WHERE 1=1 AND wp_15_posts.post_type = 'trip' AND (wp_15_posts.post_status = 'publish' OR wp_15_posts.post_status = 'private') AND ( (wp_15_postmeta.meta_key = 'trip_region' AND CAST(wp_15_postmeta.meta_value AS CHAR) IN ('47','46','45')) ) GROUP BY wp_15_posts.ID ORDER BY wp_15_posts.post_date DESC LIMIT 0, 10
Relevant passage I guess is: (wp_15_postmeta.meta_key = 'trip_region' AND CAST(wp_15_postmeta.meta_value AS CHAR) IN ('47','46','45'))
Looks good to me, I don't understand why it doesn't work.
I think you have to compare with IN instead of LIKE. The value must contain an array then. Here's the doc.
$filter_region = array( 'Region 1', 'Region 2' );
$get_trips_region = get_posts(array(
'post_type' => 'trip',
'meta_query' => array(
array(
'key' => 'trip_region',
'value' => $filter_region,
'compare' => 'IN'
)
)
));
You can use compare. Here is another WordPress Codex doc on Meta_Query.
I trying to create a query to get some news from category A,B,C
I wont a article which is in all categories.
Array
(
[post_type] => catalog
[order] => DESC
[orderby] => date
[status] => publish
[paged] => 1
[tax_query] => Array
(
[0] => Array
(
[taxonomy] => catalog_category
[field] => id
[include_children] => 1
[operator] => AND
[terms] => Array
(
[0] => 12
[1] => 17
[2] => 43
)
)
)
)
If I use "operator" "IN" I get all articles if I use "AND" I get none results.
List of my cats and articles:
As you can see, I have only 1 article in all 3 categories.
What is my mistake?
Your query seems fine but not sure what is wrong, anyways, as an alternative you may give it a try to get all posts (custom post type = catalog) which belongs to all three categories in (a, b and c), not less/more but exact match of all categories.
$cat_Ids = array();
// get id from each category name
foreach(array('a', 'b', 'c') as $cat) {
$cat_Ids[] = get_cat_ID($cat)
}
$args = array(
'post_type' => 'catalog', // <-- post type is 'catalog', not 'news', right ?
'category__and' => $cat_Ids,
'orderby' => 'date',
'order' => 'DESC',
'status' => 'publish'
);
$query = new WP_Query($args);