Accueil Forums Forum WordPress en français Extensions WordPress HivePress Opening Hours : problème lorsque l’heure de fermeture est après 23:59 Réponse à : HivePress Opening Hours : problème lorsque l’heure de fermeture est après 23:59

#391

Bigue Nique
Membre

La réponse de @ihor a été assez rapide (~12 heures) :

Thanks for reporting this issue, I added it to the bug tracker. If you have the Opening Hours extension. The current condition is:

if($current_time>$opening_time and $current_time<$closing_time)

So this may require some extra logic to detect the time after midnight.

Ça ressemble à une demande formelle de lui proposer un patch ! J'ai donc fouillé dans le code du plugin pour retrouver la logique de filtrage. Il s'agit, effectivement, d'une requête MySQL contrôlée par un objet WP_Query auquel la méthode Opening_Hours::set_search_query( $query ) ajoute une clause meta.

La classe Opening_Hours est définie dans hivepress-opening-hours/includes/components/class-opening-hours.php. À la ligne 143 :

        // Get day and time.
        $day  = strtolower( current_time( 'l' ) );
        $time = current_time( 'G' ) * 60 + (int) current_time( 'i' );

        // Get meta query.
        $meta_query = array_filter( (array) $query->get( 'meta_query' ) );

        // Add meta clause.
        $meta_query[] = [
            'relation' => 'AND',

            [
                'key'     => hp\prefix( $day . '_from' ),
                'value'   => $time,
                'compare' => '<',
                'type'    => 'NUMERIC',
            ],
            [
                'key'     => hp\prefix( $day . '_to' ),
                'value'   => $time,
                'compare' => '>',
                'type'    => 'NUMERIC',
            ],
        ];

        // Set meta query.
        $query->set( 'meta_query', $meta_query );

Il suffit de modifier $meta_query[] pour prendre en compte la logique proposée ci-haut. Mais la class WP_Query permet-elle des conditionnelles imbriquées ? Apparemment, cela est possible depuis WordPress 3.1 ! (Voir cet exemple).

Il nous faut d'abord obtenir le jour de la semaine correspondant à la veille en plus du jour actuel. On obtient celui-ci avec : $day = strtolower( current_time( 'l' ) );. La source de la fonction current_time (définie par WordPress) nous permettrait de paraphraser l'expression par : $day = strtolower( (new DateTime( 'now', wp_timezone() ))->format( 'l' ) );.

On se servira donc de l'objet DateTime pour obtenir également le jour de semaine de la veille :

        $timezone = wp_timezone();
        $date = new DateTime( 'now', $timezone );
        $today = strtolower( $date->format( 'l' ) );
        $date->sub( new DateInterval('P1D') );
        $yesterday = strtolower( $date->format( 'l' ) );

Ne reste qu'à ré-écrire notre méta-requête imbriquée...

Et c'est ici qu'on frappe un nœud :

Effectivement, WP_Meta_Query ne permet pas de comparer deux méta-variables entre elles ! Ainsi il est impossible de vérifier les conditions de type <jour>.fermeture < <jour>.ouverture dans une seule requête. Ce serait définitivement possible en SQL, mais cela impliquerait une refonte en profondeur de l'extension.

Voie de contournement

S'il nous est impossible de vérifier les conditions de type <jour>.fermeture < <jour>.ouverture avec une seule méta-requête au moment de la requête, il nous est cependant possible de la vérifier en avance, c'est à dire au moment où les heures sont enregistrées dans la base de données. Si on ajoutait une métadonnée, eg. hp\prefix( $day . '_night' ) qui contiendrait le résultat de la précondition (1 si <jour>.fermeture < <jour>.ouverture, 0 sinon; ou -- encore mieux -- ne serait définie que si la condition est vérifiée), alors on sera en mesure de construire la méta-requête ainsi :

        $meta_query[] = [
            'relation' => 'OR',
            [
                'relation' => 'AND',
                [
                    'key'     => hp\prefix( $yesterday . '_night' ),
                    'compare' => 'EXISTS',
                ],
                [
                    'key'     => hp\prefix( $yesterday . '_to' ),
                    'value'   => $time,
                    'compare' => '>',
                    'type'    => 'NUMERIC',
                ],
            ],
            [
                'relation' => 'AND',
                [
                    'key'     => hp\prefix( $today . '_from' ),
                    'value'   => $time,
                    'compare' => '<=',
                    'type'    => 'NUMERIC',
                ],
                [
                    'relation' => 'OR',
                    [
                        'key'     => hp\prefix( $today . '_night' ),
                        'compare' => 'EXISTS',
                    ],
                    [
                        'key'     => hp\prefix( $today . '_to' ),
                        'value'   => $time,
                        'compare' => '>',
                        'type'    => 'NUMERIC',
                    ]
                ]
            ]
        ];

Reste à trouver :

À quel moment au sein de l'extension peut-on définir cette métadonnée <hp_prefix>-<jour>-night en fonction de la pré-condition <jour>.fermeture < <jour>.ouverture ?

Références :