AbstractDataTablesTwigExtension   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Importance

Changes 11
Bugs 1 Features 1
Metric Value
wmc 17
eloc 48
c 11
b 1
f 1
dl 0
loc 156
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A renderDataTablesRow() 0 16 3
A encodeOptions() 0 12 3
A jQueryDataTables() 0 17 3
A __construct() 0 5 1
A jQueryDataTablesStandalone() 0 13 2
A renderDataTablesColumn() 0 9 2
A renderDataTables() 0 13 3
1
<?php
2
3
/*
4
 * This file is part of the jquery-datatables-bundle package.
5
 *
6
 * (c) 2018 WEBEWEB
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace WBW\Bundle\JQuery\DataTablesBundle\Twig\Extension;
13
14
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
15
use Twig\Environment;
16
use WBW\Bundle\CoreBundle\Twig\Extension\AbstractTwigExtension;
17
use WBW\Bundle\CoreBundle\Twig\Extension\AssetsTwigExtension;
18
use WBW\Bundle\CoreBundle\Twig\Extension\AssetsTwigExtensionTrait;
19
use WBW\Bundle\JQuery\DataTablesBundle\Api\DataTablesColumnInterface;
20
use WBW\Bundle\JQuery\DataTablesBundle\Api\DataTablesWrapperInterface;
21
use WBW\Bundle\JQuery\DataTablesBundle\Helper\DataTablesWrapperHelper;
22
use WBW\Library\Traits\Strings\StringEnvironmentTrait;
23
24
/**
25
 * Abstract DataTables Twig extension.
26
 *
27
 * @author webeweb <https://github.com/webeweb>
28
 * @package WBW\Bundle\JQuery\DataTablesBundle\Twig\Extension
29
 * @abstract
30
 */
