Version4::generate()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 12

Duplication

Lines 12
Ratio 100 %

Importance

Changes 0
Metric Value
dl 12
loc 12
rs 9.8666
c 0
b 0
f 0
cc 3
nc 4
nop 1
1
<?php
2
3
/**
4
 * Nexcess.net Turpentine Extension for Magento
5
 * Copyright (C) 2012  Nexcess.net L.L.C.
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
 */
21
22
class Nexcessnet_Turpentine_Model_Varnish_Configurator_Version4
23
    extends Nexcessnet_Turpentine_Model_Varnish_Configurator_Abstract {
24
25
    const VCL_TEMPLATE_FILE = 'version-4.vcl';
26
    const VCL_VERSION = '4';
27
28
29
    /**
30
     * Generate the Varnish 4.0-compatible VCL
31
     *
32
     * @param bool $doClean if true, VCL will be cleaned (whitespaces stripped, etc.)
33
     * @return string
34
     */
35 View Code Duplication
    public function generate($doClean = true) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
36
        // first, check if a custom template is set
37
        $customTemplate = $this->_getCustomTemplateFilename();
38
        if ($customTemplate) { 
0 ignored issues
show
Bug Best Practice introduced by
The expression $customTemplate of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
39
            $tplFile = $customTemplate;
40
        } else { 
41
            $tplFile = $this->_getVclTemplateFilename(self::VCL_TEMPLATE_FILE);
42
        }
43
        $vcl = $this->_formatTemplate(file_get_contents($tplFile),
44
            $this->_getTemplateVars());
45
        return $doClean ? $this->_cleanVcl($vcl) : $vcl;
46
    }
47
48
    // TODO: Check this
49 View Code Duplication
    protected function _getAdvancedSessionValidation() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
50
        $validation = '';
51
        foreach ($this->_getAdvancedSessionValidationTargets() as $target) {
52
            $validation .= sprintf('hash_data(%s);'.PHP_EOL, $target);
53
        }
54
        return $validation;
55
    }
56
57
    /**
58
     * Build the list of template variables to apply to the VCL template
59
     *
60
     * @return array
61
     */
62
    protected function _getTemplateVars() {
63
        $vars = parent::_getTemplateVars();
64
        $vars['advanced_session_validation'] =
65
            $this->_getAdvancedSessionValidation();
66
67
        if (Mage::getStoreConfig('turpentine_vcl/backend/load_balancing') != 'no') {
68
            $vars['directors']          = $this->_vcl_directors();
69
            $vars['admin_backend_hint'] = 'vdir_admin.backend()';
70
            $vars['set_backend_hint']   = 'set req.backend_hint = vdir.backend();';
71
        } else {
72
            $vars['directors']          = '';
73
            $vars['admin_backend_hint'] = 'admin';
74
            $vars['set_backend_hint']   = '';
75
        }
76
77
        //dispatch event to allow other extensions to add custom vcl template variables
78
        Mage::dispatchEvent('turpentine_get_templatevars_after', array(
79
            'vars' => &$vars,
80
            'vcl_version'=> self::VCL_VERSION
81
        ));
82
83
        return $vars;
84
    }
85
86
    protected function _vcl_directors()
87
    {
88
        $tpl = <<<EOS
89
    new vdir       = directors.round_robin();
90
    new vdir_admin = directors.round_robin();
91
92
EOS;
93
94
        if ('yes_admin' == Mage::getStoreConfig('turpentine_vcl/backend/load_balancing')) {
95
            $adminBackendNodes = Mage::helper('turpentine/data')->cleanExplode(PHP_EOL,
96
                Mage::getStoreConfig('turpentine_vcl/backend/backend_nodes_admin'));
97
        } else {
98
            $adminBackendNodes = Mage::helper('turpentine/data')->cleanExplode(PHP_EOL,
99
                Mage::getStoreConfig('turpentine_vcl/backend/backend_nodes'));
100
        }
101
102
        $backendNodes = Mage::helper('turpentine/data')->cleanExplode(PHP_EOL,
103
            Mage::getStoreConfig('turpentine_vcl/backend/backend_nodes'));
104
105
        for ($i = 0, $iMax = count($backendNodes); $i < $iMax; $i++) {
106
            $tpl .= <<<EOS
107
    vdir.add_backend(web{$i});
108
109
EOS;
110
        }
111
112
        for ($i = 0, $iMax = count($adminBackendNodes); $i < $iMax; $i++) {
113
            $tpl .= <<<EOS
114
    vdir_admin.add_backend(webadmin{$i});
115
116
EOS;
117
        }
118
119
        $vars = array();
120
121
        return $this->_formatTemplate($tpl, $vars);
122
    }
