* Get environment instance (singleton)
*
* This creates and/or returns an Environment instance (singleton)
- * derived from $_SERVER variables. You may override the global server
+ * derived from $_SERVER variables. You may override the global server
* variables by using `Environment::mock()` instead.
*
* @param bool $refresh Refresh properties using global server variables?
}
if ( !isset($this->env['slim.request.form_hash']) ) {
$this->env['slim.request.form_hash'] = array();
- if ( $this->isFormData() ) {
+ if ( $this->isFormData() && is_string($this->env['slim.input']) ) {
$output = array();
if ( function_exists('mb_parse_str') && !isset($this->env['slim.tests.ignore_multibyte']) ) {
mb_parse_str($this->env['slim.input'], $output);
public static function parseCookieHeader( $header ) {
$cookies = array();
$header = rtrim($header, "\r\n");
- $headerPieces = preg_split('@\s*;\s*@', $header);
+ $headerPieces = preg_split('@\s*[;,]\s*@', $header);
foreach ( $headerPieces as $c ) {
$cParts = explode('=', $c);
if ( count($cParts) === 2 ) {
$key = urldecode($cParts[0]);
$value = urldecode($cParts[1]);
- if ( isset($cookies[$key]) ) {
- if ( is_array($cookies[$key]) ) {
- $cookies[$key][] = $value;
- } else {
- $cookies[$key] = array($cookies[$key], $value);
- }
- } else {
+ if ( !isset($cookies[$key]) ) {
$cookies[$key] = $value;
}
}
return pack("h*", $data1.$data2);
}
-}
\ No newline at end of file
+}
* @since 1.0.0
*/
class Slim_Log {
+ const FATAL = 0;
+ const ERROR = 1;
+ const WARN = 2;
+ const INFO = 3;
+ const DEBUG = 4;
+
/**
* @var array
*/
if ( is_string($this->settings['expires']) ) {
$this->settings['expires'] = strtotime($this->settings['expires']);
}
+
+ /**
+ * Session
+ *
+ * We must start a native PHP session to initialize the $_SESSION superglobal.
+ * However, we won't be using the native session store for persistence, so we
+ * disable the session cookie and cache limiter. We also set the session
+ * handler to this class instance to avoid PHP's native session file locking.
+ */
+ ini_set('session.use_cookies', 0);
+ session_cache_limiter(false);
+ session_set_save_handler(
+ array($this, 'open'),
+ array($this, 'close'),
+ array($this, 'read'),
+ array($this, 'write'),
+ array($this, 'destroy'),
+ array($this, 'gc')
+ );
}
/**
}
session_destroy();
}
+
+ /**
+ * Session Handler Stubs
+ */
+ public function open( $savePath, $sessionName ) {
+ return true;
+ }
+
+ public function close() {
+ return true;
+ }
+
+ public function read( $id ) {
+ return '';
+ }
+
+ public function write( $id, $data ) {
+ return true;
+ }
+
+ public function destroy( $id ) {
+ return true;
+ }
+
+ public function gc( $maxlifetime ) {
+ return true;
+ }
}
\ No newline at end of file
* @author Josh Lockhart
* @since 1.0.0
*/
-class Slim_Router implements IteratorAggregate {
+class Slim_Router implements Iterator {
/**
* @var Slim_Http_Request
*/
$this->namedRoutes = array();
}
- /**
- * Get Iterator
- * @return ArrayIterator
- */
- public function getIterator() {
- return new ArrayIterator($this->getMatchedRoutes());
- }
-
/**
* Get Request
* @return Slim_Http_Request
return $this->response;
}
+ /**
+ * Get Current Route
+ * @return Slim_Route|false
+ */
+ public function getCurrentRoute() {
+ return $this->current();
+ }
+
/**
* Return routes that match the current request
* @return array[Slim_Route]
}
return $this->error;
}
+
+ /**
+ * Iterator Interface: Rewind
+ * @return void
+ */
+ public function rewind() {
+ reset($this->matchedRoutes);
+ }
+
+ /**
+ * Iterator Interface: Current
+ * @return Slim_Route|false
+ */
+ public function current() {
+ return current($this->matchedRoutes);
+ }
+
+ /**
+ * Iterator Interface: Key
+ * @return int|null
+ */
+ public function key() {
+ return key($this->matchedRoutes);
+ }
+
+ /**
+ * Iterator Interface: Next
+ * @return void
+ */
+ public function next() {
+ next($this->matchedRoutes);
+ }
+
+ /**
+ * Iterator Interface: Valid
+ * @return boolean
+ */
+ public function valid() {
+ return $this->current();
+ }
}
\ No newline at end of file
* Invoke hook
* @param string $name The hook name
* @param mixed $hookArgs (Optional) Argument for hooked functions
- * @return mixed
+ * @return void
*/
public function applyHook( $name, $hookArg = null ) {
if ( !isset($this->hooks[$name]) ) {
foreach( $this->hooks[$name] as $priority ) {
if( !empty($priority) ) {
foreach($priority as $callable) {
- $hookArg = call_user_func($callable, $hookArg);
+ call_user_func($callable, $hookArg);
}
}
}
- return $hookArg; } }
+ }
+ }
/**
* Get hook listeners
$this->applyHook('slim.before.router');
$dispatched = false;
$httpMethodsAllowed = array();
+ $this->router->getMatchedRoutes();
foreach ( $this->router as $route ) {
if ( $route->supportsHttpMethod($this->environment['REQUEST_METHOD']) ) {
try {
* @since 1.0.0
*/
class Slim_View {
+ /**
+ * @var string Absolute template path
+ */
+ protected $templatePath = '';
+
/**
* @var array Key-value array of data available to the template
*/
/**
* Append data to existing View data
- * @param array $data
+ * @param mixed $data
* @return void
+ * @throws InvalidArgumentException
*/
- public function appendData( array $data ) {
+ public function appendData( $data ) {
+ if ( !is_array($data) ) {
+ throw new InvalidArgumentException('Cannot append View data, array required');
+ }
$this->data = array_merge($this->data, $data);
}
$this->templatesDirectory = rtrim($dir, '/');
}
+ /**
+ * Set template
+ * @param string $template
+ * @return void
+ * @throws RuntimeException If template file does not exist
+ */
+ public function setTemplate( $template ) {
+ $this->templatePath = $this->getTemplatesDirectory() . '/' . ltrim($template, '/');
+ if ( !file_exists($this->templatePath) ) {
+ throw new RuntimeException('View cannot render template `' . $this->templatePath . '`. Template does not exist.');
+ }
+ }
+
/**
* Display template
*
*
* @param string $template Path to template file relative to templates directoy
* @return void
+ * @throws RuntimeException If template does not exist
*/
public function display( $template ) {
- echo $this->render($template);
+ echo $this->fetch($template);
+ }
+
+ /**
+ * Fetch rendered template
+ *
+ * This method return the rendered template as a string
+ *
+ * @param string $template Path to template file relative to templates directoy
+ * @return void
+ */
+ public function fetch( $template ) {
+ return $this->render($template);
}
/**
* Render template
- * @param string $template Path to template file relative to templates directory
- * @return string Rendered template
- * @throws RuntimeException If template does not exist
+ * @return string Rendered template
+ *
+ * DEPRECATION WARNING!
+ *
+ * This method will be made PROTECTED in a future version. Please use `Slim_View::fetch` to
+ * return a rendered template instead of `Slim_View::render`.
*/
public function render( $template ) {
+ $this->setTemplate($template);
extract($this->data);
- $templatePath = $this->getTemplatesDirectory() . '/' . ltrim($template, '/');
- if ( !file_exists($templatePath) ) {
- throw new RuntimeException('View cannot render template `' . $templatePath . '`. Template does not exist.');
- }
ob_start();
- require $templatePath;
+ require $this->templatePath;
return ob_get_clean();
}
-
}
\ No newline at end of file