Passed
Push — master ( 97ce2e...4c7734 )
by Terrence
15:04
created

Skin   F

Complexity

Total Complexity 76

Size/Duplication

Total Lines 588
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 8
Bugs 0 Features 0
Metric Value
eloc 196
c 8
b 0
f 0
dl 0
loc 588
ccs 0
cts 234
cp 0
rs 2.32
wmc 76

17 Methods

Rating   Name   Duplication   Size   Complexity  
A idpBlacklisted() 0 13 4
B setMyProxyInfo() 0 40 8
B readSkinFromDatabase() 0 52 9
A hasIdpWhitelist() 0 8 3
A printSkinCSS() 0 8 2
A inPortalList() 0 13 4
A readDefaultSkin() 0 17 3
A idpWhitelisted() 0 17 5
A hasIdpBlacklist() 0 8 3
A getConfigOption() 0 17 4
F readSkinConfig() 0 55 12
B readSkinFromFile() 0 32 7
A idpAvailable() 0 10 3
A hasPortalList() 0 8 3
A init() 0 12 2
A __construct() 0 3 1
A getForceSkin() 0 11 3

How to fix   Complexity   

Complex Class

Complex classes like Skin often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Skin, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace CILogon\Service;
4
5
use CILogon\Service\Util;
6
use tubalmartin\CssMin\Minifier as CSSmin;
7
use PEAR;
8
use DB;
9
use Config;
10
11
/**
12
 * Skin
13
 *
14
 * This class reads in CSS and configuration options
15
 * for a 'skin'. The skin is set by passing the
16
 * '?skin=...' (or '?cilogon_skin=...') query parameter.
17
 * If found, the assoicated config XML and CSS are read
18
 * in from either the filesystem (under the /skin/NAME
19
 * directory) or the database. It also sets a PHP
20
 * session variable so that the skin name is remembered
21
 * across page loads. If no skin name is found, then the
22
 * default /skin/config.xml file is read in.
23
 *
24
 * Note that this class uses the SimpleXML class to parse
25
 * the config XML. This stores the XML in a special
26
 * SimpleXMLElement object, which is NOT an array. But
27
 * you can iterate over elements in the structure. See
28
 * the PHP SimpleXML online manual 'Basic Usage' for
29
 * more information.
30
 *
31
 * This class provides a getConfigOption() method to
32
 * access XML (sub)blocks to get at a config value.
33
 * It is important to rememeber that the values returned
34
 * by the getConfigOption() method must be typecast to
35
 * native datatypes in order to be used effectively.
36
 *
37
 * An example configuration file (with all available options) is at
38
 *     /var/www/html/skin/config-example.xml
39
 *
40
 * Example usage:
41
 *   require_once 'Skin.php';
42
 *   $skin = new Skin();
43
 *   // While outputting the <head> HTML block...
44
 *   $skin->printSkinCSS();
45
 *   // Get the value of a configuration option
46
 *   $idpwhitelist = $skin->getConfigOption('idpwhitelist');
47
 *   // Now, process entries in the $idpwhitelist
48
 *   if ((!is_null($idpwhitelist)) && (!empty($idpwhitelist->idp))) {
49
 *       foreach ($idpwhitelist->idp as $entityID) {
50
 *           echo '<p>' , (string)$entityID , "<\p>\n";
51
 *       }
52
 *   }
53
 *   // Check to see if <hideportalinfo> is set
54
 *   $hideportalinfo = false;
55
 *   $hpi=$skin->getConfigOption('portallistaction','hideportalinfo');
56
 *   if ((!is_null($hpi)) && ((int)$hpi > 0)) {
57
 *       $hideportalinfo = true;
58
 *   }
59
 */