123
124
    /**
125
     * Format a VCL director declaration, for load balancing
126
     *
127
     * @param string $name           name of the director, also used to select config settings
128
     * @param array  $backendOptions options for each backend
129
     * @return string
130
     */
131 View Code Duplication
    protected function _vcl_director($name, $backendOptions) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
132
        $tpl = <<<EOS
133
{{backends}}
134
EOS;
135
        if ('admin' == $name && 'yes_admin' == Mage::getStoreConfig('turpentine_vcl/backend/load_balancing')) {
136
            $backendNodes = Mage::helper('turpentine/data')->cleanExplode(PHP_EOL,
137
                Mage::getStoreConfig('turpentine_vcl/backend/backend_nodes_admin'));
138
            $probeUrl = Mage::getStoreConfig('turpentine_vcl/backend/backend_probe_url_admin');
139
            $prefix = 'admin';
140
        } else {
141
            $backendNodes = Mage::helper('turpentine/data')->cleanExplode(PHP_EOL,
142
                Mage::getStoreConfig('turpentine_vcl/backend/backend_nodes'));
143
            $probeUrl = Mage::getStoreConfig('turpentine_vcl/backend/backend_probe_url');
144
145
            if ('admin' == $name) {
146
                $prefix = 'admin';
147
            } else {
148
                $prefix = '';
149
            }
150
        }
151
152
        $backends = '';
153
        $number = 0;
154
        foreach ($backendNodes as $backendNode) {
155
            $parts = explode(':', $backendNode, 2);
156
            $host = (empty($parts[0])) ? '127.0.0.1' : $parts[0];
157
            $port = (empty($parts[1])) ? '80' : $parts[1];
158
            $backends .= $this->_vcl_director_backend($host, $port, $prefix.$number, $probeUrl, $backendOptions);
159
160
            $number++;
161
        }
162
        $vars = array(
163
            'name' => $name,
164
            'backends' => $backends
165
        );
166
        return $this->_formatTemplate($tpl, $vars);
167
    }
168
169
    /**
170
     * Format a VCL backend declaration to put inside director
171
     *
172
     * @param string $host       backend host
173
     * @param string $port       backend port
174
     * @param string $descriptor backend descriptor
175
     * @param string $probeUrl   URL to check if backend is up
176
     * @param array  $options    extra options for backend
177
     * @return string
178
     */
179 View Code Duplication
    protected function _vcl_director_backend($host, $port, $descriptor = '', $probeUrl = '', $options = array()) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
180
        $tpl = <<<EOS
181
        backend web{$descriptor} {
182
            .host = "{{host}}";
183
            .port = "{{port}}";
184
{{probe}}
185
186
EOS;
187
        $vars = array(
188
            'host'  => $host,
189
            'port'  => $port,
190
            'probe' => ''
191
        );
192
        if ( ! empty($probeUrl)) {
193
            $vars['probe'] = $this->_vcl_get_probe($probeUrl);
194
        }
195
        $str = $this->_formatTemplate($tpl, $vars);
196
        foreach ($options as $key => $value) {
197
            $str .= sprintf('            .%s = %s;', $key, $value).PHP_EOL;
198
        }
199
        $str .= <<<EOS
200
        }
201
202
EOS;
203
        return $str;
204
    }
205
}
206