JOOMLA中国
  • Joomla中国首页
  • 社区
  • 教程
  • 应用市场
  • B计划
Joomla! Framework TM
  • Namespace
  • Class
  • Tree
  • Deprecated

Namespaces

  • Composer
    • Autoload
  • Joomla
    • Application
      • Cli
        • Output
          • Processor
      • Web
    • Data
    • DI
      • Exception
    • Event
    • Filter
    • Input
    • Ldap
    • Registry
      • Format
    • Session
      • Storage
    • String
    • Uri
    • Utilities
  • None
  • PasswordCompat
    • binary
  • PHP
  • Psr
    • Log
  • Symfony
    • Component
      • Yaml
        • Exception
    • Polyfill
      • Util

Classes

  • AbstractApplication
  • AbstractCliApplication
  • AbstractDaemonApplication
  • AbstractWebApplication
  1 <?php
  2 /**
  3  * Part of the Joomla Framework Application Package
  4  *
  5  * @copyright  Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved.
  6  * @license    GNU General Public License version 2 or later; see LICENSE
  7  */
  8 
  9 namespace Joomla\Application;
 10 
 11 use Joomla\Uri\Uri;
 12 use Joomla\Input\Input;
 13 use Joomla\Session\Session;
 14 use Joomla\Registry\Registry;
 15 
 16 /**
 17  * Base class for a Joomla! Web application.
 18  *
 19  * @since  1.0
 20  */
 21 abstract class AbstractWebApplication extends AbstractApplication
 22 {
 23     /**
 24      * Character encoding string.
 25      *
 26      * @var    string
 27      * @since  1.0
 28      */
 29     public $charSet = 'utf-8';
 30 
 31     /**
 32      * Response mime type.
 33      *
 34      * @var    string
 35      * @since  1.0
 36      */
 37     public $mimeType = 'text/html';
 38 
 39     /**
 40      * The body modified date for response headers.
 41      *
 42      * @var    \DateTime
 43      * @since  1.0
 44      */
 45     public $modifiedDate;
 46 
 47     /**
 48      * The application client object.
 49      *
 50      * @var    Web\WebClient
 51      * @since  1.0
 52      */
 53     public $client;
 54 
 55     /**
 56      * The application response object.
 57      *
 58      * @var    object
 59      * @since  1.0
 60      */
 61     protected $response;
 62 
 63     /**
 64      * The application session object.
 65      *
 66      * @var    Session
 67      * @since  1.0
 68      */
 69     private $session;
 70 
 71     /**
 72      * A map of integer HTTP 1.1 response codes to the full HTTP Status for the headers.
 73      *
 74      * @var    array
 75      * @since  1.6.0
 76      * @see    https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
 77      */
 78     private $responseMap = array(
 79         300 => 'HTTP/1.1 300 Multiple Choices',
 80         301 => 'HTTP/1.1 301 Moved Permanently',
 81         302 => 'HTTP/1.1 302 Found',
 82         303 => 'HTTP/1.1 303 See other',
 83         304 => 'HTTP/1.1 304 Not Modified',
 84         305 => 'HTTP/1.1 305 Use Proxy',
 85         306 => 'HTTP/1.1 306 (Unused)',
 86         307 => 'HTTP/1.1 307 Temporary Redirect',
 87         308 => 'HTTP/1.1 308 Permanent Redirect'
 88     );
 89 
 90     /**
 91      * Class constructor.
 92      *
 93      * @param   Input          $input   An optional argument to provide dependency injection for the application's input object.  If the argument
 94      *                                  is an Input object that object will become the application's input object, otherwise a default input
 95      *                                  object is created.
 96      * @param   Registry       $config  An optional argument to provide dependency injection for the application's config object.  If the argument
 97      *                                  is a Registry object that object will become the application's config object, otherwise a default config
 98      *                                  object is created.
 99      * @param   Web\WebClient  $client  An optional argument to provide dependency injection for the application's client object.  If the argument
100      *                                  is a Web\WebClient object that object will become the application's client object, otherwise a default client
101      *                                  object is created.
102      *
103      * @since   1.0
104      */
105     public function __construct(Input $input = null, Registry $config = null, Web\WebClient $client = null)
106     {
107         $this->client = $client instanceof Web\WebClient ? $client : new Web\WebClient;
108 
109         // Setup the response object.
110         $this->response = new \stdClass;
111         $this->response->cachable = false;
112         $this->response->headers = array();
113         $this->response->body = array();
114 
115         // Call the constructor as late as possible (it runs `initialise`).
116         parent::__construct($input, $config);
117 
118         // Set the system URIs.
119         $this->loadSystemUris();
120     }
121 
122     /**
123      * Execute the application.
124      *
125      * @return  void
126      *
127      * @since   1.0
128      */
129     public function execute()
130     {
131         // @event onBeforeExecute
132 
133         // Perform application routines.
134         $this->doExecute();
135 
136         // @event onAfterExecute
137 
138         // If gzip compression is enabled in configuration and the server is compliant, compress the output.
139         if ($this->get('gzip') && !ini_get('zlib.output_compression') && (ini_get('output_handler') != 'ob_gzhandler'))
140         {
141             $this->compress();
142         }
143 
144         // @event onBeforeRespond
145 
146         // Send the application response.
147         $this->respond();
148 
149         // @event onAfterRespond
150     }
151 
152     /**
153      * Checks the accept encoding of the browser and compresses the data before
154      * sending it to the client if possible.
155      *
156      * @return  void
157      *
158      * @since   1.0
159      */
160     protected function compress()
161     {
162         // Supported compression encodings.
163         $supported = array(
164             'x-gzip' => 'gz',
165             'gzip' => 'gz',
166             'deflate' => 'deflate'
167         );
168 
169         // Get the supported encoding.
170         $encodings = array_intersect($this->client->encodings, array_keys($supported));
171 
172         // If no supported encoding is detected do nothing and return.
173         if (empty($encodings))
174         {
175             return;
176         }
177 
178         // Verify that headers have not yet been sent, and that our connection is still alive.
179         if ($this->checkHeadersSent() || !$this->checkConnectionAlive())
180         {
181             return;
182         }
183 
184         // Iterate through the encodings and attempt to compress the data using any found supported encodings.
185         foreach ($encodings as $encoding)
186         {
187             if (($supported[$encoding] == 'gz') || ($supported[$encoding] == 'deflate'))
188             {
189                 // Verify that the server supports gzip compression before we attempt to gzip encode the data.
190                 // @codeCoverageIgnoreStart
191                 if (!extension_loaded('zlib') || ini_get('zlib.output_compression'))
192                 {
193                     continue;
194                 }
195 
196                 // @codeCoverageIgnoreEnd
197 
198                 // Attempt to gzip encode the data with an optimal level 4.
199                 $data = $this->getBody();
200                 $gzdata = gzencode($data, 4, ($supported[$encoding] == 'gz') ? FORCE_GZIP : FORCE_DEFLATE);
201 
202                 // If there was a problem encoding the data just try the next encoding scheme.
203                 // @codeCoverageIgnoreStart
204                 if ($gzdata === false)
205                 {
206                     continue;
207                 }
208 
209                 // @codeCoverageIgnoreEnd
210 
211                 // Set the encoding headers.
212                 $this->setHeader('Content-Encoding', $encoding);
213                 $this->setHeader('X-Content-Encoded-By', 'Joomla');
214 
215                 // Replace the output with the encoded data.
216                 $this->setBody($gzdata);
217 
218                 // Compression complete, let's break out of the loop.
219                 break;
220             }
221         }
222     }
223 
224     /**
225      * Method to send the application response to the client.  All headers will be sent prior to the main
226      * application output data.
227      *
228      * @return  void
229      *
230      * @since   1.0
231      */
232     protected function respond()
233     {
234         // Send the content-type header.
235         $this->setHeader('Content-Type', $this->mimeType . '; charset=' . $this->charSet);
236 
237         // If the response is set to uncachable, we need to set some appropriate headers so browsers don't cache the response.
238         if (!$this->allowCache())
239         {
240             // Expires in the past.
241             $this->setHeader('Expires', 'Wed, 17 Aug 2005 00:00:00 GMT', true);
242 
243             // Always modified.
244             $this->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT', true);
245             $this->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', false);
246 
247             // HTTP 1.0
248             $this->setHeader('Pragma', 'no-cache');
249         }
250         else
251         {
252             // Expires.
253             $this->setHeader('Expires', gmdate('D, d M Y H:i:s', time() + 900) . ' GMT');
254 
255             // Last modified.
256             if ($this->modifiedDate instanceof \DateTime)
257             {
258                 $this->modifiedDate->setTimezone(new \DateTimeZone('UTC'));
259                 $this->setHeader('Last-Modified', $this->modifiedDate->format('D, d M Y H:i:s') . ' GMT');
260             }
261         }
262 
263         $this->sendHeaders();
264 
265         echo $this->getBody();
266     }
267 
268     /**
269      * Redirect to another URL.
270      *
271      * If the headers have not been sent the redirect will be accomplished using a "301 Moved Permanently"
272      * or "303 See Other" code in the header pointing to the new location. If the headers have already been
273      * sent this will be accomplished using a JavaScript statement.
274      *
275      * @param   string   $url     The URL to redirect to. Can only be http/https URL
276      * @param   integer  $status  The HTTP 1.1 status code to be provided. 303 is assumed by default.
277      *
278      * @return  void
279      *
280      * @since   1.0
281      * @throws  \InvalidArgumentException
282      */
283     public function redirect($url, $status = 303)
284     {
285         // Check for relative internal links.
286         if (preg_match('#^index\.php#', $url))
287         {
288             $url = $this->get('uri.base.full') . $url;
289         }
290 
291         // Perform a basic sanity check to make sure we don't have any CRLF garbage.
292         $url = preg_split("/[\r\n]/", $url);
293         $url = $url[0];
294 
295         /*
296          * Here we need to check and see if the URL is relative or absolute.  Essentially, do we need to
297          * prepend the URL with our base URL for a proper redirect.  The rudimentary way we are looking
298          * at this is to simply check whether or not the URL string has a valid scheme or not.
299          */
300         if (!preg_match('#^[a-z]+\://#i', $url))
301         {
302             // Get a Uri instance for the requested URI.
303             $uri = new Uri($this->get('uri.request'));
304 
305             // Get a base URL to prepend from the requested URI.
306             $prefix = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port'));
307 
308             // We just need the prefix since we have a path relative to the root.
309             if ($url[0] == '/')
310             {
311                 $url = $prefix . $url;
312             }
313             else
314             // It's relative to where we are now, so lets add that.
315             {
316                 $parts = explode('/', $uri->toString(array('path')));
317                 array_pop($parts);
318                 $path = implode('/', $parts) . '/';
319                 $url = $prefix . $path . $url;
320             }
321         }
322 
323         // If the headers have already been sent we need to send the redirect statement via JavaScript.
324         if ($this->checkHeadersSent())
325         {
326             echo "<script>document.location.href='$url';</script>\n";
327         }
328         else
329         {
330             // We have to use a JavaScript redirect here because MSIE doesn't play nice with utf-8 URLs.
331             if (($this->client->engine == Web\WebClient::TRIDENT) && !$this->isAscii($url))
332             {
333                 $html = '<html><head>';
334                 $html .= '<meta http-equiv="content-type" content="text/html; charset=' . $this->charSet . '" />';
335                 $html .= '<script>document.location.href=\'' . $url . '\';</script>';
336                 $html .= '</head><body></body></html>';
337 
338                 echo $html;
339             }
340             else
341             {
342                 // Check if we have a boolean for the status variable for compatability with v1 of the framework
343                 // @deprecated 3.0
344                 if (is_bool($status))
345                 {
346                     $status = $status ? 301 : 303;
347                 }
348 
349                 if (!is_int($status) && !isset($this->responseMap[$status]))
350                 {
351                     throw new \InvalidArgumentException('You have not supplied a valid HTTP 1.1 status code');
352                 }
353 
354                 // All other cases use the more efficient HTTP header for redirection.
355                 $this->header($this->responseMap[$status]);
356                 $this->header('Location: ' . $url);
357                 $this->header('Content-Type: text/html; charset=' . $this->charSet);
358 
359                 // Send other headers that may have been set.
360                 $this->sendHeaders();
361             }
362         }
363 
364         // Close the application after the redirect.
365         $this->close();
366     }
367 
368     /**
369      * Set/get cachable state for the response.  If $allow is set, sets the cachable state of the
370      * response.  Always returns the current state.
371      *
372      * @param   boolean  $allow  True to allow browser caching.
373      *
374      * @return  boolean
375      *
376      * @since   1.0
377      */
378     public function allowCache($allow = null)
379     {
380         if ($allow !== null)
381         {
382             $this->response->cachable = (bool) $allow;
383         }
384 
385         return $this->response->cachable;
386     }
387 
388     /**
389      * Method to set a response header.  If the replace flag is set then all headers
390      * with the given name will be replaced by the new one.  The headers are stored
391      * in an internal array to be sent when the site is sent to the browser.
392      *
393      * @param   string   $name     The name of the header to set.
394      * @param   string   $value    The value of the header to set.
395      * @param   boolean  $replace  True to replace any headers with the same name.
396      *
397      * @return  AbstractWebApplication  Instance of $this to allow chaining.
398      *
399      * @since   1.0
400      */
401     public function setHeader($name, $value, $replace = false)
402     {
403         // Sanitize the input values.
404         $name = (string) $name;
405         $value = (string) $value;
406 
407         // If the replace flag is set, unset all known headers with the given name.
408         if ($replace)
409         {
410             foreach ($this->response->headers as $key => $header)
411             {
412                 if ($name == $header['name'])
413                 {
414                     unset($this->response->headers[$key]);
415                 }
416             }
417 
418             // Clean up the array as unsetting nested arrays leaves some junk.
419             $this->response->headers = array_values($this->response->headers);
420         }
421 
422         // Add the header to the internal array.
423         $this->response->headers[] = array('name' => $name, 'value' => $value);
424 
425         return $this;
426     }
427 
428     /**
429      * Method to get the array of response headers to be sent when the response is sent
430      * to the client.
431      *
432      * @return  array
433      *
434      * @since   1.0
435      */
436     public function getHeaders()
437     {
438         return $this->response->headers;
439     }
440 
441     /**
442      * Method to clear any set response headers.
443      *
444      * @return  AbstractWebApplication  Instance of $this to allow chaining.
445      *
446      * @since   1.0
447      */
448     public function clearHeaders()
449     {
450         $this->response->headers = array();
451 
452         return $this;
453     }
454 
455     /**
456      * Send the response headers.
457      *
458      * @return  AbstractWebApplication  Instance of $this to allow chaining.
459      *
460      * @since   1.0
461      */
462     public function sendHeaders()
463     {
464         if (!$this->checkHeadersSent())
465         {
466             foreach ($this->response->headers as $header)
467             {
468                 if ('status' == strtolower($header['name']))
469                 {
470                     // 'status' headers indicate an HTTP status, and need to be handled slightly differently
471                     $this->header('HTTP/1.1 ' . $header['value'], null, (int) $header['value']);
472                 }
473                 else
474                 {
475                     $this->header($header['name'] . ': ' . $header['value']);
476                 }
477             }
478         }
479 
480         return $this;
481     }
482 
483     /**
484      * Set body content.  If body content already defined, this will replace it.
485      *
486      * @param   string  $content  The content to set as the response body.
487      *
488      * @return  AbstractWebApplication  Instance of $this to allow chaining.
489      *
490      * @since   1.0
491      */
492     public function setBody($content)
493     {
494         $this->response->body = array((string) $content);
495 
496         return $this;
497     }
498 
499     /**
500      * Prepend content to the body content
501      *
502      * @param   string  $content  The content to prepend to the response body.
503      *
504      * @return  AbstractWebApplication  Instance of $this to allow chaining.
505      *
506      * @since   1.0
507      */
508     public function prependBody($content)
509     {
510         array_unshift($this->response->body, (string) $content);
511 
512         return $this;
513     }
514 
515     /**
516      * Append content to the body content
517      *
518      * @param   string  $content  The content to append to the response body.
519      *
520      * @return  AbstractWebApplication  Instance of $this to allow chaining.
521      *
522      * @since   1.0
523      */
524     public function appendBody($content)
525     {
526         array_push($this->response->body, (string) $content);
527 
528         return $this;
529     }
530 
531     /**
532      * Return the body content
533      *
534      * @param   boolean  $asArray  True to return the body as an array of strings.
535      *
536      * @return  mixed  The response body either as an array or concatenated string.
537      *
538      * @since   1.0
539      */
540     public function getBody($asArray = false)
541     {
542         return $asArray ? $this->response->body : implode((array) $this->response->body);
543     }
544 
545     /**
546      * Method to get the application session object.
547      *
548      * @return  Session  The session object
549      *
550      * @since   1.0
551      */
552     public function getSession()
553     {
554         if ($this->session === null)
555         {
556             throw new \RuntimeException('A \Joomla\Session\Session object has not been set.');
557         }
558 
559         return $this->session;
560     }
561 
562     /**
563      * Method to check the current client connnection status to ensure that it is alive.  We are
564      * wrapping this to isolate the connection_status() function from our code base for testing reasons.
565      *
566      * @return  boolean  True if the connection is valid and normal.
567      *
568      * @codeCoverageIgnore
569      * @see     connection_status()
570      * @since   1.0
571      */
572     protected function checkConnectionAlive()
573     {
574         return (connection_status() === CONNECTION_NORMAL);
575     }
576 
577     /**
578      * Method to check to see if headers have already been sent.  We are wrapping this to isolate the
579      * headers_sent() function from our code base for testing reasons.
580      *
581      * @return  boolean  True if the headers have already been sent.
582      *
583      * @codeCoverageIgnore
584      * @see     headers_sent()
585      * @since   1.0
586      */
587     protected function checkHeadersSent()
588     {
589         return headers_sent();
590     }
591 
592     /**
593      * Method to detect the requested URI from server environment variables.
594      *
595      * @return  string  The requested URI
596      *
597      * @since   1.0
598      */
599     protected function detectRequestUri()
600     {
601         // First we need to detect the URI scheme.
602         if ($this->isSslConnection())
603         {
604             $scheme = 'https://';
605         }
606         else
607         {
608             $scheme = 'http://';
609         }
610 
611         /*
612          * There are some differences in the way that Apache and IIS populate server environment variables.  To
613          * properly detect the requested URI we need to adjust our algorithm based on whether or not we are getting
614          * information from Apache or IIS.
615          */
616 
617         $phpSelf = $this->input->server->getString('PHP_SELF', '');
618         $requestUri = $this->input->server->getString('REQUEST_URI', '');
619 
620         // If PHP_SELF and REQUEST_URI are both populated then we will assume "Apache Mode".
621         if (!empty($phpSelf) && !empty($requestUri))
622         {
623             // The URI is built from the HTTP_HOST and REQUEST_URI environment variables in an Apache environment.
624             $uri = $scheme . $this->input->server->getString('HTTP_HOST') . $requestUri;
625         }
626         else
627         // If not in "Apache Mode" we will assume that we are in an IIS environment and proceed.
628         {
629             // IIS uses the SCRIPT_NAME variable instead of a REQUEST_URI variable... thanks, MS
630             $uri = $scheme . $this->input->server->getString('HTTP_HOST') . $this->input->server->getString('SCRIPT_NAME');
631             $queryHost = $this->input->server->getString('QUERY_STRING', '');
632 
633             // If the QUERY_STRING variable exists append it to the URI string.
634             if (!empty($queryHost))
635             {
636                 $uri .= '?' . $queryHost;
637             }
638         }
639 
640         return trim($uri);
641     }
642 
643     /**
644      * Method to send a header to the client.  We are wrapping this to isolate the header() function
645      * from our code base for testing reasons.
646      *
647      * @param   string   $string   The header string.
648      * @param   boolean  $replace  The optional replace parameter indicates whether the header should
649      *                             replace a previous similar header, or add a second header of the same type.
650      * @param   integer  $code     Forces the HTTP response code to the specified value. Note that
651      *                             this parameter only has an effect if the string is not empty.
652      *
653      * @return  void
654      *
655      * @codeCoverageIgnore
656      * @see     header()
657      * @since   1.0
658      */
659     protected function header($string, $replace = true, $code = null)
660     {
661         header(str_replace(chr(0), '', $string), $replace, $code);
662     }
663 
664     /**
665      * Determine if we are using a secure (SSL) connection.
666      *
667      * @return  boolean  True if using SSL, false if not.
668      *
669      * @since   1.0
670      */
671     public function isSslConnection()
672     {
673         $serverSSLVar = $this->input->server->getString('HTTPS', '');
674 
675         return (!empty($serverSSLVar) && strtolower($serverSSLVar) != 'off');
676     }
677 
678     /**
679      * Sets the session for the application to use, if required.
680      *
681      * @param   Session  $session  A session object.
682      *
683      * @return  AbstractWebApplication  Returns itself to support chaining.
684      *
685      * @since   1.0
686      */
687     public function setSession(Session $session)
688     {
689         $this->session = $session;
690 
691         return $this;
692     }
693 
694     /**
695      * Method to load the system URI strings for the application.
696      *
697      * @param   string  $requestUri  An optional request URI to use instead of detecting one from the
698      *                               server environment variables.
699      *
700      * @return  void
701      *
702      * @since   1.0
703      */
704     protected function loadSystemUris($requestUri = null)
705     {
706         // Set the request URI.
707         // @codeCoverageIgnoreStart
708         if (!empty($requestUri))
709         {
710             $this->set('uri.request', $requestUri);
711         }
712         else
713         {
714             $this->set('uri.request', $this->detectRequestUri());
715         }
716 
717         // @codeCoverageIgnoreEnd
718 
719         // Check to see if an explicit base URI has been set.
720         $siteUri = trim($this->get('site_uri'));
721 
722         if ($siteUri != '')
723         {
724             $uri = new Uri($siteUri);
725             $path = $uri->toString(array('path'));
726         }
727         else
728         // No explicit base URI was set so we need to detect it.
729         {
730             // Start with the requested URI.
731             $uri = new Uri($this->get('uri.request'));
732 
733             $requestUri = $this->input->server->getString('REQUEST_URI', '');
734 
735             // If we are working from a CGI SAPI with the 'cgi.fix_pathinfo' directive disabled we use PHP_SELF.
736             if (strpos(php_sapi_name(), 'cgi') !== false && !ini_get('cgi.fix_pathinfo') && !empty($requestUri))
737             {
738                 // We aren't expecting PATH_INFO within PHP_SELF so this should work.
739                 $path = dirname($this->input->server->getString('PHP_SELF', ''));
740             }
741             else
742             // Pretty much everything else should be handled with SCRIPT_NAME.
743             {
744                 $path = dirname($this->input->server->getString('SCRIPT_NAME', ''));
745             }
746         }
747 
748         // Get the host from the URI.
749         $host = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port'));
750 
751         // Check if the path includes "index.php".
752         if (strpos($path, 'index.php') !== false)
753         {
754             // Remove the index.php portion of the path.
755             $path = substr_replace($path, '', strpos($path, 'index.php'), 9);
756         }
757 
758         $path = rtrim($path, '/\\');
759 
760         // Set the base URI both as just a path and as the full URI.
761         $this->set('uri.base.full', $host . $path . '/');
762         $this->set('uri.base.host', $host);
763         $this->set('uri.base.path', $path . '/');
764 
765         // Set the extended (non-base) part of the request URI as the route.
766         if (stripos($this->get('uri.request'), $this->get('uri.base.full')) === 0)
767         {
768             $this->set('uri.route', substr_replace($this->get('uri.request'), '', 0, strlen($this->get('uri.base.full'))));
769         }
770 
771         // Get an explicitly set media URI is present.
772         $mediaURI = trim($this->get('media_uri'));
773 
774         if ($mediaURI)
775         {
776             if (strpos($mediaURI, '://') !== false)
777             {
778                 $this->set('uri.media.full', $mediaURI);
779                 $this->set('uri.media.path', $mediaURI);
780             }
781             else
782             {
783                 // Normalise slashes.
784                 $mediaURI = trim($mediaURI, '/\\');
785                 $mediaURI = !empty($mediaURI) ? '/' . $mediaURI . '/' : '/';
786                 $this->set('uri.media.full', $this->get('uri.base.host') . $mediaURI);
787                 $this->set('uri.media.path', $mediaURI);
788             }
789         }
790         else
791         // No explicit media URI was set, build it dynamically from the base uri.
792         {
793             $this->set('uri.media.full', $this->get('uri.base.full') . 'media/');
794             $this->set('uri.media.path', $this->get('uri.base.path') . 'media/');
795         }
796     }
797 
798     /**
799      * Checks for a form token in the request.
800      *
801      * Use in conjunction with getFormToken.
802      *
803      * @param   string  $method  The request method in which to look for the token key.
804      *
805      * @return  boolean  True if found and valid, false otherwise.
806      *
807      * @since   1.0
808      */
809     public function checkToken($method = 'post')
810     {
811         $token = $this->getFormToken();
812 
813         if (!$this->input->$method->get($token, '', 'alnum'))
814         {
815             if ($this->getSession()->isNew())
816             {
817                 // Redirect to login screen.
818                 $this->redirect('index.php');
819                 $this->close();
820             }
821             else
822             {
823                 return false;
824             }
825         }
826         else
827         {
828             return true;
829         }
830     }
831 
832     /**
833      * Method to determine a hash for anti-spoofing variable names
834      *
835      * @param   boolean  $forceNew  If true, force a new token to be created
836      *
837      * @return  string  Hashed var name
838      *
839      * @since   1.0
840      */
841     public function getFormToken($forceNew = false)
842     {
843         // @todo we need the user id somehow here
844         $userId  = 0;
845 
846         return md5($this->get('secret') . $userId . $this->getSession()->getToken($forceNew));
847     }
848 
849     /**
850      * Tests whether a string contains only 7bit ASCII bytes.
851      *
852      * You might use this to conditionally check whether a string
853      * needs handling as UTF-8 or not, potentially offering performance
854      * benefits by using the native PHP equivalent if it's just ASCII e.g.;
855      *
856      * @param   string  $str  The string to test.
857      *
858      * @return  boolean True if the string is all ASCII
859      *
860      * @since   1.4.0
861      */
862     public static function isAscii($str)
863     {
864         // Search for any bytes which are outside the ASCII range...
865         return (preg_match('/(?:[^\x00-\x7F])/', $str) !== 1);
866     }
867 }
868 
Joomla! Framework TM API documentation generated by ApiGen 2.8.0
Joomla!® and Joomla! Framework™ are trademarks of Open Source Matters, Inc. in the United States and other countries.