31
abstract class AbstractDataTablesTwigExtension extends AbstractTwigExtension {
32
33
    use AssetsTwigExtensionTrait;
34
    use StringEnvironmentTrait;
35
36
    /**
37
     * Constructor.
38
     *
39
     * @param Environment $twigEnvironment The Twig environment.
40
     * @param AssetsTwigExtension $assetsTwigExtension The assets Twig extension.
41
     * @param string $environment The environment
42
     */
43
    public function __construct(Environment $twigEnvironment, AssetsTwigExtension $assetsTwigExtension, string $environment) {
44
        parent::__construct($twigEnvironment);
45
46
        $this->setEnvironment($environment);
47
        $this->setAssetsTwigExtension($assetsTwigExtension);
48
    }
49
50
    /**
51
     * Encode the options.
52
     *
53
     * @param array<string,mixed> $options The options.
54
     * @return string Returns the encoded options.
55
     */
56
    protected function encodeOptions(array $options): string {
57
58
        if (0 === count($options)) {
59
            return "{}";
60
        }
61
62
        ksort($options);
63
64
        $flags = "prod" === $this->getEnvironment() ? 0 : JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES;
65
        $json  = json_encode($options, $flags);
66
67
        return str_replace("\n", "\n        ", $json);
68
    }
69
70
    /**
71
     * Display a jQuery DataTables.
72
     *
73
     * @param DataTablesWrapperInterface $dtWrapper The wrapper.
74
     * @param string|null $selector The selector.
75
     * @param string|null $language The language.
76
     * @return string Returns the jQuery DataTables.
77
     * @throws FileNotFoundException Throws a file not found exception if the language file does not exist.
78
     */
79
    protected function jQueryDataTables(DataTablesWrapperInterface $dtWrapper, ?string $selector, ?string $language): string {
80
81
        $options = DataTablesWrapperHelper::getOptions($dtWrapper);
82
83
        if (null !== $language) {
84
            $options["language"] = ["url" => DataTablesWrapperHelper::getLanguageUrl($language)];
85
        }
86
87
        $var = DataTablesWrapperHelper::getName($dtWrapper);
88
89
        $searches = ["%var%", "%selector%", "%options%"];
90
        $replaces = [$var, null === $selector ? "#" . $var : $selector, $this->encodeOptions($options)];
91
        $template = file_get_contents(__DIR__ . "/AbstractDataTablesTwigExtension.jQueryDataTables.js.txt");
92
93
        $javascript = str_replace($searches, $replaces, $template);
94
95
        return $this->getAssetsTwigExtension()->coreScriptFilter($javascript);
96
    }
97
98
    /**
99
     * Display a jQuery DataTables "standalone".
100
     *
101
     * @param string $selector The selector.
102
     * @param string|null $language The language.
103
     * @param array<string,mixed> $options The options.
104
     * @return string Returns the jQuery DataTables "Standalone".
105
     * @throws FileNotFoundException Throws a file not found exception if the language file does not exist.
106
     */
107
    protected function jQueryDataTablesStandalone(string $selector, ?string $language, array $options): string {
108
109
        if (null !== $language) {
110
            $options["language"] = ["url" => DataTablesWrapperHelper::getLanguageUrl($language)];
111
        }
112
113
        $searches = ["%selector%", "%options%"];
114
        $replaces = [$selector, $this->encodeOptions($options)];
115
        $template = file_get_contents(__DIR__ . "/AbstractDataTablesTwigExtension.jQueryDataTablesStandalone.js.txt");
116
117
        $javascript = str_replace($searches, $replaces, $template);
118
119
        return $this->getAssetsTwigExtension()->coreScriptFilter($javascript);
120
    }
121
122
    /**
123
     * Render a DataTables.
124
     *
125
     * @param DataTablesWrapperInterface $dtWrapper The wrapper.
126
     * @param string|null $class The class.
127
     * @param bool $includeTHead Include thead ?
128
     * @param bool $includeTFoot Include tfoot ?
129
     * @return string Returns the rendered DataTables.
130
     */
131
    protected function renderDataTables(DataTablesWrapperInterface $dtWrapper, ?string $class, bool $includeTHead, bool $includeTFoot): string {
132
133
        $attributes = [
134
            "class" => ["table", $class],
135
            "id"    => DataTablesWrapperHelper::getName($dtWrapper),
136
        ];
137
138
        $thead = true === $includeTHead ? $this->renderDataTablesRow($dtWrapper, "thead") . "\n" : "";
139
        $tfoot = true === $includeTFoot ? $this->renderDataTablesRow($dtWrapper, "tfoot") . "\n" : "";
140
141
        $inner = "\n" . $thead . $tfoot;
142
143
        return static::coreHtmlElement("table", $inner, $attributes);
144
    }
145
146
    /**
147
     * Render a column.
148
     *
149
     * @param DataTablesColumnInterface $dtColumn The column.
150
     * @param bool $rowScope Row scope ?
151
     * @return string Returns the rendered column.
152
     */
153
    private function renderDataTablesColumn(DataTablesColumnInterface $dtColumn, bool $rowScope = false): string {
154
155
        $attributes = [
156
            "scope" => true === $rowScope ? "row" : null,
157
            "class" => $dtColumn->getClassname(),
158
            "width" => $dtColumn->getWidth(),
159
        ];
160
161
        return static::coreHtmlElement("th", $dtColumn->getTitle(), $attributes);
162
    }
163
164
    /**
165
     * Render a row.
166
     *
167
     * @param DataTablesWrapperInterface $dtWrapper The wrapper.
168
     * @param string $wrapper The wrapper (thead or tfoot)
169
     * @return string Returns the rendered row.
170
     */
171
    private function renderDataTablesRow(DataTablesWrapperInterface $dtWrapper, string $wrapper): string {
172
173
        $row = "";
174
175
        $count = count($dtWrapper->getColumns());
176
        for ($i = 0; $i < $count; ++$i) {
177
178
            $dtColumn = array_values($dtWrapper->getColumns())[$i];
179
180
            $col = $this->renderDataTablesColumn($dtColumn, ("thead" === $wrapper && 0 === $i));
181
            $row .= $col . "\n";
182
        }
183
184
        $tr = static::coreHtmlElement("tr", "\n" . $row);
185
186
        return static::coreHtmlElement($wrapper, "\n" . $tr . "\n");
187
    }
188
}
189