Completed
Push — master ( ae4f30...694b54 )
by Tim
06:08
created

present_attributes()   C

Complexity

Conditions 12
Paths 38

Size

Total Lines 81
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 56
c 1
b 0
f 0
nc 38
nop 3
dl 0
loc 81
rs 6.5333

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
session_cache_limiter('nocache');
4
5
/**
6
 * Consent script
7
 *
8
 * This script displays a page to the user, which requests that the user
9
 * authorizes the release of attributes.
10
 *
11
 * @package SimpleSAMLphp
12
 *
13
 * Explicit instruct consent page to send no-cache header to browsers to make
14
 * sure the users attribute information are not store on client disk.
15
 *
16
 * In an vanilla apache-php installation is the php variables set to:
17
 *
18
 * session.cache_limiter = nocache
19
 *
20
 * so this is just to make sure.
21
 */
22
23
$globalConfig = \SimpleSAML\Configuration::getInstance();
24
25
\SimpleSAML\Logger::info('Consent - getconsent: Accessing consent interface');
26
27
if (!array_key_exists('StateId', $_REQUEST)) {
28
    throw new \SimpleSAML\Error\BadRequest(
29
        'Missing required StateId query parameter.'
30
    );
31
}
32
33
$id = $_REQUEST['StateId'];
34
$state = \SimpleSAML\Auth\State::loadState($id, 'consent:request');
35
36
if (is_null($state)) {
37
    throw new \SimpleSAML\Error\NoState();
38
} elseif (array_key_exists('core:SP', $state)) {
39
    $spentityid = $state['core:SP'];
40
} elseif (array_key_exists('saml:sp:State', $state)) {
41
    $spentityid = $state['saml:sp:State']['core:SP'];
42
} else {
43
    $spentityid = 'UNKNOWN';
44
}
45
46
47
// The user has pressed the yes-button
48
if (array_key_exists('yes', $_REQUEST)) {
49
    if (array_key_exists('saveconsent', $_REQUEST)) {
50
        \SimpleSAML\Logger::stats('consentResponse remember');
51
    } else {
52
        \SimpleSAML\Logger::stats('consentResponse rememberNot');
53
    }
54
55
    $statsInfo = [
56
        'remember' => array_key_exists('saveconsent', $_REQUEST),
57
    ];
58
    if (isset($state['Destination']['entityid'])) {
59
        $statsInfo['spEntityID'] = $state['Destination']['entityid'];
60
    }
61
    \SimpleSAML\Stats::log('consent:accept', $statsInfo);
62
63
    if (
64
        array_key_exists('consent:store', $state)
65
        && array_key_exists('saveconsent', $_REQUEST)
66
        && $_REQUEST['saveconsent'] === '1'
67
    ) {
68
        // Save consent
69
        $store = $state['consent:store'];
70
        $userId = $state['consent:store.userId'];
71
        $targetedId = $state['consent:store.destination'];
72
        $attributeSet = $state['consent:store.attributeSet'];
73
74
        \SimpleSAML\Logger::debug(
75
            'Consent - saveConsent() : [' . $userId . '|' . $targetedId . '|' . $attributeSet . ']'
76
        );
77
        try {
78
            $store->saveConsent($userId, $targetedId, $attributeSet);
79
        } catch (\Exception $e) {
80
            \SimpleSAML\Logger::error('Consent: Error writing to storage: ' . $e->getMessage());
81
        }
82
    }
83
84
    \SimpleSAML\Auth\ProcessingChain::resumeProcessing($state);
85
}
86
87
// Prepare attributes for presentation
88
$attributes = $state['Attributes'];
89
$noconsentattributes = $state['consent:noconsentattributes'];
90
91
// Remove attributes that do not require consent
92
foreach ($attributes as $attrkey => $attrval) {
93
    if (in_array($attrkey, $noconsentattributes, true)) {
94
        unset($attributes[$attrkey]);
95
    }
96
}
97
$para = [
98
    'attributes' => &$attributes
99
];
100
101
// Reorder attributes according to attributepresentation hooks
102
\SimpleSAML\Module::callHooks('attributepresentation', $para);
103
104
// Parse parameters
105
if (array_key_exists('name', $state['Source'])) {
106
    $srcName = $state['Source']['name'];
107
} elseif (array_key_exists('OrganizationDisplayName', $state['Source'])) {
108
    $srcName = $state['Source']['OrganizationDisplayName'];
109
} else {
110
    $srcName = $state['Source']['entityid'];
111
}
112
113
if (array_key_exists('name', $state['Destination'])) {
114
    $dstName = $state['Destination']['name'];
115
} elseif (array_key_exists('OrganizationDisplayName', $state['Destination'])) {
116
    $dstName = $state['Destination']['OrganizationDisplayName'];
117
} else {
118
    $dstName = $state['Destination']['entityid'];
119
}
120
121
// Make, populate and layout consent form
122
$t = new \SimpleSAML\XHTML\Template($globalConfig, 'consent:consentform.twig');
123
$translator = $t->getTranslator();
124
$t->data['srcMetadata'] = $state['Source'];
125
$t->data['dstMetadata'] = $state['Destination'];
126
$t->data['yesTarget'] = \SimpleSAML\Module::getModuleURL('consent/getconsent.php');
127
$t->data['yesData'] = ['StateId' => $id];
128
$t->data['noTarget'] = \SimpleSAML\Module::getModuleURL('consent/noconsent.php');
129
$t->data['noData'] = ['StateId' => $id];
130
$t->data['attributes'] = $attributes;
131
$t->data['checked'] = $state['consent:checked'];
132
$t->data['stateId'] = $id;
133
134
$t->data['srcName'] = htmlspecialchars(is_array($srcName) ? $translator->t($srcName) : $srcName);
0 ignored issues
show
Bug introduced by
The method t() does not exist on SimpleSAML\Locale\Translate. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

