N
N
NoMax2016-11-18 17:06:44
Drupal
NoMax, 2016-11-18 17:06:44

How to filter nodes by date excluding year using Views in Drupal 7?

Hello. At my job, I develop an internal information resource for an educational institution. I decided to implement something like a calendar of significant days (a day in history) and birthday greetings. created content types (commemorative date and person) where dates are stored in a regular Drupal date format field.
The problem surfaced sharply with the withdrawal of nodes according to certain criteria. The standard views filter tools do not provide the ability to display nodes without taking into account the year. those. to display the nodes taking into account the comparison of dates with the current one (less/greater, taking into account the year and current time) - this is quite feasible. but to cut off the year and compare dates without taking it into account is a problem with this.
For the block of birthdays, I want to do this - if today's day and month coincide with the date value from the node field (excluding the year) - display these nodes.
for the calendar block of significant dates, I want to implement the output of nodes not by the condition "historical date" == "today", but by the condition so that the nearest memorable date is displayed: "historical date" >= "today".
Dug in the Internet, found advice to do using the context filter "provide a value from the date", set the granulation "day", but it does not work.
I was looking for modules that meet my needs - the birthdays module, but many people complain about its unstable work and the module asks to add its own field type for materials - it's not a fact that this will help, but the material is already full with a different field structure. I want to make nevertheless that from a field of type Date there were comparison and filtration.
I tried to use the Views PHP module - added the "global PHP" filtering criterion, uncovered $row->field_hd_date['und'][0]['value'], converted the field value to a date, created a variable with today's date, compared dates in the format date("j') and date("m") from these dates (and even by date("z") - if it worked, it would be possible to file a boiler with leap years), but the processing of the view began to work cumbersomely and a bunch of drupal warnings and in general,
I got to the hooks, but I don’t fully understand how, where and with what they eat it.
Maybe someone faced similar problems and was able to solve them elegantly, easily and simply?
Thanks in advance for the tips.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
N
NoMax, 2016-11-23
@NoMax

In general, everything else was from the crafty and left-handed solutions - really, what helped is the implementation of the mymodule_views_query_alter () hook
a lot of time was spent looking for easy solutions - through the usual views filters, context filters, finding a suitable module, trying to implement a filter using the Views PHP module - however, it was not possible to implement an easy and simple comparison. I tried to catch on to date formats, and comparison by day of the year, but then cut off this option. there are leap years that shift the match. I did not want to turn crutches to this. I turned to the great and mighty SQL, ran into its DATE_FORMAT() function , which allowed me to display and compare the date in the format I needed. It was then that I decided that getting the right sample right away would be much more kosher than fetching and the like. Compiled a test SQL query, checked it - it works. And it works exactly as it should:
there is a table with nodes, there is a field table that stores the date. there is a relationship between these tables - each date field is associated with a specific entry in the node table for which it was created.
we take the node id and its header from the table with nodes where there is a node-field link and the formatted date (day-month) is equal to the formatted date of today,

now the most interesting thing remains - to change the sql query that generates views.
In general, as it was suggested in the vastness of Google - I created my own module, added this wonderful function, went a little down with how to make edits to the request, came across some features, but they managed to be defeated. I did not find reference and complete information on how to specifically add / change the conditions of the sql query for views (maybe I was looking badly). my guide was fragmentary code examples from implementations found on the Internet, an abstract concept of how it can work from the point of view of programming and the method of scientific poke.
Internet sources suggested using DEVEL and dpm(), but I somehow did not work out with such a debugging view. the Views module itself helped, or rather a fad in its settings (structure-> views-> settings). A wonderful checkbox ala "Show SQL query in the view" helped me debug the newly minted module and not work blindly. "
Now in the view editing window below the functional tools there is a block that displays the SQL query that is formed for the view. Then the most interesting thing went - attempts The method was to add conditions to the SQL query of the view correctly .In general, I will postpone all iterations of the scientific poke, and I will give the code that "took off":

function myhook_views_query_alter(&$view, &$query) {
  if ($view->name == 'persons') {
    //добавляем в запрос таблицу, в которой хранятся поля с датой рождения
    $query->add_table('field_data_field_birthday');
   //добавляем условие, что день и месяц в дате рождения именинника должен совпадать с сегодняшним днем и месяцем
    $query->add_where_expression('AND',"DATE_FORMAT(field_data_field_birthday.field_birthday_value,'%m')=DATE_FORMAT(NOW(),'%m')");
   //условие взаимосвязи записей из таблицы нод и поля, хранящего даты ДР
    $query->add_where_expression('AND',"nid=field_data_field_birthday.entity_id");
  }
};

to be honest, I have never dived so deeply into drupal before, but I am glad that I was still able to solve the question posed, which initially did not seem problematic at all. the received infa to solve the issue was collected bit by bit from other examples. how to deal with $query and what constructions to apply to it - I did not find a single and full-fledged source of reference information, it's just a store of personal knowledge and an approximate understanding of how it can work. It's also embarrassing that while the if ($view->name == 'persons') construct modifies the request for the entire view, and not for its specific block or page, I will look for how to solve this.
Thank you all for your advice, special thanks to xandeadx - did not give a solution, but hinted in which direction to dig)
ps: analysis of print_r($query) gave an answer on how to hook on a specific individual block or page of death. to do this, you need to use the machine name of this current construct. you can hook onto it with $view->current_display. in my case it turned out like this:
if ($view->name == 'persons' && $view->current_display == 'block1')  {
//...
};

A
afi13, 2016-11-20
@afi13

First, think over the necessary SQL query, you need a similar condition:
Where instead of NOW you need to use the date passed to the filter.
Further, as an option, try hook_views_query_alter () and change the SQL query by adding a condition with substituted filters to it.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question