Completed
Pull Request — master (#16)
by Sergii
07:37
created

JQuery   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 3
dl 0
loc 117
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A initialize() 0 4 1
A setDate() 0 7 1
A isDateSelected() 0 22 3
A isDateAvailable() 0 12 3
A datePicker() 0 6 2
A adjustTimezone() 0 10 1
A jsDate() 0 4 1
1
<?php
2
/**
3
 * @author Sergii Bondarenko, <[email protected]>
4
 */
5
namespace Drupal\TqExtension\Utils\DatePicker;
6
7
class JQuery extends DatePickerBase
8
{
9
    const DATE_ADJUSTER = 'window.__behatDatePickerDateAdjuster';
10
11
    /**
12
     * @var string
13
     */
14
    private $jsDate = '';
15
16
    /**
17
     * {@inheritdoc}
18
     */
19
    public function initialize()
20
    {
21
        $this->jsDate = self::jsDate($this->date);
22
    }
23
24
    /**
25
     * {@inheritdoc}
26
     */
27
    public function setDate()
28
    {
29
        // @todo setDate will not work if browser window is not active.
30
        $this->datePicker([__FUNCTION__, '<date>']);
31
32
        return $this;
33
    }
34
35
    /**
36
     * {@inheritdoc}
37
     */
38
    public function isDateSelected()
39
    {
40
        $value = $this->datePicker(['getDate']);
41
        $initial = $this->session->evaluateScript($this->jsDate);
42
43
        // By some reasons DatePicker could not return a date using "getDate" method
44
        // and we'll try to use it from input value directly. An issue could occur
45
        // after saving the form and/or reloading the page.
46
        if (empty($value)) {
47
            $value = $this->session->evaluateScript(self::jsDate($this->element->getValue()));
48
        } else {
49
            $value = $this->adjustTimezone($value);
50
        }
51
52
        self::debug(['Comparing "%s" with "%s".'], [$value, $initial]);
53
54
        if ($value !== $initial) {
55
            throw new \Exception(sprintf('DatePicker contains the "%s" but should "%s".', $value, $initial));
56
        }
57
58
        return $this;
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function isDateAvailable()
65
    {
66
        // @todo For now, any out of scope variable inside of "beforeShowDay" method will be undefined.
67
        // @link https://github.com/refactoror/SelBlocks/issues/5#issuecomment-68511965
68
        $beforeShowDay = $this->datePicker(['option', 'beforeShowDay']);
69
70
        if (!empty($beforeShowDay) && !empty($this->session->evaluateScript("$beforeShowDay($this->jsDate)")[0])) {
71
            throw new \Exception(sprintf('The "%s" is not available for choosing.', $this->date));
72
        }
73
74
        return $this;
75
    }
76
77
    /**
78
     * @param array $arguments
79
     *   jQuery.fn.datepicker arguments.
80
     *
81
     * @return mixed
82
     *   Result of JS execution.
83
     */
84
    private function datePicker(array $arguments)
85
    {
86
        return $this->jQuery(sprintf("datepicker(%s);", implode(', ', array_map(function ($value) {
87
            return in_array($value, ['<date>']) ? $this->jsDate : "'$value'";
88
        }, $arguments))));
89
    }
90
91
    /**
92
     * Adjust timezone of date returned by DatePicker.
93
     *
94
     * @param string $date
95
     *   Date returned by "jQuery('#selector').datepicker('getDate')".
96
     *
97
     * @return string
98
     *   Date with correct timezone.
99
     *
100
     * @link http://stackoverflow.com/a/31560608
101
     */
102
    private function adjustTimezone($date)
103
    {
104
        $this->session->executeScript(sprintf(
105
            '%s=%s;%1$s.setMinutes(%1$s.getMinutes()-%1$s.getTimezoneOffset());',
106
            self::DATE_ADJUSTER,
107
            self::jsDate($date)
108
        ));
109
110
        return $this->session->evaluateScript(self::DATE_ADJUSTER);
111
    }
112
113
    /**
114
     * @param string $date
115
     *   The string to parse.
116
     *
117
     * @return string
118
     */
119
    protected static function jsDate($date)
120
    {
121
        return sprintf("new Date('%s')", date('c', strtotime($date)));
122
    }
123
}
124