134
$t->data['srcName'] = htmlspecialchars(is_array($srcName) ? $translator->/** @scrutinizer ignore-call */ t($srcName) : $srcName);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
135
$t->data['dstName'] = htmlspecialchars(is_array($dstName) ? $translator->t($dstName) : $dstName);
136
137
if (array_key_exists('descr_purpose', $state['Destination'])) {
138
    $t->data['dstDesc'] = $translator->getPreferredTranslation(
139
        \SimpleSAML\Utils\Arrays::arrayize(
140
            $state['Destination']['descr_purpose'],
141
            'en'
142
        )
143
    );
144
}
145
146
// Fetch privacypolicy
147
if (
148
    array_key_exists('UIInfo', $state['Destination']) &&
149
    array_key_exists('PrivacyStatementURL', $state['Destination']['UIInfo']) &&
150
    (!empty($state['Destination']['UIInfo']['PrivacyStatementURL']))
151
) {
152
    $privacypolicy = reset($state['Destination']['UIInfo']['PrivacyStatementURL']);
153
} elseif (
154
    array_key_exists('UIInfo', $state['Source']) &&
155
    array_key_exists('PrivacyStatementURL', $state['Source']['UIInfo']) &&
156
    (!empty($state['Source']['UIInfo']['PrivacyStatementURL']))
157
) {
158
    $privacypolicy = reset($state['Source']['UIInfo']['PrivacyStatementURL']);
159
} else {
160
    $privacypolicy = false;
161
}
162
if ($privacypolicy !== false) {
163
    $privacypolicy = str_replace(
164
        '%SPENTITYID%',
165
        urlencode($spentityid),
166
        $privacypolicy
167
    );
168
}
169
$t->data['sppp'] = $privacypolicy;
170
171
// Set focus element
172
switch ($state['consent:focus']) {
173
    case 'yes':
174
        $t->data['autofocus'] = 'yesbutton';
175
        break;
176
    case 'no':
177
        $t->data['autofocus'] = 'nobutton';
178
        break;
179
    case null:
180
    default:
181
        break;
182
}
183
184
$t->data['usestorage'] = array_key_exists('consent:store', $state);
185
186
if (array_key_exists('consent:hiddenAttributes', $state)) {
187
    $t->data['hiddenAttributes'] = $state['consent:hiddenAttributes'];
188
} else {
189
    $t->data['hiddenAttributes'] = [];
190
}
191
192
$t->data['attributes_html'] = present_attributes($t, $attributes, '');
193
194
$t->send();
195
196
197
/**
198
 * Recursive attribute array listing function
199
 *
200
 * @param \SimpleSAML\XHTML\Template $t          Template object
201
 * @param array                     $attributes Attributes to be presented
202
 * @param string                    $nameParent Name of parent element
203
 *
204
 * @return string HTML representation of the attributes
205
 */