60
class Skin
61
{
62
    /**
63
     * @var string $skinname The name of the skin
64
     */
65
    protected $skinname;
66
67
    /**
68
     * @var \SimpleXMLElement $configxml A SimpleXMLElement object for the
69
     *      config.xml file
70
     */
71
    protected $configxml;
72
73
    /**
74
     * @var string $css The un-minified CSS for the skin
75
     */
76
    protected $css;
77
78
    /**
79
     * @var array $forcearray An array of (URI,skinname) pairs for forcing
80
     *      skin application
81
     */
82
    protected $forcearray;
83
84
    /**
85
     *  __construct
86
     *
87
     * Default constructor. Calls init() to do the actual work.
88
     *
89
     * @return Skin A new Skin object.
90
     */
91
    public function __construct()
92
    {
93
        $this->init();
94
    }
95
96
    /**
97
     * init
98
     *
99
     * This function does the work of (re)initializing the skin object.
100
     * It finds the name of the skin (if any) and reads in the skin's
101
     * config XML file (if found). Call this function to reset the
102
     * skin in case of possible forced skin due to IdP or portal
103
     * callbackURL.
104
     *
105
     * @param bool $reset True to reset the 'cilogon_skin' PHP session var
106
     *        to blank so that readSkinConfig doesn't check for it.
107
     *        Defaults to 'false'.
108
     */
109
    public function init($reset = false)
110
    {
111
        if ($reset) {
112
            Util::unsetSessionVar('cilogon_skin');
113
        }
114
115
        $this->skinname = '';
116
        $this->configxml = null;
117
        $this->css = '';
118
        $this->forcearray = FORCE_SKIN_ARRAY;
0 ignored issues
show
Bug introduced by
The constant CILogon\Service\FORCE_SKIN_ARRAY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
119
        $this->readSkinConfig();
120
        $this->setMyProxyInfo();
121
    }
122
123
    /**
124
     * readSkinConfig
125
     *
126
     * This function checks for the name of the skin in several places:
127
     * (1) The FORCE_SKIN_ARRAY for a matching IdP entityID or portal
128
     * callbackURL, (2) in a URL parameter (can be '?skin=',
129
     * '?cilogon_skin=', '?vo='), (3) cilogon_vo form input variable
130
     * (POST for ECP case), or (4) 'cilogon_skin' PHP session
131
     * variable.  If it finds the skin name in any of these, it then
132
     * checks to see if such a named skin exists, either on the filesystem
133
     * or in the database. If found, the class variable $skinname AND the
134
     * 'cilogon_skin' PHP session variable (for use on future page
135
     * loads by the user) are set. It then reads in the config XML and the
136
     * CSS and stores them in the class variables $configxml and $css.
137
     * If no skin name is found, read in the default /skin/config.xml file.
138
     *
139
     * Side Effect: Sets the 'cilogon_skin' session variable if needed.
140
     */
141
    protected function readSkinConfig()
142
    {
143
        $skinvar = '';
144
145
        // Check for matching IdP, callbackURI (OAuth1),
146
        // redirect_uri (OAuth2), or client_id (OAuth2)
147
        // in the FORCE_SKIN_ARRAY.
148
        $uristocheck = array(
149
            Util::getGetVar('redirect_uri'),
150
            Util::getGetVar('client_id'),
151
            Util::getSessionVar('callbackuri'),
152
            Util::getSessionVar('idp')
153
        );
154
155
        foreach ($uristocheck as $value) {
156
            if (strlen($value) > 0) {
157
                $skin = $this->getForceSkin($value);
158
                if (strlen($skin) > 0) {
159
                    $skinvar = $skin;
160
                    break;
161
                }
162
            }
163
        }
164
165
        // If no force skin found, check GET and POST parameters, as well as
166
        // previously set cilogon_skin PHP session variable.
167
        if (strlen($skinvar) == 0) {
168
            // First, look for '?skin=...'
169
            $skinvar = Util::getGetVar('skin');
170
        }
171
        if (strlen($skinvar) == 0) {
172
            // Next, look for '?cilogon_skin=...'
173
            $skinvar = Util::getGetVar('cilogon_skin');
174
        }
175
        if (strlen($skinvar) == 0) {
176
            // Next, look for '?vo=...'
177
            $skinvar = Util::getGetVar('vo');
178
        }
179
        if (strlen($skinvar) == 0) {
180
            // Next, check 'cilogon_vo' form input variable
181
            $skinvar = Util::getPostVar('cilogon_vo');
182
        }
183
        if (strlen($skinvar) == 0) {
184
            // Finally, check 'cilogon_skin' PHP session variable
185
            $skinvar = Util::getSessionVar('cilogon_skin');
186
        }
187
188
        // If we found $skinvar, attempt to read the skin config/css from
189
        // either the filesystem or the database, or failing that, read the
190
        // default /skin/config.xml file.
191
        if (strlen($skinvar) > 0) {
192
            $skinvar = strtolower($skinvar); // All skin dirs are lowercase
193
            $this->readSkinFromFile($skinvar) ||
194
                $this->readSkinFromDatabase($skinvar) ||
195
                $this->readDefaultSkin();
196
        }
197
    }
198
199
    /**
200
     * readSkinFromFile
201
     *
202
     * This function reads in the skin config XML and CSS from the
203
     * filesystem into the class variables $configxml and $css.
204
     *
205
     * @param string $skinvar The name of the skin as found by
206
     *        readSkinConfig().
207
     * @return bool True if at least one of config.xml or skin.css could
208
     *         be found (and read in) for the skin (i.e., the skin
209
     *         directory exists and isn't empty). False otherwise.
210
     */
211
    protected function readSkinFromFile($skinvar)
212
    {
213
        $readin = false; // Make sure we read in either XML or CSS (or both)
214
215
        $skindir = Util::getServerVar('DOCUMENT_ROOT') . "/skin/$skinvar";
216
        if (is_dir($skindir)) {
217
            // Read in the config XML
218
            $skinconf = $skindir . '/config.xml';
219
            if (is_readable($skinconf)) {
220
                if (($xml = @simplexml_load_file($skinconf)) !== false) {
221
                    $this->configxml = $xml;
222
                    $readin = true;
223
                }
224
            }
225
            //Read in the CSS
226
            $skincss = $skindir . '/skin.css';
227
            if (is_readable($skincss)) {
228
                if (($css = file_get_contents($skincss)) !== false) {
229
                    $this->css = $css;
230
                    $readin = true;
231
                }
232
            }
233
        }
234
235
        if ($readin) {
236
            $this->skinname = $skinvar;
237
            Util::setSessionVar('cilogon_skin', $skinvar);
238
        } else {
239
            Util::unsetSessionVar('cilogon_skin');
240
        }
241
242
        return $readin;
243
    }
244
245
    /**
246
     * readSkinFromDatabase
247
     *
248
     * This function reads in the skin config XML and CSS from the
249
     * database into the class variables $configxml and $css.
250
     *
251
     * @param string $skinvar The name of the skin as found by
252
     *        readSkinConfig().
253
     * @return bool True if at least one of config XML or CSS could
254
     *         be read from the database for the skin. False otherwise.
255
     */
256
    protected function readSkinFromDatabase($skinvar)
257
    {
258
        $readin = false; // Make sure we read in either XML or CSS (or both)
259
260
        if (strlen($skinvar) > 0) {
261
            $dsn = array(
262
                'phptype'  => 'mysqli',
263
                'username' => MYSQLI_USERNAME,
0 ignored issues
show
Bug introduced by
The constant CILogon\Service\MYSQLI_USERNAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
264
                'password' => MYSQLI_PASSWORD,
0 ignored issues
show
Bug introduced by
The constant CILogon\Service\MYSQLI_PASSWORD was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
265
                'database' => 'ciloa2',
266
                'hostspec' => 'localhost'
267
            );
268
269
            $opts = array(
270
                'persistent'  => true,
271
                'portability' => DB_PORTABILITY_ALL
272
            );
273
274
            $db = DB::connect($dsn, $opts);
275
            if (!PEAR::isError($db)) {
276
                $data = $db->getRow(
277
                    'SELECT * from skins WHERE name = ?',
278
                    array($skinvar),
279
                    DB_FETCHMODE_ASSOC
280
                );
281
                if ((!DB::isError($data)) && (!empty($data))) {
282
                    // Read in the config XML
283
                    if (
284
                        (strlen(@$data['config']) > 0) &&
285
                        (($xml = @simple_xml_load_string($data['config'])) !== false)
0 ignored issues
show
Bug introduced by
The function simple_xml_load_string was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

285
                        (($xml = @/** @scrutinizer ignore-call */ simple_xml_load_string($data['config'])) !== false)
Loading history...
286
                    ) {
287
                        $this->configxml = $xml;
288
                        $readin = true;
289
                    }
290
                    //Read in the CSS
291
                    if (strlen(@$data['css']) > 0) {
292
                        $this->css = $data['css'];
293
                        $readin = true;
294
                    }
295
                }
296
                $db->disconnect();
297
            }
298
        }
299
300
        if ($readin) {
301
            $this->skinname = $skinvar;
302
            Util::setSessionVar('cilogon_skin', $skinvar);
303
        } else {
304
            Util::unsetSessionVar('cilogon_skin');
305
        }
306
307
        return $readin;
308
    }
309
310
    /**
311
     * readDefaultSkin
312
     *
313
     * If we don't read a skin from the filesystem or the database, then
314
     * read in the default "/skin/config.xml" file.
315
     *
316
     * @return bool True if the default config.xml file was read in.
317
     *         False otherwise.
318
     */
319
    protected function readDefaultSkin()
320
    {
321
        $readin = false;
322
323
        $this->skinname = '';
324
        $this->css = '';
325
        Util::unsetSessionVar('cilogon_skin');
326
327
        $skinconf = Util::getServerVar('DOCUMENT_ROOT') . '/skin/config.xml';
328
        if (is_readable($skinconf)) {
329
            if (($xml = @simplexml_load_file($skinconf)) !== false) {
330
                $this->configxml = $xml;
331
                $readin = true;
332
            }
333
        }
334
335
        return $readin;
336
    }
337
338
    /**
339
     * getConfigOption
340
     *
341
     * This method returns a SimpleXMLElement block corresponding to
342
     * the passed in arguments.  For example, to get the blacklist of
343
     * idps, call $idps = getConfigOption('idpblacklist') and then
344
     * iterate over $idps with foreach($idps as $idp) { ... }.  To get
345
     * a single subblock value such as the initial lifetime number for
346
     * the PKCS12 download option, call $life =
347
     * (int)getConfigOption('pkcs12','initiallifetime','number'). Note
348
     * that you should explicitly cast the values to int, string,
349
     * float, etc., when you use them.
350
     *
351
     * @param mixed $args Variable number of parameters corresponding to XML
352
     *              blocks (and possible sub-blocks).
353
     * @return \SimpleXMLElement|null A SimpleXMLElement corresponding to the
354
     *         passed-in XML option, or 'null' if no such option exists.
355
     */
356
    public function getConfigOption(...$args)
357
    {
358
        $retval = null;
359
        $numargs = count($args);
360
        if ($numargs > 0) {
361
            $retval = $this->configxml;
362
        }
363
        for ($i = 0; $i < $numargs; $i++) {
364
            $argval = $args[$i];
365
            if (empty($retval->$argval)) {
366
                $retval = null;
367
                break;
368
            } else {
369
                $retval = $retval->$argval;
370
            }
371
        }
372
        return $retval;
373
    }
374
375
    /**
376
     * printSkinCSS
377
     *
378
     * Call this function in the HTML <head> block to print out the
379
     * <style> tag for the internal CSS of the skin. The CSS is minified
380
     * to remove whitespace. Note that you should call readSkinConfig
381
     * to set the contents of $css.
382
     */
383
    public function printSkinCSS()
384
    {
385
        if (strlen($this->css) > 0) {
386
            $cssmin = new CSSmin();
387
            $cssmin->removeImportantComments();
388
            $cssmin->setLineBreakPosition(255);
389
            $outputcss = $cssmin->run($this->css);
390
            echo "<style>$outputcss</style>";
391
        }
392
    }
393
394
    /**
395
     * hasIdpWhitelist
396
     *
397
     * This function checks for the presence of a <idpwhitelist> block
398
     * in the skin's config file.  There must be at least one <idp>
399
     * in the <idpwhitelist>.
400
     *
401
     * @return bool True if skin has a non-empty <idpwhitelist>.
402
     */
403
    public function hasIdpWhitelist()
404
    {
405
        $retval = false;  // Assume no <idpwhitelist> configured
406
        $idpwhitelist = $this->getConfigOption('idpwhitelist');
407
        if ((!is_null($idpwhitelist)) && (!empty($idpwhitelist->idp))) {
408
            $retval = true;
409
        }
410
        return $retval;
411
    }
412
413
    /**
414
     * hasIdpBlacklist
415
     *
416
     * This function checks for the presence of a <idpblacklist> block
417
     * in the skin's config file.  There must be at least one <idp>
418
     * in the <idpblacklist>.
419
     *
420
     * @return bool True if skin has a non-empty <idpblacklist>.
421
     */
422
    public function hasIdpBlacklist()
423
    {
424
        $retval = false;  // Assume no <idpblacklist> configured
425
        $idpblacklist = $this->getConfigOption('idpblacklist');
426
        if ((!is_null($idpblacklist)) && (!empty($idpblacklist->idp))) {
427
            $retval = true;
428
        }
429
        return $retval;
430
    }
431
432
    /**
433
     * idpWhitelisted
434
     *
435
     * This method checks to see if a given entityId of an IdP
436
     * is whitelisted. 'Whitelisted' in this case means either (a) the
437
     * entityId is in the skin's <idpwhitelist> list or (b) the skin
438
     * doesn't have a <idpwhitelist> at all.  In the second case, all
439
     * IdPs are by default 'whitelisted'.  If you want to find if an
440
     * IdP should be listed in the WAYF, use 'idpAvailable' which
441
     * checks the whitelist AND the blacklist.
442
     *
443
     * @param string $entityId The entityId of an IdP to check for
444
     *        whitelisting.
445
     * @return bool True if the given IdP entityId is in the skin's
446
     *         whitelist (or if the skin doesn't have a whitelist).
447
     */
448
    public function idpWhitelisted($entityId)
449
    {
450
        $retval = true;  // Assume the entityId is 'whitelisted'
451
        if ($this->hasIdpWhitelist()) {
452
            $idpwhitelist = $this->getConfigOption('idpwhitelist');
453
            $found = false;
454
            foreach ($idpwhitelist->idp as $whiteidp) {
455
                if ($entityId == ((string)$whiteidp)) {
456
                    $found = true;
457
                    break;
458
                }
459
            }
460
            if (!$found) {
461
                $retval = false;
462
            }
463
        }
464
        return $retval;
465
    }
466
467
    /**
468
     * idpBlacklisted
469
     *
470
     * This method checks to see if a given entityId of an IdP
471
     * appears in the skin's <idpblacklist>.
472
     *
473
     * @param string $entityId The entityId of an IdP to check for
474
     *        blacklisting.
475
     * @return bool True if the given IdP entityId is in the skin's
476
     *         blacklist.
477
     */
478
    public function idpBlacklisted($entityId)
479
    {
480
        $retval = false;  // Assume entityId is NOT in the idpblacklist
481
        if ($this->hasIdpBlacklist()) {
482
            $idpblacklist = $this->getConfigOption('idpblacklist');
483
            foreach ($idpblacklist->idp as $blackidp) {
484
                if ($entityId == ((string)$blackidp)) {
485
                    $retval = true;
486
                    break;
487
                }
488
            }
489
        }
490
        return $retval;
491
    }
492
493
    /**
494
     * idpAvailable
495
     *
496
     * This method combines idpWhitelisted and idpBlacklisted to return
497
     * a 'yes/no' for if a given IdP should be made available for
498
     * selection in the WAYF.  It first checks to see if the IdP is
499
     * whitelisted.  If not, it returns false. Otherwise, it then
500
     * checks if the IdP is blacklisted.  If not, it returns true.
501
     *
502
     * @param string $entityId The entityId of an IdP to check to see if it
503
     *        should be available in the WAYF.
504
     * @return bool True if the given IdP entityId is available to be
505
     *         selected in the WAYF.
506
     */
507
    public function idpAvailable($entityId)
508
    {
509
        $retval = false;   // Assume IdP is not available in the WAYF
510
        if (
511
            ($this->idpWhitelisted($entityId)) &&
512
            (!$this->idpBlacklisted($entityId))
513
        ) {
514
            $retval = true;
515
        }
516
        return $retval;
517
    }
518
519
    /**
520
     * setMyProxyInfo
521
     *
522
     * This method sets the 'myproxyinfo' PHP session variable.  The
523
     * variable has the form 'info:key1=value1,key2=value2,...' and is
524
     * passed to the 'myproxy-logon' command as part of the username
525
     * when fetching a credential.  The MyProxy server will do extra
526
     * processing based on the content of this 'info:...' tag.  If the
527
     * skinname is not empty, that is added to the info tag.  Also,
528
     * the apache REMOTE_ADDR is added.  For other key=value pairs that
529
     * get added, see the code below.
530
     */
531
    public function setMyProxyInfo()
532
    {
533
        $infostr = '';
534
535
        // Add the skinname if available
536
        if (strlen($this->skinname) > 0) {
537
            $infostr .= 'cilogon_skin=' . $this->skinname;
538
        }
539
540
        // Add the REMOTE_ADDR
541
        $remoteaddr = Util::getServerVar('REMOTE_ADDR');
542
        if (strlen($remoteaddr) > 0) {
543
            $infostr .= (strlen($infostr) > 0 ? ',' : '') .
544
                        "remote_addr=$remoteaddr";
545
        }
546
547
        // Add eppn, eptid, open_id, and oidc if available
548
        // Note that these values are lowercase after an update to make
549
        // them the same as those used by the dbService. BUT, MyProxy
550
        // expects the old versions. So this array maps the new lowercase
551
        // versions back into the old ones.
552
        $mpid = array(
553
            'eppn' => 'ePPN',
554
            'eptid' => 'ePTID',
555
            'open_id' => 'openidID',
556
            'oidc' => 'oidcID'
557
        );
558
        foreach (array('eppn','eptid','open_id','oidc') as $id) {
559
            $sessvar = Util::getSessionVar($id);
560
            if (strlen($sessvar) > 0) {
561
                $infostr .= (strlen($infostr) > 0 ? ',' : '') .
562
                    $mpid[$id] . "=" . $sessvar;
563
            }
564
        }
565
566
        // Finally, set the 'myproxyinfo' PHP session variable
567
        if (strlen($infostr) > 0) {
568
            Util::setSessionVar('myproxyinfo', 'info:' . $infostr);
569
        } else {
570
            Util::unsetSessionVar('myproxyinfo');
571
        }
572
    }
573
574
    /**
575
     * hasPortalList
576
     *
577
     * This function checks for the presence of a <portallist> block in
578
     * the skin's config file.  There must be at least one <portal> in
579
     * the <portallist>.
580
     *
581
     * @return bool True if skin has a non-empty <portallist>.
582
     */
583
    public function hasPortalList()
584
    {
585
        $retval = false;  // Assume no <portallist> configured
586
        $portallist = $this->getConfigOption('portallist');
587
        if ((!is_null($portallist)) && (!empty($portallist->portal))) {
588
            $retval = true;
589
        }
590
        return $retval;
591
    }
592
593
    /**
594
     * inPortalList
595
     *
596
     * This function takes in a 'callback' URL of a portal passed to
597
     * the CILogon Delegate service.  It then looks through the list
598
     * of <portal> patterns in the skin's <portallist>.  If the
599
     * callback URL matches any of these patterns, true is returned.
600
     * This is used to hide the 'Site Name / Site URL / Service URL'
601
     * box on the delegation WAYF page, for example.
602
     *
603
     * @param string $portalurl A 'callback' URL of a portal accessing the
604
     *        delegate service.
605
     * @return bool True if the callback URL matches one of the patterns
606
     *         in the skin's <portallist>.  False otherwise.
607
     */
608
    public function inPortalList($portalurl)
609
    {
610
        $retval = false;  // Assume the portalurl not a listed <portal>
611
        if ($this->hasPortalList()) {
612
            $portallist = $this->getConfigOption('portallist');
613
            foreach ($portallist->portal as $portalmatch) {
614
                if (preg_match(((string)$portalmatch), $portalurl)) {
615
                    $retval = true;
616
                    break;
617
                }
618
            }
619
        }
620
        return $retval;
621
    }
622
623
    /**
624
     * getForceSkin
625
     *
626
     * The FORCE_SKIN_ARRAY contains 'uripattern'=>'skinname' pairs
627
     * corresponding to IdP entityIDs, portal callbackurls, or client_ids
628
     * that should have a particular skin force-applied. This function
629
     * looks in the FORCE_SKIN_ARRAY for a pattern-matched URI and returns
630
     * the corresponding skin name if found. If not found, empty
631
     * string is returned.
632
     *
633
     * @param string $uri A URI to search for in the FORCE_SKIN_ARRAY.
634
     * @return string The skin name for the URI, or empty string if not
635
     *         found.
636
     */
637
    protected function getForceSkin($uri)
638
    {
639
        $retval = '';  // Assume uri is not in FORCE_SKIN_ARRAY
640
641
        foreach ($this->forcearray as $key => $value) {
642
            if (preg_match($key, $uri)) {
643
                $retval = $value;
644
                break;
645
            }
646
        }
647
        return $retval;
648
    }
649
}
650