206
function present_attributes(\SimpleSAML\XHTML\Template $t, array $attributes, string $nameParent): string
207
{
208
    $translator = $t->getTranslator();
209
210
    $alternate = ['odd', 'even'];
211
    $i = 0;
212
    $summary = 'summary="' . $translator->t('List the information about you that is about to be transmitted to the service you are going to login to') . '"';
213
214
    if (strlen($nameParent) > 0) {
215
        $parentStr = strtolower($nameParent) . '_';
216
        $str = '<table class="attributes" ' . $summary . '>';
217
    } else {
218
        $parentStr = '';
219
        $str = '<table id="table_with_attributes" class="attributes" ' . $summary . '>';
220
        $str .= "\n" . '<caption>' . $translator->t('User information') . '</caption>';
221
    }
222
223
    foreach ($attributes as $name => $value) {
224
        $nameraw = $name;
225
        $name = $translator->getAttributeTranslation($parentStr . $nameraw);
226
227
        if (preg_match('/^child_/', $nameraw)) {
228
            // insert child table
229
            $parentName = preg_replace('/^child_/', '', $nameraw);
230
            foreach ($value as $child) {
231
                $str .= "\n" . '<tr class="odd"><td class="td_odd">' .
232
                    present_attributes($t, $child, $parentName) . '</td></tr>';
233
            }
234
        } else {
235
            // insert values directly
236
237
            $str .= "\n" . '<tr class="' . $alternate[($i++ % 2)] .
238
                '"><td><span class="attrname">' . htmlspecialchars($name) . '</span></td>';
239
240
            $isHidden = in_array($nameraw, $t->data['hiddenAttributes'], true);
241
            if ($isHidden) {
242
                $hiddenId = \SimpleSAML\Utils\Random::generateID();
243
                $str .= '<td><span class="attrvalue hidden" id="hidden_' . $hiddenId . '">';
244
            } else {
245
                $hiddenId = '';
246
                $str .= '<td><span class="attrvalue">';
247
            }
248
249
            if (sizeof($value) > 1) {
250
                // we hawe several values
251
                $str .= '<ul>';
252
                foreach ($value as $listitem) {
253
                    if ($nameraw === 'jpegPhoto') {
254
                        $str .= '<li><img src="data:image/jpeg;base64,' .
255
                            htmlspecialchars($listitem) . '" alt="User photo" /></li>';
256
                    } else {
257
                        $str .= '<li>' . htmlspecialchars($listitem) . '</li>';
258
                    }
259
                }
260
                $str .= '</ul>';
261
            } elseif (isset($value[0])) {
262
                // we hawe only one value
263
                if ($nameraw === 'jpegPhoto') {
264
                    $str .= '<img src="data:image/jpeg;base64,' .
265
                        htmlspecialchars($value[0]) . '" alt="User photo" />';
266
                } else {
267
                    $str .= htmlspecialchars($value[0]);
268
                }
269
            } // end of if multivalue
270
            $str .= '</span>';
271
272
            if ($isHidden) {
273
                $str .= '<div class="attrvalue consent_showattribute" id="visible_' . $hiddenId . '">';
274
                $str .= '... ';
275
                $str .= '<a class="consent_showattributelink" href="javascript:SimpleSAML_show(\'hidden_' . $hiddenId;
276
                $str .= '\'); SimpleSAML_hide(\'visible_' . $hiddenId . '\');">';
277
                $str .= $translator->t('Show attributes');
278
                $str .= '</a>';
279
                $str .= '</div>';
280
            }
281
282
            $str .= '</td></tr>';
283
        }       // end else: not child table
284
    }   // end foreach
285
    $str .= '</table>';
286
    return $str;
287
}
288