Profile
+ @include('user.profile')
+
+Similarly, you can use **@render**, which behaves the same as **@include** except the rendered view will **not** inherit the data from the current view.
+
+ @render('admin.list')
+
+#### Blade comments:
+
+ {{-- This is a comment --}}
+
+ {{--
+ This is a
+ multi-line
+ comment.
+ --}}
+
+> **Note:** Unlike HTML comments, Blade comments are not visible in the HTML source.
+
+
+## Blade Control Structures
+
+#### For Loop:
+
+ @for ($i = 0; $i <= count($comments); $i++)
+ The comment body is {{ $comments[$i] }}
+ @endfor
+
+#### Foreach Loop:
+
+ @foreach ($comments as $comment)
+ The comment body is {{ $comment->body }}.
+ @endforeach
+
+#### While Loop:
+
+ @while ($something)
+ I am still looping!
+ @endwhile
+
+#### If Statement:
+
+ @if ( $message == true )
+ I'm displaying the message!
+ @endif
+
+#### If Else Statement:
+
+ @if (count($comments) > 0)
+ I have comments!
+ @else
+ I have no comments!
+ @endif
+
+#### Else If Statement:
+
+ @if ( $message == 'success' )
+ It was a success!
+ @elseif ( $message == 'error' )
+ An error occurred.
+ @else
+ Did it work?
+ @endif
+
+#### For Else Statement:
+
+ @forelse ($posts as $post)
+ {{ $post->body }}
+ @empty
+ There are not posts in the array!
+ @endforelse
+
+#### Unless Statement:
+
+ @unless(Auth::check())
+ Login
+ @endunless
+
+ // Equivalent to...
+
+
+ Login
+
+
+
+## Blade Layouts
+
+Not only does Blade provide clean, elegant syntax for common PHP control structures, it also gives you a beautiful method of using layouts for your views. For example, perhaps your application uses a "master" view to provide a common look and feel for your application. It may look something like this:
+
+
+
+
+
+ @yield('content')
+
+
+
+Notice the "content" section being yielded. We need to fill this section with some text, so let's make another view that uses this layout:
+
+ @layout('master')
+
+ @section('content')
+ Welcome to the profile page!
+ @endsection
+
+Great! Now, we can simply return the "profile" view from our route:
+
+ return View::make('profile');
+
+The profile view will automatically use the "master" template thanks to Blade's **@layout** expression.
+
+> **Important:** The **@layout** call must always be on the very first line of the file, with no leading whitespaces or newline breaks.
+
+#### Appending with @parent
+
+Sometimes you may want to only append to a section of a layout rather than overwrite it. For example, consider the navigation list in our "master" layout. Let's assume we just want to append a new list item. Here's how to do it:
+
+ @layout('master')
+
+ @section('navigation')
+ @parent
+
Unhandled Exception
-Message:
-".$exception->getMessage()."-
Location:
-".$exception->getFile()." on line ".$exception->getLine()."+ $response_body = "
Unhandled Exception
+Message:
+".$message."+
Location:
+".$file." on line ".$exception->getLine().""; + + if ($trace) + { + $response_body .= "
Stack Trace:
".$exception->getTraceAsString().""; + } + + $response = Response::make($response_body, 500); } // If we're not using detailed error messages, we'll use the event @@ -35,9 +56,13 @@ public static function exception($exception) { $response = Event::first('500'); - return Response::prepare($response)->send(); + $response = Response::prepare($response); } + $response->render(); + $response->send(); + $response->foundation->finish(); + exit(1); } @@ -54,7 +79,7 @@ public static function native($code, $error, $file, $line) { if (error_reporting() === 0) return; - // For a PHP error, we'll create an ErrorExcepetion and then feed that + // For a PHP error, we'll create an ErrorException and then feed that // exception to the exception method, which will create a simple view // of the exception details for the developer. $exception = new \ErrorException($error, $code, 0, $file, $line); @@ -62,8 +87,6 @@ public static function native($code, $error, $file, $line) if (in_array($code, Config::get('error.ignore'))) { return static::log($exception); - - return true; } static::exception($exception); @@ -76,7 +99,7 @@ public static function native($code, $error, $file, $line) */ public static function shutdown() { - // If a fatal error occured that we have not handled yet, we will + // If a fatal error occurred that we have not handled yet, we will // create an ErrorException and feed it to the exception handler, // as it will not yet have been handled. $error = error_get_last(); @@ -85,7 +108,7 @@ public static function shutdown() { extract($error, EXTR_SKIP); - static::exception(new \ErrorException($message, $type, 0, $file, $line)); + static::exception(new \ErrorException($message, $type, 0, $file, $line), false); } } @@ -103,4 +126,4 @@ public static function log($exception) } } -} \ No newline at end of file +} diff --git a/app/laravel/event.php b/app/laravel/event.php index 7fdc13688..ccc3bf1c0 100644 --- a/app/laravel/event.php +++ b/app/laravel/event.php @@ -9,6 +9,20 @@ class Event { */ public static $events = array(); + /** + * The queued events waiting for flushing. + * + * @var array + */ + public static $queued = array(); + + /** + * All of the registered queue flusher callbacks. + * + * @var array + */ + public static $flushers = array(); + /** * Determine if an event has any registered listeners. * @@ -54,6 +68,31 @@ public static function override($event, $callback) static::listen($event, $callback); } + /** + * Add an item to an event queue for processing. + * + * @param string $queue + * @param string $key + * @param mixed $data + * @return void + */ + public static function queue($queue, $key, $data = array()) + { + static::$queued[$queue][$key] = $data; + } + + /** + * Register a queue flusher callback. + * + * @param string $queue + * @param mixed $callback + * @return void + */ + public static function flusher($queue, $callback) + { + static::$flushers[$queue][] = $callback; + } + /** * Clear all event listeners for a given event. * @@ -86,7 +125,7 @@ public static function first($event, $parameters = array()) } /** - * Fire an event and return the the first response. + * Fire an event and return the first response. * * Execution will be halted after the first valid response is found. * @@ -99,6 +138,30 @@ public static function until($event, $parameters = array()) return static::fire($event, $parameters, true); } + /** + * Flush an event queue, firing the flusher for each payload. + * + * @param string $queue + * @return void + */ + public static function flush($queue) + { + foreach (static::$flushers[$queue] as $flusher) + { + // We will simply spin through each payload registered for the event and + // fire the flusher, passing each payloads as we go. This allows all + // the events on the queue to be processed by the flusher easily. + if ( ! isset(static::$queued[$queue])) continue; + + foreach (static::$queued[$queue] as $key => $payload) + { + array_unshift($payload, $key); + + call_user_func_array($flusher, $payload); + } + } + } + /** * Fire an event so that all listeners are called. * @@ -108,14 +171,17 @@ public static function until($event, $parameters = array()) * * // Fire the "start" event passing an array of parameters * $responses = Event::fire('start', array('Laravel', 'Framework')); + * + * // Fire multiple events with the same parameters + * $responses = Event::fire(array('start', 'loading'), $parameters); * * - * @param string $event - * @param array $parameters - * @param bool $halt + * @param string|array $events + * @param array $parameters + * @param bool $halt * @return array */ - public static function fire($event, $parameters = array(), $halt = false) + public static function fire($events, $parameters = array(), $halt = false) { $responses = array(); @@ -124,28 +190,31 @@ public static function fire($event, $parameters = array(), $halt = false) // If the event has listeners, we will simply iterate through them and call // each listener, passing in the parameters. We will add the responses to // an array of event responses and return the array. - if (static::listeners($event)) + foreach ((array) $events as $event) { - foreach (static::$events[$event] as $callback) + if (static::listeners($event)) { - $response = call_user_func_array($callback, $parameters); - - // If the event is set to halt, we will return the first response - // that is not null. This allows the developer to easily stack - // events but still get the first valid response. - if ($halt and ! is_null($response)) + foreach (static::$events[$event] as $callback) { - return $response; + $response = call_user_func_array($callback, $parameters); + + // If the event is set to halt, we will return the first response + // that is not null. This allows the developer to easily stack + // events but still get the first valid response. + if ($halt and ! is_null($response)) + { + return $response; + } + + // After the handler has been called, we'll add the response to + // an array of responses and return the array to the caller so + // all of the responses can be easily examined. + $responses[] = $response; } - - // After the handler has been called, we'll add the response to - // an array of responses and return the array to the caller so - // all of the responses can be easily examined. - $responses[] = $response; } } - return $responses; + return $halt ? null : $responses; } } \ No newline at end of file diff --git a/app/laravel/file.php b/app/laravel/file.php index 0346c83c7..5ac39cac1 100644 --- a/app/laravel/file.php +++ b/app/laravel/file.php @@ -1,4 +1,4 @@ -isDir()) { static::rmdir($item->getRealPath()); @@ -306,6 +307,7 @@ public static function rmdir($directory, $preserve = false) } } + unset($items); if ( ! $preserve) @rmdir($directory); } @@ -329,16 +331,22 @@ public static function cleandir($directory) */ public static function latest($directory, $options = fIterator::SKIP_DOTS) { + $latest = null; + $time = 0; $items = new fIterator($directory, $options); - // To get the latest created file, we'll simply spin through the + // To get the latest created file, we'll simply loop through the // directory, setting the latest file if we encounter a file // with a UNIX timestamp greater than the latest one. foreach ($items as $item) { - if ($item->getMTime() > $time) $latest = $item; + if ($item->getMTime() > $time) + { + $latest = $item; + $time = $item->getMTime(); + } } return $latest; diff --git a/app/laravel/form.php b/app/laravel/form.php index a768f503e..5a450b526 100644 --- a/app/laravel/form.php +++ b/app/laravel/form.php @@ -8,7 +8,7 @@ class Form { * @var array */ public static $labels = array(); - + /** * The registered custom macros. * @@ -16,13 +16,13 @@ class Form { */ public static $macros = array(); - /** - * Registers a custom macro. - * - * @param string $name - * @param Closure $input - * @return void - */ + /** + * Registers a custom macro. + * + * @param string $name + * @param Closure $macro + * @return void + */ public static function macro($name, $macro) { static::$macros[$name] = $macro; @@ -51,12 +51,12 @@ public static function macro($name, $macro) * @param bool $https * @return string */ - public static function open($action = null, $method = 'POST', $attributes = array(), $https = false) + public static function open($action = null, $method = 'POST', $attributes = array(), $https = null) { $method = strtoupper($method); $attributes['method'] = static::method($method); - + $attributes['action'] = static::action($action, $https); // If a character encoding has not been specified in the attributes, we will @@ -128,8 +128,8 @@ public static function open_secure($action = null, $method = 'POST', $attributes * @param array $attributes * @param bool $https * @return string - */ - public static function open_for_files($action = null, $method = 'POST', $attributes = array(), $https = false) + */ + public static function open_for_files($action = null, $method = 'POST', $attributes = array(), $https = null) { $attributes['enctype'] = 'multipart/form-data'; @@ -143,7 +143,7 @@ public static function open_for_files($action = null, $method = 'POST', $attribu * @param string $method * @param array $attributes * @return string - */ + */ public static function open_secure_for_files($action = null, $method = 'POST', $attributes = array()) { return static::open_for_files($action, $method, $attributes, true); @@ -181,7 +181,7 @@ public static function token() * @param string $value * @param array $attributes * @return string - */ + */ public static function label($name, $value, $attributes = array()) { static::$labels[] = $name; @@ -209,7 +209,7 @@ public static function label($name, $value, $attributes = array()) * @param mixed $value * @param array $attributes * @return string - */ + */ public static function input($type, $name, $value = null, $attributes = array()) { $name = (isset($attributes['name'])) ? $attributes['name'] : $name; @@ -240,7 +240,7 @@ public static function text($name, $value = null, $attributes = array()) * @param string $name * @param array $attributes * @return string - */ + */ public static function password($name, $attributes = array()) { return static::input('password', $name, null, $attributes); @@ -266,7 +266,7 @@ public static function hidden($name, $value = null, $attributes = array()) * @param string $value * @param array $attributes * @return string - */ + */ public static function search($name, $value = null, $attributes = array()) { return static::input('search', $name, $value, $attributes); @@ -279,7 +279,7 @@ public static function search($name, $value = null, $attributes = array()) * @param string $value * @param array $attributes * @return string - */ + */ public static function email($name, $value = null, $attributes = array()) { return static::input('email', $name, $value, $attributes); @@ -305,7 +305,7 @@ public static function telephone($name, $value = null, $attributes = array()) * @param string $value * @param array $attributes * @return string - */ + */ public static function url($name, $value = null, $attributes = array()) { return static::input('url', $name, $value, $attributes); @@ -318,12 +318,12 @@ public static function url($name, $value = null, $attributes = array()) * @param string $value * @param array $attributes * @return string - */ + */ public static function number($name, $value = null, $attributes = array()) { return static::input('number', $name, $value, $attributes); } - + /** * Create a HTML date input element. * @@ -331,7 +331,7 @@ public static function number($name, $value = null, $attributes = array()) * @param string $value * @param array $attributes * @return string - */ + */ public static function date($name, $value = null, $attributes = array()) { return static::input('date', $name, $value, $attributes); @@ -343,7 +343,7 @@ public static function date($name, $value = null, $attributes = array()) * @param string $name * @param array $attributes * @return string - */ + */ public static function file($name, $attributes = array()) { return static::input('file', $name, null, $attributes); @@ -386,23 +386,50 @@ public static function textarea($name, $value = '', $attributes = array()) * @param string $selected * @param array $attributes * @return string - */ + */ public static function select($name, $options = array(), $selected = null, $attributes = array()) { $attributes['id'] = static::id($name, $attributes); - + $attributes['name'] = $name; $html = array(); foreach ($options as $value => $display) { - $html[] = static::option($value, $display, $selected); + if (is_array($display)) + { + $html[] = static::optgroup($display, $value, $selected); + } + else + { + $html[] = static::option($value, $display, $selected); + } } return ''; } + /** + * Create a HTML select element optgroup. + * + * @param array $options + * @param string $label + * @param string $selected + * @return string + */ + protected static function optgroup($options, $label, $selected) + { + $html = array(); + + foreach ($options as $value => $display) + { + $html[] = static::option($value, $display, $selected); + } + + return ''; + } + /** * Create a HTML select element option. * @@ -419,7 +446,7 @@ protected static function option($value, $display, $selected) } else { - $selected = ($value == $selected) ? 'selected' : null; + $selected = ((string) $value == (string) $selected) ? 'selected' : null; } $attributes = array('value' => HTML::entities($value), 'selected' => $selected); @@ -499,7 +526,7 @@ protected static function checkable($type, $name, $value, $checked, $attributes) * @param array $attributes * @return string */ - public static function submit($value, $attributes = array()) + public static function submit($value = null, $attributes = array()) { return static::input('submit', null, $value, $attributes); } @@ -511,7 +538,7 @@ public static function submit($value, $attributes = array()) * @param array $attributes * @return string */ - public static function reset($value, $attributes = array()) + public static function reset($value = null, $attributes = array()) { return static::input('reset', null, $value, $attributes); } @@ -543,7 +570,7 @@ public static function image($url, $name = null, $attributes = array()) * @param array $attributes * @return string */ - public static function button($value, $attributes = array()) + public static function button($value = null, $attributes = array()) { return ''; } @@ -580,12 +607,12 @@ protected static function id($name, $attributes) */ public static function __callStatic($method, $parameters) { - if (isset(static::$macros[$method])) - { - return call_user_func_array(static::$macros[$method], $parameters); - } - - throw new \Exception("Method [$method] does not exist."); + if (isset(static::$macros[$method])) + { + return call_user_func_array(static::$macros[$method], $parameters); + } + + throw new \Exception("Method [$method] does not exist."); } } diff --git a/app/laravel/helpers.php b/app/laravel/helpers.php index b04a8c490..513e3baae 100644 --- a/app/laravel/helpers.php +++ b/app/laravel/helpers.php @@ -10,7 +10,7 @@ */ function e($value) { - return Laravel\HTML::entities($value); + return HTML::entities($value); } /** @@ -23,7 +23,21 @@ function e($value) */ function __($key, $replacements = array(), $language = null) { - return Laravel\Lang::line($key, $replacements, $language); + return Lang::line($key, $replacements, $language); +} + +/** + * Dump the given value and kill the script. + * + * @param mixed $value + * @return void + */ +function dd($value) +{ + echo "
"; + var_dump($value); + echo ""; + die; } /** @@ -218,6 +232,62 @@ function array_divide($array) return array(array_keys($array), array_values($array)); } +/** + * Pluck an array of values from an array. + * + * @param array $array + * @param string $key + * @return array + */ +function array_pluck($array, $key) +{ + return array_map(function($v) use ($key) + { + return is_object($v) ? $v->$key : $v[$key]; + + }, $array); +} + +/** + * Get a subset of the items from the given array. + * + * @param array $array + * @param array $keys + * @return array + */ +function array_only($array, $keys) +{ + return array_intersect_key( $array, array_flip((array) $keys) ); +} + +/** + * Get all of the given array except for a specified array of items. + * + * @param array $array + * @param array $keys + * @return array + */ +function array_except($array, $keys) +{ + return array_diff_key( $array, array_flip((array) $keys) ); +} + +/** + * Transform Eloquent models to a JSON object. + * + * @param Eloquent|array $models + * @return object + */ +function eloquent_to_json($models) +{ + if ($models instanceof Laravel\Database\Eloquent\Model) + { + return json_encode($models->to_array()); + } + + return json_encode(array_map(function($m) { return $m->to_array(); }, $models)); +} + /** * Determine if "Magic Quotes" are enabled on the server. * @@ -246,17 +316,17 @@ function head($array) * *
* // Create a URL to a location within the application
- * $url = path('user/profile');
+ * $url = url('user/profile');
*
* // Create a HTTPS URL to a location within the application
- * $url = path('user/profile', true);
+ * $url = url('user/profile', true);
*
*
* @param string $url
* @param bool $https
* @return string
*/
-function url($url = '', $https = false)
+function url($url = '', $https = null)
{
return Laravel\URL::to($url, $https);
}
@@ -268,7 +338,7 @@ function url($url = '', $https = false)
* @param bool $https
* @return string
*/
-function asset($url, $https = false)
+function asset($url, $https = null)
{
return Laravel\URL::to_asset($url, $https);
}
@@ -340,13 +410,18 @@ function ends_with($haystack, $needle)
/**
* Determine if a given string contains a given sub-string.
*
- * @param string $haystack
- * @param string $needle
+ * @param string $haystack
+ * @param string|array $needle
* @return bool
*/
function str_contains($haystack, $needle)
{
- return strpos($haystack, $needle) !== false;
+ foreach ((array) $needle as $n)
+ {
+ if (strpos($haystack, $n) !== false) return true;
+ }
+
+ return false;
}
/**
@@ -361,6 +436,17 @@ function str_finish($value, $cap)
return rtrim($value, $cap).$cap;
}
+/**
+ * Determine if the given object has a toString method.
+ *
+ * @param object $value
+ * @return bool
+ */
+function str_object($value)
+{
+ return is_object($value) and method_exists($value, '__toString');
+}
+
/**
* Get the root namespace of a given class.
*
@@ -379,7 +465,7 @@ function root_namespace($class, $separator = '\\')
/**
* Get the "class basename" of a class or object.
*
- * The basename is considered the name of the class minus all namespaces.
+ * The basename is considered to be the name of the class minus all namespaces.
*
* @param object|string $class
* @return string
@@ -401,7 +487,7 @@ function class_basename($class)
*/
function value($value)
{
- return ($value instanceof Closure) ? call_user_func($value) : $value;
+ return (is_callable($value) and ! is_string($value)) ? call_user_func($value) : $value;
}
/**
@@ -457,7 +543,7 @@ function render($view, $data = array())
/**
* Get the rendered contents of a partial from a loop.
*
- * @param string $view
+ * @param string $partial
* @param array $data
* @param string $iterator
* @param string $empty
@@ -477,4 +563,36 @@ function render_each($partial, array $data, $iterator, $empty = 'raw|')
function yield($section)
{
return Laravel\Section::yield($section);
+}
+
+/**
+ * Get a CLI option from the argv $_SERVER variable.
+ *
+ * @param string $option
+ * @param mixed $default
+ * @return string
+ */
+function get_cli_option($option, $default = null)
+{
+ foreach (Laravel\Request::foundation()->server->get('argv') as $argument)
+ {
+ if (starts_with($argument, "--{$option}="))
+ {
+ return substr($argument, strlen($option) + 3);
+ }
+ }
+
+ return value($default);
+}
+
+/**
+ * Calculate the human-readable file size (with proper units).
+ *
+ * @param int $size
+ * @return string
+ */
+function get_file_size($size)
+{
+ $units = array('Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB');
+ return @round($size / pow(1024, ($i = floor(log($size, 1024)))), 2).' '.$units[$i];
}
\ No newline at end of file
diff --git a/app/laravel/html.php b/app/laravel/html.php
index d1f199aaf..33d91dd65 100644
--- a/app/laravel/html.php
+++ b/app/laravel/html.php
@@ -9,13 +9,13 @@ class HTML {
*/
public static $macros = array();
- /**
- * Registers a custom macro.
- *
- * @param string $name
- * @param Closure $input
- * @return void
- */
+ /**
+ * Registers a custom macro.
+ *
+ * @param string $name
+ * @param Closure $macro
+ * @return void
+ */
public static function macro($name, $macro)
{
static::$macros[$name] = $macro;
@@ -45,6 +45,19 @@ public static function decode($value)
return html_entity_decode($value, ENT_QUOTES, Config::get('application.encoding'));
}
+ /**
+ * Convert HTML special characters.
+ *
+ * The encoding specified in the application configuration file will be used.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function specialchars($value)
+ {
+ return htmlspecialchars($value, ENT_QUOTES, Config::get('application.encoding'), false);
+ }
+
/**
* Generate a link to a JavaScript file.
*
@@ -124,10 +137,12 @@ public static function span($value, $attributes = array())
* @param bool $https
* @return string
*/
- public static function link($url, $title, $attributes = array(), $https = false)
+ public static function link($url, $title = null, $attributes = array(), $https = null)
{
$url = URL::to($url, $https);
+ if (is_null($title)) $title = $url;
+
return ''.static::entities($title).'';
}
@@ -139,7 +154,7 @@ public static function link($url, $title, $attributes = array(), $https = false)
* @param array $attributes
* @return string
*/
- public static function link_to_secure($url, $title, $attributes = array())
+ public static function link_to_secure($url, $title = null, $attributes = array())
{
return static::link($url, $title, $attributes, true);
}
@@ -155,9 +170,11 @@ public static function link_to_secure($url, $title, $attributes = array())
* @param bool $https
* @return string
*/
- public static function link_to_asset($url, $title, $attributes = array(), $https = null)
+ public static function link_to_asset($url, $title = null, $attributes = array(), $https = null)
{
$url = URL::to_asset($url, $https);
+
+ if (is_null($title)) $title = $url;
return ''.static::entities($title).'';
}
@@ -170,7 +187,7 @@ public static function link_to_asset($url, $title, $attributes = array(), $https
* @param array $attributes
* @return string
*/
- public static function link_to_secure_asset($url, $title, $attributes = array())
+ public static function link_to_secure_asset($url, $title = null, $attributes = array())
{
return static::link_to_asset($url, $title, $attributes, true);
}
@@ -194,7 +211,7 @@ public static function link_to_secure_asset($url, $title, $attributes = array())
* @param array $attributes
* @return string
*/
- public static function link_to_route($name, $title, $parameters = array(), $attributes = array())
+ public static function link_to_route($name, $title = null, $parameters = array(), $attributes = array())
{
return static::link(URL::to_route($name, $parameters), $title, $attributes);
}
@@ -218,7 +235,7 @@ public static function link_to_route($name, $title, $parameters = array(), $attr
* @param array $attributes
* @return string
*/
- public static function link_to_action($action, $title, $parameters = array(), $attributes = array())
+ public static function link_to_action($action, $title = null, $parameters = array(), $attributes = array())
{
return static::link(URL::to_action($action, $parameters), $title, $attributes);
}
@@ -306,6 +323,8 @@ private static function listing($type, $list, $attributes = array())
{
$html = '';
+ if (count($list) == 0) return $html;
+
foreach ($list as $key => $value)
{
// If the value is an array, we will recurse the function so that we can
@@ -313,7 +332,14 @@ private static function listing($type, $list, $attributes = array())
// lists may exist within nested lists, etc.
if (is_array($value))
{
- $html .= static::listing($type, $value);
+ if (is_int($key))
+ {
+ $html .= static::listing($type, $value);
+ }
+ else
+ {
+ $html .= '- '.$html.'
+ * // Get the "email" item from the query string
+ * $email = Input::query('email');
+ *
+ * // Return a default value if the specified item doesn't exist
+ * $email = Input::query('name', 'Taylor');
+ *
+ *
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public static function query($key = null, $default = null)
+ {
+ return array_get(Request::foundation()->query->all(), $key, $default);
+ }
+
+ /**
+ * Get the JSON payload for the request.
+ *
+ * @param bool $as_array
+ * @return object
+ */
+ public static function json($as_array = false)
+ {
+ if ( ! is_null(static::$json)) return static::$json;
+
+ return static::$json = json_decode(Request::foundation()->getContent(), $as_array);
}
/**
@@ -77,7 +128,7 @@ public static function get($key = null, $default = null)
*/
public static function only($keys)
{
- return array_intersect_key(static::get(), array_flip((array) $keys));
+ return array_only(static::get(), $keys);
}
/**
@@ -96,7 +147,7 @@ public static function only($keys)
*/
public static function except($keys)
{
- return array_diff_key(static::get(), array_flip($keys));
+ return array_except(static::get(), $keys);
}
/**
@@ -136,39 +187,48 @@ public static function old($key = null, $default = null)
*
* // Get the array of information for the "picture" upload
* $picture = Input::file('picture');
- *
- * // Get a specific element from within the file's data array
- * $size = Input::file('picture.size');
*
*
- * @param string $key
- * @param mixed $default
- * @return array
+ * @param string $key
+ * @param mixed $default
+ * @return UploadedFile
*/
public static function file($key = null, $default = null)
{
return array_get($_FILES, $key, $default);
}
+ /**
+ * Determine if the uploaded data contains a file.
+ *
+ * @param string $key
+ * @return bool
+ */
+ public static function has_file($key)
+ {
+ return strlen(static::file("{$key}.tmp_name", "")) > 0;
+ }
+
/**
* Move an uploaded file to permanent storage.
*
* This method is simply a convenient wrapper around move_uploaded_file.
*
*
- * // Move the "picture" file to a permanent location on disk
- * Input::upload('picture', 'path/to/photos/picture.jpg');
+ * // Move the "picture" file to a new permanent location on disk
+ * Input::upload('picture', 'path/to/photos', 'picture.jpg');
*
*
* @param string $key
- * @param string $path
+ * @param string $directory
+ * @param string $name
* @return bool
*/
- public static function upload($key, $path)
+ public static function upload($key, $directory, $name = null)
{
if (is_null(static::file($key))) return false;
- return move_uploaded_file(static::file("{$key}.tmp_name"), $path);
+ return Request::foundation()->files->get($key)->move($directory, $name);
}
/**
@@ -206,4 +266,35 @@ public static function flush()
Session::flash(Input::old_input, array());
}
+ /**
+ * Merge new input into the current request's input array.
+ *
+ * @param array $input
+ * @return void
+ */
+ public static function merge(array $input)
+ {
+ Request::foundation()->request->add($input);
+ }
+
+ /**
+ * Replace the input for the current request.
+ *
+ * @param array $input
+ * @return void
+ */
+ public static function replace(array $input)
+ {
+ Request::foundation()->request->replace($input);
+ }
+
+ /**
+ * Clear the input for the current request.
+ * @return void
+ */
+ public static function clear()
+ {
+ Request::foundation()->request->replace(array());
+ }
+
}
\ No newline at end of file
diff --git a/app/laravel/ioc.php b/app/laravel/ioc.php
index b02280f9f..4347cbcbe 100644
--- a/app/laravel/ioc.php
+++ b/app/laravel/ioc.php
@@ -20,12 +20,14 @@ class IoC {
* Register an object and its resolver.
*
* @param string $name
- * @param Closure $resolver
+ * @param mixed $resolver
* @param bool $singleton
* @return void
*/
- public static function register($name, Closure $resolver, $singleton = false)
+ public static function register($name, $resolver = null, $singleton = false)
{
+ if (is_null($resolver)) $resolver = $name;
+
static::$registry[$name] = compact('resolver', 'singleton');
}
@@ -49,7 +51,7 @@ public static function registered($name)
* @param Closure $resolver
* @return void
*/
- public static function singleton($name, $resolver)
+ public static function singleton($name, $resolver = null)
{
static::register($name, $resolver, true);
}
@@ -72,70 +74,135 @@ public static function instance($name, $instance)
}
/**
- * Register a controller with the IoC container.
- *
- * @param string $name
- * @param Closure $resolver
- * @return void
- */
- public static function controller($name, $resolver)
- {
- static::register("controller: {$name}", $resolver);
- }
-
- /**
- * Resolve a core Laravel class from the container.
+ * Resolve a given type to an instance.
*
*
- * // Resolve the "laravel.router" class from the container
- * $input = IoC::core('router');
+ * // Get an instance of the "mailer" object registered in the container
+ * $mailer = IoC::resolve('mailer');
*
- * // Equivalent resolution of the router using the "resolve" method
- * $input = IoC::resolve('laravel.router');
+ * // Get an instance of the "mailer" object and pass parameters to the resolver
+ * $mailer = IoC::resolve('mailer', array('test'));
*
*
- * @param string $name
+ * @param string $type
* @param array $parameters
* @return mixed
*/
- public static function core($name, $parameters = array())
+ public static function resolve($type, $parameters = array())
{
- return static::resolve("laravel.{$name}", $parameters);
+ // If an instance of the type is currently being managed as a singleton, we will
+ // just return the existing instance instead of instantiating a fresh instance
+ // so the developer can keep re-using the exact same object instance from us.
+ if (isset(static::$singletons[$type]))
+ {
+ return static::$singletons[$type];
+ }
+
+ // If we don't have a registered resolver or concrete for the type, we'll just
+ // assume the type is the concrete name and will attempt to resolve it as is
+ // since the container should be able to resolve concretes automatically.
+ if ( ! isset(static::$registry[$type]))
+ {
+ $concrete = $type;
+ }
+ else
+ {
+ $concrete = array_get(static::$registry[$type], 'resolver', $type);
+ }
+
+ // We're ready to instantiate an instance of the concrete type registered for
+ // the binding. This will instantiate the type, as well as resolve any of
+ // its nested dependencies recursively until they are each resolved.
+ if ($concrete == $type or $concrete instanceof Closure)
+ {
+ $object = static::build($concrete, $parameters);
+ }
+ else
+ {
+ $object = static::resolve($concrete);
+ }
+
+ // If the requested type is registered as a singleton, we want to cache off
+ // the instance in memory so we can return it later without creating an
+ // entirely new instances of the object on each subsequent request.
+ if (isset(static::$registry[$type]['singleton']) && static::$registry[$type]['singleton'] === true)
+ {
+ static::$singletons[$type] = $object;
+ }
+
+ Event::fire('laravel.resolving', array($type, $object));
+
+ return $object;
}
/**
- * Resolve an object instance from the container.
- *
- *
- * // Get an instance of the "mailer" object registered in the container
- * $mailer = IoC::resolve('mailer');
+ * Instantiate an instance of the given type.
*
- * // Get an instance of the "mailer" object and pass parameters to the resolver
- * $mailer = IoC::resolve('mailer', array('test'));
- *
- *
- * @param string $name
+ * @param string $type
* @param array $parameters
* @return mixed
*/
- public static function resolve($name, $parameters = array())
+ protected static function build($type, $parameters = array())
{
- if (array_key_exists($name, static::$singletons))
+ // If the concrete type is actually a Closure, we will just execute it and
+ // hand back the results of the function, which allows functions to be
+ // used as resolvers for more fine-tuned resolution of the objects.
+ if ($type instanceof Closure)
{
- return static::$singletons[$name];
+ return call_user_func_array($type, $parameters);
}
- $object = call_user_func(static::$registry[$name]['resolver'], $parameters);
+ $reflector = new \ReflectionClass($type);
- // If the resolver is registering as a singleton resolver, we will cache
- // the instance of the object in the container so we can resolve it next
- // time without having to instantiate a brand new instance.
- if (static::$registry[$name]['singleton'])
+ // If the type is not instantiable, the developer is attempting to resolve
+ // an abstract type such as an Interface of an Abstract Class and there is
+ // no binding registered for the abstraction so we need to bail out.
+ if ( ! $reflector->isInstantiable())
{
- return static::$singletons[$name] = $object;
+ throw new \Exception("Resolution target [$type] is not instantiable.");
}
- return $object;
+ $constructor = $reflector->getConstructor();
+
+ // If there is no constructor, that means there are no dependencies and
+ // we can just resolve an instance of the object right away without
+ // resolving any other types or dependencies from the container.
+ if (is_null($constructor))
+ {
+ return new $type;
+ }
+
+ $dependencies = static::dependencies($constructor->getParameters());
+
+ return $reflector->newInstanceArgs($dependencies);
+ }
+
+ /**
+ * Resolve all of the dependencies from the ReflectionParameters.
+ *
+ * @param array $parameters
+ * @return array
+ */
+ protected static function dependencies($parameters)
+ {
+ $dependencies = array();
+
+ foreach ($parameters as $parameter)
+ {
+ $dependency = $parameter->getClass();
+
+ // If the class is null, it means the dependency is a string or some other
+ // primitive type, which we can not resolve since it is not a class and
+ // we'll just bomb out with an error since we have nowhere to go.
+ if (is_null($dependency))
+ {
+ throw new \Exception("Unresolvable dependency resolving [$parameter].");
+ }
+
+ $dependencies[] = static::resolve($dependency->name);
+ }
+
+ return (array) $dependencies;
}
}
\ No newline at end of file
diff --git a/app/laravel/lang.php b/app/laravel/lang.php
index 87be5f3d4..fd3bf1771 100644
--- a/app/laravel/lang.php
+++ b/app/laravel/lang.php
@@ -1,4 +1,4 @@
-key = $key;
$this->language = $language;
- $this->replacements = $replacements;
+ $this->replacements = (array) $replacements;
}
/**
@@ -89,7 +89,7 @@ public static function line($key, $replacements = array(), $language = null)
*/
public static function has($key, $language = null)
{
- return ! is_null(static::line($key, array(), $language)->get());
+ return static::line($key, array(), $language)->get() !== $key;
}
/**
@@ -103,7 +103,7 @@ public static function has($key, $language = null)
* $line = Lang::line('validation.required')->get('sp');
*
* // Return a default value if the line doesn't exist
- * $line = Lang::line('validation.required', null, 'Default');
+ * $line = Lang::line('validation.required')->get(null, 'Default');
*
*
* @param string $language
@@ -112,13 +112,18 @@ public static function has($key, $language = null)
*/
public function get($language = null, $default = null)
{
+ // If no default value is specified by the developer, we'll just return the
+ // key of the language line. This should indicate which language line we
+ // were attempting to render and is better than giving nothing back.
+ if (is_null($default)) $default = $this->key;
+
if (is_null($language)) $language = $this->language;
list($bundle, $file, $line) = $this->parse($this->key);
- // If the file doesn't exist, we'll just return the default value that was
+ // If the file does not exist, we'll just return the default value that was
// given to the method. The default value is also returned even when the
- // file exists and the file does not actually contain any lines.
+ // file exists and that file does not actually contain any lines.
if ( ! static::load($bundle, $language, $file))
{
return value($default);
@@ -129,7 +134,7 @@ public function get($language = null, $default = null)
$line = array_get($lines, $line, $default);
// If the line is not a string, it probably means the developer asked for
- // the entire langauge file and the value of the requested value will be
+ // the entire language file and the value of the requested value will be
// an array containing all of the lines in the file.
if (is_string($line))
{
@@ -244,4 +249,4 @@ public function __toString()
return (string) $this->get();
}
-}
\ No newline at end of file
+}
diff --git a/app/laravel/laravel.php b/app/laravel/laravel.php
index b54ca5706..0b669ae12 100644
--- a/app/laravel/laravel.php
+++ b/app/laravel/laravel.php
@@ -1,5 +1,7 @@
$config)
{
- case 'GET':
- $input = $_GET;
- break;
-
- case 'POST':
- $input = $_POST;
- break;
-
- default:
- if (Request::spoofed())
- {
- $input = $_POST;
- }
- else
- {
- parse_str(file_get_contents('php://input'), $input);
-
- if (magic_quotes()) $input = array_strip_slashes($input);
- }
+ if ($config['auto']) Bundle::start($bundle);
}
/*
|--------------------------------------------------------------------------
-| Remove The Spoofer Input
+| Register The Catch-All Route
|--------------------------------------------------------------------------
|
-| The spoofed request method is removed from the input so it is not in
-| the Input::all() or Input::get() results. Leaving it in the array
-| could cause unexpected results since the developer won't be
-| expecting it to be present.
+| This route will catch all requests that do not hit another route in
+| the application, and will raise the 404 error event so the error
+| can be handled by the developer in their 404 event listener.
|
*/
-unset($input[Request::spoofer]);
-
-Input::$input = $input;
+Router::register('*', '(:all)', function()
+{
+ return Event::first('404');
+});
/*
|--------------------------------------------------------------------------
-| Start The Application Bundle
+| Gather The URI And Locales
|--------------------------------------------------------------------------
|
-| The application "bundle" is the default bundle for the installation and
-| we'll fire it up first. In this bundle's bootstrap, more configuration
-| will take place and the developer can hook into some of the core
-| framework events such as the configuration loader.
+| When routing, we'll need to grab the URI and the supported locales for
+| the route so we can properly set the language and route the request
+| to the proper end-point in the application.
|
*/
-Bundle::start(DEFAULT_BUNDLE);
+$uri = URI::current();
+
+$languages = Config::get('application.languages', array());
+
+$languages[] = Config::get('application.language');
/*
|--------------------------------------------------------------------------
-| Auto-Start Other Bundles
+| Set The Locale Based On The Route
|--------------------------------------------------------------------------
|
-| Bundles that are used throughout the application may be auto-started
-| so they are immediately available on every request without needing
-| to explicitly start them within the application.
+| If the URI starts with one of the supported languages, we will set
+| the default lagnauge to match that URI segment and shorten the
+| URI we'll pass to the router to not include the lang segment.
|
*/
-foreach (Bundle::$bundles as $bundle => $config)
+foreach ($languages as $language)
{
- if ($config['auto']) Bundle::start($bundle);
+ if (preg_match("#^{$language}(?:$|/)#i", $uri))
+ {
+ Config::set('application.language', $language);
+
+ $uri = trim(substr($uri, strlen($language)), '/'); break;
+ }
}
-/*
-|--------------------------------------------------------------------------
-| Register The Catch-All Route
-|--------------------------------------------------------------------------
-|
-| This route will catch all requests that do not hit another route in
-| the application, and will raise the 404 error event so the error
-| can be handled by the developer in their 404 event listener.
-|
-*/
+if ($uri == '') $uri = '/';
-Routing\Router::register('*', '(:all)', function()
-{
- return Event::first('404');
-});
+URI::$uri = $uri;
/*
|--------------------------------------------------------------------------
@@ -186,40 +162,38 @@
|
*/
-$uri = URI::current();
-
-Request::$route = Routing\Router::route(Request::method(), $uri);
+Request::$route = Router::route(Request::method(), $uri);
$response = Request::$route->call();
/*
|--------------------------------------------------------------------------
-| Persist The Session To Storage
+| "Render" The Response
|--------------------------------------------------------------------------
|
-| If a session driver has been configured, we will save the session to
-| storage so it is avaiable for the next request. This will also set
-| the session cookie in the cookie jar to be sent to the user.
+| The render method evaluates the content of the response and converts it
+| to a string. This evaluates any views and sub-responses within the
+| content and sets the raw string result as the new response.
|
*/
-if (Config::get('session.driver') !== '')
-{
- Session::save();
-}
+$response->render();
/*
|--------------------------------------------------------------------------
-| Let's Eat Cookies
+| Persist The Session To Storage
|--------------------------------------------------------------------------
|
-| All cookies set during the request are actually stored in a cookie jar
-| until the end of the request so they can be expected by unit tests or
-| the developer. Here, we'll push them out to the browser.
+| If a session driver has been configured, we will save the session to
+| storage so it is available for the next request. This will also set
+| the session cookie in the cookie jar to be sent to the user.
|
*/
-Cookie::send();
+if (Config::get('session.driver') !== '')
+{
+ Session::save();
+}
/*
|--------------------------------------------------------------------------
@@ -240,10 +214,24 @@
| And We're Done!
|--------------------------------------------------------------------------
|
-| Raise the "done" event so extra output can be attached to the response
+| Raise the "done" event so extra output can be attached to the response.
| This allows the adding of debug toolbars, etc. to the view, or may be
| used to do some kind of logging by the application.
|
*/
-Event::fire('laravel.done', array($response));
\ No newline at end of file
+Event::fire('laravel.done', array($response));
+
+/*
+|--------------------------------------------------------------------------
+| Finish the request for PHP-FastCGI
+|--------------------------------------------------------------------------
+|
+| Stopping the PHP process for PHP-FastCGI users to speed up some
+| PHP queries. Acceleration is possible when there are actions in the
+| process of script execution that do not affect server response.
+| For example, saving the session in memcached can occur after the page
+| has been formed and passed to a web server.
+*/
+
+$response->foundation->finish();
diff --git a/app/laravel/log.php b/app/laravel/log.php
index 4cd3a30e6..f2b2b3f89 100644
--- a/app/laravel/log.php
+++ b/app/laravel/log.php
@@ -28,7 +28,7 @@ protected static function exception_line($e)
* Write a message to the log file.
*
*
- * // Write an "error" messge to the log file
+ * // Write an "error" message to the log file
* Log::write('error', 'Something went horribly wrong!');
*
* // Write an "error" message using the class' magic method
@@ -49,22 +49,17 @@ public static function write($type, $message)
Event::fire('laravel.log', array($type, $message));
}
- // If there aren't listeners on the log event, we'll just write to the
- // log files using the default conventions, writing one log file per
- // day so they files don't get too crowded.
- else
- {
- $message = static::format($type, $message);
+ $message = static::format($type, $message);
- File::append(path('storage').'logs/'.date('Y-m-d').'.log', $message);
- }
+ File::append(path('storage').'logs/'.date('Y-m-d').'.log', $message);
}
/**
* Format a log message for logging.
*
* @param string $type
- * @param
+ * @param string $message
+ * @return string
*/
protected static function format($type, $message)
{
diff --git a/app/laravel/memcached.php b/app/laravel/memcached.php
index 548e29841..d66710bb6 100644
--- a/app/laravel/memcached.php
+++ b/app/laravel/memcached.php
@@ -35,16 +35,16 @@ public static function connection()
/**
* Create a new Memcached connection instance.
*
- * @param array $servers
+ * @param array $servers
* @return Memcached
*/
protected static function connect($servers)
{
- $memcache = new \Memcache;
+ $memcache = new \Memcached;
foreach ($servers as $server)
{
- $memcache->addServer($server['host'], $server['port'], true, $server['weight']);
+ $memcache->addServer($server['host'], $server['port'], $server['weight']);
}
if ($memcache->getVersion() === false)
@@ -68,7 +68,7 @@ protected static function connect($servers)
*/
public static function __callStatic($method, $parameters)
{
- return call_user_func_array(array(static::instance(), $method), $parameters);
+ return call_user_func_array(array(static::connection(), $method), $parameters);
}
}
\ No newline at end of file
diff --git a/app/laravel/messages.php b/app/laravel/messages.php
index 5ca75a6a1..bf5d61c3b 100644
--- a/app/laravel/messages.php
+++ b/app/laravel/messages.php
@@ -9,6 +9,13 @@ class Messages {
*/
public $messages;
+ /**
+ * Default format for message output.
+ *
+ * @var string
+ */
+ public $format = ':message';
+
/**
* Create a new Messages instance.
*
@@ -68,6 +75,21 @@ public function has($key = null)
return $this->first($key) !== '';
}
+ /**
+ * Set the default message format for output.
+ *
+ *
+ * // Apply a new default format.
+ * $messages->format('email', 'this is my :message
');
+ *
+ *
+ * @param string $format
+ */
+ public function format($format = ':message')
+ {
+ $this->format = $format;
+ }
+
/**
* Get the first message from the container for a given key.
*
@@ -86,8 +108,10 @@ public function has($key = null)
* @param string $format
* @return string
*/
- public function first($key = null, $format = ':message')
+ public function first($key = null, $format = null)
{
+ $format = ($format === null) ? $this->format : $format;
+
$messages = is_null($key) ? $this->all($format) : $this->get($key, $format);
return (count($messages) > 0) ? $messages[0] : '';
@@ -108,11 +132,13 @@ public function first($key = null, $format = ':message')
* @param string $format
* @return array
*/
- public function get($key, $format = ':message')
+ public function get($key, $format = null)
{
+ $format = ($format === null) ? $this->format : $format;
+
if (array_key_exists($key, $this->messages))
{
- return $this->format($this->messages[$key], $format);
+ return $this->transform($this->messages[$key], $format);
}
return array();
@@ -132,13 +158,15 @@ public function get($key, $format = ':message')
* @param string $format
* @return array
*/
- public function all($format = ':message')
+ public function all($format = null)
{
+ $format = ($format === null) ? $this->format : $format;
+
$all = array();
foreach ($this->messages as $messages)
{
- $all = array_merge($all, $this->format($messages, $format));
+ $all = array_merge($all, $this->transform($messages, $format));
}
return $all;
@@ -151,7 +179,7 @@ public function all($format = ':message')
* @param string $format
* @return array
*/
- protected function format($messages, $format)
+ protected function transform($messages, $format)
{
$messages = (array) $messages;
diff --git a/app/laravel/paginator.php b/app/laravel/paginator.php
index ceffbe85b..e9b95e359 100644
--- a/app/laravel/paginator.php
+++ b/app/laravel/paginator.php
@@ -47,7 +47,7 @@ class Paginator {
/**
* The compiled appendage that will be appended to the links.
*
- * This consists of a sprintf format with a page place-holder and query string.
+ * This consists of a sprintf format with a page place-holder and query string.
*
* @var string
*/
@@ -65,7 +65,7 @@ class Paginator {
*
* @var string
*/
- protected $dots = '...';
+ protected $dots = '... ';
/**
* Create a new Paginator instance.
@@ -183,7 +183,7 @@ public function links($adjacent = 3)
$links = $this->slider($adjacent);
}
- $content = $this->previous().' '.$links.' '.$this->next();
+ $content = '' . $this->previous() . $links . $this->next() . '
';
return ''.$content.'';
}
@@ -300,7 +300,7 @@ protected function element($element, $page, $text, $disabled)
// the "first" element should be a span instead of a link.
if ($disabled($this->page, $this->last))
{
- return HTML::span($text, array('class' => "{$class} disabled"));
+ return '"{$class} disabled")).'>'.$text.' ';
}
else
{
@@ -349,7 +349,7 @@ protected function range($start, $end)
{
if ($this->page == $page)
{
- $pages[] = HTML::span($page, array('class' => 'current'));
+ $pages[] = ''.$page.' ';
}
else
{
@@ -372,7 +372,7 @@ protected function link($page, $text, $class)
{
$query = '?page='.$page.$this->appendage($this->appends);
- return HTML::link(URI::current().$query, $text, compact('class'), Request::secure());
+ return ' $class)).'>'. HTML::link(URI::current().$query, $text, array(), Request::secure()).' ';
}
/**
diff --git a/app/laravel/pluralizer.php b/app/laravel/pluralizer.php
index 857a7ff56..2ce72f0ba 100644
--- a/app/laravel/pluralizer.php
+++ b/app/laravel/pluralizer.php
@@ -24,6 +24,7 @@ class Pluralizer {
/**
* Create a new pluralizer instance.
*
+ * @param array $config
* @return void
*/
public function __construct($config)
@@ -48,7 +49,7 @@ public function singular($value)
}
// English words may be automatically inflected using regular expressions.
- // If the word is english, we'll just pass off the word to the automatic
+ // If the word is English, we'll just pass off the word to the automatic
// inflection method and return the result, which is cached.
$irregular = $this->config['irregular'];
@@ -77,7 +78,7 @@ public function plural($value, $count = 2)
}
// English words may be automatically inflected using regular expressions.
- // If the word is english, we'll just pass off the word to the automatic
+ // If the word is English, we'll just pass off the word to the automatic
// inflection method and return the result, which is cached.
$irregular = array_flip($this->config['irregular']);
@@ -104,7 +105,7 @@ protected function auto($value, $source, $irregular)
return $value;
}
- // Next we will check the "irregular" patterns, which contains words
+ // Next, we will check the "irregular" patterns, which contain words
// like "children" and "teeth" which can not be inflected using the
// typically used regular expression matching approach.
foreach ($irregular as $irregular => $pattern)
diff --git a/app/laravel/profiling/profiler.css b/app/laravel/profiling/profiler.css
new file mode 100755
index 000000000..63fc7658f
--- /dev/null
+++ b/app/laravel/profiling/profiler.css
@@ -0,0 +1,225 @@
+.anbu
+{
+ font-family:Helvetica, "Helvetica Neue", Arial, sans-serif !important;
+ font-size:14px !important;
+ background-color:#222 !important;
+ position:fixed !important;
+ bottom:0 !important;
+ right:0 !important;
+ width:100%;
+ z-index: 9999 !important;
+}
+
+.anbu-tabs
+{
+ margin:0 !important;
+ padding:0 !important;
+ overflow:hidden !important;
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAAtCAYAAADxwQZkAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9wEBBI7MaEE338AAAsjSURBVGje1Zp/sB51dcY/z713NwGjBhIJSSDASFKhaRTEUXahpChRI/AurUkHsFScprX8tBimTQMFR0upYAajMA7WsdRqqlDdJXQ0thNEsksFLCaBisYSiIRfhiQVUpLdJE//2H1v3oT35t7k3k5vduad98fud3fPc55zznPOviqTSEIhIEMfZhxigszRxlMkvQWYZDxJaCJwlM1RkseDnrF9eZgVqziEN5VJfJbgTuAtwBEDHLfLUAlK6lcF9ACTgBU2l4RZ/tKhCkIf9tkWM0AINoKfAu0wvCLYBLxs+JXgZeNNQpua98lACrxf+Nwqib4apIUPSSZUrXgmYi02FstAfxam+YuDLaySuMdwveBG4GnsM/rOnLJRC+855EDoMX4SezkCWXOwp3QY2nVR2YoI0ny3YBmwxnA80kItvIdygDWjGgRgJ2KpEcYTJF1UtqIxBoI0704fCer9Pwd/XVBhrq6S+B1hmg8I3qgFIcwKsNYK7hfC5gpJE7WfRUGaUyURAEZ3AqvBAr7CfsAbzUwgyPIXgW8gkBhruNyzZ+93YZAWAIRpvtVwO9I24NQqiS875MKhg7qrjB8DEHxy55vL8fvLC51bmOZ/D/5J83VxmcRHDnXtqAChTd0gzZ8UfL9tF/AXQzlBOyywrjHsACbJfKodFmV7///hNtxr9NTZvu0xfdv2hubzZWUrOjIYJNEFaUHZigmy/GGZu4BexO9VSXQGjQwdUYNbURcmFp37jyiTaHrZiqIqiT9UJfEJg4slIMz62fBwmcQPAcdYvBFYBFzrwQxpWyquMySCyZg/rVrRY0FWbCtbcf81hgfA3uepkmia0TTMNOBYwbEWU4FjJKYZHyX0o7IVXRxmxX9VSdw1aasT4TArKFvR+5C+IxiH/UuLd4dp8fxghlStiCArqJL4Y8ZfEdoOXBikeTrCTJCkpcBJ4CNtJjT9zWF1tQLBL+uKxQvgjxj9h+CsIM13dgOip59SWdF+/zfZq5vyd7TQZXuhNVBYNOsNKdYqYCzmmiqJJ44kCGFWGDMXeK/h7aAdmPuAxcAHBb+BfbrtS4CP23xacDrwNQB3oXXP3gkmbvPjs2AkAvC5ZSuaGmSDiyC3IsI034y4GYPhTONW2Yp6qpFMkPJ828h6QfKVQZbPB/7WZkWQ5j8PsmJjmBVbgjTfFWbFTcB9wPyyFf1lmBWvU7U9+5S6drK7F7TONblOQvrwUESQGjYICsSyhpy3Co4M0oKqFY9AJYgJ0uLHSNdZngK6qmzFE2uDc3dzqs2HgQ2IxWUSz2nb2b6fni6NUZvWNzQ/jQHOK1vR0Z0LB84NMUGab7G5S2iTYLzRZxpRNvxwSHOq82OEbxN6EJiLWFAmcW+3Y8skJszyEvNB1Z3y7VUSn9i+n6oVvR6Efm/b/yT0jDGCsySdNSRD1O4v+D5iefP5T6okfs+ICageCNJiG7AQ2Cz4K8Fvd3NS2Ej8IMufBBbYPhFYUiXxEe0b7RmgTa4TEP50u5QaX1S24jcPdn9Bg36Q5jZeavs522B/oWpFPUGad631B7J1hOUjhpuBseDbqlZ0VLfc1Zb4tpdJusXmPGBhlcS9QZp3B2HPRXSf0AYwQucjThmijG6LmJ9I+rrEbkvvtPhkZxc6XNEUpLkxX8b+LmYWYkk7CXQTWGFW2OYGxLeAPzfM75oT+jP93Hdh/LLxHe6vv74a6K2G4MmODHwj6AXZElpQJfH0kWBDWGsSwizfarjO6CXQxVUrvirIir2kdLv8V0l0DPgC2ROMezF3lEk8a1CXVEl8Cma58dTGg7OCNF87tL6iFiZlK7qw6VKN9aUwy0ek02wLvKZ/uEboFsOvhWcHabG6bEWHS5wNmlPrCk9uhspjgd56mqafDQWEMcCtwBXNT1mQ5smB3nCVxAW1aHnW8Idhmq8c6UaqSuL7gdnUivFp8HtAQZdDt2KvNKRCqQbrzsK0oEqiua6bo4k1G3xykBY/be8fYqc3S2h1Ha3+muDyIC1eGQqTuoRaoLp0Hwa8FXgvMMfmVMS4DqN2AdttSsQz2N+VtDxI84e69g6D1P43NOLnPOrpUxpm+QVD9lBdtoT4ou3LJO0GkiDNl+9rtO1+inf83gdMAMbbTJV4N3BG83pTfzKUSmAT9uFI420eQf6S0IogzTcOBLCGGtdVEl+KWYoYZ7uSOC1IizUDeWuAJmu60QOIyYKHgA8Fab5lgOtOAabZPl7SSYZTgVNlT0FqGw2wCfyUzXpJa5qyOQtzK+LHgnlBmq/fH7P6hupN429Kuhp4u0QvaFHTJR6A5ucpweeBm8GnY11C/Z2m0ZppmCl4GzDdMB3pBGwk4focBtYirQGvAX4KejLM8l90AJgjvxN0oeFzVSu6KMiK7QMOjodK51pixtcabpLos/0cUitM80c7s/T+2uymTE0C3W04E3uzpFuBd2COd/1E62iJMW564uYGXzY8iL1K9Yj/WcTzYVps3U/lmAl8EzhZ0vVBmn9moPvUgZSiMonHCJ4FTwTZ5o4wy68YKKF2GcWd0pSrjwEzXHv4tc5ZQO11AD1qewVopeR1hleFXgnSfOe+472gc7LUce06hL0UcbjN2WFWPNAtJA5YulWt6EZLN9QxyRNCFwdpvrrT2x20nGGYI3i/zemSx9n0IPWpJrYRat42A98z3Cv4gfFWWTuRdwVDrEDdJlBVEv+D7Y9I+hUwI0jz/24z+6BBKFvRGyRtsR2otmMR8FlEH/XzyXME52DONkzcQ2m3L7cLswuxsxEtPTY/C7P8bSOsGdoJ/Y3Ao8AM4F+DNJ+zb4j2HOiJw6zYZlgq1dZJulRwj9AvZJ4WfBl7PuoEgFdBzxseB76K+H3wccb/2TRy06okvnIkQWgPiIM0fwV7AfA/ht8pW/Gi9iSsLf91kCgfY1gv3FdXqravTc0OdgqeA54H1hn+XbAqSPPV+7DqAkn/DJbR44IPBGm+sVtojQAjFtm+CelF1VXt/vb+noM5qWGj4K/duLFB4CWhH9r+O+FrgUuBuUGa/0GY5re3AejsQsOs+A5mZe0LnwT88R4vjdCDG/cz428kfUv2JNufqpJo6kHnhI7kMw6cIKZhXgTWS1pvsyHM8l37y+D7VJzfFDzeiJ+nDL8bDpBoD8xZEaC9KkHVit+FvAoUGj6HvTjMih3DbuzLVtQTZsXu14/ozGBZvYOqnwdfVUtyL5FYHKTF9uHQv+O7gHNt5gmfhnQiENTF2Odj/qXvIA3v79P3BWAoA9l+pjbDD+MlQpcYxku6EvOPwGMH6vkgLfqvXSbxKYIFhrnYEyQOA/V2XHu3JA8rHEa4nPUBnzC+pf57gO+VNC9I8/IAnTNF0keBjwLTuxyyG1gHfAFYFqT55lEDQgPEW4EUe6brEdwHgjRf0fFk63U0t32YpCMw51j8kSB2u8+o3214DfMq8nKsO8Msf7hz+iWPIhAawz5hswQsSeuxTw6yvXNDlURvsjVZ8m8ZzQOfDxqrPTwHaQf2c6AnkL+N9Y0gy3cMlDf6RonxBGmO4W6JeaDI+ARJi4Hrm3A5GTMLmC08x3Cs3LixEaO2NwitNaxCui9M88cHmVYzqsKhA5AF4NuMDhdss32zpOOaUdnMLul1O+iHxg/IPIT0SJDmr3abQw7yqOT/f9szyot7gZXGZ8pS5x26f5wggCfA9xh+IFgXpMXGznNpH41wSIDQWeaqVnya8Y8k9fSPdCyQfy10N/guW+sktgTpnlgfxgOt0bQ1fw3M8kcRC4Bdxq8B35OYJ+s42x+3eTDM8hfaAAz37zr/C3vl1F5cIAPZAAAAAElFTkSuQmCC);
+ background-repeat:no-repeat;
+ background-position:5px -8px;
+}
+
+.anbu-tab {
+ cursor: pointer;
+}
+
+.anbu-hidden .anbu-tabs
+{
+ background-image:none;
+}
+
+#anbu-open-tabs li:first-child
+{
+ margin-left:6em;
+}
+
+.anbu-tabs li
+{
+ display:inline;
+ line-height:1em !important;
+}
+
+.anbu-tabs a, .anbu-tabs a:visited
+{
+ color:#aaa !important;
+ text-transform:uppercase !important;
+ font-weight:bold !important;
+ display:inline-block;
+ text-decoration:none !important;
+ font-size:0.8em !important;
+ padding: 0.8em 2em 0.7em 2em !important;
+ -webkit-transition-property:color, background-color;
+ -webkit-transition-duration: 0.7s, 0.2s;
+ -webkit-transition-timing-function: ease-in, ease-in;
+ -moz-transition-property:color, background-color;
+ -moz-transition-duration: 0.7s, 0.2s;
+ -moz-transition-timing-function: ease-in, ease-in;
+ -ms-transition-property:color, background-color;
+ -ms-transition-duration: 0.7s, 0.2s;
+ -ms-transition-timing-function: ease-in, ease-in;
+ -o-transition-property:color, background-color;
+ -o-transition-duration: 0.7s, 0.2s;
+ -o-transition-timing-function: ease-in, ease-in;
+ transition-property:color, background-color;
+ transition-duration: 0.7s, 0.2s;
+ transition-timing-function: ease-in, ease-in;
+}
+
+#anbu-closed-tabs a, #anbu-closed-tabs a:visited
+{
+ padding: 0.85em 1.2em 0.85em 1.2em !important;
+}
+
+.anbu-tabs a:hover
+{
+ background-color:#333 !important;
+ color:#fff !important;
+}
+
+.anbu-tabs a.anbu-active-tab
+{
+ color:#fff !important;
+ background-color:#333 !important;
+}
+
+.anbu a:focus
+{
+ outline:none !important;
+}
+
+.anbu-tabs a:active
+{
+ background-color:#111 !important;
+}
+
+.anbu-tabs li.anbu-tab-right
+{
+ float:right !important;
+}
+
+.anbu-tabs li.anbu-tab-right a, .anbu-tabs li.anbu-tab-right a:visited
+{
+ padding: 0.86em 2em 0.7em 2em !important;
+}
+
+#anbu-closed-tabs
+{
+ display:none;
+}
+
+
+.anbu-window
+{
+ display:none;
+}
+
+.anbu-content-area
+{
+ background-color: #fff !important;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#eeeeee), to(#ffffff));
+ background-image: -webkit-linear-gradient(top, #eeeeee, #ffffff);
+ background-image: -moz-linear-gradient(top, #eeeeee, #ffffff);
+ background-image: -ms-linear-gradient(top, #eeeeee, #ffffff);
+ background-image: -o-linear-gradient(top, #eeeeee, #ffffff);
+ background-image: linear-gradient(to bottom, #eeeeee, #ffffff);
+ height:14em;
+ margin-top:6px !important;
+ overflow-x:hidden !important;
+ overflow-y:auto !important;
+}
+
+.anbu-table table
+{
+ margin:0 !important;
+ padding:0 !important;
+ font-size:0.9em !important;
+ border:0 !important;
+ border-collapse:collapse !important;
+ width:100% !important;
+ background-color:#fff !important;
+}
+
+.anbu-table pre
+{
+ margin:0 !important;
+}
+
+.anbu-table tr
+{
+ border-bottom:1px solid #ccc !important;
+}
+
+.anbu-table tr:first-child
+{
+ border:0 !important;
+}
+
+.anbu-table th
+{
+ background-color:#555 !important;
+ color:#fff !important;
+ text-transform:uppercase !important;
+}
+
+.anbu-table th, .anbu-table td
+{
+ text-align:left !important;
+ padding:0.4em 1em !important;
+ margin:0 !important;
+}
+
+.anbu-table td
+{
+ vertical-align:top !important;
+}
+
+.anbu-table-first
+{
+ background-color:#eee !important;
+ border-right:1px solid #ccc !important;
+ width:10% !important;
+}
+
+span.anbu-count
+{
+ text-transform: none !important;
+ margin-left:0.5em !important;
+ background-color:#555 !important;
+ display:inline-block !important;
+ padding:0.1em 0.5em 0.2em 0.5em !important;
+ color:#eee !important;
+ text-shadow:0 0 4px #000 !important;
+ -webkit-border-radius: 1px;
+ -moz-border-radius: 1px;
+ border-radius: 1px;
+ -moz-background-clip: padding; -webkit-background-clip: padding-box; background-clip: padding-box;
+
+}
+
+.anbu-empty
+{
+ display:block !important;
+ padding:1em !important;
+ text-align:center !important;
+ font-style:italic !important;
+ color:#ccc !important;
+ margin:1em !important;
+ text-shadow:0 1px 0px #fff !important;
+}
+
+.anbu pre
+{
+ overflow-x: auto;
+ white-space: pre-wrap;
+ white-space: -moz-pre-wrap !important;
+ white-space: -pre-wrap;
+ white-space: -o-pre-wrap;
+ word-wrap: break-word;
+}
+
+/* hide panel-open elements, will become visible through anbu.start() */
+
+#anbu-close, #anbu-zoom, .anbu-tab-pane {
+ visibility: hidden;
+}
diff --git a/app/laravel/profiling/profiler.js b/app/laravel/profiling/profiler.js
new file mode 100755
index 000000000..8fc9fe3e6
--- /dev/null
+++ b/app/laravel/profiling/profiler.js
@@ -0,0 +1,194 @@
+var anbu = {
+
+ // BOUND ELEMENTS
+ // -------------------------------------------------------------
+ // Binding these elements early, stops jQuery from "querying"
+ // the DOM every time they are used.
+
+ el: {
+ main: jQuery('.anbu'),
+ close: jQuery('#anbu-close'),
+ zoom: jQuery('#anbu-zoom'),
+ hide: jQuery('#anbu-hide'),
+ show: jQuery('#anbu-show'),
+ tab_pane: jQuery('.anbu-tab-pane'),
+ hidden_tab_pane: jQuery('.anbu-tab-pane:visible'),
+ tab: jQuery('.anbu-tab'),
+ tabs: jQuery('.anbu-tabs'),
+ tab_links: jQuery('.anbu-tabs a'),
+ window: jQuery('.anbu-window'),
+ closed_tabs: jQuery('#anbu-closed-tabs'),
+ open_tabs: jQuery('#anbu-open-tabs'),
+ content_area: jQuery('.anbu-content-area')
+ },
+
+ // CLASS ATTRIBUTES
+ // -------------------------------------------------------------
+ // Useful variable for Anbu.
+
+ // is anbu in full screen mode
+ is_zoomed: false,
+
+ // initial height of content area
+ small_height: jQuery('.anbu-content-area').height(),
+
+ // the name of the active tab css
+ active_tab: 'anbu-active-tab',
+
+ // the data attribute of the tab link
+ tab_data: 'data-anbu-tab',
+
+ // size of anbu when compact
+ mini_button_width: '2.6em',
+
+ // is the top window open?
+ window_open: false,
+
+ // current active pane
+ active_pane: '',
+
+ // START()
+ // -------------------------------------------------------------
+ // Sets up all the binds for Anbu!
+
+ start: function() {
+
+ // hide initial elements
+ anbu.el.close.css('visibility', 'visible').hide();
+ anbu.el.zoom.css('visibility', 'visible').hide();
+ anbu.el.tab_pane.css('visibility', 'visible').hide();
+
+ // bind all click events
+ anbu.el.close.click(function(event) {
+ anbu.close_window();
+ event.preventDefault();
+ });
+ anbu.el.hide.click(function(event) {
+ anbu.hide();
+ event.preventDefault();
+ });
+ anbu.el.show.click(function(event) {
+ anbu.show();
+ event.preventDefault();
+ });
+ anbu.el.zoom.click(function(event) {
+ anbu.zoom();
+ event.preventDefault();
+ });
+ anbu.el.tab.click(function(event) {
+ anbu.clicked_tab(jQuery(this));
+ event.preventDefault();
+ });
+
+ },
+
+ // CLICKED_TAB()
+ // -------------------------------------------------------------
+ // A tab has been clicked, decide what to do.
+
+ clicked_tab: function(tab) {
+
+ // if the tab is closed
+ if (anbu.window_open && anbu.active_pane == tab.attr(anbu.tab_data)) {
+ anbu.close_window();
+ } else {
+ anbu.open_window(tab);
+ }
+
+ },
+
+ // OPEN_WINDOW()
+ // -------------------------------------------------------------
+ // Animate open the top window to the appropriate tab.
+
+ open_window: function(tab) {
+
+ // can't directly assign this line, but it works
+ jQuery('.anbu-tab-pane:visible').fadeOut(200);
+ jQuery('.' + tab.attr(anbu.tab_data)).delay(220).fadeIn(300);
+ anbu.el.tab_links.removeClass(anbu.active_tab);
+ tab.addClass(anbu.active_tab);
+ anbu.el.window.slideDown(300);
+ anbu.el.close.fadeIn(300);
+ anbu.el.zoom.fadeIn(300);
+ anbu.active_pane = tab.attr(anbu.tab_data);
+ anbu.window_open = true;
+
+ },
+
+ // CLOSE_WINDOW()
+ // -------------------------------------------------------------
+ // Animate closed the top window hiding all tabs.
+
+ close_window: function() {
+
+ anbu.el.tab_pane.fadeOut(100);
+ anbu.el.window.slideUp(300);
+ anbu.el.close.fadeOut(300);
+ anbu.el.zoom.fadeOut(300);
+ anbu.el.tab_links.removeClass(anbu.active_tab);
+ anbu.active_pane = '';
+ anbu.window_open = false;
+
+ },
+
+ // SHOW()
+ // -------------------------------------------------------------
+ // Show the Anbu toolbar when it has been compacted.
+
+ show: function() {
+
+ anbu.el.closed_tabs.fadeOut(600, function () {
+ anbu.el.main.removeClass('anbu-hidden');
+ anbu.el.open_tabs.fadeIn(200);
+ });
+ anbu.el.main.animate({width: '100%'}, 700);
+
+ },
+
+ // HIDE()
+ // -------------------------------------------------------------
+ // Hide the anbu toolbar, show a tiny re-open button.
+
+ hide: function() {
+
+ anbu.close_window();
+
+ setTimeout(function() {
+ anbu.el.window.slideUp(400, function () {
+ anbu.close_window();
+ anbu.el.main.addClass('anbu-hidden');
+ anbu.el.open_tabs.fadeOut(200, function () {
+ anbu.el.closed_tabs.fadeIn(200);
+ });
+ anbu.el.main.animate({width: anbu.mini_button_width}, 700);
+ });
+ }, 100);
+
+ },
+
+ // TOGGLEZOOM()
+ // -------------------------------------------------------------
+ // Toggle the zoomed mode of the top window.
+
+ zoom: function() {
+
+ if (anbu.is_zoomed) {
+ height = anbu.small_height;
+ anbu.is_zoomed = false;
+ } else {
+ // the 6px is padding on the top of the window
+ height = (jQuery(window).height() - anbu.el.tabs.height() - 6) + 'px';
+ anbu.is_zoomed = true;
+ }
+
+ anbu.el.content_area.animate({height: height}, 700);
+
+ }
+
+};
+
+// launch anbu on jquery dom ready
+jQuery(document).ready(function() {
+ anbu.start();
+});
\ No newline at end of file
diff --git a/app/laravel/profiling/profiler.php b/app/laravel/profiling/profiler.php
new file mode 100644
index 000000000..a26396eeb
--- /dev/null
+++ b/app/laravel/profiling/profiler.php
@@ -0,0 +1,186 @@
+ array(), 'logs' => array(), 'timers' => array());
+
+ /**
+ * Get the rendered contents of the Profiler.
+ *
+ * @param Response $response
+ * @return string
+ */
+ public static function render($response)
+ {
+ // We only want to send the profiler toolbar if the request is not an AJAX
+ // request, as sending it on AJAX requests could mess up JSON driven API
+ // type applications, so we will not send anything in those scenarios.
+ if ( ! Request::ajax() and Config::get('application.profiler') )
+ {
+ static::$data['memory'] = get_file_size(memory_get_usage(true));
+ static::$data['memory_peak'] = get_file_size(memory_get_peak_usage(true));
+ static::$data['time'] = number_format((microtime(true) - LARAVEL_START) * 1000, 2);
+ foreach ( static::$data['timers'] as &$timer)
+ {
+ $timer['running_time'] = number_format((microtime(true) - $timer['start'] ) * 1000, 2);
+ }
+
+ return render('path: '.__DIR__.'/template'.BLADE_EXT, static::$data);
+ }
+ }
+
+ /**
+ * Allow a callback to be timed.
+ *
+ * @param closure $func
+ * @param string $name
+ * @return void
+ */
+ public static function time( $func, $name = 'default_func_timer' )
+ {
+ // First measure the runtime of the func
+ $start = microtime(true);
+ $func();
+ $end = microtime(true);
+
+ // Check to see if a timer by that name exists
+ if (isset(static::$data['timers'][$name]))
+ {
+ $name = $name.uniqid();
+ }
+
+ // Push the time into the timers array for display
+ static::$data['timers'][$name]['start'] = $start;
+ static::$data['timers'][$name]['end'] = $end;
+ static::$data['timers'][$name]['time'] = number_format(($end - $start) * 1000, 2);
+ }
+
+ /**
+ * Start, or add a tick to a timer.
+ *
+ * @param string $name
+ * @return void
+ */
+ public static function tick($name = 'default_timer', $callback = null)
+ {
+ $name = trim($name);
+ if (empty($name)) $name = 'default_timer';
+
+ // Is this a brand new tick?
+ if (isset(static::$data['timers'][$name]))
+ {
+ $current_timer = static::$data['timers'][$name];
+ $ticks = count($current_timer['ticks']);
+
+ // Initialize the new time for the tick
+ $new_tick = array();
+ $mt = microtime(true);
+ $new_tick['raw_time'] = $mt - $current_timer['start'];
+ $new_tick['time'] = number_format(($mt - $current_timer['start']) * 1000, 2);
+
+ // Use either the start time or the last tick for the diff
+ if ($ticks > 0)
+ {
+ $last_tick = $current_timer['ticks'][$ticks- 1]['raw_time'];
+ $new_tick['diff'] = number_format(($new_tick['raw_time'] - $last_tick) * 1000, 2);
+ }
+ else
+ {
+ $new_tick['diff'] = $new_tick['time'];
+ }
+
+ // Add the new tick to the stack of them
+ static::$data['timers'][$name]['ticks'][] = $new_tick;
+ }
+ else
+ {
+ // Initialize a start time on the first tick
+ static::$data['timers'][$name]['start'] = microtime(true);
+ static::$data['timers'][$name]['ticks'] = array();
+ }
+
+ // Run the callback for this tick if it's specified
+ if ( ! is_null($callback) and is_callable($callback))
+ {
+ // After we've ticked, call the callback function
+ call_user_func_array($callback, array(
+ static::$data['timers'][$name]
+ ));
+ }
+ }
+
+ /**
+ * Add a log entry to the log entries array.
+ *
+ * @param string $type
+ * @param string $message
+ * @return void
+ */
+ public static function log($type, $message)
+ {
+ static::$data['logs'][] = array($type, $message);
+ }
+
+ /**
+ * Add a performed SQL query to the Profiler.
+ *
+ * @param string $sql
+ * @param array $bindings
+ * @param float $time
+ * @return void
+ */
+ public static function query($sql, $bindings, $time)
+ {
+ foreach ($bindings as $binding)
+ {
+ $binding = Database::connection()->pdo->quote($binding);
+
+ $sql = preg_replace('/\?/', $binding, $sql, 1);
+ $sql = htmlspecialchars($sql);
+ }
+
+ static::$data['queries'][] = array($sql, $time);
+ }
+
+ /**
+ * Attach the Profiler's event listeners.
+ *
+ * @return void
+ */
+ public static function attach()
+ {
+ // First we'll attach to the query and log events. These allow us to catch
+ // all of the SQL queries and log messages that come through Laravel,
+ // and we will pass them onto the Profiler for simple storage.
+ Event::listen('laravel.log', function($type, $message)
+ {
+ Profiler::log($type, $message);
+ });
+
+ Event::listen('laravel.query', function($sql, $bindings, $time)
+ {
+ Profiler::query($sql, $bindings, $time);
+ });
+
+ // We'll attach the profiler to the "done" event so that we can easily
+ // attach the profiler output to the end of the output sent to the
+ // browser. This will display the profiler's nice toolbar.
+ Event::listen('laravel.done', function($response)
+ {
+ echo Profiler::render($response);
+ });
+ }
+
+}
diff --git a/app/laravel/profiling/template.blade.php b/app/laravel/profiling/template.blade.php
new file mode 100755
index 000000000..9c855b43e
--- /dev/null
+++ b/app/laravel/profiling/template.blade.php
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+ @if (count($logs) > 0)
+
+
+ Type
+ Message
+
+ @foreach ($logs as $log)
+
+
+ {{ $log[0] }}
+
+
+ {{ $log[1] }}
+
+ @endforeach
+
+
+ @else
+ There are no log entries.
+ @endif
+
+
+
+ @if (count($queries) > 0)
+
+
+ Time
+ Query
+
+ @foreach ($queries as $query)
+
+
+ {{ $query[1] }}ms
+
+
+ {{ $query[0] }}
+
+
+ @endforeach
+
+ @else
+ There have been no SQL queries executed.
+ @endif
+
+
+
+ @if (count($timers) > 0)
+
+
+ Name
+ Running Time (ms)
+ Difference
+
+ @foreach ($timers as $name => $timer)
+
+
+ {{ $name }}
+
+ {{ $timer['running_time'] }}ms (time from start to render)
+
+
+
+ @if (isset($timer['ticks']))
+ @foreach( $timer['ticks'] as $tick)
+
+
+ Tick
+
+
+ {{ $tick['time'] }}ms
+
+
+ + {{ $tick['diff'] }}ms
+
+
+ @endforeach
+ @else
+
+ Running Time
+ {{ $timer['time'] }}ms
+
+
+ @endif
+
+ @endforeach
+
+ @else
+ There have been no checkpoints set.
+ @endif
+
+
+
+
+
+ - Log {{ count($logs) }}
+ -
+ SQL
+ {{ count($queries) }}
+ @if (count($queries))
+ {{ array_sum(array_map(function($q) { return $q[1]; }, $queries)) }}ms
+ @endif
+
+
+ - Time {{ $time }}ms
+ - Memory {{ $memory }} ({{ $memory_peak }})
+ - ↦
+ - ×
+ - ⇅
+
+
+
+ - ↤
+
+
+
+
+
+
diff --git a/app/laravel/redirect.php b/app/laravel/redirect.php
index 2678f4458..874cb1726 100644
--- a/app/laravel/redirect.php
+++ b/app/laravel/redirect.php
@@ -6,10 +6,10 @@ class Redirect extends Response {
* Create a redirect response to application root.
*
* @param int $status
- * @param bool $secure
+ * @param bool $https
* @return Redirect
*/
- public static function home($status = 302, $https = false)
+ public static function home($status = 302, $https = null)
{
return static::to(URL::home($https), $status);
}
@@ -41,7 +41,7 @@ public static function back($status = 302)
* @param bool $https
* @return Redirect
*/
- public static function to($url, $status = 302, $https = false)
+ public static function to($url, $status = 302, $https = null)
{
return static::make('', $status)->header('Location', URL::to($url, $https));
}
@@ -165,4 +165,23 @@ public function with_errors($container)
return $this->with('errors', $errors);
}
+ /**
+ * Send the headers and content of the response to the browser.
+ *
+ * @return void
+ */
+ public function send()
+ {
+ // Dump all output buffering, this ensures
+ // that symphony will send our redirect headers
+ // properly if we've outputted any content from
+ // within Laravel.
+ while (ob_get_level() > 0)
+ {
+ ob_end_clean();
+ }
+
+ return parent::send();
+ }
+
}
\ No newline at end of file
diff --git a/app/laravel/redis.php b/app/laravel/redis.php
index d00b2f528..02267d322 100644
--- a/app/laravel/redis.php
+++ b/app/laravel/redis.php
@@ -17,7 +17,7 @@ class Redis {
protected $port;
/**
- * The databse number the connection selects on load.
+ * The database number the connection selects on load.
*
* @var int
*/
diff --git a/app/laravel/request.php b/app/laravel/request.php
index 59d0ec7e7..29340d71c 100644
--- a/app/laravel/request.php
+++ b/app/laravel/request.php
@@ -1,4 +1,4 @@
-getMethod();
- return (static::spoofed()) ? $_POST[Request::spoofer] : $_SERVER['REQUEST_METHOD'];
+ return ($method == 'HEAD') ? 'GET' : $method;
+ }
+
+ /**
+ * Get a header from the request.
+ *
+ *
+ * // Get a header from the request
+ * $referer = Request::header('referer');
+ *
+ *
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public static function header($key, $default = null)
+ {
+ return array_get(static::foundation()->headers->all(), $key, $default);
+ }
+
+ /**
+ * Get all of the HTTP request headers.
+ *
+ * @return array
+ */
+ public static function headers()
+ {
+ return static::foundation()->headers->all();
}
/**
@@ -50,7 +81,7 @@ public static function method()
*/
public static function server($key = null, $default = null)
{
- return array_get($_SERVER, strtoupper($key), $default);
+ return array_get(static::foundation()->server->all(), strtoupper($key), $default);
}
/**
@@ -60,7 +91,7 @@ public static function server($key = null, $default = null)
*/
public static function spoofed()
{
- return is_array($_POST) and array_key_exists(Request::spoofer, $_POST);
+ return ! is_null(static::foundation()->get(Request::spoofer));
}
/**
@@ -71,30 +102,39 @@ public static function spoofed()
*/
public static function ip($default = '0.0.0.0')
{
- if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
- {
- return $_SERVER['HTTP_X_FORWARDED_FOR'];
- }
- elseif (isset($_SERVER['HTTP_CLIENT_IP']))
- {
- return $_SERVER['HTTP_CLIENT_IP'];
- }
- elseif (isset($_SERVER['REMOTE_ADDR']))
- {
- return $_SERVER['REMOTE_ADDR'];
- }
+ $client_ip = static::foundation()->getClientIp();
+ return $client_ip === NULL ? $default : $client_ip;
+ }
- return value($default);
+ /**
+ * Get the list of acceptable content types for the request.
+ *
+ * @return array
+ */
+ public static function accept()
+ {
+ return static::foundation()->getAcceptableContentTypes();
}
/**
- * Get the HTTP protocol for the request.
+ * Determine if the request accepts a given content type.
*
- * @return string
+ * @param string $type
+ * @return bool
+ */
+ public static function accepts($type)
+ {
+ return in_array($type, static::accept());
+ }
+
+ /**
+ * Get the languages accepted by the client's browser.
+ *
+ * @return array
*/
- public static function protocol()
+ public static function languages()
{
- return array_get($_SERVER, 'SERVER_PROTOCOL', 'HTTP/1.1');
+ return static::foundation()->getLanguages();
}
/**
@@ -104,7 +144,7 @@ public static function protocol()
*/
public static function secure()
{
- return isset($_SERVER['HTTPS']) and strtolower($_SERVER['HTTPS']) !== 'off';
+ return static::foundation()->isSecure() and Config::get('application.ssl');
}
/**
@@ -126,9 +166,7 @@ public static function forged()
*/
public static function ajax()
{
- if ( ! isset($_SERVER['HTTP_X_REQUESTED_WITH'])) return false;
-
- return strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
+ return static::foundation()->isXmlHttpRequest();
}
/**
@@ -138,7 +176,17 @@ public static function ajax()
*/
public static function referrer()
{
- return array_get($_SERVER, 'HTTP_REFERER');
+ return static::foundation()->headers->get('referer');
+ }
+
+ /**
+ * Get the timestamp of the time when the request was started.
+ *
+ * @return int
+ */
+ public static function time()
+ {
+ return (int) LARAVEL_START;
}
/**
@@ -158,7 +206,18 @@ public static function cli()
*/
public static function env()
{
- if (isset($_SERVER['LARAVEL_ENV'])) return $_SERVER['LARAVEL_ENV'];
+ return static::foundation()->server->get('LARAVEL_ENV');
+ }
+
+ /**
+ * Set the Laravel environment for the current request.
+ *
+ * @param string $env
+ * @return void
+ */
+ public static function set_env($env)
+ {
+ static::foundation()->server->set('LARAVEL_ENV', $env);
}
/**
@@ -172,6 +231,30 @@ public static function is_env($env)
return static::env() === $env;
}
+ /**
+ * Detect the current environment from an environment configuration.
+ *
+ * @param array $environments
+ * @param string $uri
+ * @return string|null
+ */
+ public static function detect_env(array $environments, $uri)
+ {
+ foreach ($environments as $environment => $patterns)
+ {
+ // Essentially we just want to loop through each environment pattern
+ // and determine if the current URI matches the pattern and if so
+ // we will simply return the environment for that URI pattern.
+ foreach ($patterns as $pattern)
+ {
+ if (Str::is($pattern, $uri) or $pattern == gethostname())
+ {
+ return $environment;
+ }
+ }
+ }
+ }
+
/**
* Get the main route handling the request.
*
@@ -182,4 +265,26 @@ public static function route()
return static::$route;
}
+ /**
+ * Get the Symfony HttpFoundation Request instance.
+ *
+ * @return HttpFoundation\Request
+ */
+ public static function foundation()
+ {
+ return static::$foundation;
+ }
+
+ /**
+ * Pass any other methods to the Symfony request.
+ *
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public static function __callStatic($method, $parameters)
+ {
+ return call_user_func_array(array(static::foundation(), $method), $parameters);
+ }
+
}
\ No newline at end of file
diff --git a/app/laravel/response.php b/app/laravel/response.php
index c98414037..ccd53e1fb 100644
--- a/app/laravel/response.php
+++ b/app/laravel/response.php
@@ -1,5 +1,8 @@
'Continue',
- 101 => 'Switching Protocols',
- 200 => 'OK',
- 201 => 'Created',
- 202 => 'Accepted',
- 203 => 'Non-Authoritative Information',
- 204 => 'No Content',
- 205 => 'Reset Content',
- 206 => 'Partial Content',
- 207 => 'Multi-Status',
- 300 => 'Multiple Choices',
- 301 => 'Moved Permanently',
- 302 => 'Found',
- 303 => 'See Other',
- 304 => 'Not Modified',
- 305 => 'Use Proxy',
- 307 => 'Temporary Redirect',
- 400 => 'Bad Request',
- 401 => 'Unauthorized',
- 402 => 'Payment Required',
- 403 => 'Forbidden',
- 404 => 'Not Found',
- 405 => 'Method Not Allowed',
- 406 => 'Not Acceptable',
- 407 => 'Proxy Authentication Required',
- 408 => 'Request Timeout',
- 409 => 'Conflict',
- 410 => 'Gone',
- 411 => 'Length Required',
- 412 => 'Precondition Failed',
- 413 => 'Request Entity Too Large',
- 414 => 'Request-URI Too Long',
- 415 => 'Unsupported Media Type',
- 416 => 'Requested Range Not Satisfiable',
- 417 => 'Expectation Failed',
- 422 => 'Unprocessable Entity',
- 423 => 'Locked',
- 424 => 'Failed Dependency',
- 500 => 'Internal Server Error',
- 501 => 'Not Implemented',
- 502 => 'Bad Gateway',
- 503 => 'Service Unavailable',
- 504 => 'Gateway Timeout',
- 505 => 'HTTP Version Not Supported',
- 507 => 'Insufficient Storage',
- 509 => 'Bandwidth Limit Exceeded'
- );
+ public $foundation;
/**
* Create a new response instance.
@@ -87,9 +29,9 @@ class Response {
*/
public function __construct($content, $status = 200, $headers = array())
{
- $this->status = $status;
$this->content = $content;
- $this->headers = array_change_key_case($headers);
+
+ $this->foundation = new FoundationResponse('', $status, $headers);
}
/**
@@ -136,6 +78,46 @@ public static function view($view, $data = array())
return new static(View::make($view, $data));
}
+ /**
+ * Create a new JSON response.
+ *
+ *
+ * // Create a response instance with JSON
+ * return Response::json($data, 200, array('header' => 'value'));
+ *
+ *
+ * @param mixed $data
+ * @param int $status
+ * @param array $headers
+ * @return Response
+ */
+ public static function json($data, $status = 200, $headers = array())
+ {
+ $headers['Content-Type'] = 'application/json; charset=utf-8';
+
+ return new static(json_encode($data), $status, $headers);
+ }
+
+ /**
+ * Create a new response of JSON'd Eloquent models.
+ *
+ *
+ * // Create a new response instance with Eloquent models
+ * return Response::eloquent($data, 200, array('header' => 'value'));
+ *
+ *
+ * @param Eloquent|array $data
+ * @param int $status
+ * @param array $headers
+ * @return Response
+ */
+ public static function eloquent($data, $status = 200, $headers = array())
+ {
+ $headers['Content-Type'] = 'application/json; charset=utf-8';
+
+ return new static(eloquent_to_json($data), $status, $headers);
+ }
+
/**
* Create a new error response instance.
*
@@ -180,48 +162,75 @@ public static function download($path, $name = null, $headers = array())
{
if (is_null($name)) $name = basename($path);
+ // We'll set some sensible default headers, but merge the array given to
+ // us so that the developer has the chance to override any of these
+ // default headers with header values of their own liking.
$headers = array_merge(array(
- 'content-description' => 'File Transfer',
- 'content-type' => File::mime(File::extension($path)),
- 'content-disposition' => 'attachment; filename="'.$name.'"',
- 'content-transfer-encoding' => 'binary',
- 'expires' => 0,
- 'cache-control' => 'must-revalidate, post-check=0, pre-check=0',
- 'pragma' => 'public',
- 'content-length' => File::size($path),
+ 'Content-Description' => 'File Transfer',
+ 'Content-Type' => File::mime(File::extension($path)),
+ 'Content-Transfer-Encoding' => 'binary',
+ 'Expires' => 0,
+ 'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
+ 'Pragma' => 'public',
+ 'Content-Length' => File::size($path),
), $headers);
- return new static(File::get($path), 200, $headers);
+ // Once we create the response, we need to set the content disposition
+ // header on the response based on the file's name. We'll pass this
+ // off to the HttpFoundation and let it create the header text.
+ $response = new static(File::get($path), 200, $headers);
+
+ $d = $response->disposition($name);
+
+ return $response->header('Content-Disposition', $d);
}
/**
- * Prepare a response from the given value.
+ * Create the proper Content-Disposition header.
*
- * If the value is not a response, it will be converted into a response
- * instance and the content will be cast to a string.
+ * @param string $file
+ * @return string
+ */
+ public function disposition($file)
+ {
+ $type = ResponseHeaderBag::DISPOSITION_ATTACHMENT;
+
+ return $this->foundation->headers->makeDisposition($type, $file);
+ }
+
+ /**
+ * Prepare a response from the given value.
*
* @param mixed $response
* @return Response
*/
public static function prepare($response)
{
+ // We will need to force the response to be a string before closing
+ // the session since the developer may be utilizing the session
+ // within the view, and we can't age it until rendering.
if ( ! $response instanceof Response)
{
$response = new static($response);
}
- // We'll need to force the response to be a string before closing the session,
- // since the developer may be using the session within a view, and we can't
- // age the flash data until the view is rendered.
- //
- // Since this method is used by both the Route and Controller classes, it is
- // a convenient spot to cast the application response to a string before it
- // is returned to the main request handler.
- $response->render();
-
return $response;
}
+ /**
+ * Send the headers and content of the response to the browser.
+ *
+ * @return void
+ */
+ public function send()
+ {
+ $this->cookies();
+
+ $this->foundation->prepare(Request::foundation());
+
+ $this->foundation->send();
+ }
+
/**
* Convert the content of the Response to a string and return it.
*
@@ -229,7 +238,10 @@ public static function prepare($response)
*/
public function render()
{
- if (is_object($this->content) and method_exists($this->content, '__toString'))
+ // If the content is a stringable object, we'll go ahead and call
+ // the toString method so that we can get the string content of
+ // the content object. Otherwise we'll just cast to string.
+ if (str_object($this->content))
{
$this->content = $this->content->__toString();
}
@@ -238,96 +250,98 @@ public function render()
$this->content = (string) $this->content;
}
+ // Once we obtain the string content, we can set the content on
+ // the HttpFoundation's Response instance in preparation for
+ // sending it back to client browser when all is finished.
+ $this->foundation->setContent($this->content);
+
return $this->content;
}
/**
- * Send the headers and content of the response to the browser.
+ * Send all of the response headers to the browser.
*
* @return void
*/
- public function send()
+ public function send_headers()
{
- if ( ! headers_sent()) $this->send_headers();
+ $this->foundation->prepare(Request::foundation());
- echo (string) $this->content;
+ $this->foundation->sendHeaders();
}
/**
- * Send all of the response headers to the browser.
+ * Set the cookies on the HttpFoundation Response.
*
* @return void
*/
- public function send_headers()
+ protected function cookies()
{
- // If the server is using FastCGI, we need to send a slightly different
- // protocol and status header than we normally would. Otherwise it will
- // not call any custom scripts setup to handle 404 responses.
- //
- // The status header will contain both the code and the status message,
- // such as "OK" or "Not Found". For typical servers, the HTTP protocol
- // will also be included with the status.
- if (isset($_SERVER['FCGI_SERVER_VERSION']))
- {
- header('Status: '.$this->status.' '.$this->message());
- }
- else
- {
- header(Request::protocol().' '.$this->status.' '.$this->message());
- }
+ $ref = new \ReflectionClass('Symfony\Component\HttpFoundation\Cookie');
- // If the content type was not set by the developer, we will set the
- // header to a default value that indicates to the browser that the
- // response is HTML and that it uses the default encoding.
- if ( ! isset($this->headers['content-type']))
+ // All of the cookies for the response are actually stored on the
+ // Cookie class until we're ready to send the response back to
+ // the browser. This allows our cookies to be set easily.
+ foreach (Cookie::$jar as $name => $cookie)
{
- $encoding = Config::get('application.encoding');
+ $config = array_values($cookie);
- $this->header('content-type', 'text/html; charset='.$encoding);
+ $this->headers()->setCookie($ref->newInstanceArgs($config));
}
+ }
- // Once the framework controlled headers have been sentm, we can
- // simply iterate over the developer's headers and send each one
- // back to the browser for the response.
- foreach ($this->headers as $name => $value)
- {
- header("{$name}: {$value}", true);
- }
+ /**
+ * Add a header to the array of response headers.
+ *
+ * @param string $name
+ * @param string $value
+ * @return Response
+ */
+ public function header($name, $value)
+ {
+ $this->foundation->headers->set($name, $value);
+
+ return $this;
}
/**
- * Get the status code message for the response.
+ * Get the HttpFoundation Response headers.
*
- * @return string
+ * @return ResponseParameterBag
*/
- public function message()
+ public function headers()
{
- return static::$statuses[$this->status];
+ return $this->foundation->headers;
}
/**
- * Add a header to the array of response headers.
+ * Get / set the response status code.
*
- * @param string $name
- * @param string $value
- * @return Response
+ * @param int $status
+ * @return mixed
*/
- public function header($name, $value)
+ public function status($status = null)
{
- $this->headers[strtolower($name)] = $value;
- return $this;
+ if (is_null($status))
+ {
+ return $this->foundation->getStatusCode();
+ }
+ else
+ {
+ $this->foundation->setStatusCode($status);
+
+ return $this;
+ }
}
/**
- * Set the response status code.
+ * Render the response when cast to string
*
- * @param int $status
- * @return Response
+ * @return string
*/
- public function status($status)
+ public function __toString()
{
- $this->status = $status;
- return $this;
+ return $this->render();
}
}
\ No newline at end of file
diff --git a/app/laravel/routing/controller.php b/app/laravel/routing/controller.php
index f75ef4b8a..e81d6b5f3 100644
--- a/app/laravel/routing/controller.php
+++ b/app/laravel/routing/controller.php
@@ -140,9 +140,19 @@ public static function call($destination, $parameters = array())
// improve speed since the bundle is not loaded on every request.
Bundle::start($bundle);
- list($controller, $method) = explode('@', $destination);
+ list($name, $method) = explode('@', $destination);
- $controller = static::resolve($bundle, $controller);
+ $controller = static::resolve($bundle, $name);
+
+ // For convenience we will set the current controller and action on the
+ // Request's route instance so they can be easily accessed from the
+ // application. This is sometimes useful for dynamic situations.
+ if ( ! is_null($route = Request::route()))
+ {
+ $route->controller = $name;
+
+ $route->controller_action = $method;
+ }
// If the controller could not be resolved, we're out of options and
// will return the 404 error response. If we found the controller,
@@ -169,6 +179,8 @@ protected static function references(&$destination, &$parameters)
// controllers with much less code than would be usual.
foreach ($parameters as $key => $value)
{
+ if ( ! is_string($value)) continue;
+
$search = '(:'.($key + 1).')';
$destination = str_replace($search, $value, $destination, $count);
diff --git a/app/laravel/routing/filter.php b/app/laravel/routing/filter.php
index 14b6e2e33..80beec939 100644
--- a/app/laravel/routing/filter.php
+++ b/app/laravel/routing/filter.php
@@ -14,7 +14,7 @@ class Filter {
public static $filters = array();
/**
- * The route filters that are based on pattern.
+ * The route filters that are based on a pattern.
*
* @var array
*/
diff --git a/app/laravel/routing/route.php b/app/laravel/routing/route.php
index 6349a0e84..090aa59ea 100644
--- a/app/laravel/routing/route.php
+++ b/app/laravel/routing/route.php
@@ -1,6 +1,7 @@
parameters($uri, $action, $parameters);
+ // are needed, we'll merge in the defaults.
+ $this->parameters($action, $parameters);
}
/**
* Set the parameters array to the correct value.
*
- * @param string $uri
* @param array $action
* @param array $parameters
* @return void
*/
- protected function parameters($uri, $action, $parameters)
+ protected function parameters($action, $parameters)
{
$defaults = (array) array_get($action, 'defaults');
// If there are less parameters than wildcards, we will figure out how
// many parameters we need to inject from the array of defaults and
- // merge them in into the main array for the route.
+ // merge them into the main array for the route.
if (count($defaults) > count($parameters))
{
$defaults = array_slice($defaults, count($parameters));
@@ -113,7 +126,7 @@ public function call()
// We always return a Response instance from the route calls, so
// we'll use the prepare method on the Response class to make
- // sure we have a valid Response isntance.
+ // sure we have a valid Response instance.
$response = Response::prepare($response);
Filter::run($this->filters('after'), array($response));
@@ -198,8 +211,17 @@ protected function patterns()
// if they match we'll attach the filter.
foreach (Filter::$patterns as $pattern => $filter)
{
- if (URI::is($pattern, $this->uri))
+ if (Str::is($pattern, $this->uri))
{
+ // If the filter provided is an array then we need to register
+ // the filter before we can assign it to the route.
+ if (is_array($filter))
+ {
+ list($filter, $callback) = array_values($filter);
+
+ Filter::register($filter, $callback);
+ }
+
$filters[] = $filter;
}
}
@@ -251,7 +273,7 @@ public function is($name)
/**
* Register a controller with the router.
*
- * @param string|array $controller
+ * @param string|array $controllers
* @param string|array $defaults
* @return void
*/
@@ -393,4 +415,4 @@ public static function forward($method, $uri)
return Router::route(strtoupper($method), $uri)->call();
}
-}
\ No newline at end of file
+}
diff --git a/app/laravel/routing/router.php b/app/laravel/routing/router.php
index a6577b3f6..e9935e4c4 100644
--- a/app/laravel/routing/router.php
+++ b/app/laravel/routing/router.php
@@ -55,7 +55,7 @@ class Router {
public static $group;
/**
- * The "handes" clause for the bundle currently being routed.
+ * The "handles" clause for the bundle currently being routed.
*
* @var string
*/
@@ -75,7 +75,7 @@ class Router {
*/
public static $patterns = array(
'(:num)' => '([0-9]+)',
- '(:any)' => '([a-zA-Z0-9\.\-_%]+)',
+ '(:any)' => '([a-zA-Z0-9\.\-_%=]+)',
'(:all)' => '(.*)',
);
@@ -86,7 +86,7 @@ class Router {
*/
public static $optional = array(
'/(:num?)' => '(?:/([0-9]+)',
- '/(:any?)' => '(?:/([a-zA-Z0-9\.\-_%]+)',
+ '/(:any?)' => '(?:/([a-zA-Z0-9\.\-_%=]+)',
'/(:all?)' => '(?:/(.*)',
);
@@ -119,7 +119,7 @@ public static function secure($method, $route, $action)
*
*
* // Register a group of URIs for an action
- * Router::share(array('GET', '/'), array('POST', '/'), 'home@index');
+ * Router::share(array(array('GET', '/'), array('POST', '/')), 'home@index');
*
*
* @param array $routes
@@ -174,6 +174,8 @@ public static function group($attributes, Closure $callback)
*/
public static function register($method, $route, $action)
{
+ if (ctype_digit($route)) $route = "({$route})";
+
if (is_string($route)) $route = explode(', ', $route);
// If the developer is registering multiple request methods to handle
@@ -204,7 +206,12 @@ public static function register($method, $route, $action)
continue;
}
- $uri = str_replace('(:bundle)', static::$bundle, $uri);
+ $uri = ltrim(str_replace('(:bundle)', static::$bundle, $uri), '/');
+
+ if($uri == '')
+ {
+ $uri = '/';
+ }
// If the URI begins with a wildcard, we want to add this route to the
// array of "fallback" routes. Fallback routes are always processed
@@ -290,18 +297,18 @@ public static function secure_controller($controllers, $defaults = 'index')
/**
* Register a controller with the router.
*
- * @param string|array $controller
+ * @param string|array $controllers
* @param string|array $defaults
* @param bool $https
* @return void
*/
- public static function controller($controllers, $defaults = 'index', $https = false)
+ public static function controller($controllers, $defaults = 'index', $https = null)
{
foreach ((array) $controllers as $identifier)
{
list($bundle, $controller) = Bundle::parse($identifier);
- // First we need to replace the dots with slashes in thte controller name
+ // First we need to replace the dots with slashes in the controller name
// so that it is in directory format. The dots allow the developer to use
// a cleaner syntax when specifying the controller. We will also grab the
// root URI for the controller's bundle.
@@ -309,7 +316,7 @@ public static function controller($controllers, $defaults = 'index', $https = fa
$root = Bundle::option($bundle, 'handles');
- // If the controller is a "home" controller, we'll need to also build a
+ // If the controller is a "home" controller, we'll need to also build an
// index method route for the controller. We'll remove "home" from the
// route root and setup a route to point to the index method.
if (ends_with($controller, 'home'))
@@ -426,7 +433,7 @@ public static function uses($action)
// To find the route, we'll simply spin through the routes looking
// for a route with a "uses" key matching the action, and if we
- // find one we cache and return it.
+ // find one, we cache and return it.
foreach (static::routes() as $method => $routes)
{
foreach ($routes as $key => $value)
@@ -482,7 +489,7 @@ protected static function match($method, $uri)
{
foreach (static::method($method) as $route => $action)
{
- // We only need to check routes with regular expression since all other
+ // We only need to check routes with regular expression since all others
// would have been able to be matched by the search for literal matches
// we just did before we started searching.
if (str_contains($route, '('))
diff --git a/app/laravel/section.php b/app/laravel/section.php
index ff12889f2..9638880ce 100644
--- a/app/laravel/section.php
+++ b/app/laravel/section.php
@@ -39,7 +39,7 @@ public static function start($section, $content = '')
}
else
{
- static::append($section, $content);
+ static::extend($section, $content);
}
}
@@ -79,19 +79,19 @@ public static function yield_section()
*/
public static function stop()
{
- static::append($last = array_pop(static::$last), ob_get_clean());
+ static::extend($last = array_pop(static::$last), ob_get_clean());
return $last;
}
/**
- * Append content to a given section.
+ * Extend the content in a given section.
*
* @param string $section
* @param string $content
* @return void
*/
- protected static function append($section, $content)
+ protected static function extend($section, $content)
{
if (isset(static::$sections[$section]))
{
@@ -103,6 +103,25 @@ protected static function append($section, $content)
}
}
+ /**
+ * Append content to a given section.
+ *
+ * @param string $section
+ * @param string $content
+ * @return void
+ */
+ public static function append($section, $content)
+ {
+ if (isset(static::$sections[$section]))
+ {
+ static::$sections[$section] .= $content;
+ }
+ else
+ {
+ static::$sections[$section] = $content;
+ }
+ }
+
/**
* Get the string contents of a section.
*
diff --git a/app/laravel/session.php b/app/laravel/session.php
index bdc549a55..877b5a454 100644
--- a/app/laravel/session.php
+++ b/app/laravel/session.php
@@ -1,4 +1,4 @@
-cookie($config);
- // Some session drivers implement the Sweeper interface, meaning that
- // they must clean up expired sessions manually. If the driver is a
- // sweeper, we need to determine if garbage collection should be
- // run for the request.
+ // Some session drivers implement the Sweeper interface meaning that
+ // they must clean up expired sessions manually. Here we'll calculate
+ // if we need to run garbage collection.
$sweepage = $config['sweepage'];
- if ($this->driver instanceof Sweeper and (mt_rand(1, $sweepage[1]) <= $sweepage[0]))
+ if (mt_rand(1, $sweepage[1]) <= $sweepage[0])
{
- $this->driver->sweep(time() - ($config['lifetime'] * 60));
+ $this->sweep();
+ }
+ }
+
+ /**
+ * Clean up expired sessions.
+ *
+ * If the session driver is a sweeper, it must clean up expired sessions
+ * from time to time. This method triggers garbage collection.
+ *
+ * @return void
+ */
+ public function sweep()
+ {
+ if ($this->driver instanceof Sweeper)
+ {
+ $this->driver->sweep(time() - (Config::get('session.lifetime') * 60));
}
}
diff --git a/app/laravel/str.php b/app/laravel/str.php
index 78a554edf..681300420 100644
--- a/app/laravel/str.php
+++ b/app/laravel/str.php
@@ -9,17 +9,22 @@ class Str {
*/
public static $pluralizer;
- /**
- * Get the default string encoding for the application.
- *
- * This method is simply a short-cut to Config::get('application.encoding').
- *
- * @return string
- */
- public static function encoding()
- {
- return Config::get('application.encoding');
- }
+ /**
+ * Cache application encoding locally to save expensive calls to Config::get().
+ *
+ * @var string
+ */
+ public static $encoding = null;
+
+ /**
+ * Get the appliction.encoding without needing to request it from Config::get() each time.
+ *
+ * @return string
+ */
+ protected static function encoding()
+ {
+ return static::$encoding ?: static::$encoding = Config::get('application.encoding');
+ }
/**
* Get the length of a string.
@@ -130,6 +135,31 @@ public static function limit($value, $limit = 100, $end = '...')
return substr($value, 0, $limit).$end;
}
+ /**
+ * Limit the number of chracters in a string including custom ending
+ *
+ *
+ * // Returns "Taylor..."
+ * echo Str::limit_exact('Taylor Otwell', 9);
+ *
+ * // Limit the number of characters and append a custom ending
+ * echo Str::limit_exact('Taylor Otwell', 9, '---');
+ *
+ *
+ * @param string $value
+ * @param int $limit
+ * @param string $end
+ * @return string
+ */
+ public static function limit_exact($value, $limit = 100, $end = '...')
+ {
+ if (static::length($value) <= $limit) return $value;
+
+ $limit -= static::length($end);
+
+ return static::limit($value, $limit, $end);
+ }
+
/**
* Limit the number of words in a string.
*
@@ -148,7 +178,9 @@ public static function limit($value, $limit = 100, $end = '...')
*/
public static function words($value, $words = 100, $end = '...')
{
- preg_match('/^\s*+(?:\S++\s*+){1,'.$words.'}/', $value, $matches);
+ if (trim($value) == '') return '';
+
+ preg_match('/^\s*+(?:\S++\s*+){1,'.$words.'}/u', $value, $matches);
if (static::length($value) == static::length($matches[0]))
{
@@ -300,6 +332,30 @@ public static function random($length, $type = 'alnum')
return substr(str_shuffle(str_repeat(static::pool($type), 5)), 0, $length);
}
+ /**
+ * Determine if a given string matches a given pattern.
+ *
+ * @param string $pattern
+ * @param string $value
+ * @return bool
+ */
+ public static function is($pattern, $value)
+ {
+ // Asterisks are translated into zero-or-more regular expression wildcards
+ // to make it convenient to check if the URI starts with a given pattern
+ // such as "library/*". This is only done when not root.
+ if ($pattern !== '/')
+ {
+ $pattern = str_replace('*', '(.*)', $pattern).'\z';
+ }
+ else
+ {
+ $pattern = '^/$';
+ }
+
+ return preg_match('#'.$pattern.'#', $value);
+ }
+
/**
* Get the character pool for a given type of random string.
*
diff --git a/app/laravel/tests/application/bundles.php b/app/laravel/tests/application/bundles.php
new file mode 100644
index 000000000..1013f0cf8
--- /dev/null
+++ b/app/laravel/tests/application/bundles.php
@@ -0,0 +1,36 @@
+ array(
+| 'location' => 'admin',
+| 'handles' => 'admin',
+| ),
+|
+| Note that the "location" is relative to the "bundles" directory.
+| Now the bundle will be recognized by Laravel and will be able
+| to respond to requests beginning with "admin"!
+|
+| Have a bundle that lives in the root of the bundle directory
+| and doesn't respond to any requests? Just add the bundle
+| name to the array and we'll take care of the rest.
+|
+*/
+
+return array('dashboard' => array('handles' => 'dashboard'), 'dummy');
\ No newline at end of file
diff --git a/app/laravel/tests/application/config/application.php b/app/laravel/tests/application/config/application.php
new file mode 100644
index 000000000..596baa245
--- /dev/null
+++ b/app/laravel/tests/application/config/application.php
@@ -0,0 +1,158 @@
+ '',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Application Index
+ |--------------------------------------------------------------------------
+ |
+ | If you are including the "index.php" in your URLs, you can ignore this.
+ |
+ | However, if you are using mod_rewrite to get cleaner URLs, just set
+ | this option to an empty string and we'll take care of the rest.
+ |
+ */
+
+ 'index' => 'index.php',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Application Key
+ |--------------------------------------------------------------------------
+ |
+ | This key is used by the encryption and cookie classes to generate secure
+ | encrypted strings and hashes. It is extremely important that this key
+ | remain secret and should not be shared with anyone. Make it about 32
+ | characters of random gibberish.
+ |
+ */
+
+ 'key' => '',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Application Character Encoding
+ |--------------------------------------------------------------------------
+ |
+ | The default character encoding used by your application. This encoding
+ | will be used by the Str, Text, Form, and any other classes that need
+ | to know what type of encoding to use for your awesome application.
+ |
+ */
+
+ 'encoding' => 'UTF-8',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Application Language
+ |--------------------------------------------------------------------------
+ |
+ | The default language of your application. This language will be used by
+ | Lang library as the default language when doing string localization.
+ |
+ */
+
+ 'language' => 'en',
+
+ /*
+ |--------------------------------------------------------------------------
+ | SSL Link Generation
+ |--------------------------------------------------------------------------
+ |
+ | Many sites use SSL to protect their users data. However, you may not
+ | always be able to use SSL on your development machine, meaning all HTTPS
+ | will be broken during development.
+ |
+ | For this reason, you may wish to disable the generation of HTTPS links
+ | throughout your application. This option does just that. All attempts to
+ | generate HTTPS links will generate regular HTTP links instead.
+ |
+ */
+
+ 'ssl' => true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Application Timezone
+ |--------------------------------------------------------------------------
+ |
+ | The default timezone of your application. This timezone will be used when
+ | Laravel needs a date, such as when writing to a log file or travelling
+ | to a distant star at warp speed.
+ |
+ */
+
+ 'timezone' => 'UTC',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Class Aliases
+ |--------------------------------------------------------------------------
+ |
+ | Here, you can specify any class aliases that you would like registered
+ | when Laravel loads. Aliases are lazy-loaded, so add as many as you want.
+ |
+ | Aliases make it more convenient to use namespaced classes. Instead of
+ | referring to the class using its full namespace, you may simply use
+ | the alias defined here.
+ |
+ | We have already aliased common Laravel classes to make your life easier.
+ |
+ */
+
+ 'aliases' => array(
+ 'Auth' => 'Laravel\\Auth',
+ 'Asset' => 'Laravel\\Asset',
+ 'Autoloader' => 'Laravel\\Autoloader',
+ 'Blade' => 'Laravel\\Blade',
+ 'Bundle' => 'Laravel\\Bundle',
+ 'Cache' => 'Laravel\\Cache',
+ 'Config' => 'Laravel\\Config',
+ 'Controller' => 'Laravel\\Routing\\Controller',
+ 'Cookie' => 'Laravel\\Cookie',
+ 'Crypter' => 'Laravel\\Crypter',
+ 'DB' => 'Laravel\\Database',
+ 'Event' => 'Laravel\\Event',
+ 'File' => 'Laravel\\File',
+ 'Filter' => 'Laravel\\Routing\\Filter',
+ 'Form' => 'Laravel\\Form',
+ 'Hash' => 'Laravel\\Hash',
+ 'HTML' => 'Laravel\\HTML',
+ 'Input' => 'Laravel\\Input',
+ 'IoC' => 'Laravel\\IoC',
+ 'Lang' => 'Laravel\\Lang',
+ 'Log' => 'Laravel\\Log',
+ 'Memcached' => 'Laravel\\Memcached',
+ 'Paginator' => 'Laravel\\Paginator',
+ 'URL' => 'Laravel\\URL',
+ 'Redirect' => 'Laravel\\Redirect',
+ 'Redis' => 'Laravel\\Redis',
+ 'Request' => 'Laravel\\Request',
+ 'Response' => 'Laravel\\Response',
+ 'Route' => 'Laravel\\Routing\\Route',
+ 'Router' => 'Laravel\\Routing\\Router',
+ 'Schema' => 'Laravel\\Database\\Schema',
+ 'Section' => 'Laravel\\Section',
+ 'Session' => 'Laravel\\Session',
+ 'Str' => 'Laravel\\Str',
+ 'Task' => 'Laravel\\CLI\\Tasks\\Task',
+ 'URI' => 'Laravel\\URI',
+ 'Validator' => 'Laravel\\Validator',
+ 'View' => 'Laravel\\View',
+ ),
+
+);
diff --git a/app/laravel/tests/application/config/auth.php b/app/laravel/tests/application/config/auth.php
new file mode 100644
index 000000000..d715f063f
--- /dev/null
+++ b/app/laravel/tests/application/config/auth.php
@@ -0,0 +1,73 @@
+ 'fluent',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Authentication Username
+ |--------------------------------------------------------------------------
+ |
+ | Here you may specify the database column that should be considered the
+ | "username" for your users. Typically, this will either be "username"
+ | or "email". Of course, you're free to change the value to anything.
+ |
+ */
+
+ 'username' => 'username',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Authentication Password
+ |--------------------------------------------------------------------------
+ |
+ | Here you may specify the database column that should be considered the
+ | "password" for your users. Typically, this will be "password" but,
+ | again, you're free to change the value to anything you see fit.
+ |
+ */
+
+ 'password' => 'password',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Authentication Model
+ |--------------------------------------------------------------------------
+ |
+ | When using the "eloquent" authentication driver, you may specify the
+ | model that should be considered the "User" model. This model will
+ | be used to authenticate and load the users of your application.
+ |
+ */
+
+ 'model' => 'User',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Authentication Table
+ |--------------------------------------------------------------------------
+ |
+ | When using the "fluent" authentication driver, the database table used
+ | to load users may be specified here. This table will be used in by
+ | the fluent query builder to authenticate and load your users.
+ |
+ */
+
+ 'table' => 'users',
+
+);
diff --git a/app/laravel/tests/application/config/cache.php b/app/laravel/tests/application/config/cache.php
new file mode 100644
index 000000000..73fd4c9ca
--- /dev/null
+++ b/app/laravel/tests/application/config/cache.php
@@ -0,0 +1,71 @@
+ 'file',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Cache Key
+ |--------------------------------------------------------------------------
+ |
+ | This key will be prepended to item keys stored using Memcached and APC
+ | to prevent collisions with other applications on the server. Since the
+ | memory based stores could be shared by other applications, we need to
+ | be polite and use a prefix to uniquely identifier our items.
+ |
+ */
+
+ 'key' => 'laravel',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Cache Database
+ |--------------------------------------------------------------------------
+ |
+ | When using the database cache driver, this database table will be used
+ | to store the cached item. You may also add a "connection" option to
+ | the array to specify which database connection should be used.
+ |
+ */
+
+ 'database' => array('table' => 'laravel_cache'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Memcached Servers
+ |--------------------------------------------------------------------------
+ |
+ | The Memcached servers used by your application. Memcached is a free and
+ | open source, high-performance, distributed memory caching system. It is
+ | generic in nature but intended for use in speeding up web applications
+ | by alleviating database load.
+ |
+ | For more information, check out: http://memcached.org
+ |
+ */
+
+ 'memcached' => array(
+
+ array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100),
+
+ ),
+
+);
\ No newline at end of file
diff --git a/app/laravel/tests/application/config/database.php b/app/laravel/tests/application/config/database.php
new file mode 100644
index 000000000..b7b9fd962
--- /dev/null
+++ b/app/laravel/tests/application/config/database.php
@@ -0,0 +1,108 @@
+ 'sqlite',
+
+ /*
+ |--------------------------------------------------------------------------
+ | PDO Fetch Style
+ |--------------------------------------------------------------------------
+ |
+ | By default, database results will be returned as instances of the PHP
+ | stdClass object; however, you may wish to retrieve records as arrays
+ | instead of objects. Here you can control the PDO fetch style of the
+ | database queries run by your application.
+ |
+ */
+
+ 'fetch' => PDO::FETCH_CLASS,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Database Connections
+ |--------------------------------------------------------------------------
+ |
+ | All of the database connections used by your application. Many of your
+ | applications will no doubt only use one connection; however, you have
+ | the freedom to specify as many connections as you can handle.
+ |
+ | All database work in Laravel is done through the PHP's PDO facilities,
+ | so make sure you have the PDO drivers for your particlar database of
+ | choice installed on your machine.
+ |
+ | Drivers: 'mysql', 'pgsql', 'sqlsrv', 'sqlite'.
+ |
+ */
+
+ 'connections' => array(
+
+ 'sqlite' => array(
+ 'driver' => 'sqlite',
+ 'database' => 'application',
+ 'prefix' => '',
+ ),
+
+ 'mysql' => array(
+ 'driver' => 'mysql',
+ 'host' => 'localhost',
+ 'database' => 'database',
+ 'username' => 'root',
+ 'password' => 'password',
+ 'charset' => 'utf8',
+ 'prefix' => '',
+ ),
+
+ 'pgsql' => array(
+ 'driver' => 'pgsql',
+ 'host' => 'localhost',
+ 'database' => 'database',
+ 'username' => 'root',
+ 'password' => 'password',
+ 'charset' => 'utf8',
+ 'prefix' => '',
+ ),
+
+ 'sqlsrv' => array(
+ 'driver' => 'sqlsrv',
+ 'host' => 'localhost',
+ 'database' => 'database',
+ 'username' => 'root',
+ 'password' => 'password',
+ 'prefix' => '',
+ ),
+
+ ),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Redis Databases
+ |--------------------------------------------------------------------------
+ |
+ | Redis is an open source, fast, and advanced key-value store. However, it
+ | provides a richer set of commands than a typical key-value store such as
+ | APC or memcached. All the cool kids are using it.
+ |
+ | To get the scoop on Redis, check out: http://redis.io
+ |
+ */
+
+ 'redis' => array(
+
+ 'default' => array('host' => '127.0.0.1', 'port' => 6379),
+
+ ),
+
+);
\ No newline at end of file
diff --git a/app/laravel/tests/application/config/error.php b/app/laravel/tests/application/config/error.php
new file mode 100644
index 000000000..87db96653
--- /dev/null
+++ b/app/laravel/tests/application/config/error.php
@@ -0,0 +1,69 @@
+ array(E_NOTICE, E_USER_NOTICE, E_DEPRECATED, E_USER_DEPRECATED),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Error Detail
+ |--------------------------------------------------------------------------
+ |
+ | Detailed error messages contain information about the file in which an
+ | error occurs, as well as a PHP stack trace containing the call stack.
+ | You'll want them when you're trying to debug your application.
+ |
+ | If your application is in production, you'll want to turn off the error
+ | details for enhanced security and user experience since the exception
+ | stack trace could contain sensitive information.
+ |
+ */
+
+ 'detail' => true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Error Logging
+ |--------------------------------------------------------------------------
+ |
+ | When error logging is enabled, the "logger" Closure defined below will
+ | be called for every error in your application. You are free to log the
+ | errors however you want. Enjoy the flexibility.
+ |
+ */
+
+ 'log' => false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Error Logger
+ |--------------------------------------------------------------------------
+ |
+ | Because of the various ways of managing error logging, you get complete
+ | flexibility to manage error logging as you see fit. This function will
+ | be called anytime an error occurs within your application and error
+ | logging is enabled.
+ |
+ | You may log the error message however you like; however, a simple log
+ | solution has been setup for you which will log all error messages to
+ | text files within the application storage directory.
+ |
+ */
+
+ 'logger' => function($exception)
+ {
+ Log::exception($exception);
+ },
+
+);
\ No newline at end of file
diff --git a/app/laravel/tests/application/config/local/database.php b/app/laravel/tests/application/config/local/database.php
new file mode 100644
index 000000000..bd94d7ba3
--- /dev/null
+++ b/app/laravel/tests/application/config/local/database.php
@@ -0,0 +1,7 @@
+ 'sqlite',
+
+);
\ No newline at end of file
diff --git a/app/laravel/tests/application/config/mimes.php b/app/laravel/tests/application/config/mimes.php
new file mode 100644
index 000000000..e2bd4fbb1
--- /dev/null
+++ b/app/laravel/tests/application/config/mimes.php
@@ -0,0 +1,97 @@
+ 'application/mac-binhex40',
+ 'cpt' => 'application/mac-compactpro',
+ 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream'),
+ 'bin' => 'application/macbinary',
+ 'dms' => 'application/octet-stream',
+ 'lha' => 'application/octet-stream',
+ 'lzh' => 'application/octet-stream',
+ 'exe' => array('application/octet-stream', 'application/x-msdownload'),
+ 'class' => 'application/octet-stream',
+ 'psd' => 'application/x-photoshop',
+ 'so' => 'application/octet-stream',
+ 'sea' => 'application/octet-stream',
+ 'dll' => 'application/octet-stream',
+ 'oda' => 'application/oda',
+ 'pdf' => array('application/pdf', 'application/x-download'),
+ 'ai' => 'application/postscript',
+ 'eps' => 'application/postscript',
+ 'ps' => 'application/postscript',
+ 'smi' => 'application/smil',
+ 'smil' => 'application/smil',
+ 'mif' => 'application/vnd.mif',
+ 'xls' => array('application/excel', 'application/vnd.ms-excel', 'application/msexcel'),
+ 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint'),
+ 'wbxml' => 'application/wbxml',
+ 'wmlc' => 'application/wmlc',
+ 'dcr' => 'application/x-director',
+ 'dir' => 'application/x-director',
+ 'dxr' => 'application/x-director',
+ 'dvi' => 'application/x-dvi',
+ 'gtar' => 'application/x-gtar',
+ 'gz' => 'application/x-gzip',
+ 'php' => array('application/x-httpd-php', 'text/x-php'),
+ 'php4' => 'application/x-httpd-php',
+ 'php3' => 'application/x-httpd-php',
+ 'phtml' => 'application/x-httpd-php',
+ 'phps' => 'application/x-httpd-php-source',
+ 'js' => 'application/x-javascript',
+ 'swf' => 'application/x-shockwave-flash',
+ 'sit' => 'application/x-stuffit',
+ 'tar' => 'application/x-tar',
+ 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'),
+ 'xhtml' => 'application/xhtml+xml',
+ 'xht' => 'application/xhtml+xml',
+ 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'),
+ 'mid' => 'audio/midi',
+ 'midi' => 'audio/midi',
+ 'mpga' => 'audio/mpeg',
+ 'mp2' => 'audio/mpeg',
+ 'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'),
+ 'aif' => 'audio/x-aiff',
+ 'aiff' => 'audio/x-aiff',
+ 'aifc' => 'audio/x-aiff',
+ 'ram' => 'audio/x-pn-realaudio',
+ 'rm' => 'audio/x-pn-realaudio',
+ 'rpm' => 'audio/x-pn-realaudio-plugin',
+ 'ra' => 'audio/x-realaudio',
+ 'rv' => 'video/vnd.rn-realvideo',
+ 'wav' => 'audio/x-wav',
+ 'bmp' => 'image/bmp',
+ 'gif' => 'image/gif',
+ 'jpeg' => array('image/jpeg', 'image/pjpeg'),
+ 'jpg' => array('image/jpeg', 'image/pjpeg'),
+ 'jpe' => array('image/jpeg', 'image/pjpeg'),
+ 'png' => 'image/png',
+ 'tiff' => 'image/tiff',
+ 'tif' => 'image/tiff',
+ 'css' => 'text/css',
+ 'html' => 'text/html',
+ 'htm' => 'text/html',
+ 'shtml' => 'text/html',
+ 'txt' => 'text/plain',
+ 'text' => 'text/plain',
+ 'log' => array('text/plain', 'text/x-log'),
+ 'rtx' => 'text/richtext',
+ 'rtf' => 'text/rtf',
+ 'xml' => 'text/xml',
+ 'xsl' => 'text/xml',
+ 'mpeg' => 'video/mpeg',
+ 'mpg' => 'video/mpeg',
+ 'mpe' => 'video/mpeg',
+ 'qt' => 'video/quicktime',
+ 'mov' => 'video/quicktime',
+ 'avi' => 'video/x-msvideo',
+ 'movie' => 'video/x-sgi-movie',
+ 'doc' => 'application/msword',
+ 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'word' => array('application/msword', 'application/octet-stream'),
+ 'xl' => 'application/excel',
+ 'eml' => 'message/rfc822',
+ 'json' => array('application/json', 'text/json'),
+
+);
\ No newline at end of file
diff --git a/app/laravel/tests/application/config/session.php b/app/laravel/tests/application/config/session.php
new file mode 100644
index 000000000..3b6e6a694
--- /dev/null
+++ b/app/laravel/tests/application/config/session.php
@@ -0,0 +1,117 @@
+ '',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Session Database
+ |--------------------------------------------------------------------------
+ |
+ | The database table on which the session should be stored. It probably
+ | goes without saying that this option only matters if you are using
+ | the super slick database session driver.
+ |
+ */
+
+ 'table' => 'sessions',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Session Garbage Collection Probability
+ |--------------------------------------------------------------------------
+ |
+ | Some session drivers require the manual clean-up of expired sessions.
+ | This option specifies the probability of session garbage collection
+ | occuring for any given request.
+ |
+ | For example, the default value states that garbage collection has a
+ | 2% chance of occuring for any given request to the application.
+ | Feel free to tune this to your application's size and speed.
+ |
+ */
+
+ 'sweepage' => array(2, 100),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Session Lifetime
+ |--------------------------------------------------------------------------
+ |
+ | The number of minutes a session can be idle before expiring.
+ |
+ */
+
+ 'lifetime' => 60,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Session Expiration On Close
+ |--------------------------------------------------------------------------
+ |
+ | Determines if the session should expire when the user's web browser closes.
+ |
+ */
+
+ 'expire_on_close' => false,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Session Cookie Name
+ |--------------------------------------------------------------------------
+ |
+ | The name that should be given to the session cookie.
+ |
+ */
+
+ 'cookie' => 'laravel_session',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Session Cookie Path
+ |--------------------------------------------------------------------------
+ |
+ | The path for which the session cookie is available.
+ |
+ */
+
+ 'path' => '/',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Session Cookie Domain
+ |--------------------------------------------------------------------------
+ |
+ | The domain for which the session cookie is available.
+ |
+ */
+
+ 'domain' => null,
+
+ /*
+ |--------------------------------------------------------------------------
+ | HTTPS Only Session Cookie
+ |--------------------------------------------------------------------------
+ |
+ | Determines if the cookie should only be sent over HTTPS.
+ |
+ */
+
+ 'secure' => false,
+
+);
\ No newline at end of file
diff --git a/app/laravel/tests/application/config/strings.php b/app/laravel/tests/application/config/strings.php
new file mode 100644
index 000000000..bbbe230c9
--- /dev/null
+++ b/app/laravel/tests/application/config/strings.php
@@ -0,0 +1,190 @@
+ array(
+ '/(quiz)$/i' => "$1zes",
+ '/^(ox)$/i' => "$1en",
+ '/([m|l])ouse$/i' => "$1ice",
+ '/(matr|vert|ind)ix|ex$/i' => "$1ices",
+ '/(x|ch|ss|sh)$/i' => "$1es",
+ '/([^aeiouy]|qu)y$/i' => "$1ies",
+ '/(hive)$/i' => "$1s",
+ '/(?:([^f])fe|([lr])f)$/i' => "$1$2ves",
+ '/(shea|lea|loa|thie)f$/i' => "$1ves",
+ '/sis$/i' => "ses",
+ '/([ti])um$/i' => "$1a",
+ '/(tomat|potat|ech|her|vet)o$/i' => "$1oes",
+ '/(bu)s$/i' => "$1ses",
+ '/(alias)$/i' => "$1es",
+ '/(octop)us$/i' => "$1i",
+ '/(ax|test)is$/i' => "$1es",
+ '/(us)$/i' => "$1es",
+ '/s$/i' => "s",
+ '/$/' => "s"
+ ),
+
+ 'singular' => array(
+ '/(quiz)zes$/i' => "$1",
+ '/(matr)ices$/i' => "$1ix",
+ '/(vert|ind)ices$/i' => "$1ex",
+ '/^(ox)en$/i' => "$1",
+ '/(alias)es$/i' => "$1",
+ '/(octop|vir)i$/i' => "$1us",
+ '/(cris|ax|test)es$/i' => "$1is",
+ '/(shoe)s$/i' => "$1",
+ '/(o)es$/i' => "$1",
+ '/(bus)es$/i' => "$1",
+ '/([m|l])ice$/i' => "$1ouse",
+ '/(x|ch|ss|sh)es$/i' => "$1",
+ '/(m)ovies$/i' => "$1ovie",
+ '/(s)eries$/i' => "$1eries",
+ '/([^aeiouy]|qu)ies$/i' => "$1y",
+ '/([lr])ves$/i' => "$1f",
+ '/(tive)s$/i' => "$1",
+ '/(hive)s$/i' => "$1",
+ '/(li|wi|kni)ves$/i' => "$1fe",
+ '/(shea|loa|lea|thie)ves$/i' => "$1f",
+ '/(^analy)ses$/i' => "$1sis",
+ '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => "$1$2sis",
+ '/([ti])a$/i' => "$1um",
+ '/(n)ews$/i' => "$1ews",
+ '/(h|bl)ouses$/i' => "$1ouse",
+ '/(corpse)s$/i' => "$1",
+ '/(us)es$/i' => "$1",
+ '/(us|ss)$/i' => "$1",
+ '/s$/i' => "",
+ ),
+
+ 'irregular' => array(
+ 'child' => 'children',
+ 'foot' => 'feet',
+ 'goose' => 'geese',
+ 'man' => 'men',
+ 'move' => 'moves',
+ 'person' => 'people',
+ 'sex' => 'sexes',
+ 'tooth' => 'teeth',
+ ),
+
+ 'uncountable' => array(
+ 'audio',
+ 'equipment',
+ 'deer',
+ 'fish',
+ 'gold',
+ 'information',
+ 'money',
+ 'rice',
+ 'police',
+ 'series',
+ 'sheep',
+ 'species',
+ 'moose',
+ 'chassis',
+ 'traffic',
+ ),
+
+ /*
+ |--------------------------------------------------------------------------
+ | ASCII Characters
+ |--------------------------------------------------------------------------
+ |
+ | This array contains foreign characters and their 7-bit ASCII equivalents.
+ | The array is used by the "ascii" method on the Str class to get strings
+ | ready for inclusion in a URL slug.
+ |
+ | Of course, the "ascii" method may also be used by you for whatever your
+ | application requires. Feel free to add any characters we missed, and be
+ | sure to let us know about them!
+ |
+ */
+
+ 'ascii' => array(
+
+ '/æ|ǽ/' => 'ae',
+ '/œ/' => 'oe',
+ '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|А/' => 'A',
+ '/à|á|â|ã|ä|å|ǻ|ā|ă|ą|ǎ|ª|а/' => 'a',
+ '/Б/' => 'B',
+ '/б/' => 'b',
+ '/Ç|Ć|Ĉ|Ċ|Č|Ц/' => 'C',
+ '/ç|ć|ĉ|ċ|č|ц/' => 'c',
+ '/Ð|Ď|Đ|Д/' => 'Dj',
+ '/ð|ď|đ|д/' => 'dj',
+ '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Е|Ё|Э/' => 'E',
+ '/è|é|ê|ë|ē|ĕ|ė|ę|ě|е|ё|э/' => 'e',
+ '/Ф/' => 'F',
+ '/ƒ|ф/' => 'f',
+ '/Ĝ|Ğ|Ġ|Ģ|Г/' => 'G',
+ '/ĝ|ğ|ġ|ģ|г/' => 'g',
+ '/Ĥ|Ħ|Х/' => 'H',
+ '/ĥ|ħ|х/' => 'h',
+ '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|И/' => 'I',
+ '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|и/' => 'i',
+ '/Ĵ|Й/' => 'J',
+ '/ĵ|й/' => 'j',
+ '/Ķ|К/' => 'K',
+ '/ķ|к/' => 'k',
+ '/Ĺ|Ļ|Ľ|Ŀ|Ł|Л/' => 'L',
+ '/ĺ|ļ|ľ|ŀ|ł|л/' => 'l',
+ '/М/' => 'M',
+ '/м/' => 'm',
+ '/Ñ|Ń|Ņ|Ň|Н/' => 'N',
+ '/ñ|ń|ņ|ň|ʼn|н/' => 'n',
+ '/Ö|Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|О/' => 'O',
+ '/ö|ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|о/' => 'o',
+ '/П/' => 'P',
+ '/п/' => 'p',
+ '/Ŕ|Ŗ|Ř|Р/' => 'R',
+ '/ŕ|ŗ|ř|р/' => 'r',
+ '/Ś|Ŝ|Ş|Ș|Š|С/' => 'S',
+ '/ś|ŝ|ş|ș|š|ſ|с/' => 's',
+ '/Ţ|Ț|Ť|Ŧ|Т/' => 'T',
+ '/ţ|ț|ť|ŧ|т/' => 't',
+ '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ü|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|У/' => 'U',
+ '/ù|ú|û|ũ|ū|ŭ|ů|ü|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|у/' => 'u',
+ '/В/' => 'V',
+ '/в/' => 'v',
+ '/Ý|Ÿ|Ŷ|Ы/' => 'Y',
+ '/ý|ÿ|ŷ|ы/' => 'y',
+ '/Ŵ/' => 'W',
+ '/ŵ/' => 'w',
+ '/Ź|Ż|Ž|З/' => 'Z',
+ '/ź|ż|ž|з/' => 'z',
+ '/Æ|Ǽ/' => 'AE',
+ '/ß/'=> 'ss',
+ '/IJ/' => 'IJ',
+ '/ij/' => 'ij',
+ '/Œ/' => 'OE',
+ '/Ч/' => 'Ch',
+ '/ч/' => 'ch',
+ '/Ю/' => 'Ju',
+ '/ю/' => 'ju',
+ '/Я/' => 'Ja',
+ '/я/' => 'ja',
+ '/Ш/' => 'Sh',
+ '/ш/' => 'sh',
+ '/Щ/' => 'Shch',
+ '/щ/' => 'shch',
+ '/Ж/' => 'Zh',
+ '/ж/' => 'zh',
+
+ ),
+
+);
diff --git a/app/laravel/tests/application/controllers/admin/panel.php b/app/laravel/tests/application/controllers/admin/panel.php
new file mode 100644
index 000000000..da3b49d7d
--- /dev/null
+++ b/app/laravel/tests/application/controllers/admin/panel.php
@@ -0,0 +1,10 @@
+filter('before', 'test-all-before');
+ $this->filter('after', 'test-all-after');
+ $this->filter('before', 'test-profile-before')->only(array('profile'));
+ $this->filter('before', 'test-except')->except(array('index', 'profile'));
+ $this->filter('before', 'test-on-post')->on(array('post'));
+ $this->filter('before', 'test-on-get-put')->on(array('get', 'put'));
+ $this->filter('before', 'test-before-filter')->only('login');
+ $this->filter('after', 'test-before-filter')->only('logout');
+ $this->filter('before', 'test-param:1,2')->only('edit');
+ $this->filter('before', 'test-multi-1|test-multi-2')->only('save');
+ }
+
+ public function action_index()
+ {
+ return __FUNCTION__;
+ }
+
+ public function action_profile()
+ {
+ return __FUNCTION__;
+ }
+
+ public function action_show()
+ {
+ return __FUNCTION__;
+ }
+
+ public function action_edit()
+ {
+ return __FUNCTION__;
+ }
+
+ public function action_save()
+ {
+ return __FUNCTION__;
+ }
+
+ public function action_login()
+ {
+ return __FUNCTION__;
+ }
+
+ public function action_logout()
+ {
+ return __FUNCTION__;
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/application/controllers/home.php b/app/laravel/tests/application/controllers/home.php
new file mode 100644
index 000000000..3f442005c
--- /dev/null
+++ b/app/laravel/tests/application/controllers/home.php
@@ -0,0 +1,42 @@
+ '« Previous',
+ 'next' => 'Next »',
+
+);
\ No newline at end of file
diff --git a/app/laravel/tests/application/language/en/validation.php b/app/laravel/tests/application/language/en/validation.php
new file mode 100644
index 000000000..5c6354ddb
--- /dev/null
+++ b/app/laravel/tests/application/language/en/validation.php
@@ -0,0 +1,96 @@
+ "The :attribute must be accepted.",
+ "active_url" => "The :attribute is not a valid URL.",
+ "alpha" => "The :attribute may only contain letters.",
+ "alpha_dash" => "The :attribute may only contain letters, numbers, and dashes.",
+ "alpha_num" => "The :attribute may only contain letters and numbers.",
+ "between" => array(
+ "numeric" => "The :attribute must be between :min - :max.",
+ "file" => "The :attribute must be between :min - :max kilobytes.",
+ "string" => "The :attribute must be between :min - :max characters.",
+ ),
+ "confirmed" => "The :attribute confirmation does not match.",
+ "different" => "The :attribute and :other must be different.",
+ "email" => "The :attribute format is invalid.",
+ "exists" => "The selected :attribute is invalid.",
+ "image" => "The :attribute must be an image.",
+ "in" => "The selected :attribute is invalid.",
+ "integer" => "The :attribute must be an integer.",
+ "ip" => "The :attribute must be a valid IP address.",
+ "max" => array(
+ "numeric" => "The :attribute must be less than :max.",
+ "file" => "The :attribute must be less than :max kilobytes.",
+ "string" => "The :attribute must be less than :max characters.",
+ ),
+ "mimes" => "The :attribute must be a file of type: :values.",
+ "min" => array(
+ "numeric" => "The :attribute must be at least :min.",
+ "file" => "The :attribute must be at least :min kilobytes.",
+ "string" => "The :attribute must be at least :min characters.",
+ ),
+ "not_in" => "The selected :attribute is invalid.",
+ "numeric" => "The :attribute must be a number.",
+ "required" => "The :attribute field is required.",
+ "same" => "The :attribute and :other must match.",
+ "size" => array(
+ "numeric" => "The :attribute must be :size.",
+ "file" => "The :attribute must be :size kilobyte.",
+ "string" => "The :attribute must be :size characters.",
+ ),
+ "unique" => "The :attribute has already been taken.",
+ "url" => "The :attribute format is invalid.",
+
+ /*
+ |--------------------------------------------------------------------------
+ | Custom Validation Language Lines
+ |--------------------------------------------------------------------------
+ |
+ | Here you may specify custom validation messages for attributes using the
+ | convention "attribute_rule" to name the lines. This helps keep your
+ | custom validation clean and tidy.
+ |
+ | So, say you want to use a custom validation message when validating that
+ | the "email" attribute is unique. Just add "email_unique" to this array
+ | with your custom message. The Validator will handle the rest!
+ |
+ */
+
+ 'custom' => array('custom_required' => 'This field is required!'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Validation Attributes
+ |--------------------------------------------------------------------------
+ |
+ | The following language lines are used to swap attribute place-holders
+ | with something more reader friendly such as "E-Mail Address" instead
+ | of "email". Your users will thank you.
+ |
+ | The Validator class will automatically search this array of lines it
+ | is attempting to replace the :attribute place-holder in messages.
+ | It's pretty slick. We think you'll like it.
+ |
+ */
+
+ 'attributes' => array('test_attribute' => 'attribute'),
+
+);
\ No newline at end of file
diff --git a/app/laravel/tests/application/language/sp/validation.php b/app/laravel/tests/application/language/sp/validation.php
new file mode 100644
index 000000000..b9bcbe747
--- /dev/null
+++ b/app/laravel/tests/application/language/sp/validation.php
@@ -0,0 +1,7 @@
+ 'El campo de atributo es necesario.',
+
+);
\ No newline at end of file
diff --git a/app/laravel/tests/application/libraries/.gitignore b/app/laravel/tests/application/libraries/.gitignore
new file mode 100644
index 000000000..e69de29bb
diff --git a/app/laravel/tests/application/migrations/.gitignore b/app/laravel/tests/application/migrations/.gitignore
new file mode 100644
index 000000000..e69de29bb
diff --git a/app/laravel/tests/application/models/.gitignore b/app/laravel/tests/application/models/.gitignore
new file mode 100644
index 000000000..e69de29bb
diff --git a/app/laravel/tests/application/models/autoloader.php b/app/laravel/tests/application/models/autoloader.php
new file mode 100644
index 000000000..0e9027dce
--- /dev/null
+++ b/app/laravel/tests/application/models/autoloader.php
@@ -0,0 +1,3 @@
+set_attribute('setter', 'setter: '.$setter);
+ }
+
+ public function get_getter()
+ {
+ return 'getter: '.$this->get_attribute('getter');
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/application/models/repositories/user.php b/app/laravel/tests/application/models/repositories/user.php
new file mode 100644
index 000000000..093ec2b00
--- /dev/null
+++ b/app/laravel/tests/application/models/repositories/user.php
@@ -0,0 +1,3 @@
+ 'home', function()
+{
+ return View::make('home.index');
+}));
+
+Route::controller(array(
+ 'auth', 'filter', 'home', 'restful',
+ 'template.basic', 'template.name', 'template.override',
+ 'admin.panel',
+));
+
+/*
+|--------------------------------------------------------------------------
+| Route Filters
+|--------------------------------------------------------------------------
+|
+| Filters provide a convenient method for attaching functionality to your
+| routes. The built-in "before" and "after" filters are called before and
+| after every request to your application, and you may even create other
+| filters that can be attached to individual routes.
+|
+| Let's walk through an example...
+|
+| First, define a filter:
+|
+| Filter::register('filter', function()
+| {
+| return 'Filtered!';
+| });
+|
+| Next, attach the filter to a route:
+|
+| Router::register('GET /', array('before' => 'filter', function()
+| {
+| return 'Hello World!';
+| }));
+|
+*/
+
+Filter::register('before', function()
+{
+ $_SERVER['before'] = true;
+});
+
+Filter::register('after', function()
+{
+ $_SERVER['after'] = true;
+});
+
+Filter::register('csrf', function()
+{
+ if (Request::forged()) return Response::error('500');
+});
+
+Filter::register('auth', function()
+{
+ if (Auth::guest()) return Redirect::to('login');
+});
\ No newline at end of file
diff --git a/app/laravel/tests/application/start.php b/app/laravel/tests/application/start.php
new file mode 100644
index 000000000..085dd090f
--- /dev/null
+++ b/app/laravel/tests/application/start.php
@@ -0,0 +1,157 @@
+ path('app').'controllers/base.php',
+));
+
+/*
+|--------------------------------------------------------------------------
+| Auto-Loader Directories
+|--------------------------------------------------------------------------
+|
+| The Laravel auto-loader can search directories for files using the PSR-0
+| naming convention. This convention basically organizes classes by using
+| the class namespace to indicate the directory structure.
+|
+*/
+
+Autoloader::directories(array(
+ path('app').'models',
+ path('app').'libraries',
+));
+
+/*
+|--------------------------------------------------------------------------
+| Laravel View Loader
+|--------------------------------------------------------------------------
+|
+| The Laravel view loader is responsible for returning the full file path
+| for the given bundle and view. Of course, a default implementation is
+| provided to load views according to typical Laravel conventions but
+| you may change this to customize how your views are organized.
+|
+*/
+
+Event::listen(View::loader, function($bundle, $view)
+{
+ return View::file($bundle, $view, Bundle::path($bundle).'views');
+});
+
+/*
+|--------------------------------------------------------------------------
+| Laravel Language Loader
+|--------------------------------------------------------------------------
+|
+| The Laravel language loader is responsible for returning the array of
+| language lines for a given bundle, language, and "file". A default
+| implementation has been provided which uses the default language
+| directories included with Laravel.
+|
+*/
+
+Event::listen(Lang::loader, function($bundle, $language, $file)
+{
+ return Lang::file($bundle, $language, $file);
+});
+
+/*
+|--------------------------------------------------------------------------
+| Enable The Blade View Engine
+|--------------------------------------------------------------------------
+|
+| The Blade view engine provides a clean, beautiful templating language
+| for your application, including syntax for echoing data and all of
+| the typical PHP control structures. We'll simply enable it here.
+|
+*/
+
+Blade::sharpen();
+
+/*
+|--------------------------------------------------------------------------
+| Set The Default Timezone
+|--------------------------------------------------------------------------
+|
+| We need to set the default timezone for the application. This controls
+| the timezone that will be used by any of the date methods and classes
+| utilized by Laravel or your application. The timezone may be set in
+| your application configuration file.
+|
+*/
+
+date_default_timezone_set(Config::get('application.timezone'));
+
+/*
+|--------------------------------------------------------------------------
+| Start / Load The User Session
+|--------------------------------------------------------------------------
+|
+| Sessions allow the web, which is stateless, to simulate state. In other
+| words, sessions allow you to store information about the current user
+| and state of your application. Here we'll just fire up the session
+| if a session driver has been configured.
+|
+*/
+
+if ( ! Request::cli() and Config::get('session.driver') !== '')
+{
+ Session::load();
+}
\ No newline at end of file
diff --git a/app/laravel/tests/application/tasks/.gitignore b/app/laravel/tests/application/tasks/.gitignore
new file mode 100644
index 000000000..e69de29bb
diff --git a/app/laravel/tests/application/views/error/404.php b/app/laravel/tests/application/views/error/404.php
new file mode 100644
index 000000000..9b9bf55bc
--- /dev/null
+++ b/app/laravel/tests/application/views/error/404.php
@@ -0,0 +1,103 @@
+
+
+
+
+
+ Error 404 - Not Found
+
+
+
+
+
+
+
+
+
+ Server Error: 404 (Not Found)
+
+ What does this mean?
+
+
+ We couldn't find the page you requested on our servers. We're really sorry
+ about that. It's our fault, not yours. We'll work hard to get this page
+ back online as soon as possible.
+
+
+
+ Perhaps you would like to go to our ?
+
+
+
+
\ No newline at end of file
diff --git a/app/laravel/tests/application/views/error/500.php b/app/laravel/tests/application/views/error/500.php
new file mode 100644
index 000000000..4dcd92ada
--- /dev/null
+++ b/app/laravel/tests/application/views/error/500.php
@@ -0,0 +1,103 @@
+
+
+
+
+
+ Error 500 - Internal Server Error
+
+
+
+
+
+
+
+
+
+ Server Error: 500 (Internal Server Error)
+
+ What does this mean?
+
+
+ Something went wrong on our servers while we were processing your request.
+ We're really sorry about this, and will work hard to get this resolved as
+ soon as possible.
+
+
+
+ Perhaps you would like to go to our ?
+
+
+
+
\ No newline at end of file
diff --git a/app/laravel/tests/application/views/home/index.php b/app/laravel/tests/application/views/home/index.php
new file mode 100644
index 000000000..394971462
--- /dev/null
+++ b/app/laravel/tests/application/views/home/index.php
@@ -0,0 +1,122 @@
+
+
+
+
+
+ Laravel - A Framework For Web Artisans
+
+
+
+
+
+ Welcome To Laravel
+
+ A Framework For Web Artisans
+
+
+ You have successfully installed the Laravel framework. Laravel is a simple framework
+ that helps web artisans create beautiful, creative applications using elegant, expressive
+ syntax. You'll love using it.
+
+
+ Learn the terrain.
+
+
+ You've landed yourself on our default home page. The route that
+ is generating this page lives at:
+
+
+ APP_PATH/routes.php
+
+ And the view sitting before you can be found at:
+
+ APP_PATH/views/home/index.php
+
+ Create something beautiful.
+
+
+ Now that you're up and running, it's time to start creating!
+ Here are some links to help you get started:
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/laravel/tests/application/views/tests/basic.php b/app/laravel/tests/application/views/tests/basic.php
new file mode 100644
index 000000000..c961dc2fd
--- /dev/null
+++ b/app/laravel/tests/application/views/tests/basic.php
@@ -0,0 +1 @@
+ is
\ No newline at end of file
diff --git a/app/laravel/tests/application/views/tests/nested.php b/app/laravel/tests/application/views/tests/nested.php
new file mode 100644
index 000000000..9ce498e56
--- /dev/null
+++ b/app/laravel/tests/application/views/tests/nested.php
@@ -0,0 +1 @@
+Taylor
\ No newline at end of file
diff --git a/app/laravel/tests/bundles/.gitignore b/app/laravel/tests/bundles/.gitignore
new file mode 100644
index 000000000..e69de29bb
diff --git a/app/laravel/tests/bundles/dashboard/config/meta.php b/app/laravel/tests/bundles/dashboard/config/meta.php
new file mode 100644
index 000000000..a82d17035
--- /dev/null
+++ b/app/laravel/tests/bundles/dashboard/config/meta.php
@@ -0,0 +1,7 @@
+ 'dashboard',
+
+);
\ No newline at end of file
diff --git a/app/laravel/tests/bundles/dashboard/controllers/panel.php b/app/laravel/tests/bundles/dashboard/controllers/panel.php
new file mode 100644
index 000000000..b532296d1
--- /dev/null
+++ b/app/laravel/tests/bundles/dashboard/controllers/panel.php
@@ -0,0 +1,10 @@
+ 'dashboard', function()
+{
+ //
+}));
+
+Route::controller('dashboard::panel');
\ No newline at end of file
diff --git a/app/laravel/tests/bundles/dummy/routes.php b/app/laravel/tests/bundles/dummy/routes.php
new file mode 100644
index 000000000..2117e2e08
--- /dev/null
+++ b/app/laravel/tests/bundles/dummy/routes.php
@@ -0,0 +1,6 @@
+assertTrue($container === Asset::container('foo'));
+ $this->assertInstanceOf('\\Laravel\\Asset_Container', $container);
+ }
+
+ /**
+ * Test the Asset::container method for default container creation.
+ *
+ * @group laravel
+ */
+ public function testDefaultContainerCreatedByDefault()
+ {
+ $this->assertEquals('default', Asset::container()->name);
+ }
+
+ /**
+ * Test the Asset::__callStatic method.
+ *
+ * @group laravel
+ */
+ public function testContainerMethodsCanBeDynamicallyCalled()
+ {
+ Asset::style('common', 'common.css');
+
+ $this->assertEquals('common.css', Asset::container()->assets['style']['common']['source']);
+ }
+
+ /**
+ * Test the Asset_Container constructor.
+ *
+ * @group laravel
+ */
+ public function testNameIsSetOnAssetContainerConstruction()
+ {
+ $container = $this->getContainer();
+
+ $this->assertEquals('foo', $container->name);
+ }
+
+ /**
+ * Test the Asset_Container::add method.
+ *
+ * @group laravel
+ */
+ public function testAddMethodProperlySniffsAssetType()
+ {
+ $container = $this->getContainer();
+
+ $container->add('jquery', 'jquery.js');
+ $container->add('common', 'common.css');
+
+ $this->assertEquals('jquery.js', $container->assets['script']['jquery']['source']);
+ $this->assertEquals('common.css', $container->assets['style']['common']['source']);
+ }
+
+ /**
+ * Test the Asset_Container::style method.
+ *
+ * @group laravel
+ */
+ public function testStyleMethodProperlyRegistersAnAsset()
+ {
+ $container = $this->getContainer();
+
+ $container->style('common', 'common.css');
+
+ $this->assertEquals('common.css', $container->assets['style']['common']['source']);
+ }
+
+ /**
+ * Test the Asset_Container::style method sets media attribute.
+ *
+ * @group laravel
+ */
+ public function testStyleMethodProperlySetsMediaAttributeIfNotSet()
+ {
+ $container = $this->getContainer();
+
+ $container->style('common', 'common.css');
+
+ $this->assertEquals('all', $container->assets['style']['common']['attributes']['media']);
+ }
+
+ /**
+ * Test the Asset_Container::style method sets media attribute.
+ *
+ * @group laravel
+ */
+ public function testStyleMethodProperlyIgnoresMediaAttributeIfSet()
+ {
+ $container = $this->getContainer();
+
+ $container->style('common', 'common.css', array(), array('media' => 'print'));
+
+ $this->assertEquals('print', $container->assets['style']['common']['attributes']['media']);
+ }
+
+ /**
+ * Test the Asset_Container::script method.
+ *
+ * @group laravel
+ */
+ public function testScriptMethodProperlyRegistersAnAsset()
+ {
+ $container = $this->getContainer();
+
+ $container->script('jquery', 'jquery.js');
+
+ $this->assertEquals('jquery.js', $container->assets['script']['jquery']['source']);
+ }
+
+ /**
+ * Test the Asset_Container::add method properly sets dependencies.
+ *
+ * @group laravel
+ */
+ public function testAddMethodProperlySetsDependencies()
+ {
+ $container = $this->getContainer();
+
+ $container->add('common', 'common.css', 'jquery');
+ $container->add('jquery', 'jquery.js', array('jquery-ui'));
+
+ $this->assertEquals(array('jquery'), $container->assets['style']['common']['dependencies']);
+ $this->assertEquals(array('jquery-ui'), $container->assets['script']['jquery']['dependencies']);
+ }
+
+ /**
+ * Test the Asset_Container::add method properly sets attributes.
+ *
+ * @group laravel
+ */
+ public function testAddMethodProperlySetsAttributes()
+ {
+ $container = $this->getContainer();
+
+ $container->add('common', 'common.css', array(), array('media' => 'print'));
+ $container->add('jquery', 'jquery.js', array(), array('defer'));
+
+ $this->assertEquals(array('media' => 'print'), $container->assets['style']['common']['attributes']);
+ $this->assertEquals(array('defer'), $container->assets['script']['jquery']['attributes']);
+ }
+
+ /**
+ * Test the Asset_Container::bundle method.
+ *
+ * @group laravel
+ */
+ public function testBundleMethodCorrectlySetsTheAssetBundle()
+ {
+ $container = $this->getContainer();
+
+ $container->bundle('eloquent');
+
+ $this->assertEquals('eloquent', $container->bundle);
+ }
+
+ /**
+ * Test the Asset_Container::path method.
+ *
+ * @group laravel
+ */
+ public function testPathMethodReturnsCorrectPathForABundleAsset()
+ {
+ $container = $this->getContainer();
+
+ $container->bundle('eloquent');
+
+ $this->assertEquals('/bundles/eloquent/foo.jpg', $container->path('foo.jpg'));
+ }
+
+ /**
+ * Test the Asset_Container::path method.
+ *
+ * @group laravel
+ */
+ public function testPathMethodReturnsCorrectPathForAnApplicationAsset()
+ {
+ $container = $this->getContainer();
+
+ $this->assertEquals('/foo.jpg', $container->path('foo.jpg'));
+ }
+
+ /**
+ * Test the Asset_Container::scripts method.
+ *
+ * @group laravel
+ */
+ public function testScriptsCanBeRetrieved()
+ {
+ $container = $this->getContainer();
+
+ $container->script('dojo', 'dojo.js', array('jquery-ui'));
+ $container->script('jquery', 'jquery.js', array('jquery-ui', 'dojo'));
+ $container->script('jquery-ui', 'jquery-ui.js');
+
+ $scripts = $container->scripts();
+
+ $this->assertTrue(strpos($scripts, 'jquery.js') > 0);
+ $this->assertTrue(strpos($scripts, 'jquery.js') > strpos($scripts, 'jquery-ui.js'));
+ $this->assertTrue(strpos($scripts, 'dojo.js') > strpos($scripts, 'jquery-ui.js'));
+ }
+
+ /**
+ * Test the Asset_Container::styles method.
+ *
+ * @group laravel
+ */
+ public function testStylesCanBeRetrieved()
+ {
+ $container = $this->getContainer();
+
+ $container->style('dojo', 'dojo.css', array('jquery-ui'), array('media' => 'print'));
+ $container->style('jquery', 'jquery.css', array('jquery-ui', 'dojo'));
+ $container->style('jquery-ui', 'jquery-ui.css');
+
+ $styles = $container->styles();
+
+ $this->assertTrue(strpos($styles, 'jquery.css') > 0);
+ $this->assertTrue(strpos($styles, 'media="print"') > 0);
+ $this->assertTrue(strpos($styles, 'jquery.css') > strpos($styles, 'jquery-ui.css'));
+ $this->assertTrue(strpos($styles, 'dojo.css') > strpos($styles, 'jquery-ui.css'));
+ }
+
+ /**
+ * Get an asset container instance.
+ *
+ * @param string $name
+ * @return Asset_Container
+ */
+ private function getContainer($name = 'foo')
+ {
+ return new Laravel\Asset_Container($name);
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/auth.test.php b/app/laravel/tests/cases/auth.test.php
new file mode 100644
index 000000000..3be1c1e5f
--- /dev/null
+++ b/app/laravel/tests/cases/auth.test.php
@@ -0,0 +1,356 @@
+user = null;
+ Session::$instance = null;
+ Config::set('database.default', 'sqlite');
+ }
+
+ /**
+ * Tear down the test environment.
+ */
+ public function tearDown()
+ {
+ $_SERVER['auth.login.stub'] = null;
+ Cookie::$jar = array();
+ Config::$items = array();
+ Auth::driver()->user = null;
+ Session::$instance = null;
+ Config::set('database.default', 'mysql');
+ }
+
+ /**
+ * Set one of the $_SERVER variables.
+ *
+ * @param string $key
+ * @param string $value
+ */
+ protected function setServerVar($key, $value)
+ {
+ $_SERVER[$key] = $value;
+
+ $this->restartRequest();
+ }
+
+ /**
+ * Reinitialize the global request.
+ *
+ * @return void
+ */
+ protected function restartRequest()
+ {
+ // FIXME: Ugly hack, but old contents from previous requests seem to
+ // trip up the Foundation class.
+ $_FILES = array();
+
+ Request::$foundation = RequestFoundation::createFromGlobals();
+ }
+
+ /**
+ * Test the Auth::user method.
+ *
+ * @group laravel
+ */
+ public function testUserMethodReturnsCurrentUser()
+ {
+ Auth::driver()->user = 'Taylor';
+
+ $this->assertEquals('Taylor', Auth::user());
+ }
+
+ /**
+ * Test the Auth::check method.
+ *
+ * @group laravel
+ */
+ public function testCheckMethodReturnsTrueWhenUserIsSet()
+ {
+ $auth = new AuthUserReturnsDummy;
+
+ $this->assertTrue($auth->check());
+ }
+
+ /**
+ * Test the Auth::check method.
+ *
+ * @group laravel
+ */
+ public function testCheckMethodReturnsFalseWhenNoUserIsSet()
+ {
+ $auth = new AuthUserReturnsNull;
+
+ $this->assertFalse($auth->check());
+ }
+
+ /**
+ * Test the Auth::guest method.
+ *
+ * @group laravel
+ */
+ public function testGuestReturnsTrueWhenNoUserIsSet()
+ {
+ $auth = new AuthUserReturnsNull;
+
+ $this->assertTrue($auth->guest());
+ }
+
+ /**
+ * Test the Auth::guest method.
+ *
+ * @group laravel
+ */
+ public function testGuestReturnsFalseWhenUserIsSet()
+ {
+ $auth = new AuthUserReturnsDummy;
+
+ $this->assertFalse($auth->guest());
+ }
+
+ /**
+ * Test the Auth::user method.
+ *
+ * @group laravel
+ */
+ public function testUserMethodReturnsNullWhenNoUserExistsAndNoRecallerExists()
+ {
+ Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver'));
+
+ $this->assertNull(Auth::user());
+ }
+
+ /**
+ * Test the Auth::user method.
+ *
+ * @group laravel
+ */
+ public function testUserReturnsUserByID()
+ {
+ Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver'));
+
+ Auth::login(1);
+
+ $this->assertEquals('Taylor Otwell', Auth::user()->name);
+
+ Auth::logout();
+ }
+
+ /**
+ * Test the Auth::user method.
+ *
+ * @group laravel
+ */
+ public function testNullReturnedWhenUserIDNotValidInteger()
+ {
+ Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver'));
+
+ Auth::login('asdlkasd');
+
+ $this->assertNull(Auth::user());
+ }
+
+ /**
+ * Test the Auth::recall method.
+ *
+ * @group laravel
+ */
+ public function testUserCanBeRecalledViaCookie()
+ {
+ Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver'));
+
+ $cookie = Crypter::encrypt('1|'.Str::random(40));
+ Cookie::forever('authloginstub_remember', $cookie);
+
+ $auth = new AuthLoginStub;
+
+ $this->assertEquals('Taylor Otwell', $auth->user()->name);
+
+ $this->assertTrue($auth->user()->id === $_SERVER['auth.login.stub']['user']);
+ }
+
+ /**
+ * Test the Auth::attempt method.
+ *
+ * @group laravel
+ */
+ public function testAttemptMethodReturnsFalseWhenCredentialsAreInvalid()
+ {
+ $this->assertFalse(Auth::attempt(array('username' => 'foo', 'password' => 'foo')));
+ $this->assertFalse(Auth::attempt(array('username' => 'foo', 'password' => null)));
+ $this->assertFalse(Auth::attempt(array('username' => null, 'password' => null)));
+ $this->assertFalse(Auth::attempt(array('username' => 'taylor', 'password' => 'password')));
+ $this->assertFalse(Auth::attempt(array('username' => 'taylor', 'password' => 232)));
+ }
+
+ /**
+ * Test the Auth::attempt method.
+ *
+ * @group laravel
+ */
+ public function testAttemptReturnsTrueWhenCredentialsAreCorrect()
+ {
+ Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver'));
+
+ $auth = new AuthLoginStub;
+
+ $this->assertTrue($auth->attempt(array('username' => 'taylor', 'password' => 'password1')));
+ $this->assertEquals('1', $_SERVER['auth.login.stub']['user']);
+ $this->assertFalse($_SERVER['auth.login.stub']['remember']);
+
+ $auth_secure = new AuthLoginStub;
+
+ $this->assertTrue($auth_secure->attempt(array('username' => 'taylor', 'password' => 'password1', 'remember' => true)));
+ $this->assertEquals('1', $_SERVER['auth.login.stub']['user']);
+ $this->assertTrue($_SERVER['auth.login.stub']['remember']);
+
+ $auth_secure->logout();
+ $auth->logout();
+ }
+
+ /**
+ * Test Auth::login method.
+ *
+ * @group laravel
+ */
+ public function testLoginMethodStoresUserKeyInSession()
+ {
+ Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver'));
+
+ $user = new StdClass;
+ $user->id = 10;
+ Auth::login($user);
+ // FIXME: Not sure whether hard-coding the key is a good idea.
+ $user = Session::$instance->session['data']['laravel_auth_drivers_fluent_login'];
+ $this->assertEquals(10, $user->id);
+
+
+ Auth::logout();
+
+ Auth::login(5);
+ $user = Session::$instance->session['data']['laravel_auth_drivers_fluent_login'];
+ $this->assertEquals(5, $user);
+ Auth::logout(5);
+ }
+
+ /**
+ * Test the Auth::login method.
+ *
+ * @group laravel
+ */
+ public function testLoginStoresRememberCookieWhenNeeded()
+ {
+ Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver'));
+
+ $this->setServerVar('HTTPS', 'on');
+
+ // Set the session vars to make sure remember cookie uses them
+ Config::set('session.path', 'foo');
+ Config::set('session.domain', 'bar');
+ Config::set('session.secure', true);
+
+ Auth::login(1, true);
+
+ $this->assertTrue(isset(Cookie::$jar['laravel_auth_drivers_fluent_remember']));
+
+ $cookie = Cookie::get('laravel_auth_drivers_fluent_remember');
+ $cookie = explode('|', Crypter::decrypt($cookie));
+ $this->assertEquals(1, $cookie[0]);
+ $this->assertEquals('foo', Cookie::$jar['laravel_auth_drivers_fluent_remember']['path']);
+ $this->assertEquals('bar', Cookie::$jar['laravel_auth_drivers_fluent_remember']['domain']);
+ $this->assertTrue(Cookie::$jar['laravel_auth_drivers_fluent_remember']['secure']);
+
+ Auth::logout();
+
+ $this->setServerVar('HTTPS', 'off');
+ }
+
+ /**
+ * Test the Auth::logout method.
+ *
+ * @group laravel
+ */
+ public function testLogoutMethodLogsOutUser()
+ {
+ Session::$instance = new Payload($this->getMock('Laravel\\Session\\Drivers\\Driver'));
+
+ $data = Session::$instance->session['data']['laravel_auth_drivers_fluent_login'] = 1;
+
+ Auth::logout();
+
+ $this->assertNull(Auth::user());
+
+ $this->assertFalse(isset(Session::$instance->session['data']['laravel_auth_drivers_fluent_login']));
+ $this->assertTrue(Cookie::$jar['laravel_auth_drivers_fluent_remember']['expiration'] < time());
+ }
+
+}
+
+class AuthUserReturnsNull extends Laravel\Auth\Drivers\Driver {
+
+ public function user() { return null; }
+
+ public function retrieve($id) { return null; }
+
+ public function attempt($arguments = array()) { return null; }
+
+}
+
+class AuthUserReturnsDummy extends Laravel\Auth\Drivers\Driver {
+
+ public function user() { return 'Taylor'; }
+
+ public function retrieve($id) { return null; }
+
+ public function attempt($arguments = array())
+ {
+ return $this->login($arguments['username']);
+ }
+
+}
+
+class AuthLoginStub extends Laravel\Auth\Drivers\Fluent {
+
+ public function login($user, $remember = false)
+ {
+ if (is_null($remember)) $remember = false;
+
+ $_SERVER['auth.login.stub'] = compact('user', 'remember');
+
+ return parent::login($user, $remember);
+ }
+
+ public function logout()
+ {
+ parent::logout();
+ }
+
+ public function retrieve($id)
+ {
+ $user = parent::retrieve($id);
+
+ $_SERVER['auth.login.stub'] = array(
+ 'user' => $user->id,
+ 'remember' => false,
+ );
+
+ return $user;
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/autoloader.test.php b/app/laravel/tests/cases/autoloader.test.php
new file mode 100644
index 000000000..80605447c
--- /dev/null
+++ b/app/laravel/tests/cases/autoloader.test.php
@@ -0,0 +1,102 @@
+ path('app').'models/foo.php',
+ ));
+
+ $this->assertEquals(path('app').'models/foo.php', Autoloader::$mappings['Foo']);
+ }
+
+ /**
+ * Test the Autoloader::alias method.
+ *
+ * @group laravel
+ */
+ public function testAliasesCanBeRegistered()
+ {
+ Autoloader::alias('Foo\\Bar', 'Foo');
+
+ $this->assertEquals('Foo\\Bar', Autoloader::$aliases['Foo']);
+ }
+
+ /**
+ * Test the Autoloader::directories method.
+ *
+ * @group laravel
+ */
+ public function testPsrDirectoriesCanBeRegistered()
+ {
+ Autoloader::directories(array(
+ path('app').'foo'.DS.'bar',
+ path('app').'foo'.DS.'baz'.DS.DS,
+ ));
+
+ $this->assertTrue(in_array(path('app').'foo'.DS.'bar'.DS, Autoloader::$directories));
+ $this->assertTrue(in_array(path('app').'foo'.DS.'baz'.DS, Autoloader::$directories));
+ }
+
+ /**
+ * Test the Autoloader::namespaces method.
+ *
+ * @group laravel
+ */
+ public function testNamespacesCanBeRegistered()
+ {
+ Autoloader::namespaces(array(
+ 'Autoloader_1' => path('bundle').'autoload'.DS.'models',
+ 'Autoloader_2' => path('bundle').'autoload'.DS.'libraries'.DS.DS,
+ ));
+
+ $this->assertEquals(path('bundle').'autoload'.DS.'models'.DS, Autoloader::$namespaces['Autoloader_1\\']);
+ $this->assertEquals(path('bundle').'autoload'.DS.'libraries'.DS, Autoloader::$namespaces['Autoloader_2\\']);
+ }
+
+ /**
+ * Test the loading of PSR-0 models and libraries.
+ *
+ * @group laravel
+ */
+ public function testPsrLibrariesAndModelsCanBeLoaded()
+ {
+ $this->assertInstanceOf('User', new User);
+ $this->assertInstanceOf('Repositories\\User', new Repositories\User);
+ }
+
+ /**
+ * Test the loading of hard-coded classes.
+ *
+ * @group laravel
+ */
+ public function testHardcodedClassesCanBeLoaded()
+ {
+ Autoloader::map(array(
+ 'Autoloader_HardCoded' => path('app').'models'.DS.'autoloader.php',
+ ));
+
+ $this->assertInstanceOf('Autoloader_HardCoded', new Autoloader_HardCoded);
+ }
+
+ /**
+ * Test the loading of classes mapped by namespaces.
+ *
+ * @group laravel
+ */
+ public function testClassesMappedByNamespaceCanBeLoaded()
+ {
+ Autoloader::namespaces(array(
+ 'Dashboard' => path('bundle').'dashboard'.DS.'models',
+ ));
+
+ $this->assertInstanceOf('Dashboard\\Repository', new Dashboard\Repository);
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/blade.test.php b/app/laravel/tests/cases/blade.test.php
new file mode 100644
index 000000000..fb60cc21a
--- /dev/null
+++ b/app/laravel/tests/cases/blade.test.php
@@ -0,0 +1,120 @@
+assertEquals('', Blade::compile_string($blade1));
+ $this->assertEquals('', Blade::compile_string($blade2));
+ }
+
+ /**
+ * Test the compilation of comments statements.
+ *
+ * @group laravel
+ */
+ public function testCommentsAreConvertedProperly()
+ {
+ $blade1 = "{{-- This is a comment --}}";
+ $blade2 = "{{--\nThis is a\nmulti-line\ncomment.\n--}}";
+
+ $this->assertEquals("\n", Blade::compile_string($blade1));
+ $this->assertEquals("\n", Blade::compile_string($blade2));
+ }
+
+ /**
+ * Test the compilation of control structures.
+ *
+ * @group laravel
+ */
+ public function testControlStructuresAreCreatedCorrectly()
+ {
+ $blade1 = "@if (true)\nfoo\n@endif";
+ $blade2 = "@if (count(".'$something'.") > 0)\nfoo\n@endif";
+ $blade3 = "@if (true)\nfoo\n@elseif (false)\nbar\n@else\nfoobar\n@endif";
+ $blade4 = "@if (true)\nfoo\n@elseif (false)\nbar\n@endif";
+ $blade5 = "@if (true)\nfoo\n@else\nbar\n@endif";
+ $blade6 = "@unless (count(".'$something'.") > 0)\nfoobar\n@endunless";
+ $blade7 = "@for (Foo::all() as ".'$foo'.")\nfoo\n@endfor";
+ $blade8 = "@foreach (Foo::all() as ".'$foo'.")\nfoo\n@endforeach";
+ $blade9 = "@forelse (Foo::all() as ".'$foo'.")\nfoo\n@empty\nbar\n@endforelse";
+ $blade10 = "@while (true)\nfoo\n@endwhile";
+ $blade11 = "@while (Foo::bar())\nfoo\n@endwhile";
+
+
+ $this->assertEquals("\nfoo\n", Blade::compile_string($blade1));
+ $this->assertEquals(" 0): ?>\nfoo\n", Blade::compile_string($blade2));
+ $this->assertEquals("\nfoo\n\nbar\n\nfoobar\n", Blade::compile_string($blade3));
+ $this->assertEquals("\nfoo\n\nbar\n", Blade::compile_string($blade4));
+ $this->assertEquals("\nfoo\n\nbar\n", Blade::compile_string($blade5));
+ $this->assertEquals(" 0))): ?>\nfoobar\n", Blade::compile_string($blade6));
+ $this->assertEquals("\nfoo\n", Blade::compile_string($blade7));
+ $this->assertEquals("\nfoo\n", Blade::compile_string($blade8));
+ $this->assertEquals(" 0): ?>\nfoo\n\nbar\n", Blade::compile_string($blade9));
+ $this->assertEquals("\nfoo\n", Blade::compile_string($blade10));
+ $this->assertEquals("\nfoo\n", Blade::compile_string($blade11));
+ }
+
+ /**
+ * Test the compilation of yield statements.
+ *
+ * @group laravel
+ */
+ public function testYieldsAreCompiledCorrectly()
+ {
+ $blade = "@yield('something')";
+
+ $this->assertEquals("", Blade::compile_string($blade));
+ }
+
+ /**
+ * Test the compilation of section statements.
+ *
+ * @group laravel
+ */
+ public function testSectionsAreCompiledCorrectly()
+ {
+ $blade = "@section('something')\nfoo\n@endsection";
+
+ $this->assertEquals("\nfoo\n", Blade::compile_string($blade));
+ }
+
+ /**
+ * Test the compilation of include statements.
+ *
+ * @group laravel
+ */
+ public function testIncludesAreCompiledCorrectly()
+ {
+ $blade1 = "@include('user.profile')";
+ $blade2 = "@include(Config::get('application.default_view', 'user.profile'))";
+
+ $this->assertEquals("with(get_defined_vars())->render(); ?>", Blade::compile_string($blade1));
+ $this->assertEquals("with(get_defined_vars())->render(); ?>", Blade::compile_string($blade2));
+ }
+
+ /**
+ * Test the compilation of render statements.
+ *
+ * @group laravel
+ */
+ public function testRendersAreCompiledCorrectly()
+ {
+ $blade1 = "@render('user.profile')";
+ $blade2 = "@render(Config::get('application.default_view', 'user.profile'))";
+
+ $this->assertEquals("", Blade::compile_string($blade1));
+ $this->assertEquals("", Blade::compile_string($blade2));
+
+ }
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/bundle.test.php b/app/laravel/tests/cases/bundle.test.php
new file mode 100644
index 000000000..9826a50fd
--- /dev/null
+++ b/app/laravel/tests/cases/bundle.test.php
@@ -0,0 +1,251 @@
+ 'foo-baz'));
+ $this->assertEquals('foo-baz', Bundle::$bundles['foo-baz']['handles']);
+ $this->assertFalse(Bundle::$bundles['foo-baz']['auto']);
+
+ Bundle::register('foo-bar', array());
+ $this->assertFalse(Bundle::$bundles['foo-baz']['auto']);
+ $this->assertNull(Bundle::$bundles['foo-bar']['handles']);
+
+ unset(Bundle::$bundles['foo-baz']);
+ unset(Bundle::$bundles['foo-bar']);
+ }
+
+ /**
+ * Test the Bundle::start method.
+ *
+ * @group laravel
+ */
+ public function testStartMethodStartsBundle()
+ {
+ $_SERVER['bundle.dummy.start'] = 0;
+ $_SERVER['bundle.dummy.routes'] = 0;
+
+ $_SERVER['started.dummy'] = false;
+
+ Event::listen('laravel.started: dummy', function()
+ {
+ $_SERVER['started.dummy'] = true;
+ });
+
+ Bundle::register('dummy');
+ Bundle::start('dummy');
+
+ $this->assertTrue($_SERVER['started.dummy']);
+ $this->assertEquals(1, $_SERVER['bundle.dummy.start']);
+ $this->assertEquals(1, $_SERVER['bundle.dummy.routes']);
+
+ Bundle::start('dummy');
+
+ $this->assertEquals(1, $_SERVER['bundle.dummy.start']);
+ $this->assertEquals(1, $_SERVER['bundle.dummy.routes']);
+ }
+
+ /**
+ * Test Bundle::handles method.
+ *
+ * @group laravel
+ */
+ public function testHandlesMethodReturnsBundleThatHandlesURI()
+ {
+ Bundle::register('foo', array('handles' => 'foo-bar'));
+ $this->assertEquals('foo', Bundle::handles('foo-bar/admin'));
+ unset(Bundle::$bundles['foo']);
+ }
+
+ /**
+ * Test the Bundle::exist method.
+ *
+ * @group laravel
+ */
+ public function testExistMethodIndicatesIfBundleExist()
+ {
+ $this->assertTrue(Bundle::exists('dashboard'));
+ $this->assertFalse(Bundle::exists('foo'));
+ }
+
+ /**
+ * Test the Bundle::started method.
+ *
+ * @group laravel
+ */
+ public function testStartedMethodIndicatesIfBundleIsStarted()
+ {
+ Bundle::register('dummy');
+ Bundle::start('dummy');
+ $this->assertTrue(Bundle::started('dummy'));
+ }
+
+ /**
+ * Test the Bundle::prefix method.
+ *
+ * @group laravel
+ */
+ public function testPrefixMethodReturnsCorrectPrefix()
+ {
+ $this->assertEquals('dummy::', Bundle::prefix('dummy'));
+ $this->assertEquals('', Bundle::prefix(DEFAULT_BUNDLE));
+ }
+
+ /**
+ * Test the Bundle::class_prefix method.
+ *
+ * @group laravel
+ */
+ public function testClassPrefixMethodReturnsProperClassPrefixForBundle()
+ {
+ $this->assertEquals('Dummy_', Bundle::class_prefix('dummy'));
+ $this->assertEquals('', Bundle::class_prefix(DEFAULT_BUNDLE));
+ }
+
+ /**
+ * Test the Bundle::path method.
+ *
+ * @group laravel
+ */
+ public function testPathMethodReturnsCorrectPath()
+ {
+ $this->assertEquals(path('app'), Bundle::path(null));
+ $this->assertEquals(path('app'), Bundle::path(DEFAULT_BUNDLE));
+ $this->assertEquals(path('bundle').'dashboard'.DS, Bundle::path('dashboard'));
+ }
+
+ /**
+ * Test the Bundle::asset method.
+ *
+ * @group laravel
+ */
+ public function testAssetPathReturnsPathToBundlesAssets()
+ {
+ $this->assertEquals('/bundles/dashboard/', Bundle::assets('dashboard'));
+ $this->assertEquals('/', Bundle::assets(DEFAULT_BUNDLE));
+
+ Config::set('application.url', '');
+ }
+
+ /**
+ * Test the Bundle::name method.
+ *
+ * @group laravel
+ */
+ public function testBundleNameCanBeRetrievedFromIdentifier()
+ {
+ $this->assertEquals(DEFAULT_BUNDLE, Bundle::name('something'));
+ $this->assertEquals(DEFAULT_BUNDLE, Bundle::name('something.else'));
+ $this->assertEquals('bundle', Bundle::name('bundle::something.else'));
+ }
+
+ /**
+ * Test the Bundle::element method.
+ *
+ * @group laravel
+ */
+ public function testElementCanBeRetrievedFromIdentifier()
+ {
+ $this->assertEquals('something', Bundle::element('something'));
+ $this->assertEquals('something.else', Bundle::element('something.else'));
+ $this->assertEquals('something.else', Bundle::element('bundle::something.else'));
+ }
+
+ /**
+ * Test the Bundle::identifier method.
+ *
+ * @group laravel
+ */
+ public function testIdentifierCanBeConstructed()
+ {
+ $this->assertEquals('something.else', Bundle::identifier(DEFAULT_BUNDLE, 'something.else'));
+ $this->assertEquals('dashboard::something', Bundle::identifier('dashboard', 'something'));
+ $this->assertEquals('dashboard::something.else', Bundle::identifier('dashboard', 'something.else'));
+ }
+
+ /**
+ * Test the Bundle::resolve method.
+ *
+ * @group laravel
+ */
+ public function testBundleNamesCanBeResolved()
+ {
+ $this->assertEquals(DEFAULT_BUNDLE, Bundle::resolve('foo'));
+ $this->assertEquals('dashboard', Bundle::resolve('dashboard'));
+ }
+
+ /**
+ * Test the Bundle::parse method.
+ *
+ * @group laravel
+ */
+ public function testParseMethodReturnsElementAndIdentifier()
+ {
+ $this->assertEquals(array('application', 'something'), Bundle::parse('something'));
+ $this->assertEquals(array('application', 'something.else'), Bundle::parse('something.else'));
+ $this->assertEquals(array('dashboard', 'something'), Bundle::parse('dashboard::something'));
+ $this->assertEquals(array('dashboard', 'something.else'), Bundle::parse('dashboard::something.else'));
+ }
+
+ /**
+ * Test the Bundle::get method.
+ *
+ * @group laravel
+ */
+ public function testOptionMethodReturnsBundleOption()
+ {
+ $this->assertFalse(Bundle::option('dashboard', 'auto'));
+ $this->assertEquals('dashboard', Bundle::option('dashboard', 'location'));
+ }
+
+ /**
+ * Test the Bundle::all method.
+ *
+ * @group laravel
+ */
+ public function testAllMethodReturnsBundleArray()
+ {
+ Bundle::register('foo');
+ $this->assertEquals(Bundle::$bundles, Bundle::all());
+ unset(Bundle::$bundles['foo']);
+ }
+
+ /**
+ * Test the Bundle::names method.
+ *
+ * @group laravel
+ */
+ public function testNamesMethodReturnsBundleNames()
+ {
+ Bundle::register('foo');
+ $this->assertEquals(array('dashboard', 'dummy', 'foo'), Bundle::names());
+ unset(Bundle::$bundles['foo']);
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/config.test.php b/app/laravel/tests/cases/config.test.php
new file mode 100644
index 000000000..573b8cff7
--- /dev/null
+++ b/app/laravel/tests/cases/config.test.php
@@ -0,0 +1,79 @@
+assertEquals('UTF-8', Config::get('application.encoding'));
+ $this->assertEquals('mysql', Config::get('database.connections.mysql.driver'));
+ $this->assertEquals('dashboard', Config::get('dashboard::meta.bundle'));
+ }
+
+ /**
+ * Test the Config::has method.
+ *
+ * @group laravel
+ */
+ public function testHasMethodIndicatesIfConfigItemExists()
+ {
+ $this->assertFalse(Config::has('application.foo'));
+ $this->assertTrue(Config::has('application.encoding'));
+ }
+
+ /**
+ * Test the Config::set method.
+ *
+ * @group laravel
+ */
+ public function testConfigItemsCanBeSet()
+ {
+ Config::set('application.encoding', 'foo');
+ Config::set('dashboard::meta.bundle', 'bar');
+
+ $this->assertEquals('foo', Config::get('application.encoding'));
+ $this->assertEquals('bar', Config::get('dashboard::meta.bundle'));
+ }
+
+ /**
+ * Test that environment configurations are loaded correctly.
+ *
+ * @group laravel
+ */
+ public function testEnvironmentConfigsOverrideNormalConfigurations()
+ {
+ $_SERVER['LARAVEL_ENV'] = 'local';
+
+ $this->assertEquals('sqlite', Config::get('database.default'));
+
+ unset($_SERVER['LARAVEL_ENV']);
+ }
+
+ /**
+ * Test that items can be set after the entire file has already been loaded.
+ *
+ * @group laravel
+ */
+ public function testItemsCanBeSetAfterEntireFileIsLoaded()
+ {
+ Config::get('application');
+ Config::set('application.key', 'taylor');
+ $application = Config::get('application');
+
+ $this->assertEquals('taylor', $application['key']);
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/controller.test.php b/app/laravel/tests/cases/controller.test.php
new file mode 100644
index 000000000..9eb192b91
--- /dev/null
+++ b/app/laravel/tests/cases/controller.test.php
@@ -0,0 +1,267 @@
+assertEquals('action_index', Controller::call('auth@index')->content);
+ $this->assertEquals('Admin_Panel_Index', Controller::call('admin.panel@index')->content);
+ $this->assertEquals('Taylor', Controller::call('auth@profile', array('Taylor'))->content);
+ $this->assertEquals('Dashboard_Panel_Index', Controller::call('dashboard::panel@index')->content);
+ }
+
+ /**
+ * Test basic controller filters are called.
+ *
+ * @group laravel
+ */
+ public function testAssignedBeforeFiltersAreRun()
+ {
+ $_SERVER['test-all-after'] = false;
+ $_SERVER['test-all-before'] = false;
+
+ Controller::call('filter@index');
+
+ $this->assertTrue($_SERVER['test-all-after']);
+ $this->assertTrue($_SERVER['test-all-before']);
+ }
+
+ /**
+ * Test that "only" filters only apply to their assigned methods.
+ *
+ * @group laravel
+ */
+ public function testOnlyFiltersOnlyApplyToTheirAssignedMethods()
+ {
+ $_SERVER['test-profile-before'] = false;
+
+ Controller::call('filter@index');
+
+ $this->assertFalse($_SERVER['test-profile-before']);
+
+ Controller::call('filter@profile');
+
+ $this->assertTrue($_SERVER['test-profile-before']);
+ }
+
+ /**
+ * Test that "except" filters only apply to the excluded methods.
+ *
+ * @group laravel
+ */
+ public function testExceptFiltersOnlyApplyToTheExlucdedMethods()
+ {
+ $_SERVER['test-except'] = false;
+
+ Controller::call('filter@index');
+ Controller::call('filter@profile');
+
+ $this->assertFalse($_SERVER['test-except']);
+
+ Controller::call('filter@show');
+
+ $this->assertTrue($_SERVER['test-except']);
+ }
+
+ /**
+ * Test that filters can be constrained by the request method.
+ *
+ * @group laravel
+ */
+ public function testFiltersCanBeConstrainedByRequestMethod()
+ {
+ $_SERVER['test-on-post'] = false;
+
+ Request::$foundation->setMethod('GET');
+ Controller::call('filter@index');
+
+ $this->assertFalse($_SERVER['test-on-post']);
+
+ Request::$foundation->setMethod('POST');
+ Controller::call('filter@index');
+
+ $this->assertTrue($_SERVER['test-on-post']);
+
+ $_SERVER['test-on-get-put'] = false;
+
+ Request::$foundation->setMethod('POST');
+ Controller::call('filter@index');
+
+ $this->assertFalse($_SERVER['test-on-get-put']);
+
+ Request::$foundation->setMethod('PUT');
+ Controller::call('filter@index');
+
+ $this->assertTrue($_SERVER['test-on-get-put']);
+ }
+
+ public function testGlobalBeforeFilterIsNotCalledByController()
+ {
+ $_SERVER['before'] = false;
+ $_SERVER['after'] = false;
+
+ Controller::call('auth@index');
+
+ $this->assertFalse($_SERVER['before']);
+ $this->assertFalse($_SERVER['after']);
+ }
+
+ /**
+ * Test that before filters can override the controller response.
+ *
+ * @group laravel
+ */
+ public function testBeforeFiltersCanOverrideResponses()
+ {
+ $this->assertEquals('Filtered!', Controller::call('filter@login')->content);
+ }
+
+ /**
+ * Test that after filters do not affect the response.
+ *
+ * @group laravel
+ */
+ public function testAfterFiltersDoNotAffectControllerResponse()
+ {
+ $this->assertEquals('action_logout', Controller::call('filter@logout')->content);
+ }
+
+ /**
+ * Test that filter parameters are passed to the filter.
+ *
+ * @group laravel
+ */
+ public function testFilterParametersArePassedToTheFilter()
+ {
+ $this->assertEquals('12', Controller::call('filter@edit')->content);
+ }
+
+ /**
+ * Test that multiple filters can be assigned to a single method.
+ *
+ * @group laravel
+ */
+ public function testMultipleFiltersCanBeAssignedToAnAction()
+ {
+ $_SERVER['test-multi-1'] = false;
+ $_SERVER['test-multi-2'] = false;
+
+ Controller::call('filter@save');
+
+ $this->assertTrue($_SERVER['test-multi-1']);
+ $this->assertTrue($_SERVER['test-multi-2']);
+ }
+
+ /**
+ * Test Restful controllers respond by request method.
+ *
+ * @group laravel
+ */
+ public function testRestfulControllersRespondWithRestfulMethods()
+ {
+ Request::$foundation->setMethod('GET');
+ //$_SERVER['REQUEST_METHOD'] = 'GET';
+
+ $this->assertEquals('get_index', Controller::call('restful@index')->content);
+
+ //$_SERVER['REQUEST_METHOD'] = 'PUT';
+ Request::$foundation->setMethod('PUT');
+
+ $this->assertEquals(404, Controller::call('restful@index')->status());
+
+ //$_SERVER['REQUEST_METHOD'] = 'POST';
+ Request::$foundation->setMethod('POST');
+
+ $this->assertEquals('post_index', Controller::call('restful@index')->content);
+ }
+
+ /**
+ * Test that the template is returned by template controllers.
+ *
+ * @group laravel
+ */
+ public function testTemplateControllersReturnTheTemplate()
+ {
+ $response = Controller::call('template.basic@index');
+
+ $home = file_get_contents(path('app').'views/home/index.php');
+
+ $this->assertEquals($home, $response->content);
+ }
+
+ /**
+ * Test that controller templates can be named views.
+ *
+ * @group laravel
+ */
+ public function testControllerTemplatesCanBeNamedViews()
+ {
+ View::name('home.index', 'home');
+
+ $response = Controller::call('template.named@index');
+
+ $home = file_get_contents(path('app').'views/home/index.php');
+
+ $this->assertEquals($home, $response->content);
+
+ View::$names = array();
+ }
+
+ /**
+ * Test that the "layout" method is called on the controller.
+ *
+ * @group laravel
+ */
+ public function testTheTemplateCanBeOverriden()
+ {
+ $this->assertEquals('Layout', Controller::call('template.override@index')->content);
+ }
+
+ /**
+ * Test the Controller::resolve method.
+ *
+ * @group laravel
+ */
+ public function testResolveMethodChecksTheIoCContainer()
+ {
+ IoC::register('controller: home', function()
+ {
+ require_once path('app').'controllers/home.php';
+
+ $controller = new Home_Controller;
+
+ $controller->foo = 'bar';
+
+ return $controller;
+ });
+
+ $controller = Controller::resolve(DEFAULT_BUNDLE, 'home');
+
+ $this->assertEquals('bar', $controller->foo);
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/cookie.test.php b/app/laravel/tests/cases/cookie.test.php
new file mode 100644
index 000000000..37d635539
--- /dev/null
+++ b/app/laravel/tests/cases/cookie.test.php
@@ -0,0 +1,134 @@
+restartRequest();
+ }
+
+ /**
+ * Reinitialize the global request.
+ *
+ * @return void
+ */
+ protected function restartRequest()
+ {
+ // FIXME: Ugly hack, but old contents from previous requests seem to
+ // trip up the Foundation class.
+ $_FILES = array();
+
+ Request::$foundation = RequestFoundation::createFromGlobals();
+ }
+
+ /**
+ * Test Cookie::has method.
+ *
+ * @group laravel
+ */
+ public function testHasMethodIndicatesIfCookieInSet()
+ {
+ Cookie::$jar['foo'] = array('value' => Cookie::hash('bar').'+bar');
+ $this->assertTrue(Cookie::has('foo'));
+ $this->assertFalse(Cookie::has('bar'));
+
+ Cookie::put('baz', 'foo');
+ $this->assertTrue(Cookie::has('baz'));
+ }
+
+ /**
+ * Test the Cookie::get method.
+ *
+ * @group laravel
+ */
+ public function testGetMethodCanReturnValueOfCookies()
+ {
+ Cookie::$jar['foo'] = array('value' => Cookie::hash('bar').'+bar');
+ $this->assertEquals('bar', Cookie::get('foo'));
+
+ Cookie::put('bar', 'baz');
+ $this->assertEquals('baz', Cookie::get('bar'));
+ }
+
+ /**
+ * Test Cookie::forever method.
+ *
+ * @group laravel
+ */
+ public function testForeverShouldUseATonOfMinutes()
+ {
+ Cookie::forever('foo', 'bar');
+ $this->assertEquals(Cookie::hash('bar').'+bar', Cookie::$jar['foo']['value']);
+
+ // Shouldn't be able to test this cause while we indicate -2000 seconds
+ // cookie expiration store timestamp.
+ // $this->assertEquals(525600, Cookie::$jar['foo']['expiration']);
+
+ $this->setServerVar('HTTPS', 'on');
+
+ Cookie::forever('bar', 'baz', 'path', 'domain', true);
+ $this->assertEquals('path', Cookie::$jar['bar']['path']);
+ $this->assertEquals('domain', Cookie::$jar['bar']['domain']);
+ $this->assertTrue(Cookie::$jar['bar']['secure']);
+
+ $this->setServerVar('HTTPS', 'off');
+ }
+
+ /**
+ * Test the Cookie::forget method.
+ *
+ * @group laravel
+ */
+ public function testForgetSetsCookieWithExpiration()
+ {
+ Cookie::forget('bar', 'path', 'domain');
+
+ // Shouldn't be able to test this cause while we indicate -2000 seconds
+ // cookie expiration store timestamp.
+ //$this->assertEquals(-2000, Cookie::$jar['bar']['expiration']);
+
+ $this->assertEquals('path', Cookie::$jar['bar']['path']);
+ $this->assertEquals('domain', Cookie::$jar['bar']['domain']);
+ $this->assertFalse(Cookie::$jar['bar']['secure']);
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/database.test.php b/app/laravel/tests/cases/database.test.php
new file mode 100644
index 000000000..84b1faaf6
--- /dev/null
+++ b/app/laravel/tests/cases/database.test.php
@@ -0,0 +1,74 @@
+assertTrue(isset(DB::$connections[Config::get('database.default')]));
+
+ $connection = DatabaseConnectStub::connection('mysql');
+ $this->assertTrue(isset(DB::$connections['mysql']));
+ $this->assertEquals(DB::$connections['mysql']->pdo->laravel_config, Config::get('database.connections.mysql'));
+ }
+
+ /**
+ * Test the DB::profile method.
+ *
+ * @group laravel
+ */
+ public function testProfileMethodReturnsQueries()
+ {
+ Laravel\Database\Connection::$queries = array('Taylor');
+ $this->assertEquals(array('Taylor'), DB::profile());
+ Laravel\Database\Connection::$queries = array();
+ }
+
+ /**
+ * Test the __callStatic method.
+ *
+ * @group laravel
+ */
+ public function testConnectionMethodsCanBeCalledStaticly()
+ {
+ $this->assertEquals('sqlite', DB::driver());
+ }
+
+}
+
+class DatabaseConnectStub extends Laravel\Database {
+
+ protected static function connect($config) { return new PDOStub($config); }
+
+}
+
+class PDOStub extends PDO {
+
+ public $laravel_config;
+
+ public function __construct($config) { $this->laravel_config = $config; }
+
+ public function foo() { return 'foo'; }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/eloquent.test.php b/app/laravel/tests/cases/eloquent.test.php
new file mode 100644
index 000000000..ac489f396
--- /dev/null
+++ b/app/laravel/tests/cases/eloquent.test.php
@@ -0,0 +1,292 @@
+ 'Taylor', 'age' => 25, 'setter' => 'foo');
+
+ $model = new Model($array);
+
+ $this->assertEquals('Taylor', $model->name);
+ $this->assertEquals(25, $model->age);
+ $this->assertEquals('setter: foo', $model->setter);
+ }
+
+ /**
+ * Test the Model::fill method.
+ *
+ * @group laravel
+ */
+ public function testAttributesAreSetByFillMethod()
+ {
+ $array = array('name' => 'Taylor', 'age' => 25, 'setter' => 'foo');
+
+ $model = new Model();
+ $model->fill($array);
+
+ $this->assertEquals('Taylor', $model->name);
+ $this->assertEquals(25, $model->age);
+ $this->assertEquals('setter: foo', $model->setter);
+ }
+
+ /**
+ * Test the Model::fill_raw method.
+ *
+ * @group laravel
+ */
+ public function testAttributesAreSetByFillRawMethod()
+ {
+ $array = array('name' => 'Taylor', 'age' => 25, 'setter' => 'foo');
+
+ $model = new Model();
+ $model->fill_raw($array);
+
+ $this->assertEquals($array, $model->attributes);
+ }
+
+ /**
+ * Test the Model::fill method with accessible.
+ *
+ * @group laravel
+ */
+ public function testAttributesAreSetByFillMethodWithAccessible()
+ {
+ Model::$accessible = array('name', 'age');
+
+ $array = array('name' => 'Taylor', 'age' => 25, 'foo' => 'bar');
+
+ $model = new Model();
+ $model->fill($array);
+
+ $this->assertEquals('Taylor', $model->name);
+ $this->assertEquals(25, $model->age);
+ $this->assertNull($model->foo);
+
+ Model::$accessible = null;
+ }
+
+ /**
+ * Test the Model::fill method with empty accessible array.
+ *
+ * @group laravel
+ */
+ public function testAttributesAreSetByFillMethodWithEmptyAccessible()
+ {
+ Model::$accessible = array();
+
+ $array = array('name' => 'Taylor', 'age' => 25, 'foo' => 'bar');
+
+ $model = new Model();
+ $model->fill($array);
+
+ $this->assertEquals(array(), $model->attributes);
+ $this->assertNull($model->name);
+ $this->assertNull($model->age);
+ $this->assertNull($model->foo);
+
+ Model::$accessible = null;
+ }
+
+ /**
+ * Test the Model::fill_raw method with accessible.
+ *
+ * @group laravel
+ */
+ public function testAttributesAreSetByFillRawMethodWithAccessible()
+ {
+ Model::$accessible = array('name', 'age');
+
+ $array = array('name' => 'taylor', 'age' => 25, 'setter' => 'foo');
+
+ $model = new Model();
+ $model->fill_raw($array);
+
+ $this->assertEquals($array, $model->attributes);
+
+ Model::$accessible = null;
+ }
+
+ /**
+ * Test the Model::__set method.
+ *
+ * @group laravel
+ */
+ public function testAttributeMagicSetterMethodChangesAttribute()
+ {
+ Model::$accessible = array('setter');
+
+ $array = array('setter' => 'foo', 'getter' => 'bar');
+
+ $model = new Model($array);
+ $model->setter = 'bar';
+ $model->getter = 'foo';
+
+ $this->assertEquals('setter: bar', $model->get_attribute('setter'));
+ $this->assertEquals('foo', $model->get_attribute('getter'));
+
+ Model::$accessible = null;
+ }
+
+ /**
+ * Test the Model::__get method.
+ *
+ * @group laravel
+ */
+ public function testAttributeMagicGetterMethodReturnsAttribute()
+ {
+ $array = array('setter' => 'foo', 'getter' => 'bar');
+
+ $model = new Model($array);
+
+ $this->assertEquals('setter: foo', $model->setter);
+ $this->assertEquals('getter: bar', $model->getter);
+ }
+
+ /**
+ * Test the Model::set_* method.
+ *
+ * @group laravel
+ */
+ public function testAttributeSetterMethodChangesAttribute()
+ {
+ Model::$accessible = array('setter');
+
+ $array = array('setter' => 'foo', 'getter' => 'bar');
+
+ $model = new Model($array);
+ $model->set_setter('bar');
+ $model->set_getter('foo');
+
+ $this->assertEquals('setter: bar', $model->get_attribute('setter'));
+ $this->assertEquals('foo', $model->get_attribute('getter'));
+
+ Model::$accessible = null;
+ }
+
+ /**
+ * Test the Model::get_* method.
+ *
+ * @group laravel
+ */
+ public function testAttributeGetterMethodReturnsAttribute()
+ {
+ $array = array('setter' => 'foo', 'getter' => 'bar');
+
+ $model = new Model($array);
+
+ $this->assertEquals('setter: foo', $model->get_setter());
+ $this->assertEquals('getter: bar', $model->get_getter());
+ }
+
+ /**
+ * Test determination of dirty/changed attributes.
+ *
+ * @group laravel
+ */
+ public function testDeterminationOfChangedAttributes()
+ {
+ $array = array('name' => 'Taylor', 'age' => 25, 'foo' => null);
+
+ $model = new Model($array, true);
+ $model->name = 'Otwell';
+ $model->new = null;
+
+ $this->assertTrue($model->changed('name'));
+ $this->assertFalse($model->changed('age'));
+ $this->assertFalse($model->changed('foo'));
+ $this->assertFalse($model->changed('new'));
+ $this->assertTrue($model->dirty());
+ $this->assertEquals(array('name' => 'Otwell', 'new' => null), $model->get_dirty());
+
+ $model->sync();
+
+ $this->assertFalse($model->changed('name'));
+ $this->assertFalse($model->changed('age'));
+ $this->assertFalse($model->changed('foo'));
+ $this->assertFalse($model->changed('new'));
+ $this->assertFalse($model->dirty());
+ $this->assertEquals(array(), $model->get_dirty());
+ }
+
+ /**
+ * Test the Model::purge method.
+ *
+ * @group laravel
+ */
+ public function testAttributePurge()
+ {
+ $array = array('name' => 'Taylor', 'age' => 25);
+
+ $model = new Model($array);
+ $model->name = 'Otwell';
+ $model->age = 26;
+
+ $model->purge('name');
+
+ $this->assertFalse($model->changed('name'));
+ $this->assertNull($model->name);
+ $this->assertTrue($model->changed('age'));
+ $this->assertEquals(26, $model->age);
+ $this->assertEquals(array('age' => 26), $model->get_dirty());
+ }
+
+ /**
+ * Test the Model::table method.
+ *
+ * @group laravel
+ */
+ public function testTableMethodReturnsCorrectName()
+ {
+ $model = new Model();
+ $this->assertEquals('models', $model->table());
+
+ Model::$table = 'table';
+ $this->assertEquals('table', $model->table());
+
+ Model::$table = null;
+ $this->assertEquals('models', $model->table());
+ }
+
+ /**
+ * Test the Model::to_array method.
+ *
+ * @group laravel
+ */
+ public function testConvertingToArray()
+ {
+ Model::$hidden = array('password', 'hidden');
+
+ $array = array('name' => 'Taylor', 'age' => 25, 'password' => 'laravel', 'null' => null);
+
+ $model = new Model($array);
+
+ $first = new Model(array('first' => 'foo', 'password' => 'hidden'));
+ $second = new Model(array('second' => 'bar', 'password' => 'hidden'));
+ $third = new Model(array('third' => 'baz', 'password' => 'hidden'));
+
+ $model->relationships['one'] = new Model(array('foo' => 'bar', 'password' => 'hidden'));
+ $model->relationships['many'] = array($first, $second, $third);
+ $model->relationships['hidden'] = new Model(array('should' => 'visible'));
+ $model->relationships['null'] = null;
+
+ $this->assertEquals(array(
+ 'name' => 'Taylor', 'age' => 25, 'null' => null,
+ 'one' => array('foo' => 'bar'),
+ 'many' => array(
+ array('first' => 'foo'),
+ array('second' => 'bar'),
+ array('third' => 'baz'),
+ ),
+ 'hidden' => array('should' => 'visible'),
+ 'null' => null,
+ ), $model->to_array());
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/event.test.php b/app/laravel/tests/cases/event.test.php
new file mode 100644
index 000000000..520638330
--- /dev/null
+++ b/app/laravel/tests/cases/event.test.php
@@ -0,0 +1,43 @@
+assertEquals(1, $responses[0]);
+ $this->assertEquals(2, $responses[1]);
+ }
+
+ /**
+ * Test parameters can be passed to event listeners.
+ *
+ * @group laravel
+ */
+ public function testParametersCanBePassedToEvents()
+ {
+ Event::listen('test.event', function($var) { return $var; });
+
+ $responses = Event::fire('test.event', array('Taylor'));
+
+ $this->assertEquals('Taylor', $responses[0]);
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/fluent.test.php b/app/laravel/tests/cases/fluent.test.php
new file mode 100644
index 000000000..87c0e0dbb
--- /dev/null
+++ b/app/laravel/tests/cases/fluent.test.php
@@ -0,0 +1,50 @@
+ 'Taylor', 'age' => 25);
+
+ $fluent = new Fluent($array);
+
+ $this->assertEquals($array, $fluent->attributes);
+ }
+
+ /**
+ * Test the Fluent::get method.
+ *
+ * @group laravel
+ */
+ public function testGetMethodReturnsAttribute()
+ {
+ $fluent = new Fluent(array('name' => 'Taylor'));
+
+ $this->assertEquals('Taylor', $fluent->get('name'));
+ $this->assertEquals('Default', $fluent->get('foo', 'Default'));
+ $this->assertEquals('Taylor', $fluent->name);
+ $this->assertNull($fluent->foo);
+ }
+
+ public function testMagicMethodsCanBeUsedToSetAttributes()
+ {
+ $fluent = new Fluent;
+
+ $fluent->name = 'Taylor';
+ $fluent->developer();
+ $fluent->age(25);
+
+ $this->assertEquals('Taylor', $fluent->name);
+ $this->assertTrue($fluent->developer);
+ $this->assertEquals(25, $fluent->age);
+ $this->assertInstanceOf('Laravel\\Fluent', $fluent->programmer());
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/form.test.php b/app/laravel/tests/cases/form.test.php
new file mode 100644
index 000000000..5f6f7fa35
--- /dev/null
+++ b/app/laravel/tests/cases/form.test.php
@@ -0,0 +1,451 @@
+ 'UTF-16', 'class' => 'form'));
+ $form4 = Form::open('foobar', 'DELETE', array('class' => 'form'));
+
+ $this->assertEquals('', Form::close());
+ }
+
+ /**
+ * Test the compilation of form label
+ *
+ * @group laravel
+ */
+ public function testFormLabel()
+ {
+ $form1 = Form::label('foo', 'Foobar');
+ $form2 = Form::label('foo', 'Foobar', array('class' => 'control-label'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals('', $form2);
+ }
+
+ /**
+ * Test the compilation of form input
+ *
+ * @group laravel
+ */
+ public function testFormInput()
+ {
+ $form1 = Form::input('text', 'foo');
+ $form2 = Form::input('text', 'foo', 'foobar');
+ $form3 = Form::input('date', 'foobar', null, array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals('', $form2);
+ $this->assertEquals('', $form3);
+ }
+
+ /**
+ * Test the compilation of form text
+ *
+ * @group laravel
+ */
+ public function testFormText()
+ {
+ $form1 = Form::input('text', 'foo');
+ $form2 = Form::text('foo');
+ $form3 = Form::text('foo', 'foobar');
+ $form4 = Form::text('foo', null, array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals($form1, $form2);
+ $this->assertEquals('', $form3);
+ $this->assertEquals('', $form4);
+ }
+
+ /**
+ * Test the compilation of form password
+ *
+ * @group laravel
+ */
+ public function testFormPassword()
+ {
+ $form1 = Form::input('password', 'foo');
+ $form2 = Form::password('foo');
+ $form3 = Form::password('foo', array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals($form1, $form2);
+ $this->assertEquals('', $form3);
+ }
+
+ /**
+ * Test the compilation of form hidden
+ *
+ * @group laravel
+ */
+ public function testFormHidden()
+ {
+ $form1 = Form::input('hidden', 'foo');
+ $form2 = Form::hidden('foo');
+ $form3 = Form::hidden('foo', 'foobar');
+ $form4 = Form::hidden('foo', null, array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals($form1, $form2);
+ $this->assertEquals('', $form3);
+ $this->assertEquals('', $form4);
+ }
+
+ /**
+ * Test the compilation of form search
+ *
+ * @group laravel
+ */
+ public function testFormSearch()
+ {
+ $form1 = Form::input('search', 'foo');
+ $form2 = Form::search('foo');
+ $form3 = Form::search('foo', 'foobar');
+ $form4 = Form::search('foo', null, array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals($form1, $form2);
+ $this->assertEquals('', $form3);
+ $this->assertEquals('', $form4);
+ }
+
+ /**
+ * Test the compilation of form email
+ *
+ * @group laravel
+ */
+ public function testFormEmail()
+ {
+ $form1 = Form::input('email', 'foo');
+ $form2 = Form::email('foo');
+ $form3 = Form::email('foo', 'foobar');
+ $form4 = Form::email('foo', null, array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals($form1, $form2);
+ $this->assertEquals('', $form3);
+ $this->assertEquals('', $form4);
+ }
+
+ /**
+ * Test the compilation of form telephone
+ *
+ * @group laravel
+ */
+ public function testFormTelephone()
+ {
+ $form1 = Form::input('tel', 'foo');
+ $form2 = Form::telephone('foo');
+ $form3 = Form::telephone('foo', 'foobar');
+ $form4 = Form::telephone('foo', null, array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals($form1, $form2);
+ $this->assertEquals('', $form3);
+ $this->assertEquals('', $form4);
+ }
+
+ /**
+ * Test the compilation of form url
+ *
+ * @group laravel
+ */
+ public function testFormUrl()
+ {
+ $form1 = Form::input('url', 'foo');
+ $form2 = Form::url('foo');
+ $form3 = Form::url('foo', 'foobar');
+ $form4 = Form::url('foo', null, array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals($form1, $form2);
+ $this->assertEquals('', $form3);
+ $this->assertEquals('', $form4);
+ }
+
+ /**
+ * Test the compilation of form number
+ *
+ * @group laravel
+ */
+ public function testFormNumber()
+ {
+ $form1 = Form::input('number', 'foo');
+ $form2 = Form::number('foo');
+ $form3 = Form::number('foo', 'foobar');
+ $form4 = Form::number('foo', null, array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals($form1, $form2);
+ $this->assertEquals('', $form3);
+ $this->assertEquals('', $form4);
+ }
+
+ /**
+ * Test the compilation of form date
+ *
+ * @group laravel
+ */
+ public function testFormDate()
+ {
+ $form1 = Form::input('date', 'foo');
+ $form2 = Form::date('foo');
+ $form3 = Form::date('foo', 'foobar');
+ $form4 = Form::date('foo', null, array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals($form1, $form2);
+ $this->assertEquals('', $form3);
+ $this->assertEquals('', $form4);
+ }
+
+ /**
+ * Test the compilation of form file
+ *
+ * @group laravel
+ */
+ public function testFormFile()
+ {
+ $form1 = Form::input('file', 'foo');
+ $form2 = Form::file('foo');
+ $form3 = Form::file('foo', array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals($form1, $form2);
+ $this->assertEquals('', $form3);
+ }
+
+ /**
+ * Test the compilation of form textarea
+ *
+ * @group laravel
+ */
+ public function testFormTextarea()
+ {
+ $form1 = Form::textarea('foo');
+ $form2 = Form::textarea('foo', 'foobar');
+ $form3 = Form::textarea('foo', null, array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals('', $form2);
+ $this->assertEquals('', $form3);
+ }
+
+ /**
+ * Test the compilation of form select
+ *
+ * @group laravel
+ */
+ public function testFormSelect()
+ {
+ $select1 = array(
+ 'foobar' => 'Foobar',
+ 'hello' => 'Hello World',
+ );
+
+ $select2 = array(
+ 'foo' => array(
+ 'foobar' => 'Foobar',
+ ),
+ 'hello' => 'Hello World',
+ );
+
+ $form1 = Form::select('foo');
+ $form2 = Form::select('foo', $select1, 'foobar');
+ $form3 = Form::select('foo', $select1, null, array('class' => 'span2'));
+ $form4 = Form::select('foo', $select2, 'foobar');
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals('', $form2);
+ $this->assertEquals('', $form3);
+ $this->assertEquals('', $form4);
+ }
+
+ /**
+ * Test the compilation of form checkbox
+ *
+ * @group laravel
+ */
+ public function testFormCheckbox()
+ {
+ $form1 = Form::input('checkbox', 'foo');
+ $form2 = Form::checkbox('foo');
+ $form3 = Form::checkbox('foo', 'foobar', true);
+ $form4 = Form::checkbox('foo', 'foobar', false, array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals('', $form2);
+ $this->assertEquals('', $form3);
+ $this->assertEquals('', $form4);
+ }
+
+ /**
+ * Test the compilation of form date
+ *
+ * @group laravel
+ */
+ public function testFormRadio()
+ {
+ $form1 = Form::input('radio', 'foo');
+ $form2 = Form::radio('foo');
+ $form3 = Form::radio('foo', 'foobar', true);
+ $form4 = Form::radio('foo', 'foobar', false, array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals('', $form2);
+ $this->assertEquals('', $form3);
+ $this->assertEquals('', $form4);
+ }
+
+ /**
+ * Test the compilation of form submit
+ *
+ * @group laravel
+ */
+ public function testFormSubmit()
+ {
+ $form1 = Form::submit('foo');
+ $form2 = Form::submit('foo', array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals('', $form2);
+ }
+
+ /**
+ * Test the compilation of form reset
+ *
+ * @group laravel
+ */
+ public function testFormReset()
+ {
+ $form1 = Form::reset('foo');
+ $form2 = Form::reset('foo', array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals('', $form2);
+ }
+
+ /**
+ * Test the compilation of form image
+ *
+ * @group laravel
+ */
+ public function testFormImage()
+ {
+ $form1 = Form::image('foo/bar', 'foo');
+ $form2 = Form::image('foo/bar', 'foo', array('class' => 'span2'));
+ $form3 = Form::image('http://google.com/foobar', 'foobar');
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals('', $form2);
+ $this->assertEquals('', $form3);
+
+ }
+
+ /**
+ * Test the compilation of form button
+ *
+ * @group laravel
+ */
+ public function testFormButton()
+ {
+ $form1 = Form::button('foo');
+ $form2 = Form::button('foo', array('class' => 'span2'));
+
+ $this->assertEquals('', $form1);
+ $this->assertEquals('', $form2);
+ }
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/hash.test.php b/app/laravel/tests/cases/hash.test.php
new file mode 100644
index 000000000..4dca27138
--- /dev/null
+++ b/app/laravel/tests/cases/hash.test.php
@@ -0,0 +1,37 @@
+assertTrue(strlen(Hash::make('taylor')) == 60);
+ }
+
+ /**
+ * Test the Hash::check method.
+ *
+ * @group laravel
+ */
+ public function testHashCheckFailsWhenNotMatching()
+ {
+ $hash = Hash::make('taylor');
+
+ $this->assertFalse(Hash::check('foo', $hash));
+ }
+
+ /**
+ * Test the Hash::check method.
+ *
+ * @group laravel
+ */
+ public function testHashCheckPassesWhenMatches()
+ {
+ $this->assertTrue(Hash::check('taylor', Hash::make('taylor')));
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/html.test.php b/app/laravel/tests/cases/html.test.php
new file mode 100644
index 000000000..3af4efde3
--- /dev/null
+++ b/app/laravel/tests/cases/html.test.php
@@ -0,0 +1,242 @@
+ 'text/javascript'));
+
+ $this->assertEquals(''."\n", $html1);
+ $this->assertEquals(''."\n", $html2);
+ $this->assertEquals(''."\n", $html3);
+ }
+
+ /**
+ * Test generating a link to CSS files
+ *
+ * @group laravel
+ */
+ public function testGeneratingStyle()
+ {
+ $html1 = HTML::style('foo.css');
+ $html2 = HTML::style('http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js');
+ $html3 = HTML::style('foo.css', array('media' => 'print'));
+
+ $this->assertEquals(''."\n", $html1);
+ $this->assertEquals(''."\n", $html2);
+ $this->assertEquals(''."\n", $html3);
+ }
+
+ /**
+ * Test generating proper span
+ *
+ * @group laravel
+ */
+ public function testGeneratingSpan()
+ {
+ $html1 = HTML::span('foo');
+ $html2 = HTML::span('foo', array('class' => 'badge'));
+
+ $this->assertEquals('foo', $html1);
+ $this->assertEquals('foo', $html2);
+ }
+
+ /**
+ * Test generating proper link
+ *
+ * @group laravel
+ */
+ public function testGeneratingLink()
+ {
+ $html1 = HTML::link('foo');
+ $html2 = HTML::link('foo', 'Foobar');
+ $html3 = HTML::link('foo', 'Foobar', array('class' => 'btn'));
+ $html4 = HTML::link('http://google.com', 'Google');
+
+ $this->assertEquals('http://localhost/index.php/foo', $html1);
+ $this->assertEquals('Foobar', $html2);
+ $this->assertEquals('Foobar', $html3);
+ $this->assertEquals('Google', $html4);
+ }
+
+ /**
+ * Test generating proper link to secure
+ *
+ * @group laravel
+ */
+ public function testGeneratingLinkToSecure()
+ {
+ $html1 = HTML::link_to_secure('foo');
+ $html2 = HTML::link_to_secure('foo', 'Foobar');
+ $html3 = HTML::link_to_secure('foo', 'Foobar', array('class' => 'btn'));
+ $html4 = HTML::link_to_secure('http://google.com', 'Google');
+
+ $this->assertEquals('https://localhost/index.php/foo', $html1);
+ $this->assertEquals('Foobar', $html2);
+ $this->assertEquals('Foobar', $html3);
+ $this->assertEquals('Google', $html4);
+ }
+
+ /**
+ * Test generating proper link to asset
+ *
+ * @group laravel
+ */
+ public function testGeneratingAssetLink()
+ {
+ $html1 = HTML::link_to_asset('foo.css');
+ $html2 = HTML::link_to_asset('foo.css', 'Foobar');
+ $html3 = HTML::link_to_asset('foo.css', 'Foobar', array('class' => 'btn'));
+ $html4 = HTML::link_to_asset('http://google.com/images.jpg', 'Google');
+
+ $this->assertEquals('http://localhost/foo.css', $html1);
+ $this->assertEquals('Foobar', $html2);
+ $this->assertEquals('Foobar', $html3);
+ $this->assertEquals('Google', $html4);
+ }
+
+ /**
+ * Test generating proper link to secure asset
+ *
+ * @group laravel
+ */
+ public function testGeneratingAssetLinkToSecure()
+ {
+ $html1 = HTML::link_to_secure_asset('foo.css');
+ $html2 = HTML::link_to_secure_asset('foo.css', 'Foobar');
+ $html3 = HTML::link_to_secure_asset('foo.css', 'Foobar', array('class' => 'btn'));
+ $html4 = HTML::link_to_secure_asset('http://google.com/images.jpg', 'Google');
+
+ $this->assertEquals('https://localhost/foo.css', $html1);
+ $this->assertEquals('Foobar', $html2);
+ $this->assertEquals('Foobar', $html3);
+ $this->assertEquals('Google', $html4);
+ }
+
+ /**
+ * Test generating proper link to route
+ *
+ * @group laravel
+ */
+ public function testGeneratingLinkToRoute()
+ {
+ Route::get('dashboard', array('as' => 'foo'));
+
+ $html1 = HTML::link_to_route('foo');
+ $html2 = HTML::link_to_route('foo', 'Foobar');
+ $html3 = HTML::link_to_route('foo', 'Foobar', array(), array('class' => 'btn'));
+
+ $this->assertEquals('http://localhost/index.php/dashboard', $html1);
+ $this->assertEquals('Foobar', $html2);
+ $this->assertEquals('Foobar', $html3);
+ }
+
+ /**
+ * Test generating proper link to action
+ *
+ * @group laravel
+ */
+ public function testGeneratingLinkToAction()
+ {
+ $html1 = HTML::link_to_action('foo@bar');
+ $html2 = HTML::link_to_action('foo@bar', 'Foobar');
+ $html3 = HTML::link_to_action('foo@bar', 'Foobar', array(), array('class' => 'btn'));
+
+ $this->assertEquals('http://localhost/index.php/foo/bar', $html1);
+ $this->assertEquals('Foobar', $html2);
+ $this->assertEquals('Foobar', $html3);
+ }
+
+ /**
+ * Test generating proper listing
+ *
+ * @group laravel
+ */
+ public function testGeneratingListing()
+ {
+ $list = array(
+ 'foo',
+ 'foobar' => array(
+ 'hello',
+ 'hello world',
+ ),
+ );
+
+ $html1 = HTML::ul($list);
+ $html2 = HTML::ul($list, array('class' => 'nav'));
+ $html3 = HTML::ol($list);
+ $html4 = HTML::ol($list, array('class' => 'nav'));
+
+ $this->assertEquals('- foo
- foobar
- hello
- hello world
', $html1);
+ $this->assertEquals(' ', $html2);
+ $this->assertEquals('- foo
- foobar
- hello
- hello world
', $html3);
+ $this->assertEquals(' ', $html4);
+ }
+
+ /**
+ * Test generating proper listing
+ *
+ * @group laravel
+ */
+ public function testGeneratingDefinition()
+ {
+ $definition = array(
+ 'foo' => 'foobar',
+ 'hello' => 'hello world',
+ );
+
+ $html1 = HTML::dl($definition);
+ $html2 = HTML::dl($definition, array('class' => 'nav'));
+
+ $this->assertEquals('- foo
- foobar
- hello
- hello world
', $html1);
+ $this->assertEquals(' ', $html2);
+ }
+
+ /**
+ * Test generating proper image link
+ *
+ * @group laravel
+ */
+ public function testGeneratingAssetLinkImage()
+ {
+ $html1 = HTML::image('foo.jpg');
+ $html2 = HTML::image('foo.jpg', 'Foobar');
+ $html3 = HTML::image('foo.jpg', 'Foobar', array('class' => 'btn'));
+ $html4 = HTML::image('http://google.com/images.jpg', 'Google');
+
+ $this->assertEquals('', $html1);
+ $this->assertEquals('', $html2);
+ $this->assertEquals('', $html3);
+ $this->assertEquals('', $html4);
+ }
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/input.test.php b/app/laravel/tests/cases/input.test.php
new file mode 100644
index 000000000..5a1890f06
--- /dev/null
+++ b/app/laravel/tests/cases/input.test.php
@@ -0,0 +1,174 @@
+request->add(array('name' => 'Taylor'));
+
+ $_FILES = array('age' => 25);
+
+ $this->assertEquals(Input::all(), array('name' => 'Taylor', 'age' => 25));
+ }
+
+ /**
+ * Test the Input::has method.
+ *
+ * @group laravel
+ */
+ public function testHasMethodIndicatesTheExistenceOfInput()
+ {
+ $this->assertFalse(Input::has('foo'));
+
+ Request::foundation()->request->add(array('name' => 'Taylor'));
+
+ $this->assertTrue(Input::has('name'));
+ }
+
+ /**
+ * Test the Input::get method.
+ *
+ * @group laravel
+ */
+ public function testGetMethodReturnsInputValue()
+ {
+ Request::foundation()->request->add(array('name' => 'Taylor'));
+
+ $this->assertEquals('Taylor', Input::get('name'));
+ $this->assertEquals('Default', Input::get('foo', 'Default'));
+ }
+
+ /**
+ * Test the Input::only method.
+ *
+ * @group laravel
+ */
+ public function testOnlyMethodReturnsSubsetOfInput()
+ {
+ Request::foundation()->request->add(array('name' => 'Taylor', 'age' => 25));
+
+ $this->assertEquals(array('name' => 'Taylor'), Input::only(array('name')));
+ }
+
+ /**
+ * Test the Input::except method.
+ *
+ * @group laravel
+ */
+ public function testExceptMethodReturnsSubsetOfInput()
+ {
+ Request::foundation()->request->add(array('name' => 'Taylor', 'age' => 25));
+
+ $this->assertEquals(array('age' => 25), Input::except(array('name')));
+ }
+
+ /**
+ * Test the Input::old method.
+ *
+ * @group laravel
+ */
+ public function testOldInputCanBeRetrievedFromSession()
+ {
+ $this->setSession();
+
+ Session::$instance->session['data']['laravel_old_input'] = array('name' => 'Taylor');
+
+ $this->assertNull(Input::old('foo'));
+ $this->assertTrue(Input::had('name'));
+ $this->assertFalse(Input::had('foo'));
+ $this->assertEquals('Taylor', Input::old('name'));
+ }
+
+ /**
+ * Test the Input::file method.
+ *
+ * @group laravel
+ */
+ public function testFileMethodReturnsFromFileArray()
+ {
+ $_FILES['foo'] = array('name' => 'Taylor', 'size' => 100);
+
+ $this->assertEquals('Taylor', Input::file('foo.name'));
+ $this->assertEquals(array('name' => 'Taylor', 'size' => 100), Input::file('foo'));
+ }
+
+ /**
+ * Test the Input::flash method.
+ *
+ * @group laravel
+ */
+ public function testFlashMethodFlashesInputToSession()
+ {
+ $this->setSession();
+
+ $input = array('name' => 'Taylor', 'age' => 25);
+ Request::foundation()->request->add($input);
+
+ Input::flash();
+
+ $this->assertEquals($input, Session::$instance->session['data'][':new:']['laravel_old_input']);
+
+ Input::flash('only', array('name'));
+
+ $this->assertEquals(array('name' => 'Taylor'), Session::$instance->session['data'][':new:']['laravel_old_input']);
+
+ Input::flash('except', array('name'));
+
+ $this->assertEquals(array('age' => 25), Session::$instance->session['data'][':new:']['laravel_old_input']);
+ }
+
+ /**
+ * Test the Input::flush method.
+ *
+ * @group laravel
+ */
+ public function testFlushMethodClearsFlashedInput()
+ {
+ $this->setSession();
+
+ $input = array('name' => 'Taylor', 'age' => 30);
+ Request::foundation()->request->add($input);
+
+ Input::flash();
+
+ $this->assertEquals($input, Session::$instance->session['data'][':new:']['laravel_old_input']);
+
+ Input::flush();
+
+ $this->assertEquals(array(), Session::$instance->session['data'][':new:']['laravel_old_input']);
+ }
+
+ /**
+ * Set the session payload instance.
+ */
+ protected function setSession()
+ {
+ $driver = $this->getMock('Laravel\\Session\\Drivers\\Driver');
+
+ Session::$instance = new Laravel\Session\Payload($driver);
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/ioc.test.php b/app/laravel/tests/cases/ioc.test.php
new file mode 100644
index 000000000..56918337c
--- /dev/null
+++ b/app/laravel/tests/cases/ioc.test.php
@@ -0,0 +1,74 @@
+assertEquals('Taylor', IoC::resolve('foo'));
+ }
+
+ /**
+ * Test that singletons are created once.
+ *
+ * @group laravel
+ */
+ public function testSingletonsAreCreatedOnce()
+ {
+ IoC::singleton('foo', function()
+ {
+ return new StdClass;
+ });
+
+ $object = IoC::resolve('foo');
+
+ $this->assertTrue($object === IoC::resolve('foo'));
+ }
+
+ /**
+ * Test the IoC::instance method.
+ *
+ * @group laravel
+ */
+ public function testInstancesAreReturnedBySingleton()
+ {
+ $object = new StdClass;
+
+ IoC::instance('bar', $object);
+
+ $this->assertTrue($object === IoC::resolve('bar'));
+ }
+
+ /**
+ * Test the IoC::registered method.
+ */
+ public function testRegisteredMethodIndicatesIfRegistered()
+ {
+ IoC::register('foo', function() {});
+
+ $this->assertTrue(IoC::registered('foo'));
+ $this->assertFalse(IoC::registered('baz'));
+ }
+
+ /**
+ * Test the IoC::controller method.
+ *
+ * @group laravel
+ */
+ public function testControllerMethodRegistersAController()
+ {
+ IoC::register('controller: ioc.test', function() {});
+
+ $this->assertTrue(IoC::registered('controller: ioc.test'));
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/lang.test.php b/app/laravel/tests/cases/lang.test.php
new file mode 100644
index 000000000..74640ccdc
--- /dev/null
+++ b/app/laravel/tests/cases/lang.test.php
@@ -0,0 +1,68 @@
+assertEquals($validation['required'], Lang::line('validation.required')->get());
+ $this->assertEquals('Taylor', Lang::line('validation.foo')->get(null, 'Taylor'));
+ }
+
+ /**
+ * Test the Lang::line method.
+ *
+ * @group laravel
+ */
+ public function testGetMethodCanGetLinesForAGivenLanguage()
+ {
+ $validation = require path('app').'language/sp/validation.php';
+
+ $this->assertEquals($validation['required'], Lang::line('validation.required')->get('sp'));
+ }
+
+ /**
+ * Test the __toString method.
+ *
+ * @group laravel
+ */
+ public function testLineCanBeCastAsString()
+ {
+ $validation = require path('app').'language/en/validation.php';
+
+ $this->assertEquals($validation['required'], (string) Lang::line('validation.required'));
+ }
+
+ /**
+ * Test that string replacements are made on lines.
+ *
+ * @group laravel
+ */
+ public function testReplacementsAreMadeOnLines()
+ {
+ $validation = require path('app').'language/en/validation.php';
+
+ $line = str_replace(':attribute', 'e-mail', $validation['required']);
+
+ $this->assertEquals($line, Lang::line('validation.required', array('attribute' => 'e-mail'))->get());
+ }
+
+ /**
+ * Test the Lang::has method.
+ *
+ * @group laravel
+ */
+ public function testHasMethodIndicatesIfLangaugeLineExists()
+ {
+ $this->assertTrue(Lang::has('validation'));
+ $this->assertTrue(Lang::has('validation.required'));
+ $this->assertFalse(Lang::has('validation.foo'));
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/messages.test.php b/app/laravel/tests/cases/messages.test.php
new file mode 100644
index 000000000..f007ecb75
--- /dev/null
+++ b/app/laravel/tests/cases/messages.test.php
@@ -0,0 +1,115 @@
+messages = new Laravel\Messages;
+ }
+
+ /**
+ * Test the Messages::add method.
+ *
+ * @group laravel
+ */
+ public function testAddingMessagesDoesNotCreateDuplicateMessages()
+ {
+ $this->messages->add('email', 'test');
+ $this->messages->add('email', 'test');
+ $this->assertCount(1, $this->messages->messages);
+ }
+
+ /**
+ * Test the Messages::add method.
+ *
+ * @group laravel
+ */
+ public function testAddMethodPutsMessageInMessagesArray()
+ {
+ $this->messages->add('email', 'test');
+ $this->assertArrayHasKey('email', $this->messages->messages);
+ $this->assertEquals('test', $this->messages->messages['email'][0]);
+ }
+
+ /**
+ * Test the Messages::has method.
+ *
+ * @group laravel
+ */
+ public function testHasMethodReturnsTrue()
+ {
+ $this->messages->add('email', 'test');
+ $this->assertTrue($this->messages->has('email'));
+ }
+
+ /**
+ * Test the Messages::has method.
+ *
+ * @group laravel
+ */
+ public function testHasMethodReturnsFalse()
+ {
+ $this->assertFalse($this->messages->has('something'));
+ }
+
+ /**
+ * Test the Messages::first method.
+ *
+ * @group laravel
+ */
+ public function testFirstMethodReturnsSingleString()
+ {
+ $this->messages->add('email', 'test');
+ $this->assertEquals('test', $this->messages->first('email'));
+ $this->assertEquals('', $this->messages->first('something'));
+ }
+
+ /**
+ * Test the Messages::get method.
+ *
+ * @group laravel
+ */
+ public function testGetMethodReturnsAllMessagesForAttribute()
+ {
+ $messages = array('email' => array('something', 'else'));
+ $this->messages->messages = $messages;
+ $this->assertEquals(array('something', 'else'), $this->messages->get('email'));
+ }
+
+ /**
+ * Test the Messages::all method.
+ *
+ * @group laravel
+ */
+ public function testAllMethodReturnsAllErrorMessages()
+ {
+ $messages = array('email' => array('something', 'else'), 'name' => array('foo'));
+ $this->messages->messages = $messages;
+ $this->assertEquals(array('something', 'else', 'foo'), $this->messages->all());
+ }
+
+ /**
+ * Test the Messages::get method.
+ *
+ * @group laravel
+ */
+ public function testMessagesRespectFormat()
+ {
+ $this->messages->add('email', 'test');
+ $this->assertEquals('test
', $this->messages->first('email', ':message
'));
+ $this->assertEquals(array('test
'), $this->messages->get('email', ':message
'));
+ $this->assertEquals(array('test
'), $this->messages->all(':message
'));
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/query.test.php b/app/laravel/tests/cases/query.test.php
new file mode 100644
index 000000000..17279150d
--- /dev/null
+++ b/app/laravel/tests/cases/query.test.php
@@ -0,0 +1,48 @@
+assertEquals('taylor@example.com', $this->query()->find(1)->email);
+ }
+
+ /**
+ * Test the select method.
+ *
+ * @group laravel
+ */
+ public function testSelectMethodLimitsColumns()
+ {
+ $result = $this->query()->select(array('email'))->first();
+
+ $this->assertTrue(isset($result->email));
+ $this->assertFalse(isset($result->name));
+ }
+
+ /**
+ * Test the raw_where method.
+ *
+ * @group laravel
+ */
+ public function testRawWhereCanBeUsed()
+ {
+
+ }
+
+ /**
+ * Get the query instance for the test case.
+ *
+ * @return Query
+ */
+ protected function query()
+ {
+ return DB::table('query_test');
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/redirect.test.php b/app/laravel/tests/cases/redirect.test.php
new file mode 100644
index 000000000..cce63a81b
--- /dev/null
+++ b/app/laravel/tests/cases/redirect.test.php
@@ -0,0 +1,143 @@
+assertEquals(302, $redirect->status());
+ $this->assertEquals('http://localhost/user/profile', $redirect->headers()->get('location'));
+
+ $redirect = Redirect::to('user/profile', 301, true);
+
+ $this->assertEquals(301, $redirect->status());
+ $this->assertEquals('https://localhost/user/profile', $redirect->headers()->get('location'));
+
+ $redirect = Redirect::to_secure('user/profile', 301);
+
+ $this->assertEquals(301, $redirect->status());
+ $this->assertEquals('https://localhost/user/profile', $redirect->headers()->get('location'));
+ }
+
+ /**
+ * Test the Redirect::to_route method.
+ *
+ * @group laravel
+ */
+ public function testRedirectsCanBeGeneratedForNamedRoutes()
+ {
+ Route::get('redirect', array('as' => 'redirect'));
+ Route::get('redirect/(:any)/(:any)', array('as' => 'redirect-2'));
+ Route::get('secure/redirect', array('https' => true, 'as' => 'redirect-3'));
+
+ $this->assertEquals(301, Redirect::to_route('redirect', array(), 301, true)->status());
+ $this->assertEquals('http://localhost/redirect', Redirect::to_route('redirect')->headers()->get('location'));
+ $this->assertEquals('https://localhost/secure/redirect', Redirect::to_route('redirect-3', array(), 302)->headers()->get('location'));
+ $this->assertEquals('http://localhost/redirect/1/2', Redirect::to_route('redirect-2', array('1', '2'))->headers()->get('location'));
+ }
+
+ /**
+ * Test the Redirect::with method.
+ *
+ * @group laravel
+ */
+ public function testWithMethodFlashesItemToSession()
+ {
+ $this->setSession();
+
+ $redirect = Redirect::to('')->with('name', 'Taylor');
+
+ $this->assertEquals('Taylor', Session::$instance->session['data'][':new:']['name']);
+ }
+
+ /**
+ * Test the Redirect::with_input function.
+ *
+ * @group laravel
+ */
+ public function testWithInputMethodFlashesInputToTheSession()
+ {
+ $this->setSession();
+
+ $input = array('name' => 'Taylor', 'age' => 25);
+ Request::foundation()->request->add($input);
+
+ $redirect = Redirect::to('')->with_input();
+
+ $this->assertEquals($input, Session::$instance->session['data'][':new:']['laravel_old_input']);
+
+ $redirect = Redirect::to('')->with_input('only', array('name'));
+
+ $this->assertEquals(array('name' => 'Taylor'), Session::$instance->session['data'][':new:']['laravel_old_input']);
+
+ $redirect = Redirect::to('')->with_input('except', array('name'));
+
+ $this->assertEquals(array('age' => 25), Session::$instance->session['data'][':new:']['laravel_old_input']);
+ }
+
+ /**
+ * Test the Redirect::with_errors method.
+ *
+ * @group laravel
+ */
+ public function testWithErrorsFlashesErrorsToTheSession()
+ {
+ $this->setSession();
+
+ Redirect::to('')->with_errors(array('name' => 'Taylor'));
+
+ $this->assertEquals(array('name' => 'Taylor'), Session::$instance->session['data'][':new:']['errors']);
+
+ $validator = Validator::make(array(), array());
+ $validator->errors = array('name' => 'Taylor');
+
+ Redirect::to('')->with_errors($validator);
+
+ $this->assertEquals(array('name' => 'Taylor'), Session::$instance->session['data'][':new:']['errors']);
+ }
+
+ /**
+ * Set the session payload instance.
+ */
+ protected function setSession()
+ {
+ $driver = $this->getMock('Laravel\\Session\\Drivers\\Driver');
+
+ Session::$instance = new Laravel\Session\Payload($driver);
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/request.test.php b/app/laravel/tests/cases/request.test.php
new file mode 100644
index 000000000..4641a532c
--- /dev/null
+++ b/app/laravel/tests/cases/request.test.php
@@ -0,0 +1,177 @@
+restartRequest();
+ }
+
+ /**
+ * Set one of the $_POST variables.
+ *
+ * @param string $key
+ * @param string $value
+ */
+ protected function setPostVar($key, $value)
+ {
+ $_POST[$key] = $value;
+
+ $this->restartRequest();
+ }
+
+ /**
+ * Reinitialize the global request.
+ *
+ * @return void
+ */
+ protected function restartRequest()
+ {
+ // FIXME: Ugly hack, but old contents from previous requests seem to
+ // trip up the Foundation class.
+ $_FILES = array();
+
+ Request::$foundation = RequestFoundation::createFromGlobals();
+ }
+
+ /**
+ * Test the Request::method method.
+ *
+ * @group laravel
+ */
+ public function testMethodReturnsTheHTTPRequestMethod()
+ {
+ $this->setServerVar('REQUEST_METHOD', 'POST');
+
+ $this->assertEquals('POST', Request::method());
+
+ $this->setPostVar(Request::spoofer, 'PUT');
+
+ $this->assertEquals('PUT', Request::method());
+ }
+
+ /**
+ * Test the Request::server method.
+ *
+ * @group laravel
+ */
+ public function testServerMethodReturnsFromServerArray()
+ {
+ $this->setServerVar('TEST', 'something');
+ $this->setServerVar('USER', array('NAME' => 'taylor'));
+
+ $this->assertEquals('something', Request::server('test'));
+ $this->assertEquals('taylor', Request::server('user.name'));
+ }
+
+ /**
+ * Test the Request::ip method.
+ *
+ * @group laravel
+ */
+ public function testIPMethodReturnsClientIPAddress()
+ {
+ $this->setServerVar('REMOTE_ADDR', 'something');
+ $this->assertEquals('something', Request::ip());
+
+ $this->setServerVar('HTTP_CLIENT_IP', 'something');
+ $this->assertEquals('something', Request::ip());
+
+ $this->setServerVar('HTTP_CLIENT_IP', 'something');
+ $this->assertEquals('something', Request::ip());
+
+ $_SERVER = array();
+ $this->restartRequest();
+ $this->assertEquals('0.0.0.0', Request::ip());
+ }
+
+ /**
+ * Test the Request::secure method.
+ *
+ * @group laravel
+ */
+ public function testSecureMethodsIndicatesIfHTTPS()
+ {
+ $this->setServerVar('HTTPS', 'on');
+
+ $this->assertTrue(Request::secure());
+
+ $this->setServerVar('HTTPS', 'off');
+
+ $this->assertFalse(Request::secure());
+ }
+
+ /**
+ * Test the Request::ajax method.
+ *
+ * @group laravel
+ */
+ public function testAjaxMethodIndicatesWhenAjax()
+ {
+ $this->assertFalse(Request::ajax());
+
+ $this->setServerVar('HTTP_X_REQUESTED_WITH', 'XMLHttpRequest');
+
+ $this->assertTrue(Request::ajax());
+ }
+
+ /**
+ * Test the Request::forged method.
+ *
+ * @group laravel
+ */
+ public function testForgedMethodIndicatesIfRequestWasForged()
+ {
+ Session::$instance = new SessionPayloadTokenStub;
+
+ $input = array(Session::csrf_token => 'Foo');
+ Request::foundation()->request->add($input);
+
+ $this->assertTrue(Request::forged());
+
+ $input = array(Session::csrf_token => 'Taylor');
+ Request::foundation()->request->add($input);
+
+ $this->assertFalse(Request::forged());
+ }
+
+ /**
+ * Test the Request::route method.
+ *
+ * @group laravel
+ */
+ public function testRouteMethodReturnsStaticRoute()
+ {
+ Request::$route = 'Taylor';
+
+ $this->assertEquals('Taylor', Request::route());
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/response.test.php b/app/laravel/tests/cases/response.test.php
new file mode 100644
index 000000000..11e48e74f
--- /dev/null
+++ b/app/laravel/tests/cases/response.test.php
@@ -0,0 +1,89 @@
+ 'baz'));
+
+ $this->assertEquals('foo', $response->content);
+ $this->assertEquals(201, $response->status());
+ $this->assertArrayHasKey('bar', $response->headers()->all());
+ $this->assertEquals('baz', $response->headers()->get('bar'));
+ }
+
+ /**
+ * Test the Response::view method.
+ *
+ * @group laravel
+ */
+ public function testViewMethodSetsContentToView()
+ {
+ $response = Response::view('home.index', array('name' => 'Taylor'));
+
+ $this->assertEquals('home.index', $response->content->view);
+ $this->assertEquals('Taylor', $response->content->data['name']);
+ }
+
+ /**
+ * Test the Response::error method.
+ *
+ * @group laravel
+ */
+ public function testErrorMethodSetsContentToErrorView()
+ {
+ $response = Response::error('404', array('name' => 'Taylor'));
+
+ $this->assertEquals(404, $response->status());
+ $this->assertEquals('error.404', $response->content->view);
+ $this->assertEquals('Taylor', $response->content->data['name']);
+ }
+
+ /**
+ * Test the Response::prepare method.
+ *
+ * @group laravel
+ */
+ public function testPrepareMethodCreatesAResponseInstanceFromGivenValue()
+ {
+ $response = Response::prepare('Taylor');
+
+ $this->assertInstanceOf('Laravel\\Response', $response);
+ $this->assertEquals('Taylor', $response->content);
+
+ $response = Response::prepare(new Response('Taylor'));
+
+ $this->assertInstanceOf('Laravel\\Response', $response);
+ $this->assertEquals('Taylor', $response->content);
+ }
+
+ /**
+ * Test the Response::header method.
+ *
+ * @group laravel
+ */
+ public function testHeaderMethodSetsValueInHeaderArray()
+ {
+ $response = Response::make('')->header('foo', 'bar');
+
+ $this->assertEquals('bar', $response->headers()->get('foo'));
+ }
+
+ /**
+ * Test the Response::status method.
+ *
+ * @group laravel
+ */
+ public function testStatusMethodSetsStatusCode()
+ {
+ $response = Response::make('')->status(404);
+
+ $this->assertEquals(404, $response->status());
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/route.test.php b/app/laravel/tests/cases/route.test.php
new file mode 100644
index 000000000..489191359
--- /dev/null
+++ b/app/laravel/tests/cases/route.test.php
@@ -0,0 +1,179 @@
+ 'profile'));
+ $this->assertTrue($route->is('profile'));
+ $this->assertFalse($route->is('something'));
+ }
+
+ /**
+ * Test the basic execution of a route.
+ *
+ * @group laravel
+ */
+ public function testBasicRoutesCanBeExecutedProperly()
+ {
+ $route = new Route('GET', '', array(function() { return 'Route!'; }));
+
+ $this->assertEquals('Route!', $route->call()->content);
+ $this->assertInstanceOf('Laravel\\Response', $route->call());
+ }
+
+ /**
+ * Test that route parameters are passed into the handlers.
+ *
+ * @group laravel
+ */
+ public function testRouteParametersArePassedIntoTheHandler()
+ {
+ $route = new Route('GET', '', array(function($var) { return $var; }), array('Taylor'));
+
+ $this->assertEquals('Taylor', $route->call()->content);
+ $this->assertInstanceOf('Laravel\\Response', $route->call());
+ }
+
+ /**
+ * Test that calling a route calls the global before and after filters.
+ *
+ * @group laravel
+ */
+ public function testCallingARouteCallsTheBeforeAndAfterFilters()
+ {
+ $route = new Route('GET', '', array(function() { return 'Hi!'; }));
+
+ $_SERVER['before'] = false;
+ $_SERVER['after'] = false;
+
+ $route->call();
+
+ $this->assertTrue($_SERVER['before']);
+ $this->assertTrue($_SERVER['after']);
+ }
+
+ /**
+ * Test that before filters override the route response.
+ *
+ * @group laravel
+ */
+ public function testBeforeFiltersOverrideTheRouteResponse()
+ {
+ Filter::register('test-before', function()
+ {
+ return 'Filtered!';
+ });
+
+ $route = new Route('GET', '', array('before' => 'test-before', function() {
+ return 'Route!';
+ }));
+
+ $this->assertEquals('Filtered!', $route->call()->content);
+ }
+
+ /**
+ * Test that after filters do not affect the route response.
+ *
+ * @group laravel
+ */
+ public function testAfterFilterDoesNotAffectTheResponse()
+ {
+ $_SERVER['test-after'] = false;
+
+ Filter::register('test-after', function()
+ {
+ $_SERVER['test-after'] = true;
+ return 'Filtered!';
+ });
+
+ $route = new Route('GET', '', array('after' => 'test-after', function()
+ {
+ return 'Route!';
+ }));
+
+ $this->assertEquals('Route!', $route->call()->content);
+ $this->assertTrue($_SERVER['test-after']);
+ }
+
+ /**
+ * Test that the route calls the appropriate controller method when delegating.
+ *
+ * @group laravel
+ */
+ public function testControllerActionCalledWhenDelegating()
+ {
+ $_SERVER['REQUEST_METHOD'] = 'GET';
+
+ $route = new Route('GET', '', array('uses' => 'auth@index'));
+
+ $this->assertEquals('action_index', $route->call()->content);
+ }
+
+ /**
+ * Test that filter parameters are passed to the filter.
+ *
+ * @group laravel
+ */
+ public function testFilterParametersArePassedToFilter()
+ {
+ Filter::register('test-params', function($var1, $var2)
+ {
+ return $var1.$var2;
+ });
+
+ $route = new Route('GET', '', array('before' => 'test-params:1,2'));
+
+ $this->assertEquals('12', $route->call()->content);
+ }
+
+ /**
+ * Test that multiple filters can be assigned to a route.
+ *
+ * @group laravel
+ */
+ public function testMultipleFiltersCanBeAssignedToARoute()
+ {
+ $_SERVER['test-multi-1'] = false;
+ $_SERVER['test-multi-2'] = false;
+
+ Filter::register('test-multi-1', function() { $_SERVER['test-multi-1'] = true; });
+ Filter::register('test-multi-2', function() { $_SERVER['test-multi-2'] = true; });
+
+ $route = new Route('GET', '', array('before' => 'test-multi-1|test-multi-2'));
+
+ $route->call();
+
+ $this->assertTrue($_SERVER['test-multi-1']);
+ $this->assertTrue($_SERVER['test-multi-2']);
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/routing.test.php b/app/laravel/tests/cases/routing.test.php
new file mode 100644
index 000000000..68a112a07
--- /dev/null
+++ b/app/laravel/tests/cases/routing.test.php
@@ -0,0 +1,160 @@
+ 'home'));
+ Route::get('dashboard', array('as' => 'dashboard'));
+
+ $home = Router::find('home');
+ $dashboard = Router::find('dashboard');
+
+ $this->assertTrue(isset($home['/']));
+ $this->assertTrue(isset($dashboard['dashboard']));
+ }
+
+ /**
+ * Test the basic routing mechanism.
+ *
+ * @group laravel
+ */
+ public function testBasicRouteCanBeRouted()
+ {
+ Route::get('/', function() {});
+ Route::get('home, main', function() {});
+
+ $this->assertEquals('/', Router::route('GET', '/')->uri);
+ $this->assertEquals('home', Router::route('GET', 'home')->uri);
+ $this->assertEquals('main', Router::route('GET', 'main')->uri);
+ }
+
+ /**
+ * Test that the router can handle basic wildcards.
+ *
+ * @group laravel
+ */
+ public function testWildcardRoutesCanBeRouted()
+ {
+ Route::get('user/(:num)', function() {});
+ Route::get('profile/(:any)/(:num)', function() {});
+
+ $this->assertNull(Router::route('GET', 'user/1.5'));
+ $this->assertNull(Router::route('GET', 'user/taylor'));
+ $this->assertEquals(array(25), Router::route('GET', 'user/25')->parameters);
+ $this->assertEquals('user/(:num)', Router::route('GET', 'user/1')->uri);
+
+ $this->assertNull(Router::route('GET', 'profile/1/otwell'));
+ $this->assertNull(Router::route('POST', 'profile/taylor/1'));
+ $this->assertNull(Router::route('GET', 'profile/taylor/otwell'));
+ $this->assertNull(Router::route('GET', 'profile/taylor/1/otwell'));
+ $this->assertEquals(array('taylor', 25), Router::route('GET', 'profile/taylor/25')->parameters);
+ $this->assertEquals('profile/(:any)/(:num)', Router::route('GET', 'profile/taylor/1')->uri);
+ }
+
+ /**
+ * Test that optional wildcards can be routed.
+ *
+ * @group laravel
+ */
+ public function testOptionalWildcardsCanBeRouted()
+ {
+ Route::get('user/(:num?)', function() {});
+ Route::get('profile/(:any)/(:any?)', function() {});
+
+ $this->assertNull(Router::route('GET', 'user/taylor'));
+ $this->assertEquals('user/(:num?)', Router::route('GET', 'user')->uri);
+ $this->assertEquals(array(25), Router::route('GET', 'user/25')->parameters);
+ $this->assertEquals('user/(:num?)', Router::route('GET', 'user/1')->uri);
+
+ $this->assertNull(Router::route('GET', 'profile/taylor/otwell/test'));
+ $this->assertEquals('profile/(:any)/(:any?)', Router::route('GET', 'profile/taylor')->uri);
+ $this->assertEquals('profile/(:any)/(:any?)', Router::route('GET', 'profile/taylor/25')->uri);
+ $this->assertEquals('profile/(:any)/(:any?)', Router::route('GET', 'profile/taylor/otwell')->uri);
+ $this->assertEquals(array('taylor', 'otwell'), Router::route('GET', 'profile/taylor/otwell')->parameters);
+ }
+
+ /**
+ * Test that basic controller routing is working.
+ *
+ * @group laravel
+ */
+ public function testBasicRouteToControllerIsRouted()
+ {
+ $this->assertEquals('auth@(:1)', Router::route('GET', 'auth')->action['uses']);
+ $this->assertEquals('home@(:1)', Router::route('GET', 'home/index')->action['uses']);
+ $this->assertEquals('home@(:1)', Router::route('GET', 'home/profile')->action['uses']);
+ $this->assertEquals('admin.panel@(:1)', Router::route('GET', 'admin/panel')->action['uses']);
+ $this->assertEquals('admin.panel@(:1)', Router::route('GET', 'admin/panel/show')->action['uses']);
+ }
+
+ /**
+ * Test basic bundle route resolution.
+ *
+ * @group laravel
+ */
+ public function testRoutesToBundlesCanBeResolved()
+ {
+ $this->assertNull(Router::route('GET', 'dashboard/foo'));
+ $this->assertEquals('dashboard', Router::route('GET', 'dashboard')->uri);
+ }
+
+ /**
+ * Test bundle controller route resolution.
+ *
+ * @group laravel
+ */
+ public function testBundleControllersCanBeResolved()
+ {
+ $this->assertEquals('dashboard::panel@(:1)', Router::route('GET', 'dashboard/panel')->action['uses']);
+ $this->assertEquals('dashboard::panel@(:1)', Router::route('GET', 'dashboard/panel/show')->action['uses']);
+ }
+
+ /**
+ * Test foreign characters can be used in routes.
+ *
+ * @group laravel
+ */
+ public function testForeignCharsInRoutes()
+ {
+ Route::get(urlencode('مدرس_رياضيات').'/(:any)', function() {});
+ Route::get(urlencode('مدرس_رياضيات'), function() {});
+ Route::get(urlencode('ÇœŪ'), function() {});
+ Route::get(urlencode('私は料理が大好き'), function() {});
+
+ $this->assertEquals(array(urlencode('مدرس_رياضيات')), Router::route('GET', urlencode('مدرس_رياضيات').'/'.urlencode('مدرس_رياضيات'))->parameters);
+ $this->assertEquals(urlencode('مدرس_رياضيات'), Router::route('GET', urlencode('مدرس_رياضيات'))->uri);
+ $this->assertEquals(urlencode('ÇœŪ'), Router::route('GET', urlencode('ÇœŪ'))->uri);
+ $this->assertEquals(urlencode('私は料理が大好き'), Router::route('GET', urlencode('私は料理が大好き'))->uri);
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/session.test.php b/app/laravel/tests/cases/session.test.php
new file mode 100644
index 000000000..b310870c2
--- /dev/null
+++ b/app/laravel/tests/cases/session.test.php
@@ -0,0 +1,443 @@
+assertEquals('Foo', Session::test());
+ }
+
+ /**
+ * Test the Session::started method.
+ *
+ * @group laravel
+ */
+ public function testStartedMethodIndicatesIfSessionIsStarted()
+ {
+ $this->assertFalse(Session::started());
+ Session::$instance = 'foo';
+ $this->assertTrue(Session::started());
+ }
+
+ /**
+ * Test the Payload::load method.
+ *
+ * @group laravel
+ */
+ public function testLoadMethodCreatesNewSessionWithNullIDGiven()
+ {
+ $payload = $this->getPayload();
+ $payload->load(null);
+ $this->verifyNewSession($payload);
+ }
+
+ /**
+ * Test the Payload::load method.
+ *
+ * @group laravel
+ */
+ public function testLoadMethodCreatesNewSessionWhenSessionIsExpired()
+ {
+ $payload = $this->getPayload();
+
+ $session = $this->getSession();
+ $session['last_activity'] = time() - 10000;
+
+ $payload->driver->expects($this->any())
+ ->method('load')
+ ->will($this->returnValue($session));
+
+ $payload->load('foo');
+
+ $this->verifyNewSession($payload);
+ $this->assertTrue($payload->session['id'] !== $session['id']);
+ }
+
+ /**
+ * Assert that a session is new.
+ *
+ * @param Payload $payload
+ * @return void
+ */
+ protected function verifyNewSession($payload)
+ {
+ $this->assertFalse($payload->exists);
+ $this->assertTrue(isset($payload->session['id']));
+ $this->assertEquals(array(), $payload->session['data'][':new:']);
+ $this->assertEquals(array(), $payload->session['data'][':old:']);
+ $this->assertTrue(isset($payload->session['data'][Session::csrf_token]));
+ }
+
+ /**
+ * Test the Payload::load method.
+ *
+ * @group laravel
+ */
+ public function testLoadMethodSetsValidSession()
+ {
+ $payload = $this->getPayload();
+
+ $session = $this->getSession();
+
+ $payload->driver->expects($this->any())
+ ->method('load')
+ ->will($this->returnValue($session));
+
+ $payload->load('foo');
+
+ $this->assertEquals($session, $payload->session);
+ }
+
+ /**
+ * Test the Payload::load method.
+ *
+ * @group laravel
+ */
+ public function testLoadMethodSetsCSRFTokenIfDoesntExist()
+ {
+ $payload = $this->getPayload();
+
+ $session = $this->getSession();
+
+ unset($session['data']['csrf_token']);
+
+ $payload->driver->expects($this->any())
+ ->method('load')
+ ->will($this->returnValue($session));
+
+ $payload->load('foo');
+
+ $this->assertEquals('foo', $payload->session['id']);
+ $this->assertTrue(isset($payload->session['data']['csrf_token']));
+ }
+
+ /**
+ * Test the various data retrieval methods.
+ *
+ * @group laravel
+ */
+ public function testSessionDataCanBeRetrievedProperly()
+ {
+ $payload = $this->getPayload();
+
+ $payload->session = $this->getSession();
+
+ $this->assertTrue($payload->has('name'));
+ $this->assertEquals('Taylor', $payload->get('name'));
+ $this->assertFalse($payload->has('foo'));
+ $this->assertEquals('Default', $payload->get('foo', 'Default'));
+ $this->assertTrue($payload->has('votes'));
+ $this->assertEquals(10, $payload->get('votes'));
+ $this->assertTrue($payload->has('state'));
+ $this->assertEquals('AR', $payload->get('state'));
+ }
+
+ /**
+ * Test the various data manipulation methods.
+ *
+ * @group laravel
+ */
+ public function testDataCanBeSetProperly()
+ {
+ $payload = $this->getPayload();
+
+ $payload->session = $this->getSession();
+
+ // Test the "put" and "flash" methods.
+ $payload->put('name', 'Weldon');
+ $this->assertEquals('Weldon', $payload->session['data']['name']);
+ $payload->flash('language', 'php');
+ $this->assertEquals('php', $payload->session['data'][':new:']['language']);
+
+ // Test the "reflash" method.
+ $payload->session['data'][':new:'] = array('name' => 'Taylor');
+ $payload->session['data'][':old:'] = array('age' => 25);
+ $payload->reflash();
+ $this->assertEquals(array('name' => 'Taylor', 'age' => 25), $payload->session['data'][':new:']);
+
+ // Test the "keep" method.
+ $payload->session['data'][':new:'] = array();
+ $payload->keep(array('age'));
+ $this->assertEquals(25, $payload->session['data'][':new:']['age']);
+ }
+
+ /**
+ * Test the Payload::forget method.
+ *
+ * @group laravel
+ */
+ public function testSessionDataCanBeForgotten()
+ {
+ $payload = $this->getPayload();
+
+ $payload->session = $this->getSession();
+
+ $this->assertTrue(isset($payload->session['data']['name']));
+ $payload->forget('name');
+ $this->assertFalse(isset($payload->session['data']['name']));
+ }
+
+ /**
+ * Test the Payload::flush method.
+ *
+ * @group laravel
+ */
+ public function testFlushMaintainsTokenButDeletesEverythingElse()
+ {
+ $payload = $this->getPayload();
+
+ $payload->session = $this->getSession();
+
+ $this->assertTrue(isset($payload->session['data']['name']));
+ $payload->flush();
+ $this->assertFalse(isset($payload->session['data']['name']));
+ $this->assertEquals('bar', $payload->session['data']['csrf_token']);
+ $this->assertEquals(array(), $payload->session['data'][':new:']);
+ $this->assertEquals(array(), $payload->session['data'][':old:']);
+ }
+
+ /**
+ * Test the Payload::regenerate method.
+ *
+ * @group laravel
+ */
+ public function testRegenerateMethodSetsNewIDAndTurnsOffExistenceIndicator()
+ {
+ $payload = $this->getPayload();
+
+ $payload->sesion = $this->getSession();
+ $payload->exists = true;
+ $payload->regenerate();
+
+ $this->assertFalse($payload->exists);
+ $this->assertTrue(strlen($payload->session['id']) == 40);
+ }
+
+ /**
+ * Test the Payload::token method.
+ *
+ * @group laravel
+ */
+ public function testTokenMethodReturnsCSRFToken()
+ {
+ $payload = $this->getPayload();
+ $payload->session = $this->getSession();
+
+ $this->assertEquals('bar', $payload->token());
+ }
+
+ /**
+ * Test the Payload::save method.
+ *
+ * @group laravel
+ */
+ public function testSaveMethodCorrectlyCallsDriver()
+ {
+ $payload = $this->getPayload();
+ $session = $this->getSession();
+ $payload->session = $session;
+ $payload->exists = true;
+ $config = Laravel\Config::get('session');
+
+ $expect = $session;
+ $expect['data'][':old:'] = $session['data'][':new:'];
+ $expect['data'][':new:'] = array();
+
+ $payload->driver->expects($this->once())
+ ->method('save')
+ ->with($this->equalTo($expect), $this->equalTo($config), $this->equalTo(true));
+
+ $payload->save();
+
+ $this->assertEquals($session['data'][':new:'], $payload->session['data'][':old:']);
+ }
+
+ /**
+ * Test the Payload::save method.
+ *
+ * @group laravel
+ */
+ public function testSaveMethodSweepsIfSweeperAndOddsHitWithTimeGreaterThanThreshold()
+ {
+ Config::set('session.sweepage', array(100, 100));
+
+ $payload = $this->getPayload();
+ $payload->driver = $this->getMock('Laravel\\Session\\Drivers\\File', array('save', 'sweep'), array(null));
+ $payload->session = $this->getSession();
+
+ $expiration = time() - (Config::get('session.lifetime') * 60);
+
+ // Here we set the time to the expected expiration minus 5 seconds, just to
+ // allow plenty of room for PHP execution. In the next test, we'll do the
+ // same thing except add 5 seconds to check that the time is between a
+ // given window.
+ $payload->driver->expects($this->once())
+ ->method('sweep')
+ ->with($this->greaterThan($expiration - 5));
+
+ $payload->save();
+
+ Config::set('session.sweepage', array(2, 100));
+ }
+
+ /**
+ * Test the Payload::save method.
+ *
+ * @group laravel
+ */
+ public function testSaveMethodSweepsIfSweeperAndOddsHitWithTimeLessThanThreshold()
+ {
+ Config::set('session.sweepage', array(100, 100));
+
+ $payload = $this->getPayload();
+ $payload->driver = $this->getMock('Laravel\\Session\\Drivers\\File', array('save', 'sweep'), array(null));
+ $payload->session = $this->getSession();
+
+ $expiration = time() - (Config::get('session.lifetime') * 60);
+
+ $payload->driver->expects($this->once())
+ ->method('sweep')
+ ->with($this->lessThan($expiration + 5));
+
+ $payload->save();
+
+ Config::set('session.sweepage', array(2, 100));
+ }
+
+ /**
+ * Test that the session sweeper is never called if not a sweeper.
+ *
+ * @group laravel
+ */
+ public function testSweeperShouldntBeCalledIfDriverIsntSweeper()
+ {
+ Config::set('session.sweepage', array(100, 100));
+
+ $payload = $this->getPayload();
+ $payload->driver = $this->getMock('Laravel\\Session\\Drivers\\APC', array('save', 'sweep'), array(), '', false);
+ $payload->session = $this->getSession();
+
+ $payload->driver->expects($this->never())->method('sweep');
+
+ $payload->save();
+
+ Config::set('session.sweepage', array(2, 100));
+ }
+
+ /**
+ * Test the Payload::save method.
+ *
+ * @group laravel
+ */
+ public function testSaveMethodSetsCookieWithCorrectValues()
+ {
+ $payload = $this->getPayload();
+ $payload->session = $this->getSession();
+ $payload->save();
+
+ $this->assertTrue(isset(Cookie::$jar[Config::get('session.cookie')]));
+
+ $cookie = Cookie::$jar[Config::get('session.cookie')];
+
+ $this->assertEquals(Cookie::hash('foo').'+foo', $cookie['value']);
+ // Shouldn't be able to test this cause session.lifetime store number of minutes
+ // while cookie expiration store timestamp when it going to expired.
+ // $this->assertEquals(Config::get('session.lifetime'), $cookie['expiration']);
+ $this->assertEquals(Config::get('session.domain'), $cookie['domain']);
+ $this->assertEquals(Config::get('session.path'), $cookie['path']);
+ $this->assertEquals(Config::get('session.secure'), $cookie['secure']);
+ }
+
+ /**
+ * Test the Session::activity method.
+ *
+ * @group laravel
+ */
+ public function testActivityMethodReturnsLastActivity()
+ {
+ $payload = $this->getPayload();
+ $payload->session['last_activity'] = 10;
+ $this->assertEquals(10, $payload->activity());
+ }
+
+ /**
+ * Get a session payload instance.
+ *
+ * @return Payload
+ */
+ protected function getPayload()
+ {
+ return new Payload($this->getMockDriver());
+ }
+
+ /**
+ * Get a mock driver instance.
+ *
+ * @return Driver
+ */
+ protected function getMockDriver()
+ {
+ $mock = $this->getMock('Laravel\\Session\\Drivers\\Driver', array('id', 'load', 'save', 'delete'));
+
+ $mock->expects($this->any())->method('id')->will($this->returnValue(Str::random(40)));
+
+ return $mock;
+ }
+
+ /**
+ * Get a dummy session.
+ *
+ * @return array
+ */
+ protected function getSession()
+ {
+ return array(
+ 'id' => 'foo',
+ 'last_activity' => time(),
+ 'data' => array(
+ 'name' => 'Taylor',
+ 'age' => 25,
+ 'csrf_token' => 'bar',
+ ':new:' => array(
+ 'votes' => 10,
+ ),
+ ':old:' => array(
+ 'state' => 'AR',
+ ),
+ ));
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/str.test.php b/app/laravel/tests/cases/str.test.php
new file mode 100644
index 000000000..7c3806004
--- /dev/null
+++ b/app/laravel/tests/cases/str.test.php
@@ -0,0 +1,135 @@
+assertEquals('UTF-8', Config::get('application.encoding'));
+ Config::set('application.encoding', 'foo');
+ $this->assertEquals('foo', Config::get('application.encoding'));
+ Config::set('application.encoding', 'UTF-8');
+ }
+
+ /**
+ * Test the Str::length method.
+ *
+ * @group laravel
+ */
+ public function testStringLengthIsCorrect()
+ {
+ $this->assertEquals(6, Str::length('Taylor'));
+ $this->assertEquals(5, Str::length('ラドクリフ'));
+ }
+
+ /**
+ * Test the Str::lower method.
+ *
+ * @group laravel
+ */
+ public function testStringCanBeConvertedToLowercase()
+ {
+ $this->assertEquals('taylor', Str::lower('TAYLOR'));
+ $this->assertEquals('άχιστη', Str::lower('ΆΧΙΣΤΗ'));
+ }
+
+ /**
+ * Test the Str::upper method.
+ *
+ * @group laravel
+ */
+ public function testStringCanBeConvertedToUppercase()
+ {
+ $this->assertEquals('TAYLOR', Str::upper('taylor'));
+ $this->assertEquals('ΆΧΙΣΤΗ', Str::upper('άχιστη'));
+ }
+
+ /**
+ * Test the Str::title method.
+ *
+ * @group laravel
+ */
+ public function testStringCanBeConvertedToTitleCase()
+ {
+ $this->assertEquals('Taylor', Str::title('taylor'));
+ $this->assertEquals('Άχιστη', Str::title('άχιστη'));
+ }
+
+ /**
+ * Test the Str::limit method.
+ *
+ * @group laravel
+ */
+ public function testStringCanBeLimitedByCharacters()
+ {
+ $this->assertEquals('Tay...', Str::limit('Taylor', 3));
+ $this->assertEquals('Taylor', Str::limit('Taylor', 6));
+ $this->assertEquals('Tay___', Str::limit('Taylor', 3, '___'));
+ }
+
+ /**
+ * Test the Str::words method.
+ *
+ * @group laravel
+ */
+ public function testStringCanBeLimitedByWords()
+ {
+ $this->assertEquals('Taylor...', Str::words('Taylor Otwell', 1));
+ $this->assertEquals('Taylor___', Str::words('Taylor Otwell', 1, '___'));
+ $this->assertEquals('Taylor Otwell', Str::words('Taylor Otwell', 3));
+ }
+
+ /**
+ * Test the Str::plural and Str::singular methods.
+ *
+ * @group laravel
+ */
+ public function testStringsCanBeSingularOrPlural()
+ {
+ $this->assertEquals('user', Str::singular('users'));
+ $this->assertEquals('users', Str::plural('user'));
+ $this->assertEquals('User', Str::singular('Users'));
+ $this->assertEquals('Users', Str::plural('User'));
+ $this->assertEquals('user', Str::plural('user', 1));
+ $this->assertEquals('users', Str::plural('user', 2));
+ $this->assertEquals('chassis', Str::plural('chassis', 2));
+ $this->assertEquals('traffic', Str::plural('traffic', 2));
+ }
+
+ /**
+ * Test the Str::slug method.
+ *
+ * @group laravel
+ */
+ public function testStringsCanBeSlugged()
+ {
+ $this->assertEquals('my-new-post', Str::slug('My nEw post!!!'));
+ $this->assertEquals('my_new_post', Str::slug('My nEw post!!!', '_'));
+ }
+
+ /**
+ * Test the Str::classify method.
+ *
+ * @group laravel
+ */
+ public function testStringsCanBeClassified()
+ {
+ $this->assertEquals('Something_Else', Str::classify('something.else'));
+ $this->assertEquals('Something_Else', Str::classify('something_else'));
+ }
+
+ /**
+ * Test the Str::random method.
+ *
+ * @group laravel
+ */
+ public function testRandomStringsCanBeGenerated()
+ {
+ $this->assertEquals(40, strlen(Str::random(40)));
+ }
+
+}
diff --git a/app/laravel/tests/cases/uri.test.php b/app/laravel/tests/cases/uri.test.php
new file mode 100644
index 000000000..8f2b85ffe
--- /dev/null
+++ b/app/laravel/tests/cases/uri.test.php
@@ -0,0 +1,75 @@
+setRequestUri($uri);
+
+ $this->assertEquals($expectation, URI::current());
+ }
+
+ /**
+ * Test the URI::segment method.
+ *
+ * @group laravel
+ */
+ public function testSegmentMethodReturnsAURISegment()
+ {
+ $this->setRequestUri('/user/profile');
+
+ $this->assertEquals('user', URI::segment(1));
+ $this->assertEquals('profile', URI::segment(2));
+ }
+
+ /**
+ * Data provider for the URI::current test.
+ */
+ public function requestUriProvider()
+ {
+ return array(
+ array('/user', 'user'),
+ array('/user/', 'user'),
+ array('', '/'),
+ array('/', '/'),
+ array('//', '/'),
+ array('/user', 'user'),
+ array('/user/', 'user'),
+ array('/user/profile', 'user/profile'),
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/url.test.php b/app/laravel/tests/cases/url.test.php
new file mode 100644
index 000000000..3bf37b401
--- /dev/null
+++ b/app/laravel/tests/cases/url.test.php
@@ -0,0 +1,131 @@
+assertEquals('http://localhost/index.php/user/profile', URL::to('user/profile'));
+ $this->assertEquals('https://localhost/index.php/user/profile', URL::to('user/profile', true));
+
+ Config::set('application.index', '');
+
+ $this->assertEquals('http://localhost/user/profile', URL::to('user/profile'));
+ $this->assertEquals('https://localhost/user/profile', URL::to('user/profile', true));
+
+ Config::set('application.ssl', false);
+
+ $this->assertEquals('http://localhost/user/profile', URL::to('user/profile', true));
+ }
+
+ /**
+ * Test the URL::to_action method.
+ *
+ * @group laravel
+ */
+ public function testToActionMethodGeneratesURLToControllerAction()
+ {
+ Route::get('foo/bar/(:any?)', 'foo@baz');
+ $this->assertEquals('http://localhost/index.php/x/y', URL::to_action('x@y'));
+ $this->assertEquals('http://localhost/index.php/x/y/Taylor', URL::to_action('x@y', array('Taylor')));
+ $this->assertEquals('http://localhost/index.php/foo/bar', URL::to_action('foo@baz'));
+ $this->assertEquals('http://localhost/index.php/foo/bar/Taylor', URL::to_action('foo@baz', array('Taylor')));
+ }
+
+ /**
+ * Test the URL::to_asset method.
+ *
+ * @group laravel
+ */
+ public function testToAssetGeneratesURLWithoutFrontControllerInURL()
+ {
+ $this->assertEquals('http://localhost/image.jpg', URL::to_asset('image.jpg'));
+ $this->assertEquals('https://localhost/image.jpg', URL::to_asset('image.jpg', true));
+
+ Config::set('application.index', '');
+
+ $this->assertEquals('http://localhost/image.jpg', URL::to_asset('image.jpg'));
+ $this->assertEquals('https://localhost/image.jpg', URL::to_asset('image.jpg', true));
+
+ Request::foundation()->server->add(array('HTTPS' => 'on'));
+
+ $this->assertEquals('https://localhost/image.jpg', URL::to_asset('image.jpg'));
+
+ Request::foundation()->server->add(array('HTTPS' => 'off'));
+ }
+
+ /**
+ * Test the URL::to_route method.
+ *
+ * @group laravel
+ */
+ public function testToRouteMethodGeneratesURLsToRoutes()
+ {
+ Route::get('url/test', array('as' => 'url-test'));
+ Route::get('url/test/(:any)/(:any?)', array('as' => 'url-test-2'));
+ Route::get('url/secure/(:any)/(:any?)', array('as' => 'url-test-3', 'https' => true));
+
+ $this->assertEquals('http://localhost/index.php/url/test', URL::to_route('url-test'));
+ $this->assertEquals('http://localhost/index.php/url/test/taylor', URL::to_route('url-test-2', array('taylor')));
+ $this->assertEquals('https://localhost/index.php/url/secure/taylor', URL::to_route('url-test-3', array('taylor')));
+ $this->assertEquals('http://localhost/index.php/url/test/taylor/otwell', URL::to_route('url-test-2', array('taylor', 'otwell')));
+ }
+
+
+ /**
+ * Test language based URL generation.
+ *
+ * @group laravel
+ */
+ public function testUrlsGeneratedWithLanguages()
+ {
+ Config::set('application.languages', array('sp', 'fr'));
+ Config::set('application.language', 'sp');
+ $this->assertEquals('http://localhost/index.php/sp/foo', URL::to('foo'));
+ $this->assertEquals('http://localhost/foo.jpg', URL::to_asset('foo.jpg'));
+
+ Config::set('application.index', '');
+ $this->assertEquals('http://localhost/sp/foo', URL::to('foo'));
+
+ Config::set('application.index', 'index.php');
+ Config::set('application.language', 'en');
+ $this->assertEquals('http://localhost/index.php/foo', URL::to('foo'));
+ Config::set('application.languages', array());
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/validator.test.php b/app/laravel/tests/cases/validator.test.php
new file mode 100644
index 000000000..bde1cea12
--- /dev/null
+++ b/app/laravel/tests/cases/validator.test.php
@@ -0,0 +1,669 @@
+ 'Taylor Otwell');
+ $rules = array('name' => 'required');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['name'] = '';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ unset($input['name']);
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ $_FILES['name']['tmp_name'] = 'foo';
+ $this->assertTrue(Validator::make($_FILES, $rules)->valid());
+
+ $_FILES['name']['tmp_name'] = '';
+ $this->assertFalse(Validator::make($_FILES, $rules)->valid());
+ }
+
+ /**
+ * Test the confirmed validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheConfirmedRule()
+ {
+ $input = array('password' => 'foo', 'password_confirmation' => 'foo');
+ $rules = array('password' => 'confirmed');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['password_confirmation'] = 'foo_bar';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ unset($input['password_confirmation']);
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the different validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheDifferentRule()
+ {
+ $input = array('password' => 'foo', 'password_confirmation' => 'bar');
+ $rules = array('password' => 'different:password_confirmation');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['password_confirmation'] = 'foo';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ unset($input['password_confirmation']);
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the accepted validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheAcceptedRule()
+ {
+ $input = array('terms' => '1');
+ $rules = array('terms' => 'accepted');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['terms'] = 'yes';
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['terms'] = '2';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ // The accepted rule implies required, so should fail if field not present.
+ unset($input['terms']);
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the numeric validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheNumericRule()
+ {
+ $input = array('amount' => '1.21');
+ $rules = array('amount' => 'numeric');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['amount'] = '1';
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['amount'] = 1.2;
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['amount'] = '1.2a';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the integer validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheIntegerRule()
+ {
+ $input = array('amount' => '1');
+ $rules = array('amount' => 'integer');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['amount'] = '0';
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['amount'] = 1.2;
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ $input['amount'] = '1.2a';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the size validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheSizeRule()
+ {
+ $input = array('amount' => '1.21');
+ $rules = array('amount' => 'numeric|size:1.21');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $rules = array('amount' => 'numeric|size:1');
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ // If no numeric rule is on the field, it is treated as a string
+ $input = array('amount' => '111');
+ $rules = array('amount' => 'size:3');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $rules = array('amount' => 'size:4');
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ // The size rules checks kilobytes on files
+ $_FILES['photo']['tmp_name'] = 'foo';
+ $_FILES['photo']['size'] = 10240;
+ $rules = array('photo' => 'size:10');
+ $this->assertTrue(Validator::make($_FILES, $rules)->valid());
+
+ $_FILES['photo']['size'] = 14000;
+ $this->assertFalse(Validator::make($_FILES, $rules)->valid());
+ }
+
+ /**
+ * Test the between validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheBetweenRule()
+ {
+ $input = array('amount' => '1.21');
+ $rules = array('amount' => 'numeric|between:1,2');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $rules = array('amount' => 'numeric|between:2,3');
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ // If no numeric rule is on the field, it is treated as a string
+ $input = array('amount' => '111');
+ $rules = array('amount' => 'between:1,3');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $rules = array('amount' => 'between:100,111');
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ // The size rules checks kilobytes on files
+ $_FILES['photo']['tmp_name'] = 'foo';
+ $_FILES['photo']['size'] = 10240;
+ $rules = array('photo' => 'between:9,11');
+ $this->assertTrue(Validator::make($_FILES, $rules)->valid());
+
+ $_FILES['photo']['size'] = 14000;
+ $this->assertFalse(Validator::make($_FILES, $rules)->valid());
+ }
+
+ /**
+ * Test the between validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheMinRule()
+ {
+ $input = array('amount' => '1.21');
+ $rules = array('amount' => 'numeric|min:1');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $rules = array('amount' => 'numeric|min:2');
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ // If no numeric rule is on the field, it is treated as a string
+ $input = array('amount' => '01');
+ $rules = array('amount' => 'min:2');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $rules = array('amount' => 'min:3');
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ // The size rules checks kilobytes on files
+ $_FILES['photo']['tmp_name'] = 'foo';
+ $_FILES['photo']['size'] = 10240;
+ $rules = array('photo' => 'min:9');
+ $this->assertTrue(Validator::make($_FILES, $rules)->valid());
+
+ $_FILES['photo']['size'] = 8000;
+ $this->assertFalse(Validator::make($_FILES, $rules)->valid());
+ }
+
+ /**
+ * Test the between validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheMaxRule()
+ {
+ $input = array('amount' => '1.21');
+ $rules = array('amount' => 'numeric|max:2');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $rules = array('amount' => 'numeric|max:1');
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ // If no numeric rule is on the field, it is treated as a string
+ $input = array('amount' => '01');
+ $rules = array('amount' => 'max:3');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $rules = array('amount' => 'max:1');
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ // The size rules checks kilobytes on files
+ $_FILES['photo']['tmp_name'] = 'foo';
+ $_FILES['photo']['size'] = 10240;
+ $rules = array('photo' => 'max:11');
+ $this->assertTrue(Validator::make($_FILES, $rules)->valid());
+
+ $_FILES['photo']['size'] = 140000;
+ $this->assertFalse(Validator::make($_FILES, $rules)->valid());
+ }
+
+ /**
+ * Test the in validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheInRule()
+ {
+ $input = array('size' => 'L');
+ $rules = array('size' => 'in:S,M,L');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['size'] = 'XL';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the not-in validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheNotInRule()
+ {
+ $input = array('size' => 'L');
+ $rules = array('size' => 'not_in:S,M,L');
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ $input['size'] = 'XL';
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the IP validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheIPRule()
+ {
+ $input = array('ip' => '192.168.1.1');
+ $rules = array('ip' => 'ip');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['ip'] = '192.111';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the e-mail validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheEmailRule()
+ {
+ $input = array('email' => 'example@gmail.com');
+ $rules = array('email' => 'email');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['email'] = 'blas-asok';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the URL validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheUrlRule()
+ {
+ $input = array('url' => 'http://www.google.com');
+ $rules = array('url' => 'url');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['url'] = 'blas-asok';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the active URL validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheActiveUrlRule()
+ {
+ $input = array('url' => 'http://google.com');
+ $rules = array('url' => 'active_url');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['url'] = 'http://asdlk-aselkaiwels.com';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the image validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheImageRule()
+ {
+ $_FILES['photo']['tmp_name'] = path('storage').'files/desert.jpg';
+ $rules = array('photo' => 'image');
+ $this->assertTrue(Validator::make($_FILES, $rules)->valid());
+
+ $_FILES['photo']['tmp_name'] = path('app').'routes.php';
+ $this->assertFalse(Validator::make($_FILES, $rules)->valid());
+ }
+
+ /**
+ * Test the alpha validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheAlphaRule()
+ {
+ $input = array('name' => 'TaylorOtwell');
+ $rules = array('name' => 'alpha');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['name'] = 'Taylor Otwell';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the alpha_num validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheAlphaNumRule()
+ {
+ $input = array('name' => 'TaylorOtwell1');
+ $rules = array('name' => 'alpha_num');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['name'] = 'Taylor Otwell';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the alpha_num validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheAlphaDashRule()
+ {
+ $input = array('name' => 'Taylor-Otwell_1');
+ $rules = array('name' => 'alpha_dash');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['name'] = 'Taylor Otwell';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test the mimes validation rule.
+ *
+ * @group laravel
+ */
+ public function testTheMimesRule()
+ {
+ $_FILES['file']['tmp_name'] = path('app').'routes.php';
+ $rules = array('file' => 'mimes:php,txt');
+ $this->assertTrue(Validator::make($_FILES, $rules)->valid());
+
+ $rules = array('file' => 'mimes:jpg,bmp');
+ $this->assertFalse(Validator::make($_FILES, $rules)->valid());
+
+ $_FILES['file']['tmp_name'] = path('storage').'files/desert.jpg';
+ $rules['file'] = 'mimes:jpg,bmp';
+ $this->assertTrue(Validator::make($_FILES, $rules)->valid());
+
+ $rules['file'] = 'mimes:txt,bmp';
+ $this->assertFalse(Validator::make($_FILES, $rules)->valid());
+ }
+
+ /**
+ * Test the unique validation rule.
+ *
+ * @group laravel
+ */
+ public function testUniqueRule()
+ {
+ $input = array('code' => 'ZZ');
+ $rules = array('code' => 'unique:validation_unique');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input = array('code' => 'AR');
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ $rules = array('code' => 'unique:validation_unique,code,AR,code');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Tests the exists validation rule.
+ *
+ * @group laravel
+ */
+ public function testExistsRule()
+ {
+ $input = array('code' => 'TX');
+ $rules = array('code' => 'exists:validation_unique');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['code'] = array('TX', 'NY');
+ $rules = array('code' => 'exists:validation_unique,code');
+ $this->assertTrue(Validator::make($input, $rules)->valid());
+
+ $input['code'] = array('TX', 'XX');
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+
+ $input['code'] = 'XX';
+ $this->assertFalse(Validator::make($input, $rules)->valid());
+ }
+
+ /**
+ * Test that the validator sets the correct messages.
+ *
+ * @group laravel
+ */
+ public function testCorrectMessagesAreSet()
+ {
+ $lang = require path('app').'language/en/validation.php';
+
+ $input = array('email' => 'example-foo');
+ $rules = array('name' => 'required', 'email' => 'required|email');
+ $v = Validator::make($input, $rules);
+ $v->valid();
+ $messages = $v->errors;
+ $this->assertInstanceOf('Laravel\\Messages', $messages);
+ $this->assertEquals(str_replace(':attribute', 'name', $lang['required']), $messages->first('name'));
+ $this->assertEquals(str_replace(':attribute', 'email', $lang['email']), $messages->first('email'));
+ }
+
+ /**
+ * Test that custom messages are recognized.
+ *
+ * @group laravel
+ */
+ public function testCustomMessagesAreRecognize()
+ {
+ $messages = array('required' => 'Required!');
+ $rules = array('name' => 'required');
+ $v = Validator::make(array(), $rules, $messages);
+ $v->valid();
+ $this->assertEquals('Required!', $v->errors->first('name'));
+
+ $messages['email_required'] = 'Email Required!';
+ $rules = array('name' => 'required', 'email' => 'required');
+ $v = Validator::make(array(), $rules, $messages);
+ $v->valid();
+ $this->assertEquals('Required!', $v->errors->first('name'));
+ $this->assertEquals('Email Required!', $v->errors->first('email'));
+
+ $rules = array('custom' => 'required');
+ $v = Validator::make(array(), $rules);
+ $v->valid();
+ $this->assertEquals('This field is required!', $v->errors->first('custom'));
+ }
+
+ /**
+ * Test that size replacements are made on messages.
+ *
+ * @group laravel
+ */
+ public function testNumericSizeReplacementsAreMade()
+ {
+ $lang = require path('app').'language/en/validation.php';
+
+ $input = array('amount' => 100);
+ $rules = array('amount' => 'numeric|size:80');
+ $v = Validator::make($input, $rules);
+ $v->valid();
+ $this->assertEquals(str_replace(array(':attribute', ':size'), array('amount', '80'), $lang['size']['numeric']), $v->errors->first('amount'));
+
+ $rules = array('amount' => 'numeric|between:70,80');
+ $v = Validator::make($input, $rules);
+ $v->valid();
+ $expect = str_replace(array(':attribute', ':min', ':max'), array('amount', '70', '80'), $lang['between']['numeric']);
+ $this->assertEquals($expect, $v->errors->first('amount'));
+
+ $rules = array('amount' => 'numeric|min:120');
+ $v = Validator::make($input, $rules);
+ $v->valid();
+ $expect = str_replace(array(':attribute', ':min'), array('amount', '120'), $lang['min']['numeric']);
+ $this->assertEquals($expect, $v->errors->first('amount'));
+
+ $rules = array('amount' => 'numeric|max:20');
+ $v = Validator::make($input, $rules);
+ $v->valid();
+ $expect = str_replace(array(':attribute', ':max'), array('amount', '20'), $lang['max']['numeric']);
+ $this->assertEquals($expect, $v->errors->first('amount'));
+ }
+
+ /**
+ * Test that string size replacements are made on messages.
+ *
+ * @group laravel
+ */
+ public function testStringSizeReplacementsAreMade()
+ {
+ $lang = require path('app').'language/en/validation.php';
+
+ $input = array('amount' => '100');
+ $rules = array('amount' => 'size:80');
+ $v = Validator::make($input, $rules);
+ $v->valid();
+ $this->assertEquals(str_replace(array(':attribute', ':size'), array('amount', '80'), $lang['size']['string']), $v->errors->first('amount'));
+
+ $rules = array('amount' => 'between:70,80');
+ $v = Validator::make($input, $rules);
+ $v->valid();
+ $expect = str_replace(array(':attribute', ':min', ':max'), array('amount', '70', '80'), $lang['between']['string']);
+ $this->assertEquals($expect, $v->errors->first('amount'));
+
+ $rules = array('amount' => 'min:120');
+ $v = Validator::make($input, $rules);
+ $v->valid();
+ $expect = str_replace(array(':attribute', ':min'), array('amount', '120'), $lang['min']['string']);
+ $this->assertEquals($expect, $v->errors->first('amount'));
+
+ $rules = array('amount' => 'max:2');
+ $v = Validator::make($input, $rules);
+ $v->valid();
+ $expect = str_replace(array(':attribute', ':max'), array('amount', '2'), $lang['max']['string']);
+ $this->assertEquals($expect, $v->errors->first('amount'));
+ }
+
+ /**
+ * Test that string size replacements are made on messages.
+ *
+ * @group laravel
+ */
+ public function testFileSizeReplacementsAreMade()
+ {
+ $lang = require path('app').'language/en/validation.php';
+
+ $_FILES['amount']['tmp_name'] = 'foo';
+ $_FILES['amount']['size'] = 10000;
+ $rules = array('amount' => 'size:80');
+ $v = Validator::make($_FILES, $rules);
+ $v->valid();
+ $this->assertEquals(str_replace(array(':attribute', ':size'), array('amount', '80'), $lang['size']['file']), $v->errors->first('amount'));
+
+ $rules = array('amount' => 'between:70,80');
+ $v = Validator::make($_FILES, $rules);
+ $v->valid();
+ $expect = str_replace(array(':attribute', ':min', ':max'), array('amount', '70', '80'), $lang['between']['file']);
+ $this->assertEquals($expect, $v->errors->first('amount'));
+
+ $rules = array('amount' => 'min:120');
+ $v = Validator::make($_FILES, $rules);
+ $v->valid();
+ $expect = str_replace(array(':attribute', ':min'), array('amount', '120'), $lang['min']['file']);
+ $this->assertEquals($expect, $v->errors->first('amount'));
+
+ $rules = array('amount' => 'max:2');
+ $v = Validator::make($_FILES, $rules);
+ $v->valid();
+ $expect = str_replace(array(':attribute', ':max'), array('amount', '2'), $lang['max']['file']);
+ $this->assertEquals($expect, $v->errors->first('amount'));
+ }
+
+ /**
+ * Test that values get replaced in messages.
+ *
+ * @group laravel
+ */
+ public function testValuesGetReplaced()
+ {
+ $lang = require path('app').'language/en/validation.php';
+
+ $_FILES['file']['tmp_name'] = path('storage').'files/desert.jpg';
+ $rules = array('file' => 'mimes:php,txt');
+ $v = Validator::make($_FILES, $rules);
+ $v->valid();
+
+ $expect = str_replace(array(':attribute', ':values'), array('file', 'php, txt'), $lang['mimes']);
+ $this->assertEquals($expect, $v->errors->first('file'));
+ }
+
+ /**
+ * Test custom attribute names are replaced.
+ *
+ * @group laravel
+ */
+ public function testCustomAttributesAreReplaced()
+ {
+ $lang = require path('app').'language/en/validation.php';
+
+ $rules = array('test_attribute' => 'required');
+ $v = Validator::make(array(), $rules);
+ $v->valid();
+
+ $expect = str_replace(':attribute', 'attribute', $lang['required']);
+ $this->assertEquals($expect, $v->errors->first('test_attribute'));
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/cases/view.test.php b/app/laravel/tests/cases/view.test.php
new file mode 100644
index 000000000..9716724a1
--- /dev/null
+++ b/app/laravel/tests/cases/view.test.php
@@ -0,0 +1,255 @@
+assertInstanceOf('Laravel\\View', View::make('home.index'));
+ }
+
+ /**
+ * Test the View class constructor.
+ *
+ * @group laravel
+ */
+ public function testViewNameIsSetByConstrutor()
+ {
+ $view = new View('home.index');
+
+ $this->assertEquals('home.index', $view->view);
+ }
+
+ /**
+ * Test the View class constructor.
+ *
+ * @group laravel
+ */
+ public function testViewIsCreatedWithCorrectPath()
+ {
+ $view = new View('home.index');
+
+ $this->assertEquals(
+ str_replace(DS, '/', path('app')).'views/home/index.php',
+ str_replace(DS, '/', $view->path)
+ );
+ }
+
+ /**
+ * Test the View class constructor for bundles.
+ *
+ * @group laravel
+ */
+ public function testBundleViewIsCreatedWithCorrectPath()
+ {
+ $view = new View('home.index');
+
+ $this->assertEquals(
+ str_replace(DS, '/', Bundle::path(DEFAULT_BUNDLE)).'views/home/index.php',
+ str_replace(DS, '/', $view->path)
+ );
+ }
+
+ /**
+ * Test the View class constructor.
+ *
+ * @group laravel
+ */
+ public function testDataIsSetOnViewByConstructor()
+ {
+ $view = new View('home.index', array('name' => 'Taylor'));
+
+ $this->assertEquals('Taylor', $view->data['name']);
+ }
+
+ /**
+ * Test the View::name method.
+ *
+ * @group laravel
+ */
+ public function testNameMethodRegistersAViewName()
+ {
+ View::name('home.index', 'home');
+
+ $this->assertEquals('home.index', View::$names['home']);
+ }
+
+ /**
+ * Test the View::shared method.
+ *
+ * @group laravel
+ */
+ public function testSharedMethodAddsDataToSharedArray()
+ {
+ View::share('comment', 'Taylor');
+
+ $this->assertEquals('Taylor', View::$shared['comment']);
+ }
+
+ /**
+ * Test the View::with method.
+ *
+ * @group laravel
+ */
+ public function testViewDataCanBeSetUsingWithMethod()
+ {
+ $view = View::make('home.index')->with('comment', 'Taylor');
+
+ $this->assertEquals('Taylor', $view->data['comment']);
+ }
+
+ /**
+ * Test the View class constructor.
+ *
+ * @group laravel
+ */
+ public function testEmptyMessageContainerSetOnViewWhenNoErrorsInSession()
+ {
+ $view = new View('home.index');
+
+ $this->assertInstanceOf('Laravel\\Messages', $view->data['errors']);
+ }
+
+ /**
+ * Test the View __set method.
+ *
+ * @group laravel
+ */
+ public function testDataCanBeSetOnViewsThroughMagicMethods()
+ {
+ $view = new View('home.index');
+
+ $view->comment = 'Taylor';
+
+ $this->assertEquals('Taylor', $view->data['comment']);
+ }
+
+ /**
+ * Test the View __get method.
+ *
+ * @group laravel
+ */
+ public function testDataCanBeRetrievedFromViewsThroughMagicMethods()
+ {
+ $view = new View('home.index');
+
+ $view->comment = 'Taylor';
+
+ $this->assertEquals('Taylor', $view->comment);
+ }
+
+ /**
+ * Test the View's ArrayAccess implementation.
+ *
+ * @group laravel
+ */
+ public function testDataCanBeSetOnTheViewThroughArrayAccess()
+ {
+ $view = new View('home.index');
+
+ $view['comment'] = 'Taylor';
+
+ $this->assertEquals('Taylor', $view->data['comment']);
+ }
+
+ /**
+ * Test the View's ArrayAccess implementation.
+ *
+ * @group laravel
+ */
+ public function testDataCanBeRetrievedThroughArrayAccess()
+ {
+ $view = new View('home.index');
+
+ $view['comment'] = 'Taylor';
+
+ $this->assertEquals('Taylor', $view['comment']);
+ }
+
+ /**
+ * Test the View::nest method.
+ *
+ * @group laravel
+ */
+ public function testNestMethodSetsViewInstanceInData()
+ {
+ $view = View::make('home.index')->nest('partial', 'tests.basic');
+
+ $this->assertEquals('tests.basic', $view->data['partial']->view);
+
+ $this->assertInstanceOf('Laravel\\View', $view->data['partial']);
+ }
+
+ /**
+ * Test that the registered data is passed to the view correctly.
+ *
+ * @group laravel
+ */
+ public function testDataIsPassedToViewCorrectly()
+ {
+ View::share('name', 'Taylor');
+
+ $view = View::make('tests.basic')->with('age', 25)->render();
+
+ $this->assertEquals('Taylor is 25', $view);
+ }
+
+ /**
+ * Test that the View class renders nested views.
+ *
+ * @group laravel
+ */
+ public function testNestedViewsAreRendered()
+ {
+ $view = View::make('tests.basic')
+ ->with('age', 25)
+ ->nest('name', 'tests.nested');
+
+ $this->assertEquals('Taylor is 25', $view->render());
+ }
+
+ /**
+ * Test that the View class renders nested responses.
+ *
+ * @group laravel
+ */
+ public function testNestedResponsesAreRendered()
+ {
+ $view = View::make('tests.basic')
+ ->with('age', 25)
+ ->with('name', Response::view('tests.nested'));
+
+ $this->assertEquals('Taylor is 25', $view->render());
+ }
+
+ /**
+ * Test the View class raises a composer event.
+ *
+ * @group laravel
+ */
+ public function testComposerEventIsCalledWhenViewIsRendering()
+ {
+ View::composer('tests.basic', function($view)
+ {
+ $view->data = array('name' => 'Taylor', 'age' => 25);
+ });
+
+ $view = View::make('tests.basic')->render();
+
+ $this->assertEquals('Taylor is 25', $view);
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/tests/phpunit.php b/app/laravel/tests/phpunit.php
new file mode 100644
index 000000000..8e5ba2047
--- /dev/null
+++ b/app/laravel/tests/phpunit.php
@@ -0,0 +1,32 @@
+
* // Get the first segment of the request URI
@@ -228,26 +102,4 @@ protected static function segments($uri)
static::$segments = array_diff($segments, array(''));
}
- /**
- * Remove a given value from the URI.
- *
- * @param string $uri
- * @param string $value
- * @return string
- */
- protected static function remove($uri, $value)
- {
- return (strpos($uri, $value) === 0) ? substr($uri, strlen($value)) : $uri;
- }
-
- /**
- * Get the query string for the current request.
- *
- * @return string
- */
- protected static function query()
- {
- return (count((array) $_GET) > 0) ? '?'.http_build_query($_GET) : '';
- }
-
}
\ No newline at end of file
diff --git a/app/laravel/url.php b/app/laravel/url.php
index d523abbee..c87139e49 100644
--- a/app/laravel/url.php
+++ b/app/laravel/url.php
@@ -26,7 +26,7 @@ public static function full()
*/
public static function current()
{
- return static::to(URI::current());
+ return static::to(URI::current(), null, false, false);
}
/**
@@ -35,7 +35,7 @@ public static function current()
* @param bool $https
* @return string
*/
- public static function home($https = false)
+ public static function home($https = null)
{
$route = Router::find('home');
@@ -61,45 +61,21 @@ public static function base()
$base = 'http://localhost';
- // If the application URL configuration is set, we will just use that
+ // If the application's URL configuration is set, we will just use that
// instead of trying to guess the URL from the $_SERVER array's host
- // and script variables as this is more reliable.
+ // and script variables as this is a more reliable method.
if (($url = Config::get('application.url')) !== '')
{
$base = $url;
}
- elseif (isset($_SERVER['HTTP_HOST']))
+ else
{
- $base = static::guess();
+ $base = Request::foundation()->getRootUrl();
}
return static::$base = $base;
}
- /**
- * Guess the application URL based on the $_SERVER variables.
- *
- * @return string
- */
- protected static function guess()
- {
- $protocol = (Request::secure()) ? 'https://' : 'http://';
-
- // Basically, by removing the basename, we are removing everything after
- // the and including the front controller from the URI. Leaving us with
- // the installation path for the application.
- $script = $_SERVER['SCRIPT_NAME'];
-
- $path = str_replace(basename($script), '', $script);
-
- // Now that we have the URL, all we need to do is attach the protocol
- // protocol and HTTP_HOST to build the URL for the application, and
- // we also trim off trailing slashes for cleanliness.
- $uri = $protocol.$_SERVER['HTTP_HOST'].$path;
-
- return rtrim($uri, '/');
- }
-
/**
* Generate an application URL.
*
@@ -113,13 +89,40 @@ protected static function guess()
*
* @param string $url
* @param bool $https
+ * @param bool $asset
+ * @param bool $locale
* @return string
*/
- public static function to($url = '', $https = false)
+ public static function to($url = '', $https = null, $asset = false, $locale = true)
{
- if (filter_var($url, FILTER_VALIDATE_URL) !== false) return $url;
+ // If the given URL is already valid or begins with a hash, we'll just return
+ // the URL unchanged since it is already well formed. Otherwise we will add
+ // the base URL of the application and return the full URL.
+ if (static::valid($url) or starts_with($url, '#'))
+ {
+ return $url;
+ }
+
+ // Unless $https is specified (true or false), we maintain the current request
+ // security for any new links generated. So https for all secure links.
+ if (is_null($https)) $https = Request::secure();
- $root = static::base().'/'.Config::get('application.index');
+ $root = static::base();
+
+ if ( ! $asset)
+ {
+ $root .= '/'.Config::get('application.index');
+ }
+
+ $languages = Config::get('application.languages');
+
+ if ( ! $asset and $locale and count($languages) > 0)
+ {
+ if (in_array($default = Config::get('application.language'), $languages))
+ {
+ $root = rtrim($root, '/').'/'.$default;
+ }
+ }
// Since SSL is not often used while developing the application, we allow the
// developer to disable SSL on all framework generated links to make it more
@@ -128,6 +131,10 @@ public static function to($url = '', $https = false)
{
$root = preg_replace('~http://~', 'https://', $root, 1);
}
+ else
+ {
+ $root = preg_replace('~https://~', 'http://', $root, 1);
+ }
return rtrim($root, '/').'/'.ltrim($url, '/');
}
@@ -171,7 +178,7 @@ public static function to_action($action, $parameters = array())
}
// If no route was found that handled the given action, we'll just
// generate the URL using the typical controller routing setup
- // for URIs and turn SSL to false.
+ // for URIs and turn SSL to false by default.
else
{
return static::convention($action, $parameters);
@@ -179,7 +186,7 @@ public static function to_action($action, $parameters = array())
}
/**
- * Generate a action URL from a route definition
+ * Generate an action URL from a route definition
*
* @param array $route
* @param string $action
@@ -188,7 +195,7 @@ public static function to_action($action, $parameters = array())
*/
protected static function explicit($route, $action, $parameters)
{
- $https = array_get(current($route), 'https', false);
+ $https = array_get(current($route), 'https', null);
return static::to(static::transpose(key($route), $parameters), $https);
}
@@ -206,13 +213,11 @@ protected static function convention($action, $parameters)
$bundle = Bundle::get($bundle);
- // If a bundle exists for the action, we will attempt to use it's "handles"
+ // If a bundle exists for the action, we will attempt to use its "handles"
// clause as the root of the generated URL, as the bundle can only handle
// URIs that begin with that string and no others.
$root = $bundle['handles'] ?: '';
- $https = false;
-
$parameters = implode('/', $parameters);
// We'll replace both dots and @ signs in the URI since both are used
@@ -234,9 +239,17 @@ protected static function convention($action, $parameters)
*/
public static function to_asset($url, $https = null)
{
- if (is_null($https)) $https = Request::secure();
+ if (static::valid($url)) return $url;
+
+ // If a base asset URL is defined in the configuration, use that and don't
+ // try and change the HTTP protocol. This allows the delivery of assets
+ // through a different server or third-party content delivery network.
+ if ($root = Config::get('application.asset_url', false))
+ {
+ return rtrim($root, '/').'/'.ltrim($url, '/');
+ }
- $url = static::to($url, $https);
+ $url = static::to($url, $https, true);
// Since assets are not served by Laravel, we do not need to come through
// the front controller. So, we'll remove the application index specified
@@ -262,7 +275,6 @@ public static function to_asset($url, $https = null)
*
* @param string $name
* @param array $parameters
- * @param bool $https
* @return string
*/
public static function to_route($name, $parameters = array())
@@ -275,7 +287,7 @@ public static function to_route($name, $parameters = array())
// To determine whether the URL should be HTTPS or not, we look for the "https"
// value on the route action array. The route has control over whether the URL
// should be generated with an HTTPS protocol string or just HTTP.
- $https = array_get(current($route), 'https', false);
+ $https = array_get(current($route), 'https', null);
$uri = trim(static::transpose(key($route), $parameters), '/');
@@ -304,10 +316,21 @@ public static function transpose($uri, $parameters)
// If there are any remaining optional place-holders, we'll just replace
// them with empty strings since not every optional parameter has to be
- // in the array of parameters that were passed.
- $uri = str_replace(array_keys(Router::$optional), '', $uri);
+ // in the array of parameters that were passed to us.
+ $uri = preg_replace('/\(.+?\)/', '', $uri);
return trim($uri, '/');
}
-}
\ No newline at end of file
+ /**
+ * Determine if the given URL is valid.
+ *
+ * @param string $url
+ * @return bool
+ */
+ public static function valid($url)
+ {
+ return filter_var($url, FILTER_VALIDATE_URL) !== false;
+ }
+
+}
diff --git a/app/laravel/validator.php b/app/laravel/validator.php
index b18bf512e..ab446860f 100644
--- a/app/laravel/validator.php
+++ b/app/laravel/validator.php
@@ -214,7 +214,7 @@ protected function validatable($rule, $attribute, $value)
*/
protected function implicit($rule)
{
- return $rule == 'required' or $rule == 'accepted';
+ return $rule == 'required' or $rule == 'accepted' or $rule == 'required_with';
}
/**
@@ -249,7 +249,7 @@ protected function validate_required($attribute, $value)
{
return false;
}
- elseif ( ! is_null(Input::file($attribute)) and $value['tmp_name'] == '')
+ elseif ( ! is_null(Input::file($attribute)) and is_array($value) and $value['tmp_name'] == '')
{
return false;
}
@@ -257,6 +257,27 @@ protected function validate_required($attribute, $value)
return true;
}
+ /**
+ * Validate that an attribute exists in the attributes array, if another
+ * attribute exists in the attributes array.
+ *
+ * @param string $attribute
+ * @param mixed $value
+ * @param array $parameters
+ * @return bool
+ */
+ protected function validate_required_with($attribute, $value, $parameters)
+ {
+ $other = $parameters[0];
+
+ if ($this->validate_required($other, $this->attributes[$other]))
+ {
+ return $this->validate_required($attribute, $value);
+ }
+
+ return true;
+ }
+
/**
* Validate that an attribute has a matching confirmation attribute.
*
@@ -401,8 +422,8 @@ protected function validate_max($attribute, $value, $parameters)
protected function size($attribute, $value)
{
// This method will determine if the attribute is a number, string, or file and
- // return the proper size accordingly. If it is a number, then number itself is
- // the size; if it is a file, the size is kilobytes in the size; if it is a
+ // return the proper size accordingly. If it is a number, the number itself is
+ // the size; if it is a file, the kilobytes is the size; if it is a
// string, the length is the size.
if (is_numeric($value) and $this->has_rule($attribute, $this->numeric_rules))
{
@@ -560,7 +581,7 @@ protected function validate_active_url($attribute, $value)
{
$url = str_replace(array('http://', 'https://', 'ftp://'), '', Str::lower($value));
- return checkdnsrr($url);
+ return (trim($url) !== '') ? checkdnsrr($url) : false;
}
/**
@@ -616,6 +637,7 @@ protected function validate_alpha_dash($attribute, $value)
*
* @param string $attribute
* @param mixed $value
+ * @param array $parameters
* @return bool
*/
protected function validate_match($attribute, $value, $parameters)
@@ -646,6 +668,70 @@ protected function validate_mimes($attribute, $value, $parameters)
return false;
}
+ /**
+ * Validate that an attribute is an array
+ *
+ * @param string $attribute
+ * @param mixed $value
+ * @return bool
+ */
+ protected function validate_array($attribute, $value)
+ {
+ return is_array($value);
+ }
+
+ /**
+ * Validate that an attribute of type array has a specific count
+ *
+ * @param string $attribute
+ * @param mixed $value
+ * @param array $parameters
+ * @return bool
+ */
+ protected function validate_count($attribute, $value, $parameters)
+ {
+ return (is_array($value) && count($value) == $parameters[0]);
+ }
+
+ /**
+ * Validate that an attribute of type array has a minimum of elements.
+ *
+ * @param string $attribute
+ * @param mixed $value
+ * @param array $parameters
+ * @return bool
+ */
+ protected function validate_countmin($attribute, $value, $parameters)
+ {
+ return (is_array($value) && count($value) >= $parameters[0]);
+ }
+
+ /**
+ * Validate that an attribute of type array has a maximum of elements.
+ *
+ * @param string $attribute
+ * @param mixed $value
+ * @param array $parameters
+ * @return bool
+ */
+ protected function validate_countmax($attribute, $value, $parameters)
+ {
+ return (is_array($value) && count($value) <= $parameters[0]);
+ }
+
+ /**
+ * Validate that an attribute of type array has elements between max and min.
+ *
+ * @param string $attribute
+ * @param mixed $value
+ * @param array $parameters
+ * @return bool
+ */
+ protected function validate_countbetween($attribute, $value, $parameters)
+ {
+ return (is_array($value) && count($value) >= $parameters[0] && count($value) <= $parameters[1] );
+ }
+
/**
* Validate the date is before a given date.
*
@@ -743,7 +829,7 @@ protected function size_message($bundle, $attribute, $rule)
}
// We assume that attributes present in the $_FILES array are files,
// which makes sense. If the attribute doesn't have numeric rules
- // and isn't as file, it's a string.
+ // and isn't a file, it's a string.
elseif (array_key_exists($attribute, Input::file()))
{
$line = 'file';
@@ -862,7 +948,7 @@ protected function replace_not_in($message, $attribute, $rule, $parameters)
}
/**
- * Replace all place-holders for the not_in rule.
+ * Replace all place-holders for the mimes rule.
*
* @param string $message
* @param string $attribute
@@ -931,6 +1017,62 @@ protected function replace_after($message, $attribute, $rule, $parameters)
return str_replace(':date', $parameters[0], $message);
}
+ /**
+ * Replace all place-holders for the count rule.
+ *
+ * @param string $message
+ * @param string $attribute
+ * @param string $rule
+ * @param array $parameters
+ * @return string
+ */
+ protected function replace_count($message, $attribute, $rule, $parameters)
+ {
+ return str_replace(':count', $parameters[0], $message);
+ }
+
+ /**
+ * Replace all place-holders for the countmin rule.
+ *
+ * @param string $message
+ * @param string $attribute
+ * @param string $rule
+ * @param array $parameters
+ * @return string
+ */
+ protected function replace_countmin($message, $attribute, $rule, $parameters)
+ {
+ return str_replace(':min', $parameters[0], $message);
+ }
+
+ /**
+ * Replace all place-holders for the countmax rule.
+ *
+ * @param string $message
+ * @param string $attribute
+ * @param string $rule
+ * @param array $parameters
+ * @return string
+ */
+ protected function replace_countmax($message, $attribute, $rule, $parameters)
+ {
+ return str_replace(':max', $parameters[0], $message);
+ }
+
+ /**
+ * Replace all place-holders for the between rule.
+ *
+ * @param string $message
+ * @param string $attribute
+ * @param string $rule
+ * @param array $parameters
+ * @return string
+ */
+ protected function replace_countbetween($message, $attribute, $rule, $parameters)
+ {
+ return str_replace(array(':min', ':max'), $parameters, $message);
+ }
+
/**
* Get the displayable name for a given attribute.
*
@@ -946,17 +1088,18 @@ protected function attribute($attribute)
// of the attribute name in the message.
$line = "{$bundle}validation.attributes.{$attribute}";
- $display = Lang::line($line)->get($this->language);
+ if (Lang::has($line, $this->language))
+ {
+ return Lang::line($line)->get($this->language);
+ }
// If no language line has been specified for the attribute, all of
// the underscores are removed from the attribute name and that
- // will be used as the attribtue name.
- if (is_null($display))
+ // will be used as the attribute name.
+ else
{
return str_replace('_', ' ', $attribute);
}
-
- return $display;
}
/**
diff --git a/app/laravel/vendor/Symfony/Component/Console/Application.php b/app/laravel/vendor/Symfony/Component/Console/Application.php
new file mode 100644
index 000000000..e04940ab1
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Application.php
@@ -0,0 +1,1007 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\ArgvInput;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Console\Output\ConsoleOutputInterface;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Command\HelpCommand;
+use Symfony\Component\Console\Command\ListCommand;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Helper\FormatterHelper;
+use Symfony\Component\Console\Helper\DialogHelper;
+
+/**
+ * An Application is the container for a collection of commands.
+ *
+ * It is the main entry point of a Console application.
+ *
+ * This class is optimized for a standard CLI environment.
+ *
+ * Usage:
+ *
+ * $app = new Application('myapp', '1.0 (stable)');
+ * $app->add(new SimpleCommand());
+ * $app->run();
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class Application
+{
+ private $commands;
+ private $wantHelps = false;
+ private $runningCommand;
+ private $name;
+ private $version;
+ private $catchExceptions;
+ private $autoExit;
+ private $definition;
+ private $helperSet;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of the application
+ * @param string $version The version of the application
+ *
+ * @api
+ */
+ public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
+ {
+ $this->name = $name;
+ $this->version = $version;
+ $this->catchExceptions = true;
+ $this->autoExit = true;
+ $this->commands = array();
+ $this->helperSet = $this->getDefaultHelperSet();
+ $this->definition = $this->getDefaultInputDefinition();
+
+ foreach ($this->getDefaultCommands() as $command) {
+ $this->add($command);
+ }
+ }
+
+ /**
+ * Runs the current application.
+ *
+ * @param InputInterface $input An Input instance
+ * @param OutputInterface $output An Output instance
+ *
+ * @return integer 0 if everything went fine, or an error code
+ *
+ * @throws \Exception When doRun returns Exception
+ *
+ * @api
+ */
+ public function run(InputInterface $input = null, OutputInterface $output = null)
+ {
+ if (null === $input) {
+ $input = new ArgvInput();
+ }
+
+ if (null === $output) {
+ $output = new ConsoleOutput();
+ }
+
+ try {
+ $statusCode = $this->doRun($input, $output);
+ } catch (\Exception $e) {
+ if (!$this->catchExceptions) {
+ throw $e;
+ }
+
+ if ($output instanceof ConsoleOutputInterface) {
+ $this->renderException($e, $output->getErrorOutput());
+ } else {
+ $this->renderException($e, $output);
+ }
+ $statusCode = $e->getCode();
+
+ $statusCode = is_numeric($statusCode) && $statusCode ? $statusCode : 1;
+ }
+
+ if ($this->autoExit) {
+ if ($statusCode > 255) {
+ $statusCode = 255;
+ }
+ // @codeCoverageIgnoreStart
+ exit($statusCode);
+ // @codeCoverageIgnoreEnd
+ }
+
+ return $statusCode;
+ }
+
+ /**
+ * Runs the current application.
+ *
+ * @param InputInterface $input An Input instance
+ * @param OutputInterface $output An Output instance
+ *
+ * @return integer 0 if everything went fine, or an error code
+ */
+ public function doRun(InputInterface $input, OutputInterface $output)
+ {
+ $name = $this->getCommandName($input);
+
+ if (true === $input->hasParameterOption(array('--ansi'))) {
+ $output->setDecorated(true);
+ } elseif (true === $input->hasParameterOption(array('--no-ansi'))) {
+ $output->setDecorated(false);
+ }
+
+ if (true === $input->hasParameterOption(array('--help', '-h'))) {
+ if (!$name) {
+ $name = 'help';
+ $input = new ArrayInput(array('command' => 'help'));
+ } else {
+ $this->wantHelps = true;
+ }
+ }
+
+ if (true === $input->hasParameterOption(array('--no-interaction', '-n'))) {
+ $input->setInteractive(false);
+ }
+
+ if (function_exists('posix_isatty') && $this->getHelperSet()->has('dialog')) {
+ $inputStream = $this->getHelperSet()->get('dialog')->getInputStream();
+ if (!posix_isatty($inputStream)) {
+ $input->setInteractive(false);
+ }
+ }
+
+ if (true === $input->hasParameterOption(array('--quiet', '-q'))) {
+ $output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
+ } elseif (true === $input->hasParameterOption(array('--verbose', '-v'))) {
+ $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
+ }
+
+ if (true === $input->hasParameterOption(array('--version', '-V'))) {
+ $output->writeln($this->getLongVersion());
+
+ return 0;
+ }
+
+ if (!$name) {
+ $name = 'list';
+ $input = new ArrayInput(array('command' => 'list'));
+ }
+
+ // the command name MUST be the first element of the input
+ $command = $this->find($name);
+
+ $this->runningCommand = $command;
+ $statusCode = $command->run($input, $output);
+ $this->runningCommand = null;
+
+ return is_numeric($statusCode) ? $statusCode : 0;
+ }
+
+ /**
+ * Set a helper set to be used with the command.
+ *
+ * @param HelperSet $helperSet The helper set
+ *
+ * @api
+ */
+ public function setHelperSet(HelperSet $helperSet)
+ {
+ $this->helperSet = $helperSet;
+ }
+
+ /**
+ * Get the helper set associated with the command.
+ *
+ * @return HelperSet The HelperSet instance associated with this command
+ *
+ * @api
+ */
+ public function getHelperSet()
+ {
+ return $this->helperSet;
+ }
+
+ /**
+ * Gets the InputDefinition related to this Application.
+ *
+ * @return InputDefinition The InputDefinition instance
+ */
+ public function getDefinition()
+ {
+ return $this->definition;
+ }
+
+ /**
+ * Gets the help message.
+ *
+ * @return string A help message.
+ */
+ public function getHelp()
+ {
+ $messages = array(
+ $this->getLongVersion(),
+ '',
+ 'Usage: ',
+ sprintf(" [options] command [arguments]\n"),
+ 'Options: ',
+ );
+
+ foreach ($this->getDefinition()->getOptions() as $option) {
+ $messages[] = sprintf(' %-29s %s %s',
+ '--'.$option->getName().' ',
+ $option->getShortcut() ? '-'.$option->getShortcut().' ' : ' ',
+ $option->getDescription()
+ );
+ }
+
+ return implode(PHP_EOL, $messages);
+ }
+
+ /**
+ * Sets whether to catch exceptions or not during commands execution.
+ *
+ * @param Boolean $boolean Whether to catch exceptions or not during commands execution
+ *
+ * @api
+ */
+ public function setCatchExceptions($boolean)
+ {
+ $this->catchExceptions = (Boolean) $boolean;
+ }
+
+ /**
+ * Sets whether to automatically exit after a command execution or not.
+ *
+ * @param Boolean $boolean Whether to automatically exit after a command execution or not
+ *
+ * @api
+ */
+ public function setAutoExit($boolean)
+ {
+ $this->autoExit = (Boolean) $boolean;
+ }
+
+ /**
+ * Gets the name of the application.
+ *
+ * @return string The application name
+ *
+ * @api
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Sets the application name.
+ *
+ * @param string $name The application name
+ *
+ * @api
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Gets the application version.
+ *
+ * @return string The application version
+ *
+ * @api
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Sets the application version.
+ *
+ * @param string $version The application version
+ *
+ * @api
+ */
+ public function setVersion($version)
+ {
+ $this->version = $version;
+ }
+
+ /**
+ * Returns the long version of the application.
+ *
+ * @return string The long application version
+ *
+ * @api
+ */
+ public function getLongVersion()
+ {
+ if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) {
+ return sprintf('%s version %s ', $this->getName(), $this->getVersion());
+ }
+
+ return 'Console Tool ';
+ }
+
+ /**
+ * Registers a new command.
+ *
+ * @param string $name The command name
+ *
+ * @return Command The newly created command
+ *
+ * @api
+ */
+ public function register($name)
+ {
+ return $this->add(new Command($name));
+ }
+
+ /**
+ * Adds an array of command objects.
+ *
+ * @param Command[] $commands An array of commands
+ *
+ * @api
+ */
+ public function addCommands(array $commands)
+ {
+ foreach ($commands as $command) {
+ $this->add($command);
+ }
+ }
+
+ /**
+ * Adds a command object.
+ *
+ * If a command with the same name already exists, it will be overridden.
+ *
+ * @param Command $command A Command object
+ *
+ * @return Command The registered command
+ *
+ * @api
+ */
+ public function add(Command $command)
+ {
+ $command->setApplication($this);
+
+ if (!$command->isEnabled()) {
+ $command->setApplication(null);
+
+ return;
+ }
+
+ $this->commands[$command->getName()] = $command;
+
+ foreach ($command->getAliases() as $alias) {
+ $this->commands[$alias] = $command;
+ }
+
+ return $command;
+ }
+
+ /**
+ * Returns a registered command by name or alias.
+ *
+ * @param string $name The command name or alias
+ *
+ * @return Command A Command object
+ *
+ * @throws \InvalidArgumentException When command name given does not exist
+ *
+ * @api
+ */
+ public function get($name)
+ {
+ if (!isset($this->commands[$name])) {
+ throw new \InvalidArgumentException(sprintf('The command "%s" does not exist.', $name));
+ }
+
+ $command = $this->commands[$name];
+
+ if ($this->wantHelps) {
+ $this->wantHelps = false;
+
+ $helpCommand = $this->get('help');
+ $helpCommand->setCommand($command);
+
+ return $helpCommand;
+ }
+
+ return $command;
+ }
+
+ /**
+ * Returns true if the command exists, false otherwise.
+ *
+ * @param string $name The command name or alias
+ *
+ * @return Boolean true if the command exists, false otherwise
+ *
+ * @api
+ */
+ public function has($name)
+ {
+ return isset($this->commands[$name]);
+ }
+
+ /**
+ * Returns an array of all unique namespaces used by currently registered commands.
+ *
+ * It does not returns the global namespace which always exists.
+ *
+ * @return array An array of namespaces
+ */
+ public function getNamespaces()
+ {
+ $namespaces = array();
+ foreach ($this->commands as $command) {
+ $namespaces[] = $this->extractNamespace($command->getName());
+
+ foreach ($command->getAliases() as $alias) {
+ $namespaces[] = $this->extractNamespace($alias);
+ }
+ }
+
+ return array_values(array_unique(array_filter($namespaces)));
+ }
+
+ /**
+ * Finds a registered namespace by a name or an abbreviation.
+ *
+ * @param string $namespace A namespace or abbreviation to search for
+ *
+ * @return string A registered namespace
+ *
+ * @throws \InvalidArgumentException When namespace is incorrect or ambiguous
+ */
+ public function findNamespace($namespace)
+ {
+ $allNamespaces = array();
+ foreach ($this->getNamespaces() as $n) {
+ $allNamespaces[$n] = explode(':', $n);
+ }
+
+ $found = array();
+ foreach (explode(':', $namespace) as $i => $part) {
+ $abbrevs = static::getAbbreviations(array_unique(array_values(array_filter(array_map(function ($p) use ($i) { return isset($p[$i]) ? $p[$i] : ''; }, $allNamespaces)))));
+
+ if (!isset($abbrevs[$part])) {
+ $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace);
+
+ if (1 <= $i) {
+ $part = implode(':', $found).':'.$part;
+ }
+
+ if ($alternatives = $this->findAlternativeNamespace($part, $abbrevs)) {
+ $message .= "\n\nDid you mean one of these?\n ";
+ $message .= implode("\n ", $alternatives);
+ }
+
+ throw new \InvalidArgumentException($message);
+ }
+
+ if (count($abbrevs[$part]) > 1) {
+ throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions($abbrevs[$part])));
+ }
+
+ $found[] = $abbrevs[$part][0];
+ }
+
+ return implode(':', $found);
+ }
+
+ /**
+ * Finds a command by name or alias.
+ *
+ * Contrary to get, this command tries to find the best
+ * match if you give it an abbreviation of a name or alias.
+ *
+ * @param string $name A command name or a command alias
+ *
+ * @return Command A Command instance
+ *
+ * @throws \InvalidArgumentException When command name is incorrect or ambiguous
+ *
+ * @api
+ */
+ public function find($name)
+ {
+ // namespace
+ $namespace = '';
+ $searchName = $name;
+ if (false !== $pos = strrpos($name, ':')) {
+ $namespace = $this->findNamespace(substr($name, 0, $pos));
+ $searchName = $namespace.substr($name, $pos);
+ }
+
+ // name
+ $commands = array();
+ foreach ($this->commands as $command) {
+ if ($this->extractNamespace($command->getName()) == $namespace) {
+ $commands[] = $command->getName();
+ }
+ }
+
+ $abbrevs = static::getAbbreviations(array_unique($commands));
+ if (isset($abbrevs[$searchName]) && 1 == count($abbrevs[$searchName])) {
+ return $this->get($abbrevs[$searchName][0]);
+ }
+
+ if (isset($abbrevs[$searchName]) && count($abbrevs[$searchName]) > 1) {
+ $suggestions = $this->getAbbreviationSuggestions($abbrevs[$searchName]);
+
+ throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions));
+ }
+
+ // aliases
+ $aliases = array();
+ foreach ($this->commands as $command) {
+ foreach ($command->getAliases() as $alias) {
+ if ($this->extractNamespace($alias) == $namespace) {
+ $aliases[] = $alias;
+ }
+ }
+ }
+
+ $aliases = static::getAbbreviations(array_unique($aliases));
+ if (!isset($aliases[$searchName])) {
+ $message = sprintf('Command "%s" is not defined.', $name);
+
+ if ($alternatives = $this->findAlternativeCommands($searchName, $abbrevs)) {
+ $message .= "\n\nDid you mean one of these?\n ";
+ $message .= implode("\n ", $alternatives);
+ }
+
+ throw new \InvalidArgumentException($message);
+ }
+
+ if (count($aliases[$searchName]) > 1) {
+ throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $this->getAbbreviationSuggestions($aliases[$searchName])));
+ }
+
+ return $this->get($aliases[$searchName][0]);
+ }
+
+ /**
+ * Gets the commands (registered in the given namespace if provided).
+ *
+ * The array keys are the full names and the values the command instances.
+ *
+ * @param string $namespace A namespace name
+ *
+ * @return array An array of Command instances
+ *
+ * @api
+ */
+ public function all($namespace = null)
+ {
+ if (null === $namespace) {
+ return $this->commands;
+ }
+
+ $commands = array();
+ foreach ($this->commands as $name => $command) {
+ if ($namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) {
+ $commands[$name] = $command;
+ }
+ }
+
+ return $commands;
+ }
+
+ /**
+ * Returns an array of possible abbreviations given a set of names.
+ *
+ * @param array $names An array of names
+ *
+ * @return array An array of abbreviations
+ */
+ static public function getAbbreviations($names)
+ {
+ $abbrevs = array();
+ foreach ($names as $name) {
+ for ($len = strlen($name) - 1; $len > 0; --$len) {
+ $abbrev = substr($name, 0, $len);
+ if (!isset($abbrevs[$abbrev])) {
+ $abbrevs[$abbrev] = array($name);
+ } else {
+ $abbrevs[$abbrev][] = $name;
+ }
+ }
+ }
+
+ // Non-abbreviations always get entered, even if they aren't unique
+ foreach ($names as $name) {
+ $abbrevs[$name] = array($name);
+ }
+
+ return $abbrevs;
+ }
+
+ /**
+ * Returns a text representation of the Application.
+ *
+ * @param string $namespace An optional namespace name
+ * @param boolean $raw Whether to return raw command list
+ *
+ * @return string A string representing the Application
+ */
+ public function asText($namespace = null, $raw = false)
+ {
+ $commands = $namespace ? $this->all($this->findNamespace($namespace)) : $this->commands;
+
+ $width = 0;
+ foreach ($commands as $command) {
+ $width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width;
+ }
+ $width += 2;
+
+ if ($raw) {
+ $messages = array();
+ foreach ($this->sortCommands($commands) as $space => $commands) {
+ foreach ($commands as $name => $command) {
+ $messages[] = sprintf("%-${width}s %s", $name, $command->getDescription());
+ }
+ }
+
+ return implode(PHP_EOL, $messages);
+ }
+
+ $messages = array($this->getHelp(), '');
+ if ($namespace) {
+ $messages[] = sprintf("Available commands for the \"%s\" namespace: ", $namespace);
+ } else {
+ $messages[] = 'Available commands: ';
+ }
+
+ // add commands by namespace
+ foreach ($this->sortCommands($commands) as $space => $commands) {
+ if (!$namespace && '_global' !== $space) {
+ $messages[] = ''.$space.' ';
+ }
+
+ foreach ($commands as $name => $command) {
+ $messages[] = sprintf(" %-${width}s %s", $name, $command->getDescription());
+ }
+ }
+
+ return implode(PHP_EOL, $messages);
+ }
+
+ /**
+ * Returns an XML representation of the Application.
+ *
+ * @param string $namespace An optional namespace name
+ * @param Boolean $asDom Whether to return a DOM or an XML string
+ *
+ * @return string|DOMDocument An XML string representing the Application
+ */
+ public function asXml($namespace = null, $asDom = false)
+ {
+ $commands = $namespace ? $this->all($this->findNamespace($namespace)) : $this->commands;
+
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->formatOutput = true;
+ $dom->appendChild($xml = $dom->createElement('symfony'));
+
+ $xml->appendChild($commandsXML = $dom->createElement('commands'));
+
+ if ($namespace) {
+ $commandsXML->setAttribute('namespace', $namespace);
+ } else {
+ $namespacesXML = $dom->createElement('namespaces');
+ $xml->appendChild($namespacesXML);
+ }
+
+ // add commands by namespace
+ foreach ($this->sortCommands($commands) as $space => $commands) {
+ if (!$namespace) {
+ $namespaceArrayXML = $dom->createElement('namespace');
+ $namespacesXML->appendChild($namespaceArrayXML);
+ $namespaceArrayXML->setAttribute('id', $space);
+ }
+
+ foreach ($commands as $name => $command) {
+ if ($name !== $command->getName()) {
+ continue;
+ }
+
+ if (!$namespace) {
+ $commandXML = $dom->createElement('command');
+ $namespaceArrayXML->appendChild($commandXML);
+ $commandXML->appendChild($dom->createTextNode($name));
+ }
+
+ $node = $command->asXml(true)->getElementsByTagName('command')->item(0);
+ $node = $dom->importNode($node, true);
+
+ $commandsXML->appendChild($node);
+ }
+ }
+
+ return $asDom ? $dom : $dom->saveXml();
+ }
+
+ /**
+ * Renders a catched exception.
+ *
+ * @param Exception $e An exception instance
+ * @param OutputInterface $output An OutputInterface instance
+ */
+ public function renderException($e, $output)
+ {
+ $strlen = function ($string) {
+ if (!function_exists('mb_strlen')) {
+ return strlen($string);
+ }
+
+ if (false === $encoding = mb_detect_encoding($string)) {
+ return strlen($string);
+ }
+
+ return mb_strlen($string, $encoding);
+ };
+
+ do {
+ $title = sprintf(' [%s] ', get_class($e));
+ $len = $strlen($title);
+ $lines = array();
+ foreach (explode("\n", $e->getMessage()) as $line) {
+ $lines[] = sprintf(' %s ', $line);
+ $len = max($strlen($line) + 4, $len);
+ }
+
+ $messages = array(str_repeat(' ', $len), $title.str_repeat(' ', $len - $strlen($title)));
+
+ foreach ($lines as $line) {
+ $messages[] = $line.str_repeat(' ', $len - $strlen($line));
+ }
+
+ $messages[] = str_repeat(' ', $len);
+
+ $output->writeln("");
+ $output->writeln("");
+ foreach ($messages as $message) {
+ $output->writeln(''.$message.' ');
+ }
+ $output->writeln("");
+ $output->writeln("");
+
+ if (OutputInterface::VERBOSITY_VERBOSE === $output->getVerbosity()) {
+ $output->writeln('Exception trace: ');
+
+ // exception related properties
+ $trace = $e->getTrace();
+ array_unshift($trace, array(
+ 'function' => '',
+ 'file' => $e->getFile() != null ? $e->getFile() : 'n/a',
+ 'line' => $e->getLine() != null ? $e->getLine() : 'n/a',
+ 'args' => array(),
+ ));
+
+ for ($i = 0, $count = count($trace); $i < $count; $i++) {
+ $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
+ $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
+ $function = $trace[$i]['function'];
+ $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a';
+ $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a';
+
+ $output->writeln(sprintf(' %s%s%s() at %s:%s ', $class, $type, $function, $file, $line));
+ }
+
+ $output->writeln("");
+ $output->writeln("");
+ }
+ } while ($e = $e->getPrevious());
+
+ if (null !== $this->runningCommand) {
+ $output->writeln(sprintf('%s ', sprintf($this->runningCommand->getSynopsis(), $this->getName())));
+ $output->writeln("");
+ $output->writeln("");
+ }
+ }
+
+ /**
+ * Gets the name of the command based on input.
+ *
+ * @param InputInterface $input The input interface
+ *
+ * @return string The command name
+ */
+ protected function getCommandName(InputInterface $input)
+ {
+ return $input->getFirstArgument('command');
+ }
+
+ /**
+ * Gets the default input definition.
+ *
+ * @return InputDefinition An InputDefinition instance
+ */
+ protected function getDefaultInputDefinition()
+ {
+ return new InputDefinition(array(
+ new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),
+
+ new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message.'),
+ new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message.'),
+ new InputOption('--verbose', '-v', InputOption::VALUE_NONE, 'Increase verbosity of messages.'),
+ new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version.'),
+ new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output.'),
+ new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output.'),
+ new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question.'),
+ ));
+ }
+
+ /**
+ * Gets the default commands that should always be available.
+ *
+ * @return array An array of default Command instances
+ */
+ protected function getDefaultCommands()
+ {
+ return array(new HelpCommand(), new ListCommand());
+ }
+
+ /**
+ * Gets the default helper set with the helpers that should always be available.
+ *
+ * @return HelperSet A HelperSet instance
+ */
+ protected function getDefaultHelperSet()
+ {
+ return new HelperSet(array(
+ new FormatterHelper(),
+ new DialogHelper(),
+ ));
+ }
+
+ /**
+ * Sorts commands in alphabetical order.
+ *
+ * @param array $commands An associative array of commands to sort
+ *
+ * @return array A sorted array of commands
+ */
+ private function sortCommands($commands)
+ {
+ $namespacedCommands = array();
+ foreach ($commands as $name => $command) {
+ $key = $this->extractNamespace($name, 1);
+ if (!$key) {
+ $key = '_global';
+ }
+
+ $namespacedCommands[$key][$name] = $command;
+ }
+ ksort($namespacedCommands);
+
+ foreach ($namespacedCommands as &$commands) {
+ ksort($commands);
+ }
+
+ return $namespacedCommands;
+ }
+
+ /**
+ * Returns abbreviated suggestions in string format.
+ *
+ * @param array $abbrevs Abbreviated suggestions to convert
+ *
+ * @return string A formatted string of abbreviated suggestions
+ */
+ private function getAbbreviationSuggestions($abbrevs)
+ {
+ return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '');
+ }
+
+ /**
+ * Returns the namespace part of the command name.
+ *
+ * @param string $name The full name of the command
+ * @param string $limit The maximum number of parts of the namespace
+ *
+ * @return string The namespace of the command
+ */
+ private function extractNamespace($name, $limit = null)
+ {
+ $parts = explode(':', $name);
+ array_pop($parts);
+
+ return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit));
+ }
+
+ /**
+ * Finds alternative commands of $name
+ *
+ * @param string $name The full name of the command
+ * @param array $abbrevs The abbreviations
+ *
+ * @return array A sorted array of similar commands
+ */
+ private function findAlternativeCommands($name, $abbrevs)
+ {
+ $callback = function($item) {
+ return $item->getName();
+ };
+
+ return $this->findAlternatives($name, $this->commands, $abbrevs, $callback);
+ }
+
+ /**
+ * Finds alternative namespace of $name
+ *
+ * @param string $name The full name of the namespace
+ * @param array $abbrevs The abbreviations
+ *
+ * @return array A sorted array of similar namespace
+ */
+ private function findAlternativeNamespace($name, $abbrevs)
+ {
+ return $this->findAlternatives($name, $this->getNamespaces(), $abbrevs);
+ }
+
+ /**
+ * Finds alternative of $name among $collection,
+ * if nothing is found in $collection, try in $abbrevs
+ *
+ * @param string $name The string
+ * @param array|Traversable $collection The collecion
+ * @param array $abbrevs The abbreviations
+ * @param Closure|string|array $callback The callable to transform collection item before comparison
+ *
+ * @return array A sorted array of similar string
+ */
+ private function findAlternatives($name, $collection, $abbrevs, $callback = null) {
+ $alternatives = array();
+
+ foreach ($collection as $item) {
+ if (null !== $callback) {
+ $item = call_user_func($callback, $item);
+ }
+
+ $lev = levenshtein($name, $item);
+ if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
+ $alternatives[$item] = $lev;
+ }
+ }
+
+ if (!$alternatives) {
+ foreach ($abbrevs as $key => $values) {
+ $lev = levenshtein($name, $key);
+ if ($lev <= strlen($name) / 3 || false !== strpos($key, $name)) {
+ foreach ($values as $value) {
+ $alternatives[$value] = $lev;
+ }
+ }
+ }
+ }
+
+ asort($alternatives);
+
+ return array_keys($alternatives);
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Command/Command.php b/app/laravel/vendor/Symfony/Component/Console/Command/Command.php
new file mode 100644
index 000000000..033a95c76
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Command/Command.php
@@ -0,0 +1,612 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Command;
+
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Helper\HelperSet;
+
+/**
+ * Base class for all commands.
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class Command
+{
+ private $application;
+ private $name;
+ private $aliases;
+ private $definition;
+ private $help;
+ private $description;
+ private $ignoreValidationErrors;
+ private $applicationDefinitionMerged;
+ private $code;
+ private $synopsis;
+ private $helperSet;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of the command
+ *
+ * @throws \LogicException When the command name is empty
+ *
+ * @api
+ */
+ public function __construct($name = null)
+ {
+ $this->definition = new InputDefinition();
+ $this->ignoreValidationErrors = false;
+ $this->applicationDefinitionMerged = false;
+ $this->aliases = array();
+
+ if (null !== $name) {
+ $this->setName($name);
+ }
+
+ $this->configure();
+
+ if (!$this->name) {
+ throw new \LogicException('The command name cannot be empty.');
+ }
+ }
+
+ /**
+ * Ignores validation errors.
+ *
+ * This is mainly useful for the help command.
+ */
+ public function ignoreValidationErrors()
+ {
+ $this->ignoreValidationErrors = true;
+ }
+
+ /**
+ * Sets the application instance for this command.
+ *
+ * @param Application $application An Application instance
+ *
+ * @api
+ */
+ public function setApplication(Application $application = null)
+ {
+ $this->application = $application;
+ if ($application) {
+ $this->setHelperSet($application->getHelperSet());
+ } else {
+ $this->helperSet = null;
+ }
+ }
+
+ /**
+ * Sets the helper set.
+ *
+ * @param HelperSet $helperSet A HelperSet instance
+ */
+ public function setHelperSet(HelperSet $helperSet)
+ {
+ $this->helperSet = $helperSet;
+ }
+
+ /**
+ * Gets the helper set.
+ *
+ * @return HelperSet A HelperSet instance
+ */
+ public function getHelperSet()
+ {
+ return $this->helperSet;
+ }
+
+ /**
+ * Gets the application instance for this command.
+ *
+ * @return Application An Application instance
+ *
+ * @api
+ */
+ public function getApplication()
+ {
+ return $this->application;
+ }
+
+ /**
+ * Checks whether the command is enabled or not in the current environment
+ *
+ * Override this to check for x or y and return false if the command can not
+ * run properly under the current conditions.
+ *
+ * @return Boolean
+ */
+ public function isEnabled()
+ {
+ return true;
+ }
+
+ /**
+ * Configures the current command.
+ */
+ protected function configure()
+ {
+ }
+
+ /**
+ * Executes the current command.
+ *
+ * This method is not abstract because you can use this class
+ * as a concrete class. In this case, instead of defining the
+ * execute() method, you set the code to execute by passing
+ * a Closure to the setCode() method.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ *
+ * @return integer 0 if everything went fine, or an error code
+ *
+ * @throws \LogicException When this abstract method is not implemented
+ * @see setCode()
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ throw new \LogicException('You must override the execute() method in the concrete command class.');
+ }
+
+ /**
+ * Interacts with the user.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ */
+ protected function interact(InputInterface $input, OutputInterface $output)
+ {
+ }
+
+ /**
+ * Initializes the command just after the input has been validated.
+ *
+ * This is mainly useful when a lot of commands extends one main command
+ * where some things need to be initialized based on the input arguments and options.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ */
+ protected function initialize(InputInterface $input, OutputInterface $output)
+ {
+ }
+
+ /**
+ * Runs the command.
+ *
+ * The code to execute is either defined directly with the
+ * setCode() method or by overriding the execute() method
+ * in a sub-class.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ *
+ * @see setCode()
+ * @see execute()
+ *
+ * @api
+ */
+ public function run(InputInterface $input, OutputInterface $output)
+ {
+ // force the creation of the synopsis before the merge with the app definition
+ $this->getSynopsis();
+
+ // add the application arguments and options
+ $this->mergeApplicationDefinition();
+
+ // bind the input against the command specific arguments/options
+ try {
+ $input->bind($this->definition);
+ } catch (\Exception $e) {
+ if (!$this->ignoreValidationErrors) {
+ throw $e;
+ }
+ }
+
+ $this->initialize($input, $output);
+
+ if ($input->isInteractive()) {
+ $this->interact($input, $output);
+ }
+
+ $input->validate();
+
+ if ($this->code) {
+ return call_user_func($this->code, $input, $output);
+ }
+
+ return $this->execute($input, $output);
+ }
+
+ /**
+ * Sets the code to execute when running this command.
+ *
+ * If this method is used, it overrides the code defined
+ * in the execute() method.
+ *
+ * @param \Closure $code A \Closure
+ *
+ * @return Command The current instance
+ *
+ * @see execute()
+ *
+ * @api
+ */
+ public function setCode(\Closure $code)
+ {
+ $this->code = $code;
+
+ return $this;
+ }
+
+ /**
+ * Merges the application definition with the command definition.
+ */
+ private function mergeApplicationDefinition()
+ {
+ if (null === $this->application || true === $this->applicationDefinitionMerged) {
+ return;
+ }
+
+ $currentArguments = $this->definition->getArguments();
+ $this->definition->setArguments($this->application->getDefinition()->getArguments());
+ $this->definition->addArguments($currentArguments);
+
+ $this->definition->addOptions($this->application->getDefinition()->getOptions());
+
+ $this->applicationDefinitionMerged = true;
+ }
+
+ /**
+ * Sets an array of argument and option instances.
+ *
+ * @param array|InputDefinition $definition An array of argument and option instances or a definition instance
+ *
+ * @return Command The current instance
+ *
+ * @api
+ */
+ public function setDefinition($definition)
+ {
+ if ($definition instanceof InputDefinition) {
+ $this->definition = $definition;
+ } else {
+ $this->definition->setDefinition($definition);
+ }
+
+ $this->applicationDefinitionMerged = false;
+
+ return $this;
+ }
+
+ /**
+ * Gets the InputDefinition attached to this Command.
+ *
+ * @return InputDefinition An InputDefinition instance
+ *
+ * @api
+ */
+ public function getDefinition()
+ {
+ return $this->definition;
+ }
+
+ /**
+ * Gets the InputDefinition to be used to create XML and Text representations of this Command.
+ *
+ * Can be overridden to provide the original command representation when it would otherwise
+ * be changed by merging with the application InputDefinition.
+ *
+ * @return InputDefinition An InputDefinition instance
+ */
+ protected function getNativeDefinition()
+ {
+ return $this->getDefinition();
+ }
+
+ /**
+ * Adds an argument.
+ *
+ * @param string $name The argument name
+ * @param integer $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
+ * @param string $description A description text
+ * @param mixed $default The default value (for InputArgument::OPTIONAL mode only)
+ *
+ * @return Command The current instance
+ *
+ * @api
+ */
+ public function addArgument($name, $mode = null, $description = '', $default = null)
+ {
+ $this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
+
+ return $this;
+ }
+
+ /**
+ * Adds an option.
+ *
+ * @param string $name The option name
+ * @param string $shortcut The shortcut (can be null)
+ * @param integer $mode The option mode: One of the InputOption::VALUE_* constants
+ * @param string $description A description text
+ * @param mixed $default The default value (must be null for InputOption::VALUE_REQUIRED or InputOption::VALUE_NONE)
+ *
+ * @return Command The current instance
+ *
+ * @api
+ */
+ public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
+ {
+ $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
+
+ return $this;
+ }
+
+ /**
+ * Sets the name of the command.
+ *
+ * This method can set both the namespace and the name if
+ * you separate them by a colon (:)
+ *
+ * $command->setName('foo:bar');
+ *
+ * @param string $name The command name
+ *
+ * @return Command The current instance
+ *
+ * @throws \InvalidArgumentException When command name given is empty
+ *
+ * @api
+ */
+ public function setName($name)
+ {
+ $this->validateName($name);
+
+ $this->name = $name;
+
+ return $this;
+ }
+
+ /**
+ * Returns the command name.
+ *
+ * @return string The command name
+ *
+ * @api
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Sets the description for the command.
+ *
+ * @param string $description The description for the command
+ *
+ * @return Command The current instance
+ *
+ * @api
+ */
+ public function setDescription($description)
+ {
+ $this->description = $description;
+
+ return $this;
+ }
+
+ /**
+ * Returns the description for the command.
+ *
+ * @return string The description for the command
+ *
+ * @api
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ /**
+ * Sets the help for the command.
+ *
+ * @param string $help The help for the command
+ *
+ * @return Command The current instance
+ *
+ * @api
+ */
+ public function setHelp($help)
+ {
+ $this->help = $help;
+
+ return $this;
+ }
+
+ /**
+ * Returns the help for the command.
+ *
+ * @return string The help for the command
+ *
+ * @api
+ */
+ public function getHelp()
+ {
+ return $this->help;
+ }
+
+ /**
+ * Returns the processed help for the command replacing the %command.name% and
+ * %command.full_name% patterns with the real values dynamically.
+ *
+ * @return string The processed help for the command
+ */
+ public function getProcessedHelp()
+ {
+ $name = $this->name;
+
+ $placeholders = array(
+ '%command.name%',
+ '%command.full_name%'
+ );
+ $replacements = array(
+ $name,
+ $_SERVER['PHP_SELF'].' '.$name
+ );
+
+ return str_replace($placeholders, $replacements, $this->getHelp());
+ }
+
+ /**
+ * Sets the aliases for the command.
+ *
+ * @param array $aliases An array of aliases for the command
+ *
+ * @return Command The current instance
+ *
+ * @api
+ */
+ public function setAliases($aliases)
+ {
+ foreach ($aliases as $alias) {
+ $this->validateName($alias);
+ }
+
+ $this->aliases = $aliases;
+
+ return $this;
+ }
+
+ /**
+ * Returns the aliases for the command.
+ *
+ * @return array An array of aliases for the command
+ *
+ * @api
+ */
+ public function getAliases()
+ {
+ return $this->aliases;
+ }
+
+ /**
+ * Returns the synopsis for the command.
+ *
+ * @return string The synopsis
+ */
+ public function getSynopsis()
+ {
+ if (null === $this->synopsis) {
+ $this->synopsis = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis()));
+ }
+
+ return $this->synopsis;
+ }
+
+ /**
+ * Gets a helper instance by name.
+ *
+ * @param string $name The helper name
+ *
+ * @return mixed The helper value
+ *
+ * @throws \InvalidArgumentException if the helper is not defined
+ *
+ * @api
+ */
+ public function getHelper($name)
+ {
+ return $this->helperSet->get($name);
+ }
+
+ /**
+ * Returns a text representation of the command.
+ *
+ * @return string A string representing the command
+ */
+ public function asText()
+ {
+ $messages = array(
+ 'Usage: ',
+ ' '.$this->getSynopsis(),
+ '',
+ );
+
+ if ($this->getAliases()) {
+ $messages[] = 'Aliases: '.implode(', ', $this->getAliases()).' ';
+ }
+
+ $messages[] = $this->getNativeDefinition()->asText();
+
+ if ($help = $this->getProcessedHelp()) {
+ $messages[] = 'Help: ';
+ $messages[] = ' '.str_replace("\n", "\n ", $help)."\n";
+ }
+
+ return implode("\n", $messages);
+ }
+
+ /**
+ * Returns an XML representation of the command.
+ *
+ * @param Boolean $asDom Whether to return a DOM or an XML string
+ *
+ * @return string|DOMDocument An XML string representing the command
+ */
+ public function asXml($asDom = false)
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->formatOutput = true;
+ $dom->appendChild($commandXML = $dom->createElement('command'));
+ $commandXML->setAttribute('id', $this->name);
+ $commandXML->setAttribute('name', $this->name);
+
+ $commandXML->appendChild($usageXML = $dom->createElement('usage'));
+ $usageXML->appendChild($dom->createTextNode(sprintf($this->getSynopsis(), '')));
+
+ $commandXML->appendChild($descriptionXML = $dom->createElement('description'));
+ $descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $this->getDescription())));
+
+ $commandXML->appendChild($helpXML = $dom->createElement('help'));
+ $helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $this->getProcessedHelp())));
+
+ $commandXML->appendChild($aliasesXML = $dom->createElement('aliases'));
+ foreach ($this->getAliases() as $alias) {
+ $aliasesXML->appendChild($aliasXML = $dom->createElement('alias'));
+ $aliasXML->appendChild($dom->createTextNode($alias));
+ }
+
+ $definition = $this->getNativeDefinition()->asXml(true);
+ $commandXML->appendChild($dom->importNode($definition->getElementsByTagName('arguments')->item(0), true));
+ $commandXML->appendChild($dom->importNode($definition->getElementsByTagName('options')->item(0), true));
+
+ return $asDom ? $dom : $dom->saveXml();
+ }
+
+ private function validateName($name)
+ {
+ if (!preg_match('/^[^\:]+(\:[^\:]+)*$/', $name)) {
+ throw new \InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));
+ }
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Command/HelpCommand.php b/app/laravel/vendor/Symfony/Component/Console/Command/HelpCommand.php
new file mode 100644
index 000000000..93c81045c
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Command/HelpCommand.php
@@ -0,0 +1,84 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Command\Command;
+
+/**
+ * HelpCommand displays the help for a given command.
+ *
+ * @author Fabien Potencier
+ */
+class HelpCommand extends Command
+{
+ private $command;
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function configure()
+ {
+ $this->ignoreValidationErrors();
+
+ $this
+ ->setName('help')
+ ->setDefinition(array(
+ new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'),
+ new InputOption('xml', null, InputOption::VALUE_NONE, 'To output help as XML'),
+ ))
+ ->setDescription('Displays help for a command')
+ ->setHelp(<<%command.name% command displays help for a given command:
+
+ php %command.full_name% list
+
+You can also output the help as XML by using the --xml option:
+
+ php %command.full_name% --xml list
+EOF
+ )
+ ;
+ }
+
+ /**
+ * Sets the command
+ *
+ * @param Command $command The command to set
+ */
+ public function setCommand(Command $command)
+ {
+ $this->command = $command;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ if (null === $this->command) {
+ $this->command = $this->getApplication()->get($input->getArgument('command_name'));
+ }
+
+ if ($input->getOption('xml')) {
+ $output->writeln($this->command->asXml(), OutputInterface::OUTPUT_RAW);
+ } else {
+ $output->writeln($this->command->asText());
+ }
+
+ $this->command = null;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Command/ListCommand.php b/app/laravel/vendor/Symfony/Component/Console/Command/ListCommand.php
new file mode 100644
index 000000000..032de16c1
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Command/ListCommand.php
@@ -0,0 +1,87 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Command;
+
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputDefinition;
+
+/**
+ * ListCommand displays the list of all available commands for the application.
+ *
+ * @author Fabien Potencier
+ */
+class ListCommand extends Command
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function configure()
+ {
+ $this
+ ->setName('list')
+ ->setDefinition($this->createDefinition())
+ ->setDescription('Lists commands')
+ ->setHelp(<<%command.name% command lists all commands:
+
+ php %command.full_name%
+
+You can also display the commands for a specific namespace:
+
+ php %command.full_name% test
+
+You can also output the information as XML by using the --xml option:
+
+ php %command.full_name% --xml
+
+It's also possible to get raw list of commands (useful for embedding command runner):
+
+ php %command.full_name% --raw
+EOF
+ )
+ ;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getNativeDefinition()
+ {
+ return $this->createDefinition();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ if ($input->getOption('xml')) {
+ $output->writeln($this->getApplication()->asXml($input->getArgument('namespace')), OutputInterface::OUTPUT_RAW);
+ } else {
+ $output->writeln($this->getApplication()->asText($input->getArgument('namespace'), $input->getOption('raw')));
+ }
+ }
+
+ private function createDefinition()
+ {
+ return new InputDefinition(array(
+ new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'),
+ new InputOption('xml', null, InputOption::VALUE_NONE, 'To output help as XML'),
+ new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'),
+ ));
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Formatter/OutputFormatter.php b/app/laravel/vendor/Symfony/Component/Console/Formatter/OutputFormatter.php
new file mode 100644
index 000000000..8d60c74f8
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Formatter/OutputFormatter.php
@@ -0,0 +1,192 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter class for console output.
+ *
+ * @author Konstantin Kudryashov
+ *
+ * @api
+ */
+class OutputFormatter implements OutputFormatterInterface
+{
+ /**
+ * The pattern to phrase the format.
+ */
+ const FORMAT_PATTERN = '#<([a-z][a-z0-9_=;-]+)>(.*?)\\1?>#is';
+
+ private $decorated;
+ private $styles = array();
+
+ /**
+ * Initializes console output formatter.
+ *
+ * @param Boolean $decorated Whether this formatter should actually decorate strings
+ * @param array $styles Array of "name => FormatterStyle" instances
+ *
+ * @api
+ */
+ public function __construct($decorated = null, array $styles = array())
+ {
+ $this->decorated = (Boolean) $decorated;
+
+ $this->setStyle('error', new OutputFormatterStyle('white', 'red'));
+ $this->setStyle('info', new OutputFormatterStyle('green'));
+ $this->setStyle('comment', new OutputFormatterStyle('yellow'));
+ $this->setStyle('question', new OutputFormatterStyle('black', 'cyan'));
+
+ foreach ($styles as $name => $style) {
+ $this->setStyle($name, $style);
+ }
+ }
+
+ /**
+ * Sets the decorated flag.
+ *
+ * @param Boolean $decorated Whether to decorate the messages or not
+ *
+ * @api
+ */
+ public function setDecorated($decorated)
+ {
+ $this->decorated = (Boolean) $decorated;
+ }
+
+ /**
+ * Gets the decorated flag.
+ *
+ * @return Boolean true if the output will decorate messages, false otherwise
+ *
+ * @api
+ */
+ public function isDecorated()
+ {
+ return $this->decorated;
+ }
+
+ /**
+ * Sets a new style.
+ *
+ * @param string $name The style name
+ * @param OutputFormatterStyleInterface $style The style instance
+ *
+ * @api
+ */
+ public function setStyle($name, OutputFormatterStyleInterface $style)
+ {
+ $this->styles[strtolower($name)] = $style;
+ }
+
+ /**
+ * Checks if output formatter has style with specified name.
+ *
+ * @param string $name
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function hasStyle($name)
+ {
+ return isset($this->styles[strtolower($name)]);
+ }
+
+ /**
+ * Gets style options from style with specified name.
+ *
+ * @param string $name
+ *
+ * @return OutputFormatterStyleInterface
+ *
+ * @throws \InvalidArgumentException When style isn't defined
+ *
+ * @api
+ */
+ public function getStyle($name)
+ {
+ if (!$this->hasStyle($name)) {
+ throw new \InvalidArgumentException('Undefined style: '.$name);
+ }
+
+ return $this->styles[strtolower($name)];
+ }
+
+ /**
+ * Formats a message according to the given styles.
+ *
+ * @param string $message The message to style
+ *
+ * @return string The styled message
+ *
+ * @api
+ */
+ public function format($message)
+ {
+ return preg_replace_callback(self::FORMAT_PATTERN, array($this, 'replaceStyle'), $message);
+ }
+
+ /**
+ * Replaces style of the output.
+ *
+ * @param array $match
+ *
+ * @return string The replaced style
+ */
+ private function replaceStyle($match)
+ {
+ if (!$this->isDecorated()) {
+ return $match[2];
+ }
+
+ if (isset($this->styles[strtolower($match[1])])) {
+ $style = $this->styles[strtolower($match[1])];
+ } else {
+ $style = $this->createStyleFromString($match[1]);
+
+ if (false === $style) {
+ return $match[0];
+ }
+ }
+
+ return $style->apply($this->format($match[2]));
+ }
+
+ /**
+ * Tries to create new style instance from string.
+ *
+ * @param string $string
+ *
+ * @return Symfony\Component\Console\Format\FormatterStyle|Boolean false if string is not format string
+ */
+ private function createStyleFromString($string)
+ {
+ if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) {
+ return false;
+ }
+
+ $style = new OutputFormatterStyle();
+ foreach ($matches as $match) {
+ array_shift($match);
+
+ if ('fg' == $match[0]) {
+ $style->setForeground($match[1]);
+ } elseif ('bg' == $match[0]) {
+ $style->setBackground($match[1]);
+ } else {
+ $style->setOption($match[1]);
+ }
+ }
+
+ return $style;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Formatter/OutputFormatterInterface.php b/app/laravel/vendor/Symfony/Component/Console/Formatter/OutputFormatterInterface.php
new file mode 100644
index 000000000..f14657ce6
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Formatter/OutputFormatterInterface.php
@@ -0,0 +1,83 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter interface for console output.
+ *
+ * @author Konstantin Kudryashov
+ *
+ * @api
+ */
+interface OutputFormatterInterface
+{
+ /**
+ * Sets the decorated flag.
+ *
+ * @param Boolean $decorated Whether to decorate the messages or not
+ *
+ * @api
+ */
+ function setDecorated($decorated);
+
+ /**
+ * Gets the decorated flag.
+ *
+ * @return Boolean true if the output will decorate messages, false otherwise
+ *
+ * @api
+ */
+ function isDecorated();
+
+ /**
+ * Sets a new style.
+ *
+ * @param string $name The style name
+ * @param OutputFormatterStyleInterface $style The style instance
+ *
+ * @api
+ */
+ function setStyle($name, OutputFormatterStyleInterface $style);
+
+ /**
+ * Checks if output formatter has style with specified name.
+ *
+ * @param string $name
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ function hasStyle($name);
+
+ /**
+ * Gets style options from style with specified name.
+ *
+ * @param string $name
+ *
+ * @return OutputFormatterStyleInterface
+ *
+ * @api
+ */
+ function getStyle($name);
+
+ /**
+ * Formats a message according to the given styles.
+ *
+ * @param string $message The message to style
+ *
+ * @return string The styled message
+ *
+ * @api
+ */
+ function format($message);
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Formatter/OutputFormatterStyle.php b/app/laravel/vendor/Symfony/Component/Console/Formatter/OutputFormatterStyle.php
new file mode 100644
index 000000000..dc88f2a8c
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Formatter/OutputFormatterStyle.php
@@ -0,0 +1,218 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter style class for defining styles.
+ *
+ * @author Konstantin Kudryashov
+ *
+ * @api
+ */
+class OutputFormatterStyle implements OutputFormatterStyleInterface
+{
+ static private $availableForegroundColors = array(
+ 'black' => 30,
+ 'red' => 31,
+ 'green' => 32,
+ 'yellow' => 33,
+ 'blue' => 34,
+ 'magenta' => 35,
+ 'cyan' => 36,
+ 'white' => 37
+ );
+ static private $availableBackgroundColors = array(
+ 'black' => 40,
+ 'red' => 41,
+ 'green' => 42,
+ 'yellow' => 43,
+ 'blue' => 44,
+ 'magenta' => 45,
+ 'cyan' => 46,
+ 'white' => 47
+ );
+ static private $availableOptions = array(
+ 'bold' => 1,
+ 'underscore' => 4,
+ 'blink' => 5,
+ 'reverse' => 7,
+ 'conceal' => 8
+ );
+
+ private $foreground;
+ private $background;
+ private $options = array();
+
+ /**
+ * Initializes output formatter style.
+ *
+ * @param string $foreground style foreground color name
+ * @param string $background style background color name
+ * @param array $options style options
+ *
+ * @api
+ */
+ public function __construct($foreground = null, $background = null, array $options = array())
+ {
+ if (null !== $foreground) {
+ $this->setForeground($foreground);
+ }
+ if (null !== $background) {
+ $this->setBackground($background);
+ }
+ if (count($options)) {
+ $this->setOptions($options);
+ }
+ }
+
+ /**
+ * Sets style foreground color.
+ *
+ * @param string $color color name
+ *
+ * @throws \InvalidArgumentException When the color name isn't defined
+ *
+ * @api
+ */
+ public function setForeground($color = null)
+ {
+ if (null === $color) {
+ $this->foreground = null;
+
+ return;
+ }
+
+ if (!isset(static::$availableForegroundColors[$color])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'Invalid foreground color specified: "%s". Expected one of (%s)',
+ $color,
+ implode(', ', array_keys(static::$availableForegroundColors))
+ ));
+ }
+
+ $this->foreground = static::$availableForegroundColors[$color];
+ }
+
+ /**
+ * Sets style background color.
+ *
+ * @param string $color color name
+ *
+ * @throws \InvalidArgumentException When the color name isn't defined
+ *
+ * @api
+ */
+ public function setBackground($color = null)
+ {
+ if (null === $color) {
+ $this->background = null;
+
+ return;
+ }
+
+ if (!isset(static::$availableBackgroundColors[$color])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'Invalid background color specified: "%s". Expected one of (%s)',
+ $color,
+ implode(', ', array_keys(static::$availableBackgroundColors))
+ ));
+ }
+
+ $this->background = static::$availableBackgroundColors[$color];
+ }
+
+ /**
+ * Sets some specific style option.
+ *
+ * @param string $option option name
+ *
+ * @throws \InvalidArgumentException When the option name isn't defined
+ *
+ * @api
+ */
+ public function setOption($option)
+ {
+ if (!isset(static::$availableOptions[$option])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'Invalid option specified: "%s". Expected one of (%s)',
+ $option,
+ implode(', ', array_keys(static::$availableOptions))
+ ));
+ }
+
+ if (false === array_search(static::$availableOptions[$option], $this->options)) {
+ $this->options[] = static::$availableOptions[$option];
+ }
+ }
+
+ /**
+ * Unsets some specific style option.
+ *
+ * @param string $option option name
+ *
+ * @throws \InvalidArgumentException When the option name isn't defined
+ *
+ */
+ public function unsetOption($option)
+ {
+ if (!isset(static::$availableOptions[$option])) {
+ throw new \InvalidArgumentException(sprintf(
+ 'Invalid option specified: "%s". Expected one of (%s)',
+ $option,
+ implode(', ', array_keys(static::$availableOptions))
+ ));
+ }
+
+ $pos = array_search(static::$availableOptions[$option], $this->options);
+ if (false !== $pos) {
+ unset($this->options[$pos]);
+ }
+ }
+
+ /**
+ * Sets multiple style options at once.
+ *
+ * @param array $options
+ */
+ public function setOptions(array $options)
+ {
+ $this->options = array();
+
+ foreach ($options as $option) {
+ $this->setOption($option);
+ }
+ }
+
+ /**
+ * Applies the style to a given text.
+ *
+ * @param string $text The text to style
+ *
+ * @return string
+ */
+ public function apply($text)
+ {
+ $codes = array();
+
+ if (null !== $this->foreground) {
+ $codes[] = $this->foreground;
+ }
+ if (null !== $this->background) {
+ $codes[] = $this->background;
+ }
+ if (count($this->options)) {
+ $codes = array_merge($codes, $this->options);
+ }
+
+ return sprintf("\033[%sm%s\033[0m", implode(';', $codes), $text);
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php b/app/laravel/vendor/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php
new file mode 100644
index 000000000..212cb86ff
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Formatter/OutputFormatterStyleInterface.php
@@ -0,0 +1,72 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter style interface for defining styles.
+ *
+ * @author Konstantin Kudryashov
+ *
+ * @api
+ */
+interface OutputFormatterStyleInterface
+{
+ /**
+ * Sets style foreground color.
+ *
+ * @param string $color color name
+ *
+ * @api
+ */
+ function setForeground($color = null);
+
+ /**
+ * Sets style background color.
+ *
+ * @param string $color color name
+ *
+ * @api
+ */
+ function setBackground($color = null);
+
+ /**
+ * Sets some specific style option.
+ *
+ * @param string $option option name
+ *
+ * @api
+ */
+ function setOption($option);
+
+ /**
+ * Unsets some specific style option.
+ *
+ * @param string $option option name
+ */
+ function unsetOption($option);
+
+ /**
+ * Sets multiple style options at once.
+ *
+ * @param array $options
+ */
+ function setOptions(array $options);
+
+ /**
+ * Applies the style to a given text.
+ *
+ * @param string $text The text to style
+ *
+ * @return string
+ */
+ function apply($text);
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Helper/DialogHelper.php b/app/laravel/vendor/Symfony/Component/Console/Helper/DialogHelper.php
new file mode 100644
index 000000000..e15fdd18b
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Helper/DialogHelper.php
@@ -0,0 +1,139 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * The Dialog class provides helpers to interact with the user.
+ *
+ * @author Fabien Potencier
+ */
+class DialogHelper extends Helper
+{
+ private $inputStream;
+
+ /**
+ * Asks a question to the user.
+ *
+ * @param OutputInterface $output An Output instance
+ * @param string|array $question The question to ask
+ * @param string $default The default answer if none is given by the user
+ *
+ * @return string The user answer
+ *
+ * @throws \RuntimeException If there is no data to read in the input stream
+ */
+ public function ask(OutputInterface $output, $question, $default = null)
+ {
+ $output->write($question);
+
+ $ret = fgets($this->inputStream ?: STDIN, 4096);
+ if (false === $ret) {
+ throw new \RuntimeException('Aborted');
+ }
+ $ret = trim($ret);
+
+ return strlen($ret) > 0 ? $ret : $default;
+ }
+
+ /**
+ * Asks a confirmation to the user.
+ *
+ * The question will be asked until the user answers by nothing, yes, or no.
+ *
+ * @param OutputInterface $output An Output instance
+ * @param string|array $question The question to ask
+ * @param Boolean $default The default answer if the user enters nothing
+ *
+ * @return Boolean true if the user has confirmed, false otherwise
+ */
+ public function askConfirmation(OutputInterface $output, $question, $default = true)
+ {
+ $answer = 'z';
+ while ($answer && !in_array(strtolower($answer[0]), array('y', 'n'))) {
+ $answer = $this->ask($output, $question);
+ }
+
+ if (false === $default) {
+ return $answer && 'y' == strtolower($answer[0]);
+ }
+
+ return !$answer || 'y' == strtolower($answer[0]);
+ }
+
+ /**
+ * Asks for a value and validates the response.
+ *
+ * The validator receives the data to validate. It must return the
+ * validated data when the data is valid and throw an exception
+ * otherwise.
+ *
+ * @param OutputInterface $output An Output instance
+ * @param string|array $question The question to ask
+ * @param callback $validator A PHP callback
+ * @param integer $attempts Max number of times to ask before giving up (false by default, which means infinite)
+ * @param string $default The default answer if none is given by the user
+ *
+ * @return mixed
+ *
+ * @throws \Exception When any of the validators return an error
+ */
+ public function askAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $default = null)
+ {
+ $error = null;
+ while (false === $attempts || $attempts--) {
+ if (null !== $error) {
+ $output->writeln($this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error'));
+ }
+
+ $value = $this->ask($output, $question, $default);
+
+ try {
+ return call_user_func($validator, $value);
+ } catch (\Exception $error) {
+ }
+ }
+
+ throw $error;
+ }
+
+ /**
+ * Sets the input stream to read from when interacting with the user.
+ *
+ * This is mainly useful for testing purpose.
+ *
+ * @param resource $stream The input stream
+ */
+ public function setInputStream($stream)
+ {
+ $this->inputStream = $stream;
+ }
+
+ /**
+ * Returns the helper's input stream
+ *
+ * @return string
+ */
+ public function getInputStream()
+ {
+ return $this->inputStream;
+ }
+
+ /**
+ * Returns the helper's canonical name.
+ */
+ public function getName()
+ {
+ return 'dialog';
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Helper/FormatterHelper.php b/app/laravel/vendor/Symfony/Component/Console/Helper/FormatterHelper.php
new file mode 100644
index 000000000..d3f613bb7
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Helper/FormatterHelper.php
@@ -0,0 +1,97 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+/**
+ * The Formatter class provides helpers to format messages.
+ *
+ * @author Fabien Potencier
+ */
+class FormatterHelper extends Helper
+{
+ /**
+ * Formats a message within a section.
+ *
+ * @param string $section The section name
+ * @param string $message The message
+ * @param string $style The style to apply to the section
+ */
+ public function formatSection($section, $message, $style = 'info')
+ {
+ return sprintf('<%s>[%s]%s> %s', $style, $section, $style, $message);
+ }
+
+ /**
+ * Formats a message as a block of text.
+ *
+ * @param string|array $messages The message to write in the block
+ * @param string $style The style to apply to the whole block
+ * @param Boolean $large Whether to return a large block
+ *
+ * @return string The formatter message
+ */
+ public function formatBlock($messages, $style, $large = false)
+ {
+ $messages = (array) $messages;
+
+ $len = 0;
+ $lines = array();
+ foreach ($messages as $message) {
+ $lines[] = sprintf($large ? ' %s ' : ' %s ', $message);
+ $len = max($this->strlen($message) + ($large ? 4 : 2), $len);
+ }
+
+ $messages = $large ? array(str_repeat(' ', $len)) : array();
+ foreach ($lines as $line) {
+ $messages[] = $line.str_repeat(' ', $len - $this->strlen($line));
+ }
+ if ($large) {
+ $messages[] = str_repeat(' ', $len);
+ }
+
+ foreach ($messages as &$message) {
+ $message = sprintf('<%s>%s%s>', $style, $message, $style);
+ }
+
+ return implode("\n", $messages);
+ }
+
+ /**
+ * Returns the length of a string, using mb_strlen if it is available.
+ *
+ * @param string $string The string to check its length
+ *
+ * @return integer The length of the string
+ */
+ private function strlen($string)
+ {
+ if (!function_exists('mb_strlen')) {
+ return strlen($string);
+ }
+
+ if (false === $encoding = mb_detect_encoding($string)) {
+ return strlen($string);
+ }
+
+ return mb_strlen($string, $encoding);
+ }
+
+ /**
+ * Returns the helper's canonical name.
+ *
+ * @return string The canonical name of the helper
+ */
+ public function getName()
+ {
+ return 'formatter';
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Helper/Helper.php b/app/laravel/vendor/Symfony/Component/Console/Helper/Helper.php
new file mode 100644
index 000000000..28488cafd
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Helper/Helper.php
@@ -0,0 +1,42 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+/**
+ * Helper is the base class for all helper classes.
+ *
+ * @author Fabien Potencier
+ */
+abstract class Helper implements HelperInterface
+{
+ protected $helperSet = null;
+
+ /**
+ * Sets the helper set associated with this helper.
+ *
+ * @param HelperSet $helperSet A HelperSet instance
+ */
+ public function setHelperSet(HelperSet $helperSet = null)
+ {
+ $this->helperSet = $helperSet;
+ }
+
+ /**
+ * Gets the helper set associated with this helper.
+ *
+ * @return HelperSet A HelperSet instance
+ */
+ public function getHelperSet()
+ {
+ return $this->helperSet;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Helper/HelperInterface.php b/app/laravel/vendor/Symfony/Component/Console/Helper/HelperInterface.php
new file mode 100644
index 000000000..25ee51393
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Helper/HelperInterface.php
@@ -0,0 +1,49 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+/**
+ * HelperInterface is the interface all helpers must implement.
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+interface HelperInterface
+{
+ /**
+ * Sets the helper set associated with this helper.
+ *
+ * @param HelperSet $helperSet A HelperSet instance
+ *
+ * @api
+ */
+ function setHelperSet(HelperSet $helperSet = null);
+
+ /**
+ * Gets the helper set associated with this helper.
+ *
+ * @return HelperSet A HelperSet instance
+ *
+ * @api
+ */
+ function getHelperSet();
+
+ /**
+ * Returns the canonical name of this helper.
+ *
+ * @return string The canonical name
+ *
+ * @api
+ */
+ function getName();
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Helper/HelperSet.php b/app/laravel/vendor/Symfony/Component/Console/Helper/HelperSet.php
new file mode 100644
index 000000000..0092c4c30
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Helper/HelperSet.php
@@ -0,0 +1,104 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Command\Command;
+
+/**
+ * HelperSet represents a set of helpers to be used with a command.
+ *
+ * @author Fabien Potencier
+ */
+class HelperSet
+{
+ private $helpers;
+ private $command;
+
+ /**
+ * Constructor.
+ *
+ * @param Helper[] $helpers An array of helper.
+ */
+ public function __construct(array $helpers = array())
+ {
+ $this->helpers = array();
+ foreach ($helpers as $alias => $helper) {
+ $this->set($helper, is_int($alias) ? null : $alias);
+ }
+ }
+
+ /**
+ * Sets a helper.
+ *
+ * @param HelperInterface $helper The helper instance
+ * @param string $alias An alias
+ */
+ public function set(HelperInterface $helper, $alias = null)
+ {
+ $this->helpers[$helper->getName()] = $helper;
+ if (null !== $alias) {
+ $this->helpers[$alias] = $helper;
+ }
+
+ $helper->setHelperSet($this);
+ }
+
+ /**
+ * Returns true if the helper if defined.
+ *
+ * @param string $name The helper name
+ *
+ * @return Boolean true if the helper is defined, false otherwise
+ */
+ public function has($name)
+ {
+ return isset($this->helpers[$name]);
+ }
+
+ /**
+ * Gets a helper value.
+ *
+ * @param string $name The helper name
+ *
+ * @return HelperInterface The helper instance
+ *
+ * @throws \InvalidArgumentException if the helper is not defined
+ */
+ public function get($name)
+ {
+ if (!$this->has($name)) {
+ throw new \InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
+ }
+
+ return $this->helpers[$name];
+ }
+
+ /**
+ * Sets the command associated with this helper set.
+ *
+ * @param Command $command A Command instance
+ */
+ public function setCommand(Command $command = null)
+ {
+ $this->command = $command;
+ }
+
+ /**
+ * Gets the command associated with this helper set.
+ *
+ * @return Command A Command instance
+ */
+ public function getCommand()
+ {
+ return $this->command;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Input/ArgvInput.php b/app/laravel/vendor/Symfony/Component/Console/Input/ArgvInput.php
new file mode 100644
index 000000000..f0cfb1419
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Input/ArgvInput.php
@@ -0,0 +1,311 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * ArgvInput represents an input coming from the CLI arguments.
+ *
+ * Usage:
+ *
+ * $input = new ArgvInput();
+ *
+ * By default, the `$_SERVER['argv']` array is used for the input values.
+ *
+ * This can be overridden by explicitly passing the input values in the constructor:
+ *
+ * $input = new ArgvInput($_SERVER['argv']);
+ *
+ * If you pass it yourself, don't forget that the first element of the array
+ * is the name of the running application.
+ *
+ * When passing an argument to the constructor, be sure that it respects
+ * the same rules as the argv one. It's almost always better to use the
+ * `StringInput` when you want to provide your own input.
+ *
+ * @author Fabien Potencier
+ *
+ * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
+ * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
+ *
+ * @api
+ */
+class ArgvInput extends Input
+{
+ private $tokens;
+ private $parsed;
+
+ /**
+ * Constructor.
+ *
+ * @param array $argv An array of parameters from the CLI (in the argv format)
+ * @param InputDefinition $definition A InputDefinition instance
+ *
+ * @api
+ */
+ public function __construct(array $argv = null, InputDefinition $definition = null)
+ {
+ if (null === $argv) {
+ $argv = $_SERVER['argv'];
+ }
+
+ // strip the application name
+ array_shift($argv);
+
+ $this->tokens = $argv;
+
+ parent::__construct($definition);
+ }
+
+ protected function setTokens(array $tokens)
+ {
+ $this->tokens = $tokens;
+ }
+
+ /**
+ * Processes command line arguments.
+ */
+ protected function parse()
+ {
+ $parseOptions = true;
+ $this->parsed = $this->tokens;
+ while (null !== $token = array_shift($this->parsed)) {
+ if ($parseOptions && '--' == $token) {
+ $parseOptions = false;
+ } elseif ($parseOptions && 0 === strpos($token, '--')) {
+ $this->parseLongOption($token);
+ } elseif ($parseOptions && '-' === $token[0]) {
+ $this->parseShortOption($token);
+ } else {
+ $this->parseArgument($token);
+ }
+ }
+ }
+
+ /**
+ * Parses a short option.
+ *
+ * @param string $token The current token.
+ */
+ private function parseShortOption($token)
+ {
+ $name = substr($token, 1);
+
+ if (strlen($name) > 1) {
+ if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
+ // an option with a value (with no space)
+ $this->addShortOption($name[0], substr($name, 1));
+ } else {
+ $this->parseShortOptionSet($name);
+ }
+ } else {
+ $this->addShortOption($name, null);
+ }
+ }
+
+ /**
+ * Parses a short option set.
+ *
+ * @param string $name The current token
+ *
+ * @throws \RuntimeException When option given doesn't exist
+ */
+ private function parseShortOptionSet($name)
+ {
+ $len = strlen($name);
+ for ($i = 0; $i < $len; $i++) {
+ if (!$this->definition->hasShortcut($name[$i])) {
+ throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i]));
+ }
+
+ $option = $this->definition->getOptionForShortcut($name[$i]);
+ if ($option->acceptValue()) {
+ $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));
+
+ break;
+ } else {
+ $this->addLongOption($option->getName(), true);
+ }
+ }
+ }
+
+ /**
+ * Parses a long option.
+ *
+ * @param string $token The current token
+ */
+ private function parseLongOption($token)
+ {
+ $name = substr($token, 2);
+
+ if (false !== $pos = strpos($name, '=')) {
+ $this->addLongOption(substr($name, 0, $pos), substr($name, $pos + 1));
+ } else {
+ $this->addLongOption($name, null);
+ }
+ }
+
+ /**
+ * Parses an argument.
+ *
+ * @param string $token The current token
+ *
+ * @throws \RuntimeException When too many arguments are given
+ */
+ private function parseArgument($token)
+ {
+ $c = count($this->arguments);
+
+ // if input is expecting another argument, add it
+ if ($this->definition->hasArgument($c)) {
+ $arg = $this->definition->getArgument($c);
+ $this->arguments[$arg->getName()] = $arg->isArray()? array($token) : $token;
+
+ // if last argument isArray(), append token to last argument
+ } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
+ $arg = $this->definition->getArgument($c - 1);
+ $this->arguments[$arg->getName()][] = $token;
+
+ // unexpected argument
+ } else {
+ throw new \RuntimeException('Too many arguments.');
+ }
+ }
+
+ /**
+ * Adds a short option value.
+ *
+ * @param string $shortcut The short option key
+ * @param mixed $value The value for the option
+ *
+ * @throws \RuntimeException When option given doesn't exist
+ */
+ private function addShortOption($shortcut, $value)
+ {
+ if (!$this->definition->hasShortcut($shortcut)) {
+ throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
+ }
+
+ $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
+ }
+
+ /**
+ * Adds a long option value.
+ *
+ * @param string $name The long option key
+ * @param mixed $value The value for the option
+ *
+ * @throws \RuntimeException When option given doesn't exist
+ */
+ private function addLongOption($name, $value)
+ {
+ if (!$this->definition->hasOption($name)) {
+ throw new \RuntimeException(sprintf('The "--%s" option does not exist.', $name));
+ }
+
+ $option = $this->definition->getOption($name);
+
+ if (null === $value && $option->acceptValue()) {
+ // if option accepts an optional or mandatory argument
+ // let's see if there is one provided
+ $next = array_shift($this->parsed);
+ if ('-' !== $next[0]) {
+ $value = $next;
+ } else {
+ array_unshift($this->parsed, $next);
+ }
+ }
+
+ if (null === $value) {
+ if ($option->isValueRequired()) {
+ throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name));
+ }
+
+ $value = $option->isValueOptional() ? $option->getDefault() : true;
+ }
+
+ if ($option->isArray()) {
+ $this->options[$name][] = $value;
+ } else {
+ $this->options[$name] = $value;
+ }
+ }
+
+ /**
+ * Returns the first argument from the raw parameters (not parsed).
+ *
+ * @return string The value of the first argument or null otherwise
+ */
+ public function getFirstArgument()
+ {
+ foreach ($this->tokens as $token) {
+ if ($token && '-' === $token[0]) {
+ continue;
+ }
+
+ return $token;
+ }
+ }
+
+ /**
+ * Returns true if the raw parameters (not parsed) contain a value.
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+ *
+ * @return Boolean true if the value is contained in the raw parameters
+ */
+ public function hasParameterOption($values)
+ {
+ $values = (array) $values;
+
+ foreach ($this->tokens as $v) {
+ if (in_array($v, $values)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the value of a raw option (not parsed).
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+ * @param mixed $default The default value to return if no result is found
+ *
+ * @return mixed The option value
+ */
+ public function getParameterOption($values, $default = false)
+ {
+ $values = (array) $values;
+
+ $tokens = $this->tokens;
+ while ($token = array_shift($tokens)) {
+ foreach ($values as $value) {
+ if (0 === strpos($token, $value)) {
+ if (false !== $pos = strpos($token, '=')) {
+ return substr($token, $pos + 1);
+ }
+
+ return array_shift($tokens);
+ }
+ }
+ }
+
+ return $default;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Input/ArrayInput.php b/app/laravel/vendor/Symfony/Component/Console/Input/ArrayInput.php
new file mode 100644
index 000000000..c9d8ee98a
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Input/ArrayInput.php
@@ -0,0 +1,190 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * ArrayInput represents an input provided as an array.
+ *
+ * Usage:
+ *
+ * $input = new ArrayInput(array('name' => 'foo', '--bar' => 'foobar'));
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class ArrayInput extends Input
+{
+ private $parameters;
+
+ /**
+ * Constructor.
+ *
+ * @param array $parameters An array of parameters
+ * @param InputDefinition $definition A InputDefinition instance
+ *
+ * @api
+ */
+ public function __construct(array $parameters, InputDefinition $definition = null)
+ {
+ $this->parameters = $parameters;
+
+ parent::__construct($definition);
+ }
+
+ /**
+ * Returns the first argument from the raw parameters (not parsed).
+ *
+ * @return string The value of the first argument or null otherwise
+ */
+ public function getFirstArgument()
+ {
+ foreach ($this->parameters as $key => $value) {
+ if ($key && '-' === $key[0]) {
+ continue;
+ }
+
+ return $value;
+ }
+ }
+
+ /**
+ * Returns true if the raw parameters (not parsed) contain a value.
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The values to look for in the raw parameters (can be an array)
+ *
+ * @return Boolean true if the value is contained in the raw parameters
+ */
+ public function hasParameterOption($values)
+ {
+ $values = (array) $values;
+
+ foreach ($this->parameters as $k => $v) {
+ if (!is_int($k)) {
+ $v = $k;
+ }
+
+ if (in_array($v, $values)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the value of a raw option (not parsed).
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+ * @param mixed $default The default value to return if no result is found
+ *
+ * @return mixed The option value
+ */
+ public function getParameterOption($values, $default = false)
+ {
+ $values = (array) $values;
+
+ foreach ($this->parameters as $k => $v) {
+ if (is_int($k) && in_array($v, $values)) {
+ return true;
+ } elseif (in_array($k, $values)) {
+ return $v;
+ }
+ }
+
+ return $default;
+ }
+
+ /**
+ * Processes command line arguments.
+ */
+ protected function parse()
+ {
+ foreach ($this->parameters as $key => $value) {
+ if (0 === strpos($key, '--')) {
+ $this->addLongOption(substr($key, 2), $value);
+ } elseif ('-' === $key[0]) {
+ $this->addShortOption(substr($key, 1), $value);
+ } else {
+ $this->addArgument($key, $value);
+ }
+ }
+ }
+
+ /**
+ * Adds a short option value.
+ *
+ * @param string $shortcut The short option key
+ * @param mixed $value The value for the option
+ *
+ * @throws \InvalidArgumentException When option given doesn't exist
+ */
+ private function addShortOption($shortcut, $value)
+ {
+ if (!$this->definition->hasShortcut($shortcut)) {
+ throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
+ }
+
+ $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
+ }
+
+ /**
+ * Adds a long option value.
+ *
+ * @param string $name The long option key
+ * @param mixed $value The value for the option
+ *
+ * @throws \InvalidArgumentException When option given doesn't exist
+ * @throws \InvalidArgumentException When a required value is missing
+ */
+ private function addLongOption($name, $value)
+ {
+ if (!$this->definition->hasOption($name)) {
+ throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
+ }
+
+ $option = $this->definition->getOption($name);
+
+ if (null === $value) {
+ if ($option->isValueRequired()) {
+ throw new \InvalidArgumentException(sprintf('The "--%s" option requires a value.', $name));
+ }
+
+ $value = $option->isValueOptional() ? $option->getDefault() : true;
+ }
+
+ $this->options[$name] = $value;
+ }
+
+ /**
+ * Adds an argument value.
+ *
+ * @param string $name The argument name
+ * @param mixed $value The value for the argument
+ *
+ * @throws \InvalidArgumentException When argument given doesn't exist
+ */
+ private function addArgument($name, $value)
+ {
+ if (!$this->definition->hasArgument($name)) {
+ throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+ }
+
+ $this->arguments[$name] = $value;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Input/Input.php b/app/laravel/vendor/Symfony/Component/Console/Input/Input.php
new file mode 100644
index 000000000..70291be7e
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Input/Input.php
@@ -0,0 +1,211 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * Input is the base class for all concrete Input classes.
+ *
+ * Three concrete classes are provided by default:
+ *
+ * * `ArgvInput`: The input comes from the CLI arguments (argv)
+ * * `StringInput`: The input is provided as a string
+ * * `ArrayInput`: The input is provided as an array
+ *
+ * @author Fabien Potencier
+ */
+abstract class Input implements InputInterface
+{
+ protected $definition;
+ protected $options;
+ protected $arguments;
+ protected $interactive = true;
+
+ /**
+ * Constructor.
+ *
+ * @param InputDefinition $definition A InputDefinition instance
+ */
+ public function __construct(InputDefinition $definition = null)
+ {
+ if (null === $definition) {
+ $this->definition = new InputDefinition();
+ } else {
+ $this->bind($definition);
+ $this->validate();
+ }
+ }
+
+ /**
+ * Binds the current Input instance with the given arguments and options.
+ *
+ * @param InputDefinition $definition A InputDefinition instance
+ */
+ public function bind(InputDefinition $definition)
+ {
+ $this->arguments = array();
+ $this->options = array();
+ $this->definition = $definition;
+
+ $this->parse();
+ }
+
+ /**
+ * Processes command line arguments.
+ */
+ abstract protected function parse();
+
+ /**
+ * Validates the input.
+ *
+ * @throws \RuntimeException When not enough arguments are given
+ */
+ public function validate()
+ {
+ if (count($this->arguments) < $this->definition->getArgumentRequiredCount()) {
+ throw new \RuntimeException('Not enough arguments.');
+ }
+ }
+
+ /**
+ * Checks if the input is interactive.
+ *
+ * @return Boolean Returns true if the input is interactive
+ */
+ public function isInteractive()
+ {
+ return $this->interactive;
+ }
+
+ /**
+ * Sets the input interactivity.
+ *
+ * @param Boolean $interactive If the input should be interactive
+ */
+ public function setInteractive($interactive)
+ {
+ $this->interactive = (Boolean) $interactive;
+ }
+
+ /**
+ * Returns the argument values.
+ *
+ * @return array An array of argument values
+ */
+ public function getArguments()
+ {
+ return array_merge($this->definition->getArgumentDefaults(), $this->arguments);
+ }
+
+ /**
+ * Returns the argument value for a given argument name.
+ *
+ * @param string $name The argument name
+ *
+ * @return mixed The argument value
+ *
+ * @throws \InvalidArgumentException When argument given doesn't exist
+ */
+ public function getArgument($name)
+ {
+ if (!$this->definition->hasArgument($name)) {
+ throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+ }
+
+ return isset($this->arguments[$name]) ? $this->arguments[$name] : $this->definition->getArgument($name)->getDefault();
+ }
+
+ /**
+ * Sets an argument value by name.
+ *
+ * @param string $name The argument name
+ * @param string $value The argument value
+ *
+ * @throws \InvalidArgumentException When argument given doesn't exist
+ */
+ public function setArgument($name, $value)
+ {
+ if (!$this->definition->hasArgument($name)) {
+ throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+ }
+
+ $this->arguments[$name] = $value;
+ }
+
+ /**
+ * Returns true if an InputArgument object exists by name or position.
+ *
+ * @param string|integer $name The InputArgument name or position
+ *
+ * @return Boolean true if the InputArgument object exists, false otherwise
+ */
+ public function hasArgument($name)
+ {
+ return $this->definition->hasArgument($name);
+ }
+
+ /**
+ * Returns the options values.
+ *
+ * @return array An array of option values
+ */
+ public function getOptions()
+ {
+ return array_merge($this->definition->getOptionDefaults(), $this->options);
+ }
+
+ /**
+ * Returns the option value for a given option name.
+ *
+ * @param string $name The option name
+ *
+ * @return mixed The option value
+ *
+ * @throws \InvalidArgumentException When option given doesn't exist
+ */
+ public function getOption($name)
+ {
+ if (!$this->definition->hasOption($name)) {
+ throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
+ }
+
+ return isset($this->options[$name]) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
+ }
+
+ /**
+ * Sets an option value by name.
+ *
+ * @param string $name The option name
+ * @param string $value The option value
+ *
+ * @throws \InvalidArgumentException When option given doesn't exist
+ */
+ public function setOption($name, $value)
+ {
+ if (!$this->definition->hasOption($name)) {
+ throw new \InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
+ }
+
+ $this->options[$name] = $value;
+ }
+
+ /**
+ * Returns true if an InputOption object exists by name.
+ *
+ * @param string $name The InputOption name
+ *
+ * @return Boolean true if the InputOption object exists, false otherwise
+ */
+ public function hasOption($name)
+ {
+ return $this->definition->hasOption($name);
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Input/InputArgument.php b/app/laravel/vendor/Symfony/Component/Console/Input/InputArgument.php
new file mode 100644
index 000000000..e7cc93531
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Input/InputArgument.php
@@ -0,0 +1,132 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * Represents a command line argument.
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class InputArgument
+{
+ const REQUIRED = 1;
+ const OPTIONAL = 2;
+ const IS_ARRAY = 4;
+
+ private $name;
+ private $mode;
+ private $default;
+ private $description;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The argument name
+ * @param integer $mode The argument mode: self::REQUIRED or self::OPTIONAL
+ * @param string $description A description text
+ * @param mixed $default The default value (for self::OPTIONAL mode only)
+ *
+ * @throws \InvalidArgumentException When argument mode is not valid
+ *
+ * @api
+ */
+ public function __construct($name, $mode = null, $description = '', $default = null)
+ {
+ if (null === $mode) {
+ $mode = self::OPTIONAL;
+ } elseif (!is_int($mode) || $mode > 7 || $mode < 1) {
+ throw new \InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode));
+ }
+
+ $this->name = $name;
+ $this->mode = $mode;
+ $this->description = $description;
+
+ $this->setDefault($default);
+ }
+
+ /**
+ * Returns the argument name.
+ *
+ * @return string The argument name
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Returns true if the argument is required.
+ *
+ * @return Boolean true if parameter mode is self::REQUIRED, false otherwise
+ */
+ public function isRequired()
+ {
+ return self::REQUIRED === (self::REQUIRED & $this->mode);
+ }
+
+ /**
+ * Returns true if the argument can take multiple values.
+ *
+ * @return Boolean true if mode is self::IS_ARRAY, false otherwise
+ */
+ public function isArray()
+ {
+ return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);
+ }
+
+ /**
+ * Sets the default value.
+ *
+ * @param mixed $default The default value
+ *
+ * @throws \LogicException When incorrect default value is given
+ */
+ public function setDefault($default = null)
+ {
+ if (self::REQUIRED === $this->mode && null !== $default) {
+ throw new \LogicException('Cannot set a default value except for Parameter::OPTIONAL mode.');
+ }
+
+ if ($this->isArray()) {
+ if (null === $default) {
+ $default = array();
+ } elseif (!is_array($default)) {
+ throw new \LogicException('A default value for an array argument must be an array.');
+ }
+ }
+
+ $this->default = $default;
+ }
+
+ /**
+ * Returns the default value.
+ *
+ * @return mixed The default value
+ */
+ public function getDefault()
+ {
+ return $this->default;
+ }
+
+ /**
+ * Returns the description text.
+ *
+ * @return string The description text
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Input/InputDefinition.php b/app/laravel/vendor/Symfony/Component/Console/Input/InputDefinition.php
new file mode 100644
index 000000000..ffae4fe97
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Input/InputDefinition.php
@@ -0,0 +1,533 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * A InputDefinition represents a set of valid command line arguments and options.
+ *
+ * Usage:
+ *
+ * $definition = new InputDefinition(array(
+ * new InputArgument('name', InputArgument::REQUIRED),
+ * new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
+ * ));
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class InputDefinition
+{
+ private $arguments;
+ private $requiredCount;
+ private $hasAnArrayArgument = false;
+ private $hasOptional;
+ private $options;
+ private $shortcuts;
+
+ /**
+ * Constructor.
+ *
+ * @param array $definition An array of InputArgument and InputOption instance
+ *
+ * @api
+ */
+ public function __construct(array $definition = array())
+ {
+ $this->setDefinition($definition);
+ }
+
+ /**
+ * Sets the definition of the input.
+ *
+ * @param array $definition The definition array
+ *
+ * @api
+ */
+ public function setDefinition(array $definition)
+ {
+ $arguments = array();
+ $options = array();
+ foreach ($definition as $item) {
+ if ($item instanceof InputOption) {
+ $options[] = $item;
+ } else {
+ $arguments[] = $item;
+ }
+ }
+
+ $this->setArguments($arguments);
+ $this->setOptions($options);
+ }
+
+ /**
+ * Sets the InputArgument objects.
+ *
+ * @param array $arguments An array of InputArgument objects
+ *
+ * @api
+ */
+ public function setArguments($arguments = array())
+ {
+ $this->arguments = array();
+ $this->requiredCount = 0;
+ $this->hasOptional = false;
+ $this->hasAnArrayArgument = false;
+ $this->addArguments($arguments);
+ }
+
+ /**
+ * Adds an array of InputArgument objects.
+ *
+ * @param InputArgument[] $arguments An array of InputArgument objects
+ *
+ * @api
+ */
+ public function addArguments($arguments = array())
+ {
+ if (null !== $arguments) {
+ foreach ($arguments as $argument) {
+ $this->addArgument($argument);
+ }
+ }
+ }
+
+ /**
+ * Adds an InputArgument object.
+ *
+ * @param InputArgument $argument An InputArgument object
+ *
+ * @throws \LogicException When incorrect argument is given
+ *
+ * @api
+ */
+ public function addArgument(InputArgument $argument)
+ {
+ if (isset($this->arguments[$argument->getName()])) {
+ throw new \LogicException(sprintf('An argument with name "%s" already exist.', $argument->getName()));
+ }
+
+ if ($this->hasAnArrayArgument) {
+ throw new \LogicException('Cannot add an argument after an array argument.');
+ }
+
+ if ($argument->isRequired() && $this->hasOptional) {
+ throw new \LogicException('Cannot add a required argument after an optional one.');
+ }
+
+ if ($argument->isArray()) {
+ $this->hasAnArrayArgument = true;
+ }
+
+ if ($argument->isRequired()) {
+ ++$this->requiredCount;
+ } else {
+ $this->hasOptional = true;
+ }
+
+ $this->arguments[$argument->getName()] = $argument;
+ }
+
+ /**
+ * Returns an InputArgument by name or by position.
+ *
+ * @param string|integer $name The InputArgument name or position
+ *
+ * @return InputArgument An InputArgument object
+ *
+ * @throws \InvalidArgumentException When argument given doesn't exist
+ *
+ * @api
+ */
+ public function getArgument($name)
+ {
+ $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
+
+ if (!$this->hasArgument($name)) {
+ throw new \InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+ }
+
+ return $arguments[$name];
+ }
+
+ /**
+ * Returns true if an InputArgument object exists by name or position.
+ *
+ * @param string|integer $name The InputArgument name or position
+ *
+ * @return Boolean true if the InputArgument object exists, false otherwise
+ *
+ * @api
+ */
+ public function hasArgument($name)
+ {
+ $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
+
+ return isset($arguments[$name]);
+ }
+
+ /**
+ * Gets the array of InputArgument objects.
+ *
+ * @return array An array of InputArgument objects
+ *
+ * @api
+ */
+ public function getArguments()
+ {
+ return $this->arguments;
+ }
+
+ /**
+ * Returns the number of InputArguments.
+ *
+ * @return integer The number of InputArguments
+ */
+ public function getArgumentCount()
+ {
+ return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments);
+ }
+
+ /**
+ * Returns the number of required InputArguments.
+ *
+ * @return integer The number of required InputArguments
+ */
+ public function getArgumentRequiredCount()
+ {
+ return $this->requiredCount;
+ }
+
+ /**
+ * Gets the default values.
+ *
+ * @return array An array of default values
+ */
+ public function getArgumentDefaults()
+ {
+ $values = array();
+ foreach ($this->arguments as $argument) {
+ $values[$argument->getName()] = $argument->getDefault();
+ }
+
+ return $values;
+ }
+
+ /**
+ * Sets the InputOption objects.
+ *
+ * @param array $options An array of InputOption objects
+ *
+ * @api
+ */
+ public function setOptions($options = array())
+ {
+ $this->options = array();
+ $this->shortcuts = array();
+ $this->addOptions($options);
+ }
+
+ /**
+ * Adds an array of InputOption objects.
+ *
+ * @param InputOption[] $options An array of InputOption objects
+ *
+ * @api
+ */
+ public function addOptions($options = array())
+ {
+ foreach ($options as $option) {
+ $this->addOption($option);
+ }
+ }
+
+ /**
+ * Adds an InputOption object.
+ *
+ * @param InputOption $option An InputOption object
+ *
+ * @throws \LogicException When option given already exist
+ *
+ * @api
+ */
+ public function addOption(InputOption $option)
+ {
+ if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
+ throw new \LogicException(sprintf('An option named "%s" already exist.', $option->getName()));
+ } elseif (isset($this->shortcuts[$option->getShortcut()]) && !$option->equals($this->options[$this->shortcuts[$option->getShortcut()]])) {
+ throw new \LogicException(sprintf('An option with shortcut "%s" already exist.', $option->getShortcut()));
+ }
+
+ $this->options[$option->getName()] = $option;
+ if ($option->getShortcut()) {
+ $this->shortcuts[$option->getShortcut()] = $option->getName();
+ }
+ }
+
+ /**
+ * Returns an InputOption by name.
+ *
+ * @param string $name The InputOption name
+ *
+ * @return InputOption A InputOption object
+ *
+ * @api
+ */
+ public function getOption($name)
+ {
+ if (!$this->hasOption($name)) {
+ throw new \InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
+ }
+
+ return $this->options[$name];
+ }
+
+ /**
+ * Returns true if an InputOption object exists by name.
+ *
+ * @param string $name The InputOption name
+ *
+ * @return Boolean true if the InputOption object exists, false otherwise
+ *
+ * @api
+ */
+ public function hasOption($name)
+ {
+ return isset($this->options[$name]);
+ }
+
+ /**
+ * Gets the array of InputOption objects.
+ *
+ * @return array An array of InputOption objects
+ *
+ * @api
+ */
+ public function getOptions()
+ {
+ return $this->options;
+ }
+
+ /**
+ * Returns true if an InputOption object exists by shortcut.
+ *
+ * @param string $name The InputOption shortcut
+ *
+ * @return Boolean true if the InputOption object exists, false otherwise
+ */
+ public function hasShortcut($name)
+ {
+ return isset($this->shortcuts[$name]);
+ }
+
+ /**
+ * Gets an InputOption by shortcut.
+ *
+ * @param string $shortcut the Shortcut name
+ *
+ * @return InputOption An InputOption object
+ */
+ public function getOptionForShortcut($shortcut)
+ {
+ return $this->getOption($this->shortcutToName($shortcut));
+ }
+
+ /**
+ * Gets an array of default values.
+ *
+ * @return array An array of all default values
+ */
+ public function getOptionDefaults()
+ {
+ $values = array();
+ foreach ($this->options as $option) {
+ $values[$option->getName()] = $option->getDefault();
+ }
+
+ return $values;
+ }
+
+ /**
+ * Returns the InputOption name given a shortcut.
+ *
+ * @param string $shortcut The shortcut
+ *
+ * @return string The InputOption name
+ *
+ * @throws \InvalidArgumentException When option given does not exist
+ */
+ private function shortcutToName($shortcut)
+ {
+ if (!isset($this->shortcuts[$shortcut])) {
+ throw new \InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
+ }
+
+ return $this->shortcuts[$shortcut];
+ }
+
+ /**
+ * Gets the synopsis.
+ *
+ * @return string The synopsis
+ */
+ public function getSynopsis()
+ {
+ $elements = array();
+ foreach ($this->getOptions() as $option) {
+ $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';
+ $elements[] = sprintf('['.($option->isValueRequired() ? '%s--%s="..."' : ($option->isValueOptional() ? '%s--%s[="..."]' : '%s--%s')).']', $shortcut, $option->getName());
+ }
+
+ foreach ($this->getArguments() as $argument) {
+ $elements[] = sprintf($argument->isRequired() ? '%s' : '[%s]', $argument->getName().($argument->isArray() ? '1' : ''));
+
+ if ($argument->isArray()) {
+ $elements[] = sprintf('... [%sN]', $argument->getName());
+ }
+ }
+
+ return implode(' ', $elements);
+ }
+
+ /**
+ * Returns a textual representation of the InputDefinition.
+ *
+ * @return string A string representing the InputDefinition
+ */
+ public function asText()
+ {
+ // find the largest option or argument name
+ $max = 0;
+ foreach ($this->getOptions() as $option) {
+ $nameLength = strlen($option->getName()) + 2;
+ if ($option->getShortcut()) {
+ $nameLength += strlen($option->getShortcut()) + 3;
+ }
+
+ $max = max($max, $nameLength);
+ }
+ foreach ($this->getArguments() as $argument) {
+ $max = max($max, strlen($argument->getName()));
+ }
+ ++$max;
+
+ $text = array();
+
+ if ($this->getArguments()) {
+ $text[] = 'Arguments: ';
+ foreach ($this->getArguments() as $argument) {
+ if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) {
+ $default = sprintf(' (default: %s) ', $this->formatDefaultValue($argument->getDefault()));
+ } else {
+ $default = '';
+ }
+
+ $description = str_replace("\n", "\n".str_pad('', $max + 2, ' '), $argument->getDescription());
+
+ $text[] = sprintf(" %-${max}s %s%s", $argument->getName(), $description, $default);
+ }
+
+ $text[] = '';
+ }
+
+ if ($this->getOptions()) {
+ $text[] = 'Options: ';
+
+ foreach ($this->getOptions() as $option) {
+ if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) {
+ $default = sprintf(' (default: %s) ', $this->formatDefaultValue($option->getDefault()));
+ } else {
+ $default = '';
+ }
+
+ $multiple = $option->isArray() ? ' (multiple values allowed) ' : '';
+ $description = str_replace("\n", "\n".str_pad('', $max + 2, ' '), $option->getDescription());
+
+ $optionMax = $max - strlen($option->getName()) - 2;
+ $text[] = sprintf(" %s %-${optionMax}s%s%s%s",
+ '--'.$option->getName(),
+ $option->getShortcut() ? sprintf('(-%s) ', $option->getShortcut()) : '',
+ $description,
+ $default,
+ $multiple
+ );
+ }
+
+ $text[] = '';
+ }
+
+ return implode("\n", $text);
+ }
+
+ /**
+ * Returns an XML representation of the InputDefinition.
+ *
+ * @param Boolean $asDom Whether to return a DOM or an XML string
+ *
+ * @return string|DOMDocument An XML string representing the InputDefinition
+ */
+ public function asXml($asDom = false)
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->formatOutput = true;
+ $dom->appendChild($definitionXML = $dom->createElement('definition'));
+
+ $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments'));
+ foreach ($this->getArguments() as $argument) {
+ $argumentsXML->appendChild($argumentXML = $dom->createElement('argument'));
+ $argumentXML->setAttribute('name', $argument->getName());
+ $argumentXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0);
+ $argumentXML->setAttribute('is_array', $argument->isArray() ? 1 : 0);
+ $argumentXML->appendChild($descriptionXML = $dom->createElement('description'));
+ $descriptionXML->appendChild($dom->createTextNode($argument->getDescription()));
+
+ $argumentXML->appendChild($defaultsXML = $dom->createElement('defaults'));
+ $defaults = is_array($argument->getDefault()) ? $argument->getDefault() : (is_bool($argument->getDefault()) ? array(var_export($argument->getDefault(), true)) : ($argument->getDefault() ? array($argument->getDefault()) : array()));
+ foreach ($defaults as $default) {
+ $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
+ $defaultXML->appendChild($dom->createTextNode($default));
+ }
+ }
+
+ $definitionXML->appendChild($optionsXML = $dom->createElement('options'));
+ foreach ($this->getOptions() as $option) {
+ $optionsXML->appendChild($optionXML = $dom->createElement('option'));
+ $optionXML->setAttribute('name', '--'.$option->getName());
+ $optionXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : '');
+ $optionXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0);
+ $optionXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0);
+ $optionXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0);
+ $optionXML->appendChild($descriptionXML = $dom->createElement('description'));
+ $descriptionXML->appendChild($dom->createTextNode($option->getDescription()));
+
+ if ($option->acceptValue()) {
+ $optionXML->appendChild($defaultsXML = $dom->createElement('defaults'));
+ $defaults = is_array($option->getDefault()) ? $option->getDefault() : (is_bool($option->getDefault()) ? array(var_export($option->getDefault(), true)) : ($option->getDefault() ? array($option->getDefault()) : array()));
+ foreach ($defaults as $default) {
+ $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
+ $defaultXML->appendChild($dom->createTextNode($default));
+ }
+ }
+ }
+
+ return $asDom ? $dom : $dom->saveXml();
+ }
+
+ private function formatDefaultValue($default)
+ {
+ if (is_array($default) && $default === array_values($default)) {
+ return sprintf("array('%s')", implode("', '", $default));
+ }
+
+ return str_replace("\n", '', var_export($default, true));
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Input/InputInterface.php b/app/laravel/vendor/Symfony/Component/Console/Input/InputInterface.php
new file mode 100644
index 000000000..a4a622340
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Input/InputInterface.php
@@ -0,0 +1,152 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * InputInterface is the interface implemented by all input classes.
+ *
+ * @author Fabien Potencier
+ */
+interface InputInterface
+{
+ /**
+ * Returns the first argument from the raw parameters (not parsed).
+ *
+ * @return string The value of the first argument or null otherwise
+ */
+ function getFirstArgument();
+
+ /**
+ * Returns true if the raw parameters (not parsed) contain a value.
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The values to look for in the raw parameters (can be an array)
+ *
+ * @return Boolean true if the value is contained in the raw parameters
+ */
+ function hasParameterOption($values);
+
+ /**
+ * Returns the value of a raw option (not parsed).
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+ * @param mixed $default The default value to return if no result is found
+ *
+ * @return mixed The option value
+ */
+ function getParameterOption($values, $default = false);
+
+ /**
+ * Binds the current Input instance with the given arguments and options.
+ *
+ * @param InputDefinition $definition A InputDefinition instance
+ */
+ function bind(InputDefinition $definition);
+
+ /**
+ * Validates if arguments given are correct.
+ *
+ * Throws an exception when not enough arguments are given.
+ *
+ * @throws \RuntimeException
+ */
+ function validate();
+
+ /**
+ * Returns all the given arguments merged with the default values.
+ *
+ * @return array
+ */
+ function getArguments();
+
+ /**
+ * Gets argument by name.
+ *
+ * @param string $name The name of the argument
+ *
+ * @return mixed
+ */
+ function getArgument($name);
+
+ /**
+ * Sets an argument value by name.
+ *
+ * @param string $name The argument name
+ * @param string $value The argument value
+ *
+ * @throws \InvalidArgumentException When argument given doesn't exist
+ */
+ function setArgument($name, $value);
+
+ /**
+ * Returns true if an InputArgument object exists by name or position.
+ *
+ * @param string|integer $name The InputArgument name or position
+ *
+ * @return Boolean true if the InputArgument object exists, false otherwise
+ */
+ function hasArgument($name);
+
+ /**
+ * Returns all the given options merged with the default values.
+ *
+ * @return array
+ */
+ function getOptions();
+
+ /**
+ * Gets an option by name.
+ *
+ * @param string $name The name of the option
+ *
+ * @return mixed
+ */
+ function getOption($name);
+
+ /**
+ * Sets an option value by name.
+ *
+ * @param string $name The option name
+ * @param string $value The option value
+ *
+ * @throws \InvalidArgumentException When option given doesn't exist
+ */
+ function setOption($name, $value);
+
+ /**
+ * Returns true if an InputOption object exists by name.
+ *
+ * @param string $name The InputOption name
+ *
+ * @return Boolean true if the InputOption object exists, false otherwise
+ */
+ function hasOption($name);
+
+ /**
+ * Is this input means interactive?
+ *
+ * @return Boolean
+ */
+ function isInteractive();
+
+ /**
+ * Sets the input interactivity.
+ *
+ * @param Boolean $interactive If the input should be interactive
+ */
+ function setInteractive($interactive);
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Input/InputOption.php b/app/laravel/vendor/Symfony/Component/Console/Input/InputOption.php
new file mode 100644
index 000000000..0f2604556
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Input/InputOption.php
@@ -0,0 +1,201 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * Represents a command line option.
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class InputOption
+{
+ const VALUE_NONE = 1;
+ const VALUE_REQUIRED = 2;
+ const VALUE_OPTIONAL = 4;
+ const VALUE_IS_ARRAY = 8;
+
+ private $name;
+ private $shortcut;
+ private $mode;
+ private $default;
+ private $description;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The option name
+ * @param string $shortcut The shortcut (can be null)
+ * @param integer $mode The option mode: One of the VALUE_* constants
+ * @param string $description A description text
+ * @param mixed $default The default value (must be null for self::VALUE_REQUIRED or self::VALUE_NONE)
+ *
+ * @throws \InvalidArgumentException If option mode is invalid or incompatible
+ *
+ * @api
+ */
+ public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null)
+ {
+ if (0 === strpos($name, '--')) {
+ $name = substr($name, 2);
+ }
+
+ if (empty($shortcut)) {
+ $shortcut = null;
+ }
+
+ if (null !== $shortcut) {
+ if ('-' === $shortcut[0]) {
+ $shortcut = substr($shortcut, 1);
+ }
+ }
+
+ if (null === $mode) {
+ $mode = self::VALUE_NONE;
+ } elseif (!is_int($mode) || $mode > 15 || $mode < 1) {
+ throw new \InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode));
+ }
+
+ $this->name = $name;
+ $this->shortcut = $shortcut;
+ $this->mode = $mode;
+ $this->description = $description;
+
+ if ($this->isArray() && !$this->acceptValue()) {
+ throw new \InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.');
+ }
+
+ $this->setDefault($default);
+ }
+
+ /**
+ * Returns the option shortcut.
+ *
+ * @return string The shortcut
+ */
+ public function getShortcut()
+ {
+ return $this->shortcut;
+ }
+
+ /**
+ * Returns the option name.
+ *
+ * @return string The name
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Returns true if the option accepts a value.
+ *
+ * @return Boolean true if value mode is not self::VALUE_NONE, false otherwise
+ */
+ public function acceptValue()
+ {
+ return $this->isValueRequired() || $this->isValueOptional();
+ }
+
+ /**
+ * Returns true if the option requires a value.
+ *
+ * @return Boolean true if value mode is self::VALUE_REQUIRED, false otherwise
+ */
+ public function isValueRequired()
+ {
+ return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode);
+ }
+
+ /**
+ * Returns true if the option takes an optional value.
+ *
+ * @return Boolean true if value mode is self::VALUE_OPTIONAL, false otherwise
+ */
+ public function isValueOptional()
+ {
+ return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode);
+ }
+
+ /**
+ * Returns true if the option can take multiple values.
+ *
+ * @return Boolean true if mode is self::VALUE_IS_ARRAY, false otherwise
+ */
+ public function isArray()
+ {
+ return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode);
+ }
+
+ /**
+ * Sets the default value.
+ *
+ * @param mixed $default The default value
+ *
+ * @throws \LogicException When incorrect default value is given
+ */
+ public function setDefault($default = null)
+ {
+ if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {
+ throw new \LogicException('Cannot set a default value when using Option::VALUE_NONE mode.');
+ }
+
+ if ($this->isArray()) {
+ if (null === $default) {
+ $default = array();
+ } elseif (!is_array($default)) {
+ throw new \LogicException('A default value for an array option must be an array.');
+ }
+ }
+
+ $this->default = $this->acceptValue() ? $default : false;
+ }
+
+ /**
+ * Returns the default value.
+ *
+ * @return mixed The default value
+ */
+ public function getDefault()
+ {
+ return $this->default;
+ }
+
+ /**
+ * Returns the description text.
+ *
+ * @return string The description text
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ /**
+ * Checks whether the given option equals this one
+ *
+ * @param InputOption $option option to compare
+ * @return Boolean
+ */
+ public function equals(InputOption $option)
+ {
+ return $option->getName() === $this->getName()
+ && $option->getShortcut() === $this->getShortcut()
+ && $option->getDefault() === $this->getDefault()
+ && $option->isArray() === $this->isArray()
+ && $option->isValueRequired() === $this->isValueRequired()
+ && $option->isValueOptional() === $this->isValueOptional()
+ ;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Input/StringInput.php b/app/laravel/vendor/Symfony/Component/Console/Input/StringInput.php
new file mode 100644
index 000000000..72b725bd5
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Input/StringInput.php
@@ -0,0 +1,79 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * StringInput represents an input provided as a string.
+ *
+ * Usage:
+ *
+ * $input = new StringInput('foo --bar="foobar"');
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class StringInput extends ArgvInput
+{
+ const REGEX_STRING = '([^ ]+?)(?: |(?setTokens($this->tokenize($input));
+ }
+
+ /**
+ * Tokenizes a string.
+ *
+ * @param string $input The input to tokenize
+ *
+ * @throws \InvalidArgumentException When unable to parse input (should never happen)
+ */
+ private function tokenize($input)
+ {
+ $input = preg_replace('/(\r\n|\r|\n|\t)/', ' ', $input);
+
+ $tokens = array();
+ $length = strlen($input);
+ $cursor = 0;
+ while ($cursor < $length) {
+ if (preg_match('/\s+/A', $input, $match, null, $cursor)) {
+ } elseif (preg_match('/([^="\' ]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, null, $cursor)) {
+ $tokens[] = $match[1].$match[2].stripcslashes(str_replace(array('"\'', '\'"', '\'\'', '""'), '', substr($match[3], 1, strlen($match[3]) - 2)));
+ } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, null, $cursor)) {
+ $tokens[] = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2));
+ } elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, null, $cursor)) {
+ $tokens[] = stripcslashes($match[1]);
+ } else {
+ // should never happen
+ // @codeCoverageIgnoreStart
+ throw new \InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10)));
+ // @codeCoverageIgnoreEnd
+ }
+
+ $cursor += strlen($match[0]);
+ }
+
+ return $tokens;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/LICENSE b/app/laravel/vendor/Symfony/Component/Console/LICENSE
new file mode 100644
index 000000000..cdffe7aeb
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2012 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/app/laravel/vendor/Symfony/Component/Console/Output/ConsoleOutput.php b/app/laravel/vendor/Symfony/Component/Console/Output/ConsoleOutput.php
new file mode 100644
index 000000000..1cce3326c
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Output/ConsoleOutput.php
@@ -0,0 +1,83 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatter;
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+use Symfony\Component\Console\Output\ConsoleOutputInterface;
+
+/**
+ * ConsoleOutput is the default class for all CLI output. It uses STDOUT.
+ *
+ * This class is a convenient wrapper around `StreamOutput`.
+ *
+ * $output = new ConsoleOutput();
+ *
+ * This is equivalent to:
+ *
+ * $output = new StreamOutput(fopen('php://stdout', 'w'));
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
+{
+ private $stderr;
+
+ /**
+ * Constructor.
+ *
+ * @param integer $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL,
+ * self::VERBOSITY_VERBOSE)
+ * @param Boolean $decorated Whether to decorate messages or not (null for auto-guessing)
+ * @param OutputFormatter $formatter Output formatter instance
+ *
+ * @api
+ */
+ public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
+ {
+ parent::__construct(fopen('php://stdout', 'w'), $verbosity, $decorated, $formatter);
+ $this->stderr = new StreamOutput(fopen('php://stderr', 'w'), $verbosity, $decorated, $formatter);
+ }
+
+ public function setDecorated($decorated)
+ {
+ parent::setDecorated($decorated);
+ $this->stderr->setDecorated($decorated);
+ }
+
+ public function setFormatter(OutputFormatterInterface $formatter)
+ {
+ parent::setFormatter($formatter);
+ $this->stderr->setFormatter($formatter);
+ }
+
+ public function setVerbosity($level)
+ {
+ parent::setVerbosity($level);
+ $this->stderr->setVerbosity($level);
+ }
+
+ /**
+ * @return OutputInterface
+ */
+ public function getErrorOutput()
+ {
+ return $this->stderr;
+ }
+
+ public function setErrorOutput(OutputInterface $error)
+ {
+ $this->stderr = $error;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Output/ConsoleOutputInterface.php b/app/laravel/vendor/Symfony/Component/Console/Output/ConsoleOutputInterface.php
new file mode 100644
index 000000000..5006b8007
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Output/ConsoleOutputInterface.php
@@ -0,0 +1,30 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * ConsoleOutputInterface is the interface implemented by ConsoleOutput class.
+ * This adds information about stderr output stream.
+ *
+ * @author Dariusz Górecki
+ */
+interface ConsoleOutputInterface extends OutputInterface
+{
+ /**
+ * @return OutputInterface
+ */
+ public function getErrorOutput();
+
+ public function setErrorOutput(OutputInterface $error);
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Output/NullOutput.php b/app/laravel/vendor/Symfony/Component/Console/Output/NullOutput.php
new file mode 100644
index 000000000..f6c99ab03
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Output/NullOutput.php
@@ -0,0 +1,34 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+/**
+ * NullOutput suppresses all output.
+ *
+ * $output = new NullOutput();
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class NullOutput extends Output
+{
+ /**
+ * Writes a message to the output.
+ *
+ * @param string $message A message to write to the output
+ * @param Boolean $newline Whether to add a newline or not
+ */
+ public function doWrite($message, $newline)
+ {
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Output/Output.php b/app/laravel/vendor/Symfony/Component/Console/Output/Output.php
new file mode 100644
index 000000000..222788016
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Output/Output.php
@@ -0,0 +1,180 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+use Symfony\Component\Console\Formatter\OutputFormatter;
+
+/**
+ * Base class for output classes.
+ *
+ * There are three levels of verbosity:
+ *
+ * * normal: no option passed (normal output - information)
+ * * verbose: -v (more output - debug)
+ * * quiet: -q (no output)
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+abstract class Output implements OutputInterface
+{
+ private $verbosity;
+ private $formatter;
+
+ /**
+ * Constructor.
+ *
+ * @param integer $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL, self::VERBOSITY_VERBOSE)
+ * @param Boolean $decorated Whether to decorate messages or not (null for auto-guessing)
+ * @param OutputFormatterInterface $formatter Output formatter instance
+ *
+ * @api
+ */
+ public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
+ {
+ $this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity;
+ $this->formatter = null === $formatter ? new OutputFormatter() : $formatter;
+ $this->formatter->setDecorated((Boolean) $decorated);
+ }
+
+ /**
+ * Sets output formatter.
+ *
+ * @param OutputFormatterInterface $formatter
+ *
+ * @api
+ */
+ public function setFormatter(OutputFormatterInterface $formatter)
+ {
+ $this->formatter = $formatter;
+ }
+
+ /**
+ * Returns current output formatter instance.
+ *
+ * @return OutputFormatterInterface
+ *
+ * @api
+ */
+ public function getFormatter()
+ {
+ return $this->formatter;
+ }
+
+ /**
+ * Sets the decorated flag.
+ *
+ * @param Boolean $decorated Whether to decorate the messages or not
+ *
+ * @api
+ */
+ public function setDecorated($decorated)
+ {
+ $this->formatter->setDecorated((Boolean) $decorated);
+ }
+
+ /**
+ * Gets the decorated flag.
+ *
+ * @return Boolean true if the output will decorate messages, false otherwise
+ *
+ * @api
+ */
+ public function isDecorated()
+ {
+ return $this->formatter->isDecorated();
+ }
+
+ /**
+ * Sets the verbosity of the output.
+ *
+ * @param integer $level The level of verbosity
+ *
+ * @api
+ */
+ public function setVerbosity($level)
+ {
+ $this->verbosity = (int) $level;
+ }
+
+ /**
+ * Gets the current verbosity of the output.
+ *
+ * @return integer The current level of verbosity
+ *
+ * @api
+ */
+ public function getVerbosity()
+ {
+ return $this->verbosity;
+ }
+
+ /**
+ * Writes a message to the output and adds a newline at the end.
+ *
+ * @param string|array $messages The message as an array of lines of a single string
+ * @param integer $type The type of output
+ *
+ * @api
+ */
+ public function writeln($messages, $type = 0)
+ {
+ $this->write($messages, true, $type);
+ }
+
+ /**
+ * Writes a message to the output.
+ *
+ * @param string|array $messages The message as an array of lines of a single string
+ * @param Boolean $newline Whether to add a newline or not
+ * @param integer $type The type of output
+ *
+ * @throws \InvalidArgumentException When unknown output type is given
+ *
+ * @api
+ */
+ public function write($messages, $newline = false, $type = 0)
+ {
+ if (self::VERBOSITY_QUIET === $this->verbosity) {
+ return;
+ }
+
+ $messages = (array) $messages;
+
+ foreach ($messages as $message) {
+ switch ($type) {
+ case OutputInterface::OUTPUT_NORMAL:
+ $message = $this->formatter->format($message);
+ break;
+ case OutputInterface::OUTPUT_RAW:
+ break;
+ case OutputInterface::OUTPUT_PLAIN:
+ $message = strip_tags($this->formatter->format($message));
+ break;
+ default:
+ throw new \InvalidArgumentException(sprintf('Unknown output type given (%s)', $type));
+ }
+
+ $this->doWrite($message, $newline);
+ }
+ }
+
+ /**
+ * Writes a message to the output.
+ *
+ * @param string $message A message to write to the output
+ * @param Boolean $newline Whether to add a newline or not
+ */
+ abstract public function doWrite($message, $newline);
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Output/OutputInterface.php b/app/laravel/vendor/Symfony/Component/Console/Output/OutputInterface.php
new file mode 100644
index 000000000..8423d48c9
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Output/OutputInterface.php
@@ -0,0 +1,109 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * OutputInterface is the interface implemented by all Output classes.
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+interface OutputInterface
+{
+ const VERBOSITY_QUIET = 0;
+ const VERBOSITY_NORMAL = 1;
+ const VERBOSITY_VERBOSE = 2;
+
+ const OUTPUT_NORMAL = 0;
+ const OUTPUT_RAW = 1;
+ const OUTPUT_PLAIN = 2;
+
+ /**
+ * Writes a message to the output.
+ *
+ * @param string|array $messages The message as an array of lines of a single string
+ * @param Boolean $newline Whether to add a newline or not
+ * @param integer $type The type of output
+ *
+ * @throws \InvalidArgumentException When unknown output type is given
+ *
+ * @api
+ */
+ function write($messages, $newline = false, $type = 0);
+
+ /**
+ * Writes a message to the output and adds a newline at the end.
+ *
+ * @param string|array $messages The message as an array of lines of a single string
+ * @param integer $type The type of output
+ *
+ * @api
+ */
+ function writeln($messages, $type = 0);
+
+ /**
+ * Sets the verbosity of the output.
+ *
+ * @param integer $level The level of verbosity
+ *
+ * @api
+ */
+ function setVerbosity($level);
+
+ /**
+ * Gets the current verbosity of the output.
+ *
+ * @return integer The current level of verbosity
+ *
+ * @api
+ */
+ function getVerbosity();
+
+ /**
+ * Sets the decorated flag.
+ *
+ * @param Boolean $decorated Whether to decorate the messages or not
+ *
+ * @api
+ */
+ function setDecorated($decorated);
+
+ /**
+ * Gets the decorated flag.
+ *
+ * @return Boolean true if the output will decorate messages, false otherwise
+ *
+ * @api
+ */
+ function isDecorated();
+
+ /**
+ * Sets output formatter.
+ *
+ * @param OutputFormatterInterface $formatter
+ *
+ * @api
+ */
+ function setFormatter(OutputFormatterInterface $formatter);
+
+ /**
+ * Returns current output formatter instance.
+ *
+ * @return OutputFormatterInterface
+ *
+ * @api
+ */
+ function getFormatter();
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Output/StreamOutput.php b/app/laravel/vendor/Symfony/Component/Console/Output/StreamOutput.php
new file mode 100644
index 000000000..de1720ffc
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Output/StreamOutput.php
@@ -0,0 +1,113 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * StreamOutput writes the output to a given stream.
+ *
+ * Usage:
+ *
+ * $output = new StreamOutput(fopen('php://stdout', 'w'));
+ *
+ * As `StreamOutput` can use any stream, you can also use a file:
+ *
+ * $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class StreamOutput extends Output
+{
+ private $stream;
+
+ /**
+ * Constructor.
+ *
+ * @param mixed $stream A stream resource
+ * @param integer $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL,
+ * self::VERBOSITY_VERBOSE)
+ * @param Boolean $decorated Whether to decorate messages or not (null for auto-guessing)
+ * @param OutputFormatter $formatter Output formatter instance
+ *
+ * @throws \InvalidArgumentException When first argument is not a real stream
+ *
+ * @api
+ */
+ public function __construct($stream, $verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
+ {
+ if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) {
+ throw new \InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
+ }
+
+ $this->stream = $stream;
+
+ if (null === $decorated) {
+ $decorated = $this->hasColorSupport($decorated);
+ }
+
+ parent::__construct($verbosity, $decorated, $formatter);
+ }
+
+ /**
+ * Gets the stream attached to this StreamOutput instance.
+ *
+ * @return resource A stream resource
+ */
+ public function getStream()
+ {
+ return $this->stream;
+ }
+
+ /**
+ * Writes a message to the output.
+ *
+ * @param string $message A message to write to the output
+ * @param Boolean $newline Whether to add a newline or not
+ *
+ * @throws \RuntimeException When unable to write output (should never happen)
+ */
+ public function doWrite($message, $newline)
+ {
+ if (false === @fwrite($this->stream, $message.($newline ? PHP_EOL : ''))) {
+ // @codeCoverageIgnoreStart
+ // should never happen
+ throw new \RuntimeException('Unable to write output.');
+ // @codeCoverageIgnoreEnd
+ }
+
+ fflush($this->stream);
+ }
+
+ /**
+ * Returns true if the stream supports colorization.
+ *
+ * Colorization is disabled if not supported by the stream:
+ *
+ * - windows without ansicon
+ * - non tty consoles
+ *
+ * @return Boolean true if the stream supports colorization, false otherwise
+ */
+ protected function hasColorSupport()
+ {
+ // @codeCoverageIgnoreStart
+ if (DIRECTORY_SEPARATOR == '\\') {
+ return false !== getenv('ANSICON');
+ }
+
+ return function_exists('posix_isatty') && @posix_isatty($this->stream);
+ // @codeCoverageIgnoreEnd
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/README.md b/app/laravel/vendor/Symfony/Component/Console/README.md
new file mode 100644
index 000000000..d903776ab
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/README.md
@@ -0,0 +1,48 @@
+Console Component
+=================
+
+Console eases the creation of beautiful and testable command line interfaces.
+
+The Application object manages the CLI application:
+
+ use Symfony\Component\Console\Application;
+
+ $console = new Application();
+ $console->run();
+
+The ``run()`` method parses the arguments and options passed on the command
+line and executes the right command.
+
+Registering a new command can easily be done via the ``register()`` method,
+which returns a ``Command`` instance:
+
+ use Symfony\Component\Console\Input\InputInterface;
+ use Symfony\Component\Console\Input\InputArgument;
+ use Symfony\Component\Console\Input\InputOption;
+ use Symfony\Component\Console\Output\OutputInterface;
+
+ $console
+ ->register('ls')
+ ->setDefinition(array(
+ new InputArgument('dir', InputArgument::REQUIRED, 'Directory name'),
+ ))
+ ->setDescription('Displays the files in the given directory')
+ ->setCode(function (InputInterface $input, OutputInterface $output) {
+ $dir = $input->getArgument('dir');
+
+ $output->writeln(sprintf('Dir listing for %s ', $dir));
+ })
+ ;
+
+You can also register new commands via classes.
+
+The component provides a lot of features like output coloring, input and
+output abstractions (so that you can easily unit-test your commands),
+validation, automatic help messages, ...
+
+Resources
+---------
+
+Unit tests:
+
+https://github.com/symfony/symfony/tree/master/tests/Symfony/Tests/Component/Console
diff --git a/app/laravel/vendor/Symfony/Component/Console/Shell.php b/app/laravel/vendor/Symfony/Component/Console/Shell.php
new file mode 100644
index 000000000..6b89b048e
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Shell.php
@@ -0,0 +1,206 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Input\StringInput;
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Process\ProcessBuilder;
+use Symfony\Component\Process\PhpExecutableFinder;
+
+/**
+ * A Shell wraps an Application to add shell capabilities to it.
+ *
+ * Support for history and completion only works with a PHP compiled
+ * with readline support (either --with-readline or --with-libedit)
+ *
+ * @author Fabien Potencier
+ * @author Martin Hasoň
+ */
+class Shell
+{
+ private $application;
+ private $history;
+ private $output;
+ private $hasReadline;
+ private $prompt;
+ private $processIsolation;
+
+ /**
+ * Constructor.
+ *
+ * If there is no readline support for the current PHP executable
+ * a \RuntimeException exception is thrown.
+ *
+ * @param Application $application An application instance
+ */
+ public function __construct(Application $application)
+ {
+ $this->hasReadline = function_exists('readline');
+ $this->application = $application;
+ $this->history = getenv('HOME').'/.history_'.$application->getName();
+ $this->output = new ConsoleOutput();
+ $this->prompt = $application->getName().' > ';
+ $this->processIsolation = false;
+ }
+
+ /**
+ * Runs the shell.
+ */
+ public function run()
+ {
+ $this->application->setAutoExit(false);
+ $this->application->setCatchExceptions(true);
+
+ if ($this->hasReadline) {
+ readline_read_history($this->history);
+ readline_completion_function(array($this, 'autocompleter'));
+ }
+
+ $this->output->writeln($this->getHeader());
+ $php = null;
+ if ($this->processIsolation) {
+ $finder = new PhpExecutableFinder();
+ $php = $finder->find();
+ $this->output->writeln(<<Running with process isolation, you should consider this:
+ * each command is executed as separate process,
+ * commands don't support interactivity, all params must be passed explicitly,
+ * commands output is not colorized.
+
+EOF
+ );
+ }
+
+ while (true) {
+ $command = $this->readline();
+
+ if (false === $command) {
+ $this->output->writeln("\n");
+
+ break;
+ }
+
+ if ($this->hasReadline) {
+ readline_add_history($command);
+ readline_write_history($this->history);
+ }
+
+ if ($this->processIsolation) {
+ $pb = new ProcessBuilder();
+
+ $process = $pb
+ ->add($php)
+ ->add($_SERVER['argv'][0])
+ ->add($command)
+ ->inheritEnvironmentVariables(true)
+ ->getProcess()
+ ;
+
+ $output = $this->output;
+ $process->run(function($type, $data) use ($output) {
+ $output->writeln($data);
+ });
+
+ $ret = $process->getExitCode();
+ } else {
+ $ret = $this->application->run(new StringInput($command), $this->output);
+ }
+
+ if (0 !== $ret) {
+ $this->output->writeln(sprintf('The command terminated with an error status (%s) ', $ret));
+ }
+ }
+ }
+
+ /**
+ * Returns the shell header.
+ *
+ * @return string The header string
+ */
+ protected function getHeader()
+ {
+ return <<{$this->application->getName()} shell ({$this->application->getVersion()} ).
+
+At the prompt, type help for some help,
+or list to get a list of available commands.
+
+To exit the shell, type ^D .
+
+EOF;
+ }
+
+ /**
+ * Tries to return autocompletion for the current entered text.
+ *
+ * @param string $text The last segment of the entered text
+ * @return Boolean|array A list of guessed strings or true
+ */
+ private function autocompleter($text)
+ {
+ $info = readline_info();
+ $text = substr($info['line_buffer'], 0, $info['end']);
+
+ if ($info['point'] !== $info['end']) {
+ return true;
+ }
+
+ // task name?
+ if (false === strpos($text, ' ') || !$text) {
+ return array_keys($this->application->all());
+ }
+
+ // options and arguments?
+ try {
+ $command = $this->application->find(substr($text, 0, strpos($text, ' ')));
+ } catch (\Exception $e) {
+ return true;
+ }
+
+ $list = array('--help');
+ foreach ($command->getDefinition()->getOptions() as $option) {
+ $list[] = '--'.$option->getName();
+ }
+
+ return $list;
+ }
+
+ /**
+ * Reads a single line from standard input.
+ *
+ * @return string The single line from standard input
+ */
+ private function readline()
+ {
+ if ($this->hasReadline) {
+ $line = readline($this->prompt);
+ } else {
+ $this->output->write($this->prompt);
+ $line = fgets(STDIN, 1024);
+ $line = (!$line && strlen($line) == 0) ? false : rtrim($line);
+ }
+
+ return $line;
+ }
+
+ public function getProcessIsolation()
+ {
+ return $this->processIsolation;
+ }
+
+ public function setProcessIsolation($processIsolation)
+ {
+ $this->processIsolation = (Boolean) $processIsolation;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Tester/ApplicationTester.php b/app/laravel/vendor/Symfony/Component/Console/Tester/ApplicationTester.php
new file mode 100644
index 000000000..9412fbabf
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Tester/ApplicationTester.php
@@ -0,0 +1,102 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tester;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\StreamOutput;
+
+/**
+ * @author Fabien Potencier
+ */
+class ApplicationTester
+{
+ private $application;
+ private $input;
+ private $output;
+
+ /**
+ * Constructor.
+ *
+ * @param Application $application An Application instance to test.
+ */
+ public function __construct(Application $application)
+ {
+ $this->application = $application;
+ }
+
+ /**
+ * Executes the application.
+ *
+ * Available options:
+ *
+ * * interactive: Sets the input interactive flag
+ * * decorated: Sets the output decorated flag
+ * * verbosity: Sets the output verbosity flag
+ *
+ * @param array $input An array of arguments and options
+ * @param array $options An array of options
+ *
+ * @return integer The command exit code
+ */
+ public function run(array $input, $options = array())
+ {
+ $this->input = new ArrayInput($input);
+ if (isset($options['interactive'])) {
+ $this->input->setInteractive($options['interactive']);
+ }
+
+ $this->output = new StreamOutput(fopen('php://memory', 'w', false));
+ if (isset($options['decorated'])) {
+ $this->output->setDecorated($options['decorated']);
+ }
+ if (isset($options['verbosity'])) {
+ $this->output->setVerbosity($options['verbosity']);
+ }
+
+ return $this->application->run($this->input, $this->output);
+ }
+
+ /**
+ * Gets the display returned by the last execution of the application.
+ *
+ * @return string The display
+ */
+ public function getDisplay()
+ {
+ rewind($this->output->getStream());
+
+ return stream_get_contents($this->output->getStream());
+ }
+
+ /**
+ * Gets the input instance used by the last execution of the application.
+ *
+ * @return InputInterface The current input instance
+ */
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ /**
+ * Gets the output instance used by the last execution of the application.
+ *
+ * @return OutputInterface The current output instance
+ */
+ public function getOutput()
+ {
+ return $this->output;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/Tester/CommandTester.php b/app/laravel/vendor/Symfony/Component/Console/Tester/CommandTester.php
new file mode 100644
index 000000000..52be2781f
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/Tester/CommandTester.php
@@ -0,0 +1,100 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tester;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Output\StreamOutput;
+
+/**
+ * @author Fabien Potencier
+ */
+class CommandTester
+{
+ private $command;
+ private $input;
+ private $output;
+
+ /**
+ * Constructor.
+ *
+ * @param Command $command A Command instance to test.
+ */
+ public function __construct(Command $command)
+ {
+ $this->command = $command;
+ }
+
+ /**
+ * Executes the command.
+ *
+ * Available options:
+ *
+ * * interactive: Sets the input interactive flag
+ * * decorated: Sets the output decorated flag
+ * * verbosity: Sets the output verbosity flag
+ *
+ * @param array $input An array of arguments and options
+ * @param array $options An array of options
+ *
+ * @return integer The command exit code
+ */
+ public function execute(array $input, array $options = array())
+ {
+ $this->input = new ArrayInput($input);
+ if (isset($options['interactive'])) {
+ $this->input->setInteractive($options['interactive']);
+ }
+
+ $this->output = new StreamOutput(fopen('php://memory', 'w', false));
+ if (isset($options['decorated'])) {
+ $this->output->setDecorated($options['decorated']);
+ }
+ if (isset($options['verbosity'])) {
+ $this->output->setVerbosity($options['verbosity']);
+ }
+
+ return $this->command->run($this->input, $this->output);
+ }
+
+ /**
+ * Gets the display returned by the last execution of the command.
+ *
+ * @return string The display
+ */
+ public function getDisplay()
+ {
+ rewind($this->output->getStream());
+
+ return stream_get_contents($this->output->getStream());
+ }
+
+ /**
+ * Gets the input instance used by the last execution of the command.
+ *
+ * @return InputInterface The current input instance
+ */
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ /**
+ * Gets the output instance used by the last execution of the command.
+ *
+ * @return OutputInterface The current output instance
+ */
+ public function getOutput()
+ {
+ return $this->output;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/Console/composer.json b/app/laravel/vendor/Symfony/Component/Console/composer.json
new file mode 100644
index 000000000..961212ec0
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/Console/composer.json
@@ -0,0 +1,30 @@
+{
+ "name": "symfony/console",
+ "type": "library",
+ "description": "Symfony Console Component",
+ "keywords": [],
+ "homepage": "http://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "autoload": {
+ "psr-0": { "Symfony\\Component\\Console": "" }
+ },
+ "target-dir": "Symfony/Component/Console",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1-dev"
+ }
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/ApacheRequest.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/ApacheRequest.php
new file mode 100755
index 000000000..ca8f8eebb
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/ApacheRequest.php
@@ -0,0 +1,51 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * Request represents an HTTP request from an Apache server.
+ *
+ * @author Fabien Potencier
+ */
+class ApacheRequest extends Request
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function prepareRequestUri()
+ {
+ return $this->server->get('REQUEST_URI');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function prepareBaseUrl()
+ {
+ $baseUrl = $this->server->get('SCRIPT_NAME');
+
+ if (false === strpos($this->server->get('REQUEST_URI'), $baseUrl)) {
+ // assume mod_rewrite
+ return rtrim(dirname($baseUrl), '/\\');
+ }
+
+ return $baseUrl;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function preparePathInfo()
+ {
+ return $this->server->get('PATH_INFO') ?: substr($this->prepareRequestUri(), strlen($this->prepareBaseUrl())) ?: '/';
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Cookie.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Cookie.php
new file mode 100755
index 000000000..0511162aa
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Cookie.php
@@ -0,0 +1,203 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * Represents a cookie
+ *
+ * @author Johannes M. Schmitt
+ *
+ * @api
+ */
+class Cookie
+{
+ protected $name;
+ protected $value;
+ protected $domain;
+ protected $expire;
+ protected $path;
+ protected $secure;
+ protected $httpOnly;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of the cookie
+ * @param string $value The value of the cookie
+ * @param integer|string|\DateTime $expire The time the cookie expires
+ * @param string $path The path on the server in which the cookie will be available on
+ * @param string $domain The domain that the cookie is available to
+ * @param Boolean $secure Whether the cookie should only be transmitted over a secure HTTPS connection from the client
+ * @param Boolean $httpOnly Whether the cookie will be made accessible only through the HTTP protocol
+ *
+ * @api
+ */
+ public function __construct($name, $value = null, $expire = 0, $path = '/', $domain = null, $secure = false, $httpOnly = true)
+ {
+ // from PHP source code
+ if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
+ throw new \InvalidArgumentException(sprintf('The cookie name "%s" contains invalid characters.', $name));
+ }
+
+ if (empty($name)) {
+ throw new \InvalidArgumentException('The cookie name cannot be empty.');
+ }
+
+ // convert expiration time to a Unix timestamp
+ if ($expire instanceof \DateTime) {
+ $expire = $expire->format('U');
+ } elseif (!is_numeric($expire)) {
+ $expire = strtotime($expire);
+
+ if (false === $expire || -1 === $expire) {
+ throw new \InvalidArgumentException('The cookie expiration time is not valid.');
+ }
+ }
+
+ $this->name = $name;
+ $this->value = $value;
+ $this->domain = $domain;
+ $this->expire = $expire;
+ $this->path = empty($path) ? '/' : $path;
+ $this->secure = (Boolean) $secure;
+ $this->httpOnly = (Boolean) $httpOnly;
+ }
+
+ public function __toString()
+ {
+ $str = urlencode($this->getName()).'=';
+
+ if ('' === (string) $this->getValue()) {
+ $str .= 'deleted; expires='.gmdate("D, d-M-Y H:i:s T", time() - 31536001);
+ } else {
+ $str .= urlencode($this->getValue());
+
+ if ($this->getExpiresTime() !== 0) {
+ $str .= '; expires='.gmdate("D, d-M-Y H:i:s T", $this->getExpiresTime());
+ }
+ }
+
+ if ('/' !== $this->path) {
+ $str .= '; path='.$this->path;
+ }
+
+ if (null !== $this->getDomain()) {
+ $str .= '; domain='.$this->getDomain();
+ }
+
+ if (true === $this->isSecure()) {
+ $str .= '; secure';
+ }
+
+ if (true === $this->isHttpOnly()) {
+ $str .= '; httponly';
+ }
+
+ return $str;
+ }
+
+ /**
+ * Gets the name of the cookie.
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Gets the value of the cookie.
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Gets the domain that the cookie is available to.
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function getDomain()
+ {
+ return $this->domain;
+ }
+
+ /**
+ * Gets the time the cookie expires.
+ *
+ * @return integer
+ *
+ * @api
+ */
+ public function getExpiresTime()
+ {
+ return $this->expire;
+ }
+
+ /**
+ * Gets the path on the server in which the cookie will be available on.
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Checks whether the cookie should only be transmitted over a secure HTTPS connection from the client.
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isSecure()
+ {
+ return $this->secure;
+ }
+
+ /**
+ * Checks whether the cookie will be made accessible only through the HTTP protocol.
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isHttpOnly()
+ {
+ return $this->httpOnly;
+ }
+
+ /**
+ * Whether this cookie is about to be cleared
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isCleared()
+ {
+ return $this->expire < time();
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/AccessDeniedException.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/AccessDeniedException.php
new file mode 100755
index 000000000..9c7fe6812
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/AccessDeniedException.php
@@ -0,0 +1,30 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\Exception;
+
+/**
+ * Thrown when the access on a file was denied.
+ *
+ * @author Bernhard Schussek
+ */
+class AccessDeniedException extends FileException
+{
+ /**
+ * Constructor.
+ *
+ * @param string $path The path to the accessed file
+ */
+ public function __construct($path)
+ {
+ parent::__construct(sprintf('The file %s could not be accessed', $path));
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/FileException.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/FileException.php
new file mode 100755
index 000000000..43c6cc899
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/FileException.php
@@ -0,0 +1,21 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\Exception;
+
+/**
+ * Thrown when an error occurred in the component File
+ *
+ * @author Bernhard Schussek
+ */
+class FileException extends \RuntimeException
+{
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php
new file mode 100755
index 000000000..5b1aef8e2
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/FileNotFoundException.php
@@ -0,0 +1,30 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\Exception;
+
+/**
+ * Thrown when a file was not found
+ *
+ * @author Bernhard Schussek
+ */
+class FileNotFoundException extends FileException
+{
+ /**
+ * Constructor.
+ *
+ * @param string $path The path to the file that was not found
+ */
+ public function __construct($path)
+ {
+ parent::__construct(sprintf('The file "%s" does not exist', $path));
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/UnexpectedTypeException.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/UnexpectedTypeException.php
new file mode 100755
index 000000000..0444b8778
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/UnexpectedTypeException.php
@@ -0,0 +1,20 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\Exception;
+
+class UnexpectedTypeException extends FileException
+{
+ public function __construct($value, $expectedType)
+ {
+ parent::__construct(sprintf('Expected argument of type %s, %s given', $expectedType, is_object($value) ? get_class($value) : gettype($value)));
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/UploadException.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/UploadException.php
new file mode 100755
index 000000000..694e864d1
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/Exception/UploadException.php
@@ -0,0 +1,21 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\Exception;
+
+/**
+ * Thrown when an error occurred during file upload
+ *
+ * @author Bernhard Schussek
+ */
+class UploadException extends FileException
+{
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/File.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/File.php
new file mode 100755
index 000000000..3134ccda5
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/File.php
@@ -0,0 +1,129 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File;
+
+use Symfony\Component\HttpFoundation\File\Exception\FileException;
+use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
+use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
+use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser;
+
+/**
+ * A file in the file system.
+ *
+ * @author Bernhard Schussek
+ *
+ * @api
+ */
+class File extends \SplFileInfo
+{
+ /**
+ * Constructs a new file from the given path.
+ *
+ * @param string $path The path to the file
+ * @param Boolean $checkPath Whether to check the path or not
+ *
+ * @throws FileNotFoundException If the given path is not a file
+ *
+ * @api
+ */
+ public function __construct($path, $checkPath = true)
+ {
+ if ($checkPath && !is_file($path)) {
+ throw new FileNotFoundException($path);
+ }
+
+ parent::__construct($path);
+ }
+
+ /**
+ * Returns the extension based on the mime type.
+ *
+ * If the mime type is unknown, returns null.
+ *
+ * @return string|null The guessed extension or null if it cannot be guessed
+ *
+ * @api
+ */
+ public function guessExtension()
+ {
+ $type = $this->getMimeType();
+ $guesser = ExtensionGuesser::getInstance();
+
+ return $guesser->guess($type);
+ }
+
+ /**
+ * Returns the mime type of the file.
+ *
+ * The mime type is guessed using the functions finfo(), mime_content_type()
+ * and the system binary "file" (in this order), depending on which of those
+ * is available on the current operating system.
+ *
+ * @return string|null The guessed mime type (i.e. "application/pdf")
+ *
+ * @api
+ */
+ public function getMimeType()
+ {
+ $guesser = MimeTypeGuesser::getInstance();
+
+ return $guesser->guess($this->getPathname());
+ }
+
+ /**
+ * Returns the extension of the file.
+ *
+ * \SplFileInfo::getExtension() is not available before PHP 5.3.6
+ *
+ * @return string The extension
+ *
+ * @api
+ */
+ public function getExtension()
+ {
+ return pathinfo($this->getBasename(), PATHINFO_EXTENSION);
+ }
+
+ /**
+ * Moves the file to a new location.
+ *
+ * @param string $directory The destination folder
+ * @param string $name The new file name
+ *
+ * @return File A File object representing the new file
+ *
+ * @throws FileException if the target file could not be created
+ *
+ * @api
+ */
+ public function move($directory, $name = null)
+ {
+ if (!is_dir($directory)) {
+ if (false === @mkdir($directory, 0777, true)) {
+ throw new FileException(sprintf('Unable to create the "%s" directory', $directory));
+ }
+ } elseif (!is_writable($directory)) {
+ throw new FileException(sprintf('Unable to write in the "%s" directory', $directory));
+ }
+
+ $target = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : basename($name));
+
+ if (!@rename($this->getPathname(), $target)) {
+ $error = error_get_last();
+ throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message'])));
+ }
+
+ chmod($target, 0666);
+
+ return new File($target);
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/ExtensionGuesser.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/ExtensionGuesser.php
new file mode 100755
index 000000000..b73cd9991
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/ExtensionGuesser.php
@@ -0,0 +1,100 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\MimeType;
+
+/**
+ * A singleton mime type to file extension guesser.
+ *
+ * A default guesser is provided.
+ * You can register custom guessers by calling the register()
+ * method on the singleton instance.
+ *
+ *
+ * $guesser = ExtensionGuesser::getInstance();
+ * $guesser->register(new MyCustomExtensionGuesser());
+ *
+ *
+ * The last registered guesser is preferred over previously registered ones.
+ *
+ */
+class ExtensionGuesser implements ExtensionGuesserInterface
+{
+ /**
+ * The singleton instance
+ * @var ExtensionGuesser
+ */
+ static private $instance = null;
+
+ /**
+ * All registered ExtensionGuesserInterface instances
+ * @var array
+ */
+ protected $guessers = array();
+
+ /**
+ * Returns the singleton instance
+ *
+ * @return ExtensionGuesser
+ */
+ static public function getInstance()
+ {
+ if (null === self::$instance) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * Registers all natively provided extension guessers
+ */
+ private function __construct()
+ {
+ $this->register(new MimeTypeExtensionGuesser());
+ }
+
+ /**
+ * Registers a new extension guesser
+ *
+ * When guessing, this guesser is preferred over previously registered ones.
+ *
+ * @param ExtensionGuesserInterface $guesser
+ */
+ public function register(ExtensionGuesserInterface $guesser)
+ {
+ array_unshift($this->guessers, $guesser);
+ }
+
+ /**
+ * Tries to guess the extension
+ *
+ * The mime type is passed to each registered mime type guesser in reverse order
+ * of their registration (last registered is queried first). Once a guesser
+ * returns a value that is not NULL, this method terminates and returns the
+ * value.
+ *
+ * @param string $mimeType The mime type
+ * @return string The guessed extension or NULL, if none could be guessed
+ */
+ public function guess($mimeType)
+ {
+ foreach ($this->guessers as $guesser) {
+ $extension = $guesser->guess($mimeType);
+
+ if (null !== $extension) {
+ break;
+ }
+ }
+
+ return $extension;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/ExtensionGuesserInterface.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/ExtensionGuesserInterface.php
new file mode 100755
index 000000000..5b14ef9ed
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/ExtensionGuesserInterface.php
@@ -0,0 +1,26 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\MimeType;
+
+/**
+ * Guesses the file extension corresponding to a given mime type
+ */
+interface ExtensionGuesserInterface
+{
+ /**
+ * Makes a best guess for a file extension, given a mime type
+ *
+ * @param string $mimeType The mime type
+ * @return string The guessed extension or NULL, if none could be guessed
+ */
+ function guess($mimeType);
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php
new file mode 100755
index 000000000..12b84cdc9
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/FileBinaryMimeTypeGuesser.php
@@ -0,0 +1,89 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\MimeType;
+
+use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
+use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
+
+/**
+ * Guesses the mime type with the binary "file" (only available on *nix)
+ *
+ * @author Bernhard Schussek
+ */
+class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
+{
+ private $cmd;
+
+ /**
+ * Constructor.
+ *
+ * The $cmd pattern must contain a "%s" string that will be replaced
+ * with the file name to guess.
+ *
+ * The command output must start with the mime type of the file.
+ *
+ * @param string $cmd The command to run to get the mime type of a file
+ */
+ public function __construct($cmd = 'file -b --mime %s 2>/dev/null')
+ {
+ $this->cmd = $cmd;
+ }
+
+ /**
+ * Returns whether this guesser is supported on the current OS
+ *
+ * @return Boolean
+ */
+ static public function isSupported()
+ {
+ return !defined('PHP_WINDOWS_VERSION_BUILD');
+ }
+
+ /**
+ * Guesses the mime type of the file with the given path
+ *
+ * @see MimeTypeGuesserInterface::guess()
+ */
+ public function guess($path)
+ {
+ if (!is_file($path)) {
+ throw new FileNotFoundException($path);
+ }
+
+ if (!is_readable($path)) {
+ throw new AccessDeniedException($path);
+ }
+
+ if (!self::isSupported()) {
+ return null;
+ }
+
+ ob_start();
+
+ // need to use --mime instead of -i. see #6641
+ passthru(sprintf($this->cmd, escapeshellarg($path)), $return);
+ if ($return > 0) {
+ ob_end_clean();
+
+ return null;
+ }
+
+ $type = trim(ob_get_clean());
+
+ if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-]+)#i', $type, $match)) {
+ // it's not a type, but an error message
+ return null;
+ }
+
+ return $match[1];
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php
new file mode 100755
index 000000000..45d5a086e
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/FileinfoMimeTypeGuesser.php
@@ -0,0 +1,59 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\MimeType;
+
+use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
+use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
+
+/**
+ * Guesses the mime type using the PECL extension FileInfo
+ *
+ * @author Bernhard Schussek
+ */
+class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface
+{
+ /**
+ * Returns whether this guesser is supported on the current OS/PHP setup
+ *
+ * @return Boolean
+ */
+ static public function isSupported()
+ {
+ return function_exists('finfo_open');
+ }
+
+ /**
+ * Guesses the mime type of the file with the given path
+ *
+ * @see MimeTypeGuesserInterface::guess()
+ */
+ public function guess($path)
+ {
+ if (!is_file($path)) {
+ throw new FileNotFoundException($path);
+ }
+
+ if (!is_readable($path)) {
+ throw new AccessDeniedException($path);
+ }
+
+ if (!self::isSupported()) {
+ return null;
+ }
+
+ if (!$finfo = new \finfo(FILEINFO_MIME_TYPE)) {
+ return null;
+ }
+
+ return $finfo->file($path);
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php
new file mode 100755
index 000000000..805f223c4
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeExtensionGuesser.php
@@ -0,0 +1,743 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\Mimetype;
+
+/**
+ * Provides a best-guess mapping of mime type to file extension.
+ */
+class MimeTypeExtensionGuesser implements ExtensionGuesserInterface
+{
+ /**
+ * A map of mime types and their default extensions.
+ *
+ * This list has been placed under the public domain by the Apache HTTPD project.
+ *
+ * @see http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
+ *
+ * @var array
+ */
+ protected $defaultExtensions = array(
+ 'application/andrew-inset' => 'ez',
+ 'application/applixware' => 'aw',
+ 'application/atom+xml' => 'atom',
+ 'application/atomcat+xml' => 'atomcat',
+ 'application/atomsvc+xml' => 'atomsvc',
+ 'application/ccxml+xml' => 'ccxml',
+ 'application/cdmi-capability' => 'cdmia',
+ 'application/cdmi-container' => 'cdmic',
+ 'application/cdmi-domain' => 'cdmid',
+ 'application/cdmi-object' => 'cdmio',
+ 'application/cdmi-queue' => 'cdmiq',
+ 'application/cu-seeme' => 'cu',
+ 'application/davmount+xml' => 'davmount',
+ 'application/dssc+der' => 'dssc',
+ 'application/dssc+xml' => 'xdssc',
+ 'application/ecmascript' => 'ecma',
+ 'application/emma+xml' => 'emma',
+ 'application/epub+zip' => 'epub',
+ 'application/exi' => 'exi',
+ 'application/font-tdpfr' => 'pfr',
+ 'application/hyperstudio' => 'stk',
+ 'application/inkml+xml' => 'ink',
+ 'application/ipfix' => 'ipfix',
+ 'application/java-archive' => 'jar',
+ 'application/java-serialized-object' => 'ser',
+ 'application/java-vm' => 'class',
+ 'application/javascript' => 'js',
+ 'application/json' => 'json',
+ 'application/lost+xml' => 'lostxml',
+ 'application/mac-binhex40' => 'hqx',
+ 'application/mac-compactpro' => 'cpt',
+ 'application/mads+xml' => 'mads',
+ 'application/marc' => 'mrc',
+ 'application/marcxml+xml' => 'mrcx',
+ 'application/mathematica' => 'ma',
+ 'application/mathml+xml' => 'mathml',
+ 'application/mbox' => 'mbox',
+ 'application/mediaservercontrol+xml' => 'mscml',
+ 'application/metalink4+xml' => 'meta4',
+ 'application/mets+xml' => 'mets',
+ 'application/mods+xml' => 'mods',
+ 'application/mp21' => 'm21',
+ 'application/mp4' => 'mp4s',
+ 'application/msword' => 'doc',
+ 'application/mxf' => 'mxf',
+ 'application/octet-stream' => 'bin',
+ 'application/oda' => 'oda',
+ 'application/oebps-package+xml' => 'opf',
+ 'application/ogg' => 'ogx',
+ 'application/onenote' => 'onetoc',
+ 'application/oxps' => 'oxps',
+ 'application/patch-ops-error+xml' => 'xer',
+ 'application/pdf' => 'pdf',
+ 'application/pgp-encrypted' => 'pgp',
+ 'application/pgp-signature' => 'asc',
+ 'application/pics-rules' => 'prf',
+ 'application/pkcs10' => 'p10',
+ 'application/pkcs7-mime' => 'p7m',
+ 'application/pkcs7-signature' => 'p7s',
+ 'application/pkcs8' => 'p8',
+ 'application/pkix-attr-cert' => 'ac',
+ 'application/pkix-cert' => 'cer',
+ 'application/pkix-crl' => 'crl',
+ 'application/pkix-pkipath' => 'pkipath',
+ 'application/pkixcmp' => 'pki',
+ 'application/pls+xml' => 'pls',
+ 'application/postscript' => 'ai',
+ 'application/prs.cww' => 'cww',
+ 'application/pskc+xml' => 'pskcxml',
+ 'application/rdf+xml' => 'rdf',
+ 'application/reginfo+xml' => 'rif',
+ 'application/relax-ng-compact-syntax' => 'rnc',
+ 'application/resource-lists+xml' => 'rl',
+ 'application/resource-lists-diff+xml' => 'rld',
+ 'application/rls-services+xml' => 'rs',
+ 'application/rpki-ghostbusters' => 'gbr',
+ 'application/rpki-manifest' => 'mft',
+ 'application/rpki-roa' => 'roa',
+ 'application/rsd+xml' => 'rsd',
+ 'application/rss+xml' => 'rss',
+ 'application/rtf' => 'rtf',
+ 'application/sbml+xml' => 'sbml',
+ 'application/scvp-cv-request' => 'scq',
+ 'application/scvp-cv-response' => 'scs',
+ 'application/scvp-vp-request' => 'spq',
+ 'application/scvp-vp-response' => 'spp',
+ 'application/sdp' => 'sdp',
+ 'application/set-payment-initiation' => 'setpay',
+ 'application/set-registration-initiation' => 'setreg',
+ 'application/shf+xml' => 'shf',
+ 'application/smil+xml' => 'smi',
+ 'application/sparql-query' => 'rq',
+ 'application/sparql-results+xml' => 'srx',
+ 'application/srgs' => 'gram',
+ 'application/srgs+xml' => 'grxml',
+ 'application/sru+xml' => 'sru',
+ 'application/ssml+xml' => 'ssml',
+ 'application/tei+xml' => 'tei',
+ 'application/thraud+xml' => 'tfi',
+ 'application/timestamped-data' => 'tsd',
+ 'application/vnd.3gpp.pic-bw-large' => 'plb',
+ 'application/vnd.3gpp.pic-bw-small' => 'psb',
+ 'application/vnd.3gpp.pic-bw-var' => 'pvb',
+ 'application/vnd.3gpp2.tcap' => 'tcap',
+ 'application/vnd.3m.post-it-notes' => 'pwn',
+ 'application/vnd.accpac.simply.aso' => 'aso',
+ 'application/vnd.accpac.simply.imp' => 'imp',
+ 'application/vnd.acucobol' => 'acu',
+ 'application/vnd.acucorp' => 'atc',
+ 'application/vnd.adobe.air-application-installer-package+zip' => 'air',
+ 'application/vnd.adobe.fxp' => 'fxp',
+ 'application/vnd.adobe.xdp+xml' => 'xdp',
+ 'application/vnd.adobe.xfdf' => 'xfdf',
+ 'application/vnd.ahead.space' => 'ahead',
+ 'application/vnd.airzip.filesecure.azf' => 'azf',
+ 'application/vnd.airzip.filesecure.azs' => 'azs',
+ 'application/vnd.amazon.ebook' => 'azw',
+ 'application/vnd.americandynamics.acc' => 'acc',
+ 'application/vnd.amiga.ami' => 'ami',
+ 'application/vnd.android.package-archive' => 'apk',
+ 'application/vnd.anser-web-certificate-issue-initiation' => 'cii',
+ 'application/vnd.anser-web-funds-transfer-initiation' => 'fti',
+ 'application/vnd.antix.game-component' => 'atx',
+ 'application/vnd.apple.installer+xml' => 'mpkg',
+ 'application/vnd.apple.mpegurl' => 'm3u8',
+ 'application/vnd.aristanetworks.swi' => 'swi',
+ 'application/vnd.astraea-software.iota' => 'iota',
+ 'application/vnd.audiograph' => 'aep',
+ 'application/vnd.blueice.multipass' => 'mpm',
+ 'application/vnd.bmi' => 'bmi',
+ 'application/vnd.businessobjects' => 'rep',
+ 'application/vnd.chemdraw+xml' => 'cdxml',
+ 'application/vnd.chipnuts.karaoke-mmd' => 'mmd',
+ 'application/vnd.cinderella' => 'cdy',
+ 'application/vnd.claymore' => 'cla',
+ 'application/vnd.cloanto.rp9' => 'rp9',
+ 'application/vnd.clonk.c4group' => 'c4g',
+ 'application/vnd.cluetrust.cartomobile-config' => 'c11amc',
+ 'application/vnd.cluetrust.cartomobile-config-pkg' => 'c11amz',
+ 'application/vnd.commonspace' => 'csp',
+ 'application/vnd.contact.cmsg' => 'cdbcmsg',
+ 'application/vnd.cosmocaller' => 'cmc',
+ 'application/vnd.crick.clicker' => 'clkx',
+ 'application/vnd.crick.clicker.keyboard' => 'clkk',
+ 'application/vnd.crick.clicker.palette' => 'clkp',
+ 'application/vnd.crick.clicker.template' => 'clkt',
+ 'application/vnd.crick.clicker.wordbank' => 'clkw',
+ 'application/vnd.criticaltools.wbs+xml' => 'wbs',
+ 'application/vnd.ctc-posml' => 'pml',
+ 'application/vnd.cups-ppd' => 'ppd',
+ 'application/vnd.curl.car' => 'car',
+ 'application/vnd.curl.pcurl' => 'pcurl',
+ 'application/vnd.data-vision.rdz' => 'rdz',
+ 'application/vnd.dece.data' => 'uvf',
+ 'application/vnd.dece.ttml+xml' => 'uvt',
+ 'application/vnd.dece.unspecified' => 'uvx',
+ 'application/vnd.dece.zip' => 'uvz',
+ 'application/vnd.denovo.fcselayout-link' => 'fe_launch',
+ 'application/vnd.dna' => 'dna',
+ 'application/vnd.dolby.mlp' => 'mlp',
+ 'application/vnd.dpgraph' => 'dpg',
+ 'application/vnd.dreamfactory' => 'dfac',
+ 'application/vnd.dvb.ait' => 'ait',
+ 'application/vnd.dvb.service' => 'svc',
+ 'application/vnd.dynageo' => 'geo',
+ 'application/vnd.ecowin.chart' => 'mag',
+ 'application/vnd.enliven' => 'nml',
+ 'application/vnd.epson.esf' => 'esf',
+ 'application/vnd.epson.msf' => 'msf',
+ 'application/vnd.epson.quickanime' => 'qam',
+ 'application/vnd.epson.salt' => 'slt',
+ 'application/vnd.epson.ssf' => 'ssf',
+ 'application/vnd.eszigno3+xml' => 'es3',
+ 'application/vnd.ezpix-album' => 'ez2',
+ 'application/vnd.ezpix-package' => 'ez3',
+ 'application/vnd.fdf' => 'fdf',
+ 'application/vnd.fdsn.mseed' => 'mseed',
+ 'application/vnd.fdsn.seed' => 'seed',
+ 'application/vnd.flographit' => 'gph',
+ 'application/vnd.fluxtime.clip' => 'ftc',
+ 'application/vnd.framemaker' => 'fm',
+ 'application/vnd.frogans.fnc' => 'fnc',
+ 'application/vnd.frogans.ltf' => 'ltf',
+ 'application/vnd.fsc.weblaunch' => 'fsc',
+ 'application/vnd.fujitsu.oasys' => 'oas',
+ 'application/vnd.fujitsu.oasys2' => 'oa2',
+ 'application/vnd.fujitsu.oasys3' => 'oa3',
+ 'application/vnd.fujitsu.oasysgp' => 'fg5',
+ 'application/vnd.fujitsu.oasysprs' => 'bh2',
+ 'application/vnd.fujixerox.ddd' => 'ddd',
+ 'application/vnd.fujixerox.docuworks' => 'xdw',
+ 'application/vnd.fujixerox.docuworks.binder' => 'xbd',
+ 'application/vnd.fuzzysheet' => 'fzs',
+ 'application/vnd.genomatix.tuxedo' => 'txd',
+ 'application/vnd.geogebra.file' => 'ggb',
+ 'application/vnd.geogebra.tool' => 'ggt',
+ 'application/vnd.geometry-explorer' => 'gex',
+ 'application/vnd.geonext' => 'gxt',
+ 'application/vnd.geoplan' => 'g2w',
+ 'application/vnd.geospace' => 'g3w',
+ 'application/vnd.gmx' => 'gmx',
+ 'application/vnd.google-earth.kml+xml' => 'kml',
+ 'application/vnd.google-earth.kmz' => 'kmz',
+ 'application/vnd.grafeq' => 'gqf',
+ 'application/vnd.groove-account' => 'gac',
+ 'application/vnd.groove-help' => 'ghf',
+ 'application/vnd.groove-identity-message' => 'gim',
+ 'application/vnd.groove-injector' => 'grv',
+ 'application/vnd.groove-tool-message' => 'gtm',
+ 'application/vnd.groove-tool-template' => 'tpl',
+ 'application/vnd.groove-vcard' => 'vcg',
+ 'application/vnd.hal+xml' => 'hal',
+ 'application/vnd.handheld-entertainment+xml' => 'zmm',
+ 'application/vnd.hbci' => 'hbci',
+ 'application/vnd.hhe.lesson-player' => 'les',
+ 'application/vnd.hp-hpgl' => 'hpgl',
+ 'application/vnd.hp-hpid' => 'hpid',
+ 'application/vnd.hp-hps' => 'hps',
+ 'application/vnd.hp-jlyt' => 'jlt',
+ 'application/vnd.hp-pcl' => 'pcl',
+ 'application/vnd.hp-pclxl' => 'pclxl',
+ 'application/vnd.hydrostatix.sof-data' => 'sfd-hdstx',
+ 'application/vnd.hzn-3d-crossword' => 'x3d',
+ 'application/vnd.ibm.minipay' => 'mpy',
+ 'application/vnd.ibm.modcap' => 'afp',
+ 'application/vnd.ibm.rights-management' => 'irm',
+ 'application/vnd.ibm.secure-container' => 'sc',
+ 'application/vnd.iccprofile' => 'icc',
+ 'application/vnd.igloader' => 'igl',
+ 'application/vnd.immervision-ivp' => 'ivp',
+ 'application/vnd.immervision-ivu' => 'ivu',
+ 'application/vnd.insors.igm' => 'igm',
+ 'application/vnd.intercon.formnet' => 'xpw',
+ 'application/vnd.intergeo' => 'i2g',
+ 'application/vnd.intu.qbo' => 'qbo',
+ 'application/vnd.intu.qfx' => 'qfx',
+ 'application/vnd.ipunplugged.rcprofile' => 'rcprofile',
+ 'application/vnd.irepository.package+xml' => 'irp',
+ 'application/vnd.is-xpr' => 'xpr',
+ 'application/vnd.isac.fcs' => 'fcs',
+ 'application/vnd.jam' => 'jam',
+ 'application/vnd.jcp.javame.midlet-rms' => 'rms',
+ 'application/vnd.jisp' => 'jisp',
+ 'application/vnd.joost.joda-archive' => 'joda',
+ 'application/vnd.kahootz' => 'ktz',
+ 'application/vnd.kde.karbon' => 'karbon',
+ 'application/vnd.kde.kchart' => 'chrt',
+ 'application/vnd.kde.kformula' => 'kfo',
+ 'application/vnd.kde.kivio' => 'flw',
+ 'application/vnd.kde.kontour' => 'kon',
+ 'application/vnd.kde.kpresenter' => 'kpr',
+ 'application/vnd.kde.kspread' => 'ksp',
+ 'application/vnd.kde.kword' => 'kwd',
+ 'application/vnd.kenameaapp' => 'htke',
+ 'application/vnd.kidspiration' => 'kia',
+ 'application/vnd.kinar' => 'kne',
+ 'application/vnd.koan' => 'skp',
+ 'application/vnd.kodak-descriptor' => 'sse',
+ 'application/vnd.las.las+xml' => 'lasxml',
+ 'application/vnd.llamagraphics.life-balance.desktop' => 'lbd',
+ 'application/vnd.llamagraphics.life-balance.exchange+xml' => 'lbe',
+ 'application/vnd.lotus-1-2-3' => '123',
+ 'application/vnd.lotus-approach' => 'apr',
+ 'application/vnd.lotus-freelance' => 'pre',
+ 'application/vnd.lotus-notes' => 'nsf',
+ 'application/vnd.lotus-organizer' => 'org',
+ 'application/vnd.lotus-screencam' => 'scm',
+ 'application/vnd.lotus-wordpro' => 'lwp',
+ 'application/vnd.macports.portpkg' => 'portpkg',
+ 'application/vnd.mcd' => 'mcd',
+ 'application/vnd.medcalcdata' => 'mc1',
+ 'application/vnd.mediastation.cdkey' => 'cdkey',
+ 'application/vnd.mfer' => 'mwf',
+ 'application/vnd.mfmp' => 'mfm',
+ 'application/vnd.micrografx.flo' => 'flo',
+ 'application/vnd.micrografx.igx' => 'igx',
+ 'application/vnd.mif' => 'mif',
+ 'application/vnd.mobius.daf' => 'daf',
+ 'application/vnd.mobius.dis' => 'dis',
+ 'application/vnd.mobius.mbk' => 'mbk',
+ 'application/vnd.mobius.mqy' => 'mqy',
+ 'application/vnd.mobius.msl' => 'msl',
+ 'application/vnd.mobius.plc' => 'plc',
+ 'application/vnd.mobius.txf' => 'txf',
+ 'application/vnd.mophun.application' => 'mpn',
+ 'application/vnd.mophun.certificate' => 'mpc',
+ 'application/vnd.mozilla.xul+xml' => 'xul',
+ 'application/vnd.ms-artgalry' => 'cil',
+ 'application/vnd.ms-cab-compressed' => 'cab',
+ 'application/vnd.ms-excel' => 'xls',
+ 'application/vnd.ms-excel.addin.macroenabled.12' => 'xlam',
+ 'application/vnd.ms-excel.sheet.binary.macroenabled.12' => 'xlsb',
+ 'application/vnd.ms-excel.sheet.macroenabled.12' => 'xlsm',
+ 'application/vnd.ms-excel.template.macroenabled.12' => 'xltm',
+ 'application/vnd.ms-fontobject' => 'eot',
+ 'application/vnd.ms-htmlhelp' => 'chm',
+ 'application/vnd.ms-ims' => 'ims',
+ 'application/vnd.ms-lrm' => 'lrm',
+ 'application/vnd.ms-officetheme' => 'thmx',
+ 'application/vnd.ms-pki.seccat' => 'cat',
+ 'application/vnd.ms-pki.stl' => 'stl',
+ 'application/vnd.ms-powerpoint' => 'ppt',
+ 'application/vnd.ms-powerpoint.addin.macroenabled.12' => 'ppam',
+ 'application/vnd.ms-powerpoint.presentation.macroenabled.12' => 'pptm',
+ 'application/vnd.ms-powerpoint.slide.macroenabled.12' => 'sldm',
+ 'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => 'ppsm',
+ 'application/vnd.ms-powerpoint.template.macroenabled.12' => 'potm',
+ 'application/vnd.ms-project' => 'mpp',
+ 'application/vnd.ms-word.document.macroenabled.12' => 'docm',
+ 'application/vnd.ms-word.template.macroenabled.12' => 'dotm',
+ 'application/vnd.ms-works' => 'wps',
+ 'application/vnd.ms-wpl' => 'wpl',
+ 'application/vnd.ms-xpsdocument' => 'xps',
+ 'application/vnd.mseq' => 'mseq',
+ 'application/vnd.musician' => 'mus',
+ 'application/vnd.muvee.style' => 'msty',
+ 'application/vnd.mynfc' => 'taglet',
+ 'application/vnd.neurolanguage.nlu' => 'nlu',
+ 'application/vnd.noblenet-directory' => 'nnd',
+ 'application/vnd.noblenet-sealer' => 'nns',
+ 'application/vnd.noblenet-web' => 'nnw',
+ 'application/vnd.nokia.n-gage.data' => 'ngdat',
+ 'application/vnd.nokia.n-gage.symbian.install' => 'n-gage',
+ 'application/vnd.nokia.radio-preset' => 'rpst',
+ 'application/vnd.nokia.radio-presets' => 'rpss',
+ 'application/vnd.novadigm.edm' => 'edm',
+ 'application/vnd.novadigm.edx' => 'edx',
+ 'application/vnd.novadigm.ext' => 'ext',
+ 'application/vnd.oasis.opendocument.chart' => 'odc',
+ 'application/vnd.oasis.opendocument.chart-template' => 'otc',
+ 'application/vnd.oasis.opendocument.database' => 'odb',
+ 'application/vnd.oasis.opendocument.formula' => 'odf',
+ 'application/vnd.oasis.opendocument.formula-template' => 'odft',
+ 'application/vnd.oasis.opendocument.graphics' => 'odg',
+ 'application/vnd.oasis.opendocument.graphics-template' => 'otg',
+ 'application/vnd.oasis.opendocument.image' => 'odi',
+ 'application/vnd.oasis.opendocument.image-template' => 'oti',
+ 'application/vnd.oasis.opendocument.presentation' => 'odp',
+ 'application/vnd.oasis.opendocument.presentation-template' => 'otp',
+ 'application/vnd.oasis.opendocument.spreadsheet' => 'ods',
+ 'application/vnd.oasis.opendocument.spreadsheet-template' => 'ots',
+ 'application/vnd.oasis.opendocument.text' => 'odt',
+ 'application/vnd.oasis.opendocument.text-master' => 'odm',
+ 'application/vnd.oasis.opendocument.text-template' => 'ott',
+ 'application/vnd.oasis.opendocument.text-web' => 'oth',
+ 'application/vnd.olpc-sugar' => 'xo',
+ 'application/vnd.oma.dd2+xml' => 'dd2',
+ 'application/vnd.openofficeorg.extension' => 'oxt',
+ 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
+ 'application/vnd.openxmlformats-officedocument.presentationml.slide' => 'sldx',
+ 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'ppsx',
+ 'application/vnd.openxmlformats-officedocument.presentationml.template' => 'potx',
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'xltx',
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'dotx',
+ 'application/vnd.osgeo.mapguide.package' => 'mgp',
+ 'application/vnd.osgi.dp' => 'dp',
+ 'application/vnd.palm' => 'pdb',
+ 'application/vnd.pawaafile' => 'paw',
+ 'application/vnd.pg.format' => 'str',
+ 'application/vnd.pg.osasli' => 'ei6',
+ 'application/vnd.picsel' => 'efif',
+ 'application/vnd.pmi.widget' => 'wg',
+ 'application/vnd.pocketlearn' => 'plf',
+ 'application/vnd.powerbuilder6' => 'pbd',
+ 'application/vnd.previewsystems.box' => 'box',
+ 'application/vnd.proteus.magazine' => 'mgz',
+ 'application/vnd.publishare-delta-tree' => 'qps',
+ 'application/vnd.pvi.ptid1' => 'ptid',
+ 'application/vnd.quark.quarkxpress' => 'qxd',
+ 'application/vnd.realvnc.bed' => 'bed',
+ 'application/vnd.recordare.musicxml' => 'mxl',
+ 'application/vnd.recordare.musicxml+xml' => 'musicxml',
+ 'application/vnd.rig.cryptonote' => 'cryptonote',
+ 'application/vnd.rim.cod' => 'cod',
+ 'application/vnd.rn-realmedia' => 'rm',
+ 'application/vnd.route66.link66+xml' => 'link66',
+ 'application/vnd.sailingtracker.track' => 'st',
+ 'application/vnd.seemail' => 'see',
+ 'application/vnd.sema' => 'sema',
+ 'application/vnd.semd' => 'semd',
+ 'application/vnd.semf' => 'semf',
+ 'application/vnd.shana.informed.formdata' => 'ifm',
+ 'application/vnd.shana.informed.formtemplate' => 'itp',
+ 'application/vnd.shana.informed.interchange' => 'iif',
+ 'application/vnd.shana.informed.package' => 'ipk',
+ 'application/vnd.simtech-mindmapper' => 'twd',
+ 'application/vnd.smaf' => 'mmf',
+ 'application/vnd.smart.teacher' => 'teacher',
+ 'application/vnd.solent.sdkm+xml' => 'sdkm',
+ 'application/vnd.spotfire.dxp' => 'dxp',
+ 'application/vnd.spotfire.sfs' => 'sfs',
+ 'application/vnd.stardivision.calc' => 'sdc',
+ 'application/vnd.stardivision.draw' => 'sda',
+ 'application/vnd.stardivision.impress' => 'sdd',
+ 'application/vnd.stardivision.math' => 'smf',
+ 'application/vnd.stardivision.writer' => 'sdw',
+ 'application/vnd.stardivision.writer-global' => 'sgl',
+ 'application/vnd.stepmania.package' => 'smzip',
+ 'application/vnd.stepmania.stepchart' => 'sm',
+ 'application/vnd.sun.xml.calc' => 'sxc',
+ 'application/vnd.sun.xml.calc.template' => 'stc',
+ 'application/vnd.sun.xml.draw' => 'sxd',
+ 'application/vnd.sun.xml.draw.template' => 'std',
+ 'application/vnd.sun.xml.impress' => 'sxi',
+ 'application/vnd.sun.xml.impress.template' => 'sti',
+ 'application/vnd.sun.xml.math' => 'sxm',
+ 'application/vnd.sun.xml.writer' => 'sxw',
+ 'application/vnd.sun.xml.writer.global' => 'sxg',
+ 'application/vnd.sun.xml.writer.template' => 'stw',
+ 'application/vnd.sus-calendar' => 'sus',
+ 'application/vnd.svd' => 'svd',
+ 'application/vnd.symbian.install' => 'sis',
+ 'application/vnd.syncml+xml' => 'xsm',
+ 'application/vnd.syncml.dm+wbxml' => 'bdm',
+ 'application/vnd.syncml.dm+xml' => 'xdm',
+ 'application/vnd.tao.intent-module-archive' => 'tao',
+ 'application/vnd.tcpdump.pcap' => 'pcap',
+ 'application/vnd.tmobile-livetv' => 'tmo',
+ 'application/vnd.trid.tpt' => 'tpt',
+ 'application/vnd.triscape.mxs' => 'mxs',
+ 'application/vnd.trueapp' => 'tra',
+ 'application/vnd.ufdl' => 'ufd',
+ 'application/vnd.uiq.theme' => 'utz',
+ 'application/vnd.umajin' => 'umj',
+ 'application/vnd.unity' => 'unityweb',
+ 'application/vnd.uoml+xml' => 'uoml',
+ 'application/vnd.vcx' => 'vcx',
+ 'application/vnd.visio' => 'vsd',
+ 'application/vnd.visionary' => 'vis',
+ 'application/vnd.vsf' => 'vsf',
+ 'application/vnd.wap.wbxml' => 'wbxml',
+ 'application/vnd.wap.wmlc' => 'wmlc',
+ 'application/vnd.wap.wmlscriptc' => 'wmlsc',
+ 'application/vnd.webturbo' => 'wtb',
+ 'application/vnd.wolfram.player' => 'nbp',
+ 'application/vnd.wordperfect' => 'wpd',
+ 'application/vnd.wqd' => 'wqd',
+ 'application/vnd.wt.stf' => 'stf',
+ 'application/vnd.xara' => 'xar',
+ 'application/vnd.xfdl' => 'xfdl',
+ 'application/vnd.yamaha.hv-dic' => 'hvd',
+ 'application/vnd.yamaha.hv-script' => 'hvs',
+ 'application/vnd.yamaha.hv-voice' => 'hvp',
+ 'application/vnd.yamaha.openscoreformat' => 'osf',
+ 'application/vnd.yamaha.openscoreformat.osfpvg+xml' => 'osfpvg',
+ 'application/vnd.yamaha.smaf-audio' => 'saf',
+ 'application/vnd.yamaha.smaf-phrase' => 'spf',
+ 'application/vnd.yellowriver-custom-menu' => 'cmp',
+ 'application/vnd.zul' => 'zir',
+ 'application/vnd.zzazz.deck+xml' => 'zaz',
+ 'application/voicexml+xml' => 'vxml',
+ 'application/widget' => 'wgt',
+ 'application/winhlp' => 'hlp',
+ 'application/wsdl+xml' => 'wsdl',
+ 'application/wspolicy+xml' => 'wspolicy',
+ 'application/x-7z-compressed' => '7z',
+ 'application/x-abiword' => 'abw',
+ 'application/x-ace-compressed' => 'ace',
+ 'application/x-authorware-bin' => 'aab',
+ 'application/x-authorware-map' => 'aam',
+ 'application/x-authorware-seg' => 'aas',
+ 'application/x-bcpio' => 'bcpio',
+ 'application/x-bittorrent' => 'torrent',
+ 'application/x-bzip' => 'bz',
+ 'application/x-bzip2' => 'bz2',
+ 'application/x-cdlink' => 'vcd',
+ 'application/x-chat' => 'chat',
+ 'application/x-chess-pgn' => 'pgn',
+ 'application/x-cpio' => 'cpio',
+ 'application/x-csh' => 'csh',
+ 'application/x-debian-package' => 'deb',
+ 'application/x-director' => 'dir',
+ 'application/x-doom' => 'wad',
+ 'application/x-dtbncx+xml' => 'ncx',
+ 'application/x-dtbook+xml' => 'dtb',
+ 'application/x-dtbresource+xml' => 'res',
+ 'application/x-dvi' => 'dvi',
+ 'application/x-font-bdf' => 'bdf',
+ 'application/x-font-ghostscript' => 'gsf',
+ 'application/x-font-linux-psf' => 'psf',
+ 'application/x-font-otf' => 'otf',
+ 'application/x-font-pcf' => 'pcf',
+ 'application/x-font-snf' => 'snf',
+ 'application/x-font-ttf' => 'ttf',
+ 'application/x-font-type1' => 'pfa',
+ 'application/x-font-woff' => 'woff',
+ 'application/x-futuresplash' => 'spl',
+ 'application/x-gnumeric' => 'gnumeric',
+ 'application/x-gtar' => 'gtar',
+ 'application/x-hdf' => 'hdf',
+ 'application/x-java-jnlp-file' => 'jnlp',
+ 'application/x-latex' => 'latex',
+ 'application/x-mobipocket-ebook' => 'prc',
+ 'application/x-ms-application' => 'application',
+ 'application/x-ms-wmd' => 'wmd',
+ 'application/x-ms-wmz' => 'wmz',
+ 'application/x-ms-xbap' => 'xbap',
+ 'application/x-msaccess' => 'mdb',
+ 'application/x-msbinder' => 'obd',
+ 'application/x-mscardfile' => 'crd',
+ 'application/x-msclip' => 'clp',
+ 'application/x-msdownload' => 'exe',
+ 'application/x-msmediaview' => 'mvb',
+ 'application/x-msmetafile' => 'wmf',
+ 'application/x-msmoney' => 'mny',
+ 'application/x-mspublisher' => 'pub',
+ 'application/x-msschedule' => 'scd',
+ 'application/x-msterminal' => 'trm',
+ 'application/x-mswrite' => 'wri',
+ 'application/x-netcdf' => 'nc',
+ 'application/x-pkcs12' => 'p12',
+ 'application/x-pkcs7-certificates' => 'p7b',
+ 'application/x-pkcs7-certreqresp' => 'p7r',
+ 'application/x-rar-compressed' => 'rar',
+ 'application/x-sh' => 'sh',
+ 'application/x-shar' => 'shar',
+ 'application/x-shockwave-flash' => 'swf',
+ 'application/x-silverlight-app' => 'xap',
+ 'application/x-stuffit' => 'sit',
+ 'application/x-stuffitx' => 'sitx',
+ 'application/x-sv4cpio' => 'sv4cpio',
+ 'application/x-sv4crc' => 'sv4crc',
+ 'application/x-tar' => 'tar',
+ 'application/x-tcl' => 'tcl',
+ 'application/x-tex' => 'tex',
+ 'application/x-tex-tfm' => 'tfm',
+ 'application/x-texinfo' => 'texinfo',
+ 'application/x-ustar' => 'ustar',
+ 'application/x-wais-source' => 'src',
+ 'application/x-x509-ca-cert' => 'der',
+ 'application/x-xfig' => 'fig',
+ 'application/x-xpinstall' => 'xpi',
+ 'application/xcap-diff+xml' => 'xdf',
+ 'application/xenc+xml' => 'xenc',
+ 'application/xhtml+xml' => 'xhtml',
+ 'application/xml' => 'xml',
+ 'application/xml-dtd' => 'dtd',
+ 'application/xop+xml' => 'xop',
+ 'application/xslt+xml' => 'xslt',
+ 'application/xspf+xml' => 'xspf',
+ 'application/xv+xml' => 'mxml',
+ 'application/yang' => 'yang',
+ 'application/yin+xml' => 'yin',
+ 'application/zip' => 'zip',
+ 'audio/adpcm' => 'adp',
+ 'audio/basic' => 'au',
+ 'audio/midi' => 'mid',
+ 'audio/mp4' => 'mp4a',
+ 'audio/mpeg' => 'mpga',
+ 'audio/ogg' => 'oga',
+ 'audio/vnd.dece.audio' => 'uva',
+ 'audio/vnd.digital-winds' => 'eol',
+ 'audio/vnd.dra' => 'dra',
+ 'audio/vnd.dts' => 'dts',
+ 'audio/vnd.dts.hd' => 'dtshd',
+ 'audio/vnd.lucent.voice' => 'lvp',
+ 'audio/vnd.ms-playready.media.pya' => 'pya',
+ 'audio/vnd.nuera.ecelp4800' => 'ecelp4800',
+ 'audio/vnd.nuera.ecelp7470' => 'ecelp7470',
+ 'audio/vnd.nuera.ecelp9600' => 'ecelp9600',
+ 'audio/vnd.rip' => 'rip',
+ 'audio/webm' => 'weba',
+ 'audio/x-aac' => 'aac',
+ 'audio/x-aiff' => 'aif',
+ 'audio/x-mpegurl' => 'm3u',
+ 'audio/x-ms-wax' => 'wax',
+ 'audio/x-ms-wma' => 'wma',
+ 'audio/x-pn-realaudio' => 'ram',
+ 'audio/x-pn-realaudio-plugin' => 'rmp',
+ 'audio/x-wav' => 'wav',
+ 'chemical/x-cdx' => 'cdx',
+ 'chemical/x-cif' => 'cif',
+ 'chemical/x-cmdf' => 'cmdf',
+ 'chemical/x-cml' => 'cml',
+ 'chemical/x-csml' => 'csml',
+ 'chemical/x-xyz' => 'xyz',
+ 'image/bmp' => 'bmp',
+ 'image/cgm' => 'cgm',
+ 'image/g3fax' => 'g3',
+ 'image/gif' => 'gif',
+ 'image/ief' => 'ief',
+ 'image/jpeg' => 'jpeg',
+ 'image/ktx' => 'ktx',
+ 'image/png' => 'png',
+ 'image/prs.btif' => 'btif',
+ 'image/svg+xml' => 'svg',
+ 'image/tiff' => 'tiff',
+ 'image/vnd.adobe.photoshop' => 'psd',
+ 'image/vnd.dece.graphic' => 'uvi',
+ 'image/vnd.dvb.subtitle' => 'sub',
+ 'image/vnd.djvu' => 'djvu',
+ 'image/vnd.dwg' => 'dwg',
+ 'image/vnd.dxf' => 'dxf',
+ 'image/vnd.fastbidsheet' => 'fbs',
+ 'image/vnd.fpx' => 'fpx',
+ 'image/vnd.fst' => 'fst',
+ 'image/vnd.fujixerox.edmics-mmr' => 'mmr',
+ 'image/vnd.fujixerox.edmics-rlc' => 'rlc',
+ 'image/vnd.ms-modi' => 'mdi',
+ 'image/vnd.net-fpx' => 'npx',
+ 'image/vnd.wap.wbmp' => 'wbmp',
+ 'image/vnd.xiff' => 'xif',
+ 'image/webp' => 'webp',
+ 'image/x-cmu-raster' => 'ras',
+ 'image/x-cmx' => 'cmx',
+ 'image/x-freehand' => 'fh',
+ 'image/x-icon' => 'ico',
+ 'image/x-pcx' => 'pcx',
+ 'image/x-pict' => 'pic',
+ 'image/x-portable-anymap' => 'pnm',
+ 'image/x-portable-bitmap' => 'pbm',
+ 'image/x-portable-graymap' => 'pgm',
+ 'image/x-portable-pixmap' => 'ppm',
+ 'image/x-rgb' => 'rgb',
+ 'image/x-xbitmap' => 'xbm',
+ 'image/x-xpixmap' => 'xpm',
+ 'image/x-xwindowdump' => 'xwd',
+ 'message/rfc822' => 'eml',
+ 'model/iges' => 'igs',
+ 'model/mesh' => 'msh',
+ 'model/vnd.collada+xml' => 'dae',
+ 'model/vnd.dwf' => 'dwf',
+ 'model/vnd.gdl' => 'gdl',
+ 'model/vnd.gtw' => 'gtw',
+ 'model/vnd.mts' => 'mts',
+ 'model/vnd.vtu' => 'vtu',
+ 'model/vrml' => 'wrl',
+ 'text/calendar' => 'ics',
+ 'text/css' => 'css',
+ 'text/csv' => 'csv',
+ 'text/html' => 'html',
+ 'text/n3' => 'n3',
+ 'text/plain' => 'txt',
+ 'text/prs.lines.tag' => 'dsc',
+ 'text/richtext' => 'rtx',
+ 'text/sgml' => 'sgml',
+ 'text/tab-separated-values' => 'tsv',
+ 'text/troff' => 't',
+ 'text/turtle' => 'ttl',
+ 'text/uri-list' => 'uri',
+ 'text/vcard' => 'vcard',
+ 'text/vnd.curl' => 'curl',
+ 'text/vnd.curl.dcurl' => 'dcurl',
+ 'text/vnd.curl.scurl' => 'scurl',
+ 'text/vnd.curl.mcurl' => 'mcurl',
+ 'text/vnd.dvb.subtitle' => 'sub',
+ 'text/vnd.fly' => 'fly',
+ 'text/vnd.fmi.flexstor' => 'flx',
+ 'text/vnd.graphviz' => 'gv',
+ 'text/vnd.in3d.3dml' => '3dml',
+ 'text/vnd.in3d.spot' => 'spot',
+ 'text/vnd.sun.j2me.app-descriptor' => 'jad',
+ 'text/vnd.wap.wml' => 'wml',
+ 'text/vnd.wap.wmlscript' => 'wmls',
+ 'text/x-asm' => 's',
+ 'text/x-c' => 'c',
+ 'text/x-fortran' => 'f',
+ 'text/x-pascal' => 'p',
+ 'text/x-java-source' => 'java',
+ 'text/x-setext' => 'etx',
+ 'text/x-uuencode' => 'uu',
+ 'text/x-vcalendar' => 'vcs',
+ 'text/x-vcard' => 'vcf',
+ 'video/3gpp' => '3gp',
+ 'video/3gpp2' => '3g2',
+ 'video/h261' => 'h261',
+ 'video/h263' => 'h263',
+ 'video/h264' => 'h264',
+ 'video/jpeg' => 'jpgv',
+ 'video/jpm' => 'jpm',
+ 'video/mj2' => 'mj2',
+ 'video/mp4' => 'mp4',
+ 'video/mpeg' => 'mpeg',
+ 'video/ogg' => 'ogv',
+ 'video/quicktime' => 'qt',
+ 'video/vnd.dece.hd' => 'uvh',
+ 'video/vnd.dece.mobile' => 'uvm',
+ 'video/vnd.dece.pd' => 'uvp',
+ 'video/vnd.dece.sd' => 'uvs',
+ 'video/vnd.dece.video' => 'uvv',
+ 'video/vnd.dvb.file' => 'dvb',
+ 'video/vnd.fvt' => 'fvt',
+ 'video/vnd.mpegurl' => 'mxu',
+ 'video/vnd.ms-playready.media.pyv' => 'pyv',
+ 'video/vnd.uvvu.mp4' => 'uvu',
+ 'video/vnd.vivo' => 'viv',
+ 'video/webm' => 'webm',
+ 'video/x-f4v' => 'f4v',
+ 'video/x-fli' => 'fli',
+ 'video/x-flv' => 'flv',
+ 'video/x-m4v' => 'm4v',
+ 'video/x-ms-asf' => 'asf',
+ 'video/x-ms-wm' => 'wm',
+ 'video/x-ms-wmv' => 'wmv',
+ 'video/x-ms-wmx' => 'wmx',
+ 'video/x-ms-wvx' => 'wvx',
+ 'video/x-msvideo' => 'avi',
+ 'video/x-sgi-movie' => 'movie',
+ 'x-conference/x-cooltalk' => 'ice',
+ );
+
+ /**
+ * Returns the extension based on the mime type.
+ *
+ * If the mime type is unknown, returns null.
+ *
+ * @return string|null The guessed extension or null if it cannot be guessed
+ */
+ public function guess($mimeType)
+ {
+ return isset($this->defaultExtensions[$mimeType]) ? $this->defaultExtensions[$mimeType] : null;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesser.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesser.php
new file mode 100755
index 000000000..d73a093df
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesser.php
@@ -0,0 +1,121 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\MimeType;
+
+use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
+use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
+
+/**
+ * A singleton mime type guesser.
+ *
+ * By default, all mime type guessers provided by the framework are installed
+ * (if available on the current OS/PHP setup). You can register custom
+ * guessers by calling the register() method on the singleton instance.
+ *
+ *
+ * $guesser = MimeTypeGuesser::getInstance();
+ * $guesser->register(new MyCustomMimeTypeGuesser());
+ *
+ *
+ * The last registered guesser is preferred over previously registered ones.
+ *
+ * @author Bernhard Schussek
+ */
+class MimeTypeGuesser implements MimeTypeGuesserInterface
+{
+ /**
+ * The singleton instance
+ * @var MimeTypeGuesser
+ */
+ static private $instance = null;
+
+ /**
+ * All registered MimeTypeGuesserInterface instances
+ * @var array
+ */
+ protected $guessers = array();
+
+ /**
+ * Returns the singleton instance
+ *
+ * @return MimeTypeGuesser
+ */
+ static public function getInstance()
+ {
+ if (null === self::$instance) {
+ self::$instance = new self();
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * Registers all natively provided mime type guessers
+ */
+ private function __construct()
+ {
+ if (FileBinaryMimeTypeGuesser::isSupported()) {
+ $this->register(new FileBinaryMimeTypeGuesser());
+ }
+
+ if (FileinfoMimeTypeGuesser::isSupported()) {
+ $this->register(new FileinfoMimeTypeGuesser());
+ }
+ }
+
+ /**
+ * Registers a new mime type guesser
+ *
+ * When guessing, this guesser is preferred over previously registered ones.
+ *
+ * @param MimeTypeGuesserInterface $guesser
+ */
+ public function register(MimeTypeGuesserInterface $guesser)
+ {
+ array_unshift($this->guessers, $guesser);
+ }
+
+ /**
+ * Tries to guess the mime type of the given file
+ *
+ * The file is passed to each registered mime type guesser in reverse order
+ * of their registration (last registered is queried first). Once a guesser
+ * returns a value that is not NULL, this method terminates and returns the
+ * value.
+ *
+ * @param string $path The path to the file
+ *
+ * @return string The mime type or NULL, if none could be guessed
+ *
+ * @throws FileException If the file does not exist
+ */
+ public function guess($path)
+ {
+ if (!is_file($path)) {
+ throw new FileNotFoundException($path);
+ }
+
+ if (!is_readable($path)) {
+ throw new AccessDeniedException($path);
+ }
+
+ if (!$this->guessers) {
+ throw new \LogicException('Unable to guess the mime type as no guessers are available (Did you enable the php_fileinfo extension?)');
+ }
+
+ foreach ($this->guessers as $guesser) {
+ if (null !== $mimeType = $guesser->guess($path)) {
+ return $mimeType;
+ }
+ }
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesserInterface.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesserInterface.php
new file mode 100755
index 000000000..66178bb95
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/MimeType/MimeTypeGuesserInterface.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File\MimeType;
+
+/**
+ * Guesses the mime type of a file
+ *
+ * @author Bernhard Schussek
+ */
+interface MimeTypeGuesserInterface
+{
+ /**
+ * Guesses the mime type of the file with the given path.
+ *
+ * @param string $path The path to the file
+ *
+ * @return string The mime type or NULL, if none could be guessed
+ *
+ * @throws FileNotFoundException If the file does not exist
+ * @throws AccessDeniedException If the file could not be read
+ */
+ function guess($path);
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/File/UploadedFile.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/UploadedFile.php
new file mode 100755
index 000000000..4e51c5001
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/File/UploadedFile.php
@@ -0,0 +1,223 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\File;
+
+use Symfony\Component\HttpFoundation\File\Exception\FileException;
+use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
+
+/**
+ * A file uploaded through a form.
+ *
+ * @author Bernhard Schussek
+ * @author Florian Eckerstorfer
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class UploadedFile extends File
+{
+ /**
+ * Whether the test mode is activated.
+ *
+ * Local files are used in test mode hence the code should not enforce HTTP uploads.
+ *
+ * @var Boolean
+ */
+ private $test = false;
+
+ /**
+ * The original name of the uploaded file.
+ *
+ * @var string
+ */
+ private $originalName;
+
+ /**
+ * The mime type provided by the uploader.
+ *
+ * @var string
+ */
+ private $mimeType;
+
+ /**
+ * The file size provided by the uploader.
+ *
+ * @var string
+ */
+ private $size;
+
+ /**
+ * The UPLOAD_ERR_XXX constant provided by the uploader.
+ *
+ * @var integer
+ */
+ private $error;
+
+ /**
+ * Accepts the information of the uploaded file as provided by the PHP global $_FILES.
+ *
+ * The file object is only created when the uploaded file is valid (i.e. when the
+ * isValid() method returns true). Otherwise the only methods that could be called
+ * on an UploadedFile instance are:
+ *
+ * * getClientOriginalName,
+ * * getClientMimeType,
+ * * isValid,
+ * * getError.
+ *
+ * Calling any other method on an non-valid instance will cause an unpredictable result.
+ *
+ * @param string $path The full temporary path to the file
+ * @param string $originalName The original file name
+ * @param string $mimeType The type of the file as provided by PHP
+ * @param integer $size The file size
+ * @param integer $error The error constant of the upload (one of PHP's UPLOAD_ERR_XXX constants)
+ * @param Boolean $test Whether the test mode is active
+ *
+ * @throws FileException If file_uploads is disabled
+ * @throws FileNotFoundException If the file does not exist
+ *
+ * @api
+ */
+ public function __construct($path, $originalName, $mimeType = null, $size = null, $error = null, $test = false)
+ {
+ if (!ini_get('file_uploads')) {
+ throw new FileException(sprintf('Unable to create UploadedFile because "file_uploads" is disabled in your php.ini file (%s)', get_cfg_var('cfg_file_path')));
+ }
+
+ $this->originalName = basename($originalName);
+ $this->mimeType = $mimeType ?: 'application/octet-stream';
+ $this->size = $size;
+ $this->error = $error ?: UPLOAD_ERR_OK;
+ $this->test = (Boolean) $test;
+
+ parent::__construct($path, UPLOAD_ERR_OK === $this->error);
+ }
+
+ /**
+ * Returns the original file name.
+ *
+ * It is extracted from the request from which the file has been uploaded.
+ * Then is should not be considered as a safe value.
+ *
+ * @return string|null The original name
+ *
+ * @api
+ */
+ public function getClientOriginalName()
+ {
+ return $this->originalName;
+ }
+
+ /**
+ * Returns the file mime type.
+ *
+ * It is extracted from the request from which the file has been uploaded.
+ * Then is should not be considered as a safe value.
+ *
+ * @return string|null The mime type
+ *
+ * @api
+ */
+ public function getClientMimeType()
+ {
+ return $this->mimeType;
+ }
+
+ /**
+ * Returns the file size.
+ *
+ * It is extracted from the request from which the file has been uploaded.
+ * Then is should not be considered as a safe value.
+ *
+ * @return integer|null The file size
+ *
+ * @api
+ */
+ public function getClientSize()
+ {
+ return $this->size;
+ }
+
+ /**
+ * Returns the upload error.
+ *
+ * If the upload was successful, the constant UPLOAD_ERR_OK is returned.
+ * Otherwise one of the other UPLOAD_ERR_XXX constants is returned.
+ *
+ * @return integer The upload error
+ *
+ * @api
+ */
+ public function getError()
+ {
+ return $this->error;
+ }
+
+ /**
+ * Returns whether the file was uploaded successfully.
+ *
+ * @return Boolean True if no error occurred during uploading
+ *
+ * @api
+ */
+ public function isValid()
+ {
+ return $this->error === UPLOAD_ERR_OK;
+ }
+
+ /**
+ * Moves the file to a new location.
+ *
+ * @param string $directory The destination folder
+ * @param string $name The new file name
+ *
+ * @return File A File object representing the new file
+ *
+ * @throws FileException if the file has not been uploaded via Http
+ *
+ * @api
+ */
+ public function move($directory, $name = null)
+ {
+ if ($this->isValid() && ($this->test || is_uploaded_file($this->getPathname()))) {
+ return parent::move($directory, $name);
+ }
+
+ throw new FileException(sprintf('The file "%s" has not been uploaded via Http', $this->getPathname()));
+ }
+
+ /**
+ * Returns the maximum size of an uploaded file as configured in php.ini
+ *
+ * @return type The maximum size of an uploaded file in bytes
+ */
+ static public function getMaxFilesize()
+ {
+ $max = trim(ini_get('upload_max_filesize'));
+
+ if ('' === $max) {
+ return PHP_INT_MAX;
+ }
+
+ switch (strtolower(substr($max, -1))) {
+ case 'g':
+ $max *= 1024;
+ case 'm':
+ $max *= 1024;
+ case 'k':
+ $max *= 1024;
+ }
+
+ return (integer) $max;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/FileBag.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/FileBag.php
new file mode 100755
index 000000000..702ab84c0
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/FileBag.php
@@ -0,0 +1,158 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+use Symfony\Component\HttpFoundation\File\UploadedFile;
+
+/**
+ * FileBag is a container for HTTP headers.
+ *
+ * @author Fabien Potencier
+ * @author Bulat Shakirzyanov
+ *
+ * @api
+ */
+class FileBag extends ParameterBag
+{
+ static private $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
+
+ /**
+ * Constructor.
+ *
+ * @param array $parameters An array of HTTP files
+ *
+ * @api
+ */
+ public function __construct(array $parameters = array())
+ {
+ $this->replace($parameters);
+ }
+
+ /**
+ * (non-PHPdoc)
+ * @see Symfony\Component\HttpFoundation\ParameterBag::replace()
+ *
+ * @api
+ */
+ public function replace(array $files = array())
+ {
+ $this->parameters = array();
+ $this->add($files);
+ }
+
+ /**
+ * (non-PHPdoc)
+ * @see Symfony\Component\HttpFoundation\ParameterBag::set()
+ *
+ * @api
+ */
+ public function set($key, $value)
+ {
+ if (is_array($value) || $value instanceof UploadedFile) {
+ parent::set($key, $this->convertFileInformation($value));
+ } else {
+ throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.');
+ }
+ }
+
+ /**
+ * (non-PHPdoc)
+ * @see Symfony\Component\HttpFoundation\ParameterBag::add()
+ *
+ * @api
+ */
+ public function add(array $files = array())
+ {
+ foreach ($files as $key => $file) {
+ $this->set($key, $file);
+ }
+ }
+
+ /**
+ * Converts uploaded files to UploadedFile instances.
+ *
+ * @param array|UploadedFile $file A (multi-dimensional) array of uploaded file information
+ *
+ * @return array A (multi-dimensional) array of UploadedFile instances
+ */
+ protected function convertFileInformation($file)
+ {
+ if ($file instanceof UploadedFile) {
+ return $file;
+ }
+
+ $file = $this->fixPhpFilesArray($file);
+ if (is_array($file)) {
+ $keys = array_keys($file);
+ sort($keys);
+
+ if ($keys == self::$fileKeys) {
+ if (UPLOAD_ERR_NO_FILE == $file['error']) {
+ $file = null;
+ } else {
+ $file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['size'], $file['error']);
+ }
+ } else {
+ $file = array_map(array($this, 'convertFileInformation'), $file);
+ }
+ }
+
+ return $file;
+ }
+
+ /**
+ * Fixes a malformed PHP $_FILES array.
+ *
+ * PHP has a bug that the format of the $_FILES array differs, depending on
+ * whether the uploaded file fields had normal field names or array-like
+ * field names ("normal" vs. "parent[child]").
+ *
+ * This method fixes the array to look like the "normal" $_FILES array.
+ *
+ * It's safe to pass an already converted array, in which case this method
+ * just returns the original array unmodified.
+ *
+ * @param array $data
+ *
+ * @return array
+ */
+ protected function fixPhpFilesArray($data)
+ {
+ if (!is_array($data)) {
+ return $data;
+ }
+
+ $keys = array_keys($data);
+ sort($keys);
+
+ if (self::$fileKeys != $keys || !isset($data['name']) || !is_array($data['name'])) {
+ return $data;
+ }
+
+ $files = $data;
+ foreach (self::$fileKeys as $k) {
+ unset($files[$k]);
+ }
+
+ foreach (array_keys($data['name']) as $key) {
+ $files[$key] = $this->fixPhpFilesArray(array(
+ 'error' => $data['error'][$key],
+ 'name' => $data['name'][$key],
+ 'type' => $data['type'][$key],
+ 'tmp_name' => $data['tmp_name'][$key],
+ 'size' => $data['size'][$key]
+ ));
+ }
+
+ return $files;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/HeaderBag.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/HeaderBag.php
new file mode 100755
index 000000000..f614b094f
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/HeaderBag.php
@@ -0,0 +1,306 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * HeaderBag is a container for HTTP headers.
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class HeaderBag
+{
+ protected $headers;
+ protected $cacheControl;
+
+ /**
+ * Constructor.
+ *
+ * @param array $headers An array of HTTP headers
+ *
+ * @api
+ */
+ public function __construct(array $headers = array())
+ {
+ $this->cacheControl = array();
+ $this->headers = array();
+ foreach ($headers as $key => $values) {
+ $this->set($key, $values);
+ }
+ }
+
+ /**
+ * Returns the headers as a string.
+ *
+ * @return string The headers
+ */
+ public function __toString()
+ {
+ if (!$this->headers) {
+ return '';
+ }
+
+ $beautifier = function ($name) {
+ return preg_replace_callback('/\-(.)/', function ($match) { return '-'.strtoupper($match[1]); }, ucfirst($name));
+ };
+
+ $max = max(array_map('strlen', array_keys($this->headers))) + 1;
+ $content = '';
+ ksort($this->headers);
+ foreach ($this->headers as $name => $values) {
+ foreach ($values as $value) {
+ $content .= sprintf("%-{$max}s %s\r\n", $beautifier($name).':', $value);
+ }
+ }
+
+ return $content;
+ }
+
+ /**
+ * Returns the headers.
+ *
+ * @return array An array of headers
+ *
+ * @api
+ */
+ public function all()
+ {
+ return $this->headers;
+ }
+
+ /**
+ * Returns the parameter keys.
+ *
+ * @return array An array of parameter keys
+ *
+ * @api
+ */
+ public function keys()
+ {
+ return array_keys($this->headers);
+ }
+
+ /**
+ * Replaces the current HTTP headers by a new set.
+ *
+ * @param array $headers An array of HTTP headers
+ *
+ * @api
+ */
+ public function replace(array $headers = array())
+ {
+ $this->headers = array();
+ $this->add($headers);
+ }
+
+ /**
+ * Adds new headers the current HTTP headers set.
+ *
+ * @param array $headers An array of HTTP headers
+ *
+ * @api
+ */
+ public function add(array $headers)
+ {
+ foreach ($headers as $key => $values) {
+ $this->set($key, $values);
+ }
+ }
+
+ /**
+ * Returns a header value by name.
+ *
+ * @param string $key The header name
+ * @param mixed $default The default value
+ * @param Boolean $first Whether to return the first value or all header values
+ *
+ * @return string|array The first header value if $first is true, an array of values otherwise
+ *
+ * @api
+ */
+ public function get($key, $default = null, $first = true)
+ {
+ $key = strtr(strtolower($key), '_', '-');
+
+ if (!array_key_exists($key, $this->headers)) {
+ if (null === $default) {
+ return $first ? null : array();
+ }
+
+ return $first ? $default : array($default);
+ }
+
+ if ($first) {
+ return count($this->headers[$key]) ? $this->headers[$key][0] : $default;
+ }
+
+ return $this->headers[$key];
+ }
+
+ /**
+ * Sets a header by name.
+ *
+ * @param string $key The key
+ * @param string|array $values The value or an array of values
+ * @param Boolean $replace Whether to replace the actual value of not (true by default)
+ *
+ * @api
+ */
+ public function set($key, $values, $replace = true)
+ {
+ $key = strtr(strtolower($key), '_', '-');
+
+ $values = (array) $values;
+
+ if (true === $replace || !isset($this->headers[$key])) {
+ $this->headers[$key] = $values;
+ } else {
+ $this->headers[$key] = array_merge($this->headers[$key], $values);
+ }
+
+ if ('cache-control' === $key) {
+ $this->cacheControl = $this->parseCacheControl($values[0]);
+ }
+ }
+
+ /**
+ * Returns true if the HTTP header is defined.
+ *
+ * @param string $key The HTTP header
+ *
+ * @return Boolean true if the parameter exists, false otherwise
+ *
+ * @api
+ */
+ public function has($key)
+ {
+ return array_key_exists(strtr(strtolower($key), '_', '-'), $this->headers);
+ }
+
+ /**
+ * Returns true if the given HTTP header contains the given value.
+ *
+ * @param string $key The HTTP header name
+ * @param string $value The HTTP value
+ *
+ * @return Boolean true if the value is contained in the header, false otherwise
+ *
+ * @api
+ */
+ public function contains($key, $value)
+ {
+ return in_array($value, $this->get($key, null, false));
+ }
+
+ /**
+ * Removes a header.
+ *
+ * @param string $key The HTTP header name
+ *
+ * @api
+ */
+ public function remove($key)
+ {
+ $key = strtr(strtolower($key), '_', '-');
+
+ unset($this->headers[$key]);
+
+ if ('cache-control' === $key) {
+ $this->cacheControl = array();
+ }
+ }
+
+ /**
+ * Returns the HTTP header value converted to a date.
+ *
+ * @param string $key The parameter key
+ * @param \DateTime $default The default value
+ *
+ * @return \DateTime The filtered value
+ *
+ * @api
+ */
+ public function getDate($key, \DateTime $default = null)
+ {
+ if (null === $value = $this->get($key)) {
+ return $default;
+ }
+
+ if (false === $date = \DateTime::createFromFormat(DATE_RFC2822, $value)) {
+ throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value));
+ }
+
+ return $date;
+ }
+
+ public function addCacheControlDirective($key, $value = true)
+ {
+ $this->cacheControl[$key] = $value;
+
+ $this->set('Cache-Control', $this->getCacheControlHeader());
+ }
+
+ public function hasCacheControlDirective($key)
+ {
+ return array_key_exists($key, $this->cacheControl);
+ }
+
+ public function getCacheControlDirective($key)
+ {
+ return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null;
+ }
+
+ public function removeCacheControlDirective($key)
+ {
+ unset($this->cacheControl[$key]);
+
+ $this->set('Cache-Control', $this->getCacheControlHeader());
+ }
+
+ protected function getCacheControlHeader()
+ {
+ $parts = array();
+ ksort($this->cacheControl);
+ foreach ($this->cacheControl as $key => $value) {
+ if (true === $value) {
+ $parts[] = $key;
+ } else {
+ if (preg_match('#[^a-zA-Z0-9._-]#', $value)) {
+ $value = '"'.$value.'"';
+ }
+
+ $parts[] = "$key=$value";
+ }
+ }
+
+ return implode(', ', $parts);
+ }
+
+ /**
+ * Parses a Cache-Control HTTP header.
+ *
+ * @param string $header The value of the Cache-Control HTTP header
+ *
+ * @return array An array representing the attribute values
+ */
+ protected function parseCacheControl($header)
+ {
+ $cacheControl = array();
+ preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER);
+ foreach ($matches as $match) {
+ $cacheControl[strtolower($match[1])] = isset($match[2]) && $match[2] ? $match[2] : (isset($match[3]) ? $match[3] : true);
+ }
+
+ return $cacheControl;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/JsonResponse.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/JsonResponse.php
new file mode 100755
index 000000000..8e02926e2
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/JsonResponse.php
@@ -0,0 +1,49 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * Response represents an HTTP response in JSON format.
+ *
+ * @author Igor Wiedler
+ */
+class JsonResponse extends Response
+{
+ /**
+ * Constructor.
+ *
+ * @param mixed $data The response data
+ * @param integer $status The response status code
+ * @param array $headers An array of response headers
+ */
+ public function __construct($data = array(), $status = 200, $headers = array())
+ {
+ // root should be JSON object, not array
+ if (is_array($data) && 0 === count($data)) {
+ $data = new \ArrayObject();
+ }
+
+ parent::__construct(
+ json_encode($data),
+ $status,
+ array_merge(array('Content-Type' => 'application/json'), $headers)
+ );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ static public function create($data = array(), $status = 200, $headers = array())
+ {
+ return new static($data, $status, $headers);
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/LICENSE b/app/laravel/vendor/Symfony/Component/HttpFoundation/LICENSE
new file mode 100755
index 000000000..cdffe7aeb
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2012 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/LaravelRequest.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/LaravelRequest.php
new file mode 100644
index 000000000..7b0d46725
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/LaravelRequest.php
@@ -0,0 +1,38 @@
+server->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded')
+ || (0 === strpos($request->server->get('HTTP_CONTENT_TYPE'), 'application/x-www-form-urlencoded')))
+ && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH'))
+ ) {
+ parse_str($request->getContent(), $data);
+ if (magic_quotes()) $data = array_strip_slashes($data);
+ $request->request = new ParameterBag($data);
+ }
+
+ return $request;
+ }
+
+ /**
+ * Get the root URL of the application.
+ *
+ * @return string
+ */
+ public function getRootUrl()
+ {
+ return $this->getScheme().'://'.$this->getHttpHost().$this->getBasePath();
+ }
+
+}
\ No newline at end of file
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/LaravelResponse.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/LaravelResponse.php
new file mode 100644
index 000000000..9fe45ecf3
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/LaravelResponse.php
@@ -0,0 +1,40 @@
+
+ *
+ * @api
+ */
+class LaravelResponse extends Response
+{
+
+ /**
+ * Sends HTTP headers and content.
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function send()
+ {
+ $this->sendHeaders();
+ $this->sendContent();
+
+ return $this;
+ }
+
+ /**
+ * Finishes the request for PHP-FastCGI
+ *
+ * @return void
+ */
+ public function finish()
+ {
+ if (function_exists('fastcgi_finish_request')) {
+ fastcgi_finish_request();
+ }
+ }
+
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/ParameterBag.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/ParameterBag.php
new file mode 100755
index 000000000..a5b04da03
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/ParameterBag.php
@@ -0,0 +1,281 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * ParameterBag is a container for key/value pairs.
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class ParameterBag
+{
+ /**
+ * Parameter storage.
+ *
+ * @var array
+ */
+ protected $parameters;
+
+ /**
+ * Constructor.
+ *
+ * @param array $parameters An array of parameters
+ *
+ * @api
+ */
+ public function __construct(array $parameters = array())
+ {
+ $this->parameters = $parameters;
+ }
+
+ /**
+ * Returns the parameters.
+ *
+ * @return array An array of parameters
+ *
+ * @api
+ */
+ public function all()
+ {
+ return $this->parameters;
+ }
+
+ /**
+ * Returns the parameter keys.
+ *
+ * @return array An array of parameter keys
+ *
+ * @api
+ */
+ public function keys()
+ {
+ return array_keys($this->parameters);
+ }
+
+ /**
+ * Replaces the current parameters by a new set.
+ *
+ * @param array $parameters An array of parameters
+ *
+ * @api
+ */
+ public function replace(array $parameters = array())
+ {
+ $this->parameters = $parameters;
+ }
+
+ /**
+ * Adds parameters.
+ *
+ * @param array $parameters An array of parameters
+ *
+ * @api
+ */
+ public function add(array $parameters = array())
+ {
+ $this->parameters = array_replace($this->parameters, $parameters);
+ }
+
+ /**
+ * Returns a parameter by name.
+ *
+ * @param string $path The key
+ * @param mixed $default The default value if the parameter key does not exist
+ * @param boolean $deep If true, a path like foo[bar] will find deeper items
+ *
+ * @api
+ */
+ public function get($path, $default = null, $deep = false)
+ {
+ if (!$deep || false === $pos = strpos($path, '[')) {
+ return array_key_exists($path, $this->parameters) ? $this->parameters[$path] : $default;
+ }
+
+ $root = substr($path, 0, $pos);
+ if (!array_key_exists($root, $this->parameters)) {
+ return $default;
+ }
+
+ $value = $this->parameters[$root];
+ $currentKey = null;
+ for ($i=$pos,$c=strlen($path); $i<$c; $i++) {
+ $char = $path[$i];
+
+ if ('[' === $char) {
+ if (null !== $currentKey) {
+ throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "[" at position %d.', $i));
+ }
+
+ $currentKey = '';
+ } elseif (']' === $char) {
+ if (null === $currentKey) {
+ throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "]" at position %d.', $i));
+ }
+
+ if (!is_array($value) || !array_key_exists($currentKey, $value)) {
+ return $default;
+ }
+
+ $value = $value[$currentKey];
+ $currentKey = null;
+ } else {
+ if (null === $currentKey) {
+ throw new \InvalidArgumentException(sprintf('Malformed path. Unexpected "%s" at position %d.', $char, $i));
+ }
+
+ $currentKey .= $char;
+ }
+ }
+
+ if (null !== $currentKey) {
+ throw new \InvalidArgumentException(sprintf('Malformed path. Path must end with "]".'));
+ }
+
+ return $value;
+ }
+
+ /**
+ * Sets a parameter by name.
+ *
+ * @param string $key The key
+ * @param mixed $value The value
+ *
+ * @api
+ */
+ public function set($key, $value)
+ {
+ $this->parameters[$key] = $value;
+ }
+
+ /**
+ * Returns true if the parameter is defined.
+ *
+ * @param string $key The key
+ *
+ * @return Boolean true if the parameter exists, false otherwise
+ *
+ * @api
+ */
+ public function has($key)
+ {
+ return array_key_exists($key, $this->parameters);
+ }
+
+ /**
+ * Removes a parameter.
+ *
+ * @param string $key The key
+ *
+ * @api
+ */
+ public function remove($key)
+ {
+ unset($this->parameters[$key]);
+ }
+
+ /**
+ * Returns the alphabetic characters of the parameter value.
+ *
+ * @param string $key The parameter key
+ * @param mixed $default The default value if the parameter key does not exist
+ * @param boolean $deep If true, a path like foo[bar] will find deeper items
+ *
+ * @return string The filtered value
+ *
+ * @api
+ */
+ public function getAlpha($key, $default = '', $deep = false)
+ {
+ return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default, $deep));
+ }
+
+ /**
+ * Returns the alphabetic characters and digits of the parameter value.
+ *
+ * @param string $key The parameter key
+ * @param mixed $default The default value if the parameter key does not exist
+ * @param boolean $deep If true, a path like foo[bar] will find deeper items
+ *
+ * @return string The filtered value
+ *
+ * @api
+ */
+ public function getAlnum($key, $default = '', $deep = false)
+ {
+ return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default, $deep));
+ }
+
+ /**
+ * Returns the digits of the parameter value.
+ *
+ * @param string $key The parameter key
+ * @param mixed $default The default value if the parameter key does not exist
+ * @param boolean $deep If true, a path like foo[bar] will find deeper items
+ *
+ * @return string The filtered value
+ *
+ * @api
+ */
+ public function getDigits($key, $default = '', $deep = false)
+ {
+ // we need to remove - and + because they're allowed in the filter
+ return str_replace(array('-', '+'), '', $this->filter($key, $default, $deep, FILTER_SANITIZE_NUMBER_INT));
+ }
+
+ /**
+ * Returns the parameter value converted to integer.
+ *
+ * @param string $key The parameter key
+ * @param mixed $default The default value if the parameter key does not exist
+ * @param boolean $deep If true, a path like foo[bar] will find deeper items
+ *
+ * @return string The filtered value
+ *
+ * @api
+ */
+ public function getInt($key, $default = 0, $deep = false)
+ {
+ return (int) $this->get($key, $default, $deep);
+ }
+
+ /**
+ * Filter key.
+ *
+ * @param string $key Key.
+ * @param mixed $default Default = null.
+ * @param boolean $deep Default = false.
+ * @param integer $filter FILTER_* constant.
+ * @param mixed $options Filter options.
+ *
+ * @see http://php.net/manual/en/function.filter-var.php
+ *
+ * @return mixed
+ */
+ public function filter($key, $default = null, $deep = false, $filter=FILTER_DEFAULT, $options=array())
+ {
+ $value = $this->get($key, $default, $deep);
+
+ // Always turn $options into an array - this allows filter_var option shortcuts.
+ if (!is_array($options) && $options) {
+ $options = array('flags' => $options);
+ }
+
+ // Add a convenience check for arrays.
+ if (is_array($value) && !isset($options['flags'])) {
+ $options['flags'] = FILTER_REQUIRE_ARRAY;
+ }
+
+ return filter_var($value, $filter, $options);
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/README.md b/app/laravel/vendor/Symfony/Component/HttpFoundation/README.md
new file mode 100755
index 000000000..88adfed75
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/README.md
@@ -0,0 +1,47 @@
+HttpFoundation Component
+========================
+
+HttpFoundation defines an object-oriented layer for the HTTP specification.
+
+It provides an abstraction for requests, responses, uploaded files, cookies,
+sessions, ...
+
+In this example, we get a Request object from the current PHP global
+variables:
+
+ use Symfony\Component\HttpFoundation\Request;
+ use Symfony\Component\HttpFoundation\Response;
+
+ $request = Request::createFromGlobals();
+ echo $request->getPathInfo();
+
+You can also create a Request directly -- that's interesting for unit testing:
+
+ $request = Request::create('/?foo=bar', 'GET');
+ echo $request->getPathInfo();
+
+And here is how to create and send a Response:
+
+ $response = new Response('Not Found', 404, array('Content-Type' => 'text/plain'));
+ $response->send();
+
+The Request and the Response classes have many other methods that implement
+the HTTP specification.
+
+Loading
+-------
+
+If you are using PHP 5.3.x you must add the following to your autoloader:
+
+ // SessionHandlerInterface
+ if (!interface_exists('SessionHandlerInterface')) {
+ $loader->registerPrefixFallback(__DIR__.'/../vendor/symfony/src/Symfony/Component/HttpFoundation/Resources/stubs');
+ }
+
+
+Resources
+---------
+
+Unit tests:
+
+https://github.com/symfony/symfony/tree/master/tests/Symfony/Tests/Component/HttpFoundation
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/RedirectResponse.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/RedirectResponse.php
new file mode 100755
index 000000000..27676ec0d
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/RedirectResponse.php
@@ -0,0 +1,83 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * RedirectResponse represents an HTTP response doing a redirect.
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class RedirectResponse extends Response
+{
+ protected $targetUrl;
+
+ /**
+ * Creates a redirect response so that it conforms to the rules defined for a redirect status code.
+ *
+ * @param string $url The URL to redirect to
+ * @param integer $status The status code (302 by default)
+ * @param array $headers The headers (Location is always set to the given url)
+ *
+ * @see http://tools.ietf.org/html/rfc2616#section-10.3
+ *
+ * @api
+ */
+ public function __construct($url, $status = 302, $headers = array())
+ {
+ if (empty($url)) {
+ throw new \InvalidArgumentException('Cannot redirect to an empty URL.');
+ }
+
+ $this->targetUrl = $url;
+
+ parent::__construct(
+ sprintf('
+
+
+
+
+
+ Redirecting to %1$s
+
+
+ Redirecting to %1$s.
+
+', htmlspecialchars($url, ENT_QUOTES, 'UTF-8')),
+ $status,
+ array_merge($headers, array('Location' => $url))
+ );
+
+ if (!$this->isRedirect()) {
+ throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ static public function create($url = '', $status = 302, $headers = array())
+ {
+ return new static($url, $status, $headers);
+ }
+
+ /**
+ * Returns the target URL.
+ *
+ * @return string target URL
+ */
+ public function getTargetUrl()
+ {
+ return $this->targetUrl;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Request.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Request.php
new file mode 100755
index 000000000..eb200b85a
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Request.php
@@ -0,0 +1,1413 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+use Symfony\Component\HttpFoundation\Session\SessionInterface;
+
+/**
+ * Request represents an HTTP request.
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class Request
+{
+ static protected $trustProxy = false;
+
+ /**
+ * @var \Symfony\Component\HttpFoundation\ParameterBag
+ *
+ * @api
+ */
+ public $attributes;
+
+ /**
+ * @var \Symfony\Component\HttpFoundation\ParameterBag
+ *
+ * @api
+ */
+ public $request;
+
+ /**
+ * @var \Symfony\Component\HttpFoundation\ParameterBag
+ *
+ * @api
+ */
+ public $query;
+
+ /**
+ * @var \Symfony\Component\HttpFoundation\ServerBag
+ *
+ * @api
+ */
+ public $server;
+
+ /**
+ * @var \Symfony\Component\HttpFoundation\FileBag
+ *
+ * @api
+ */
+ public $files;
+
+ /**
+ * @var \Symfony\Component\HttpFoundation\ParameterBag
+ *
+ * @api
+ */
+ public $cookies;
+
+ /**
+ * @var \Symfony\Component\HttpFoundation\HeaderBag
+ *
+ * @api
+ */
+ public $headers;
+
+ /**
+ * @var string
+ */
+ protected $content;
+
+ /**
+ * @var string
+ */
+ protected $languages;
+
+ /**
+ * @var string
+ */
+ protected $charsets;
+
+ /**
+ * @var string
+ */
+ protected $acceptableContentTypes;
+
+ /**
+ * @var string
+ */
+ protected $pathInfo;
+
+ /**
+ * @var string
+ */
+ protected $requestUri;
+
+ /**
+ * @var string
+ */
+ protected $baseUrl;
+
+ /**
+ * @var string
+ */
+ protected $basePath;
+
+ /**
+ * @var string
+ */
+ protected $method;
+
+ /**
+ * @var string
+ */
+ protected $format;
+
+ /**
+ * @var \Symfony\Component\HttpFoundation\Session\SessionInterface
+ */
+ protected $session;
+
+ /**
+ * @var string
+ */
+ protected $locale;
+
+ /**
+ * @var string
+ */
+ protected $defaultLocale = 'en';
+
+ /**
+ * @var string
+ */
+ static protected $formats;
+
+ /**
+ * Constructor.
+ *
+ * @param array $query The GET parameters
+ * @param array $request The POST parameters
+ * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
+ * @param array $cookies The COOKIE parameters
+ * @param array $files The FILES parameters
+ * @param array $server The SERVER parameters
+ * @param string $content The raw body data
+ *
+ * @api
+ */
+ public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
+ {
+ $this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
+ }
+
+ /**
+ * Sets the parameters for this request.
+ *
+ * This method also re-initializes all properties.
+ *
+ * @param array $query The GET parameters
+ * @param array $request The POST parameters
+ * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
+ * @param array $cookies The COOKIE parameters
+ * @param array $files The FILES parameters
+ * @param array $server The SERVER parameters
+ * @param string $content The raw body data
+ *
+ * @api
+ */
+ public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
+ {
+ $this->request = new ParameterBag($request);
+ $this->query = new ParameterBag($query);
+ $this->attributes = new ParameterBag($attributes);
+ $this->cookies = new ParameterBag($cookies);
+ $this->files = new FileBag($files);
+ $this->server = new ServerBag($server);
+ $this->headers = new HeaderBag($this->server->getHeaders());
+
+ $this->content = $content;
+ $this->languages = null;
+ $this->charsets = null;
+ $this->acceptableContentTypes = null;
+ $this->pathInfo = null;
+ $this->requestUri = null;
+ $this->baseUrl = null;
+ $this->basePath = null;
+ $this->method = null;
+ $this->format = null;
+ }
+
+ /**
+ * Creates a new request with values from PHP's super globals.
+ *
+ * @return Request A new request
+ *
+ * @api
+ */
+ static public function createFromGlobals()
+ {
+ $request = new static($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER);
+
+ if (0 === strpos($request->server->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded')
+ && in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH'))
+ ) {
+ parse_str($request->getContent(), $data);
+ $request->request = new ParameterBag($data);
+ }
+
+ return $request;
+ }
+
+ /**
+ * Creates a Request based on a given URI and configuration.
+ *
+ * @param string $uri The URI
+ * @param string $method The HTTP method
+ * @param array $parameters The request (GET) or query (POST) parameters
+ * @param array $cookies The request cookies ($_COOKIE)
+ * @param array $files The request files ($_FILES)
+ * @param array $server The server parameters ($_SERVER)
+ * @param string $content The raw body data
+ *
+ * @return Request A Request instance
+ *
+ * @api
+ */
+ static public function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null)
+ {
+ $defaults = array(
+ 'SERVER_NAME' => 'localhost',
+ 'SERVER_PORT' => 80,
+ 'HTTP_HOST' => 'localhost',
+ 'HTTP_USER_AGENT' => 'Symfony/2.X',
+ 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
+ 'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5',
+ 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
+ 'REMOTE_ADDR' => '127.0.0.1',
+ 'SCRIPT_NAME' => '',
+ 'SCRIPT_FILENAME' => '',
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
+ 'REQUEST_TIME' => time(),
+ );
+
+ $components = parse_url($uri);
+ if (isset($components['host'])) {
+ $defaults['SERVER_NAME'] = $components['host'];
+ $defaults['HTTP_HOST'] = $components['host'];
+ }
+
+ if (isset($components['scheme'])) {
+ if ('https' === $components['scheme']) {
+ $defaults['HTTPS'] = 'on';
+ $defaults['SERVER_PORT'] = 443;
+ }
+ }
+
+ if (isset($components['port'])) {
+ $defaults['SERVER_PORT'] = $components['port'];
+ $defaults['HTTP_HOST'] = $defaults['HTTP_HOST'].':'.$components['port'];
+ }
+
+ if (isset($components['user'])) {
+ $defaults['PHP_AUTH_USER'] = $components['user'];
+ }
+
+ if (isset($components['pass'])) {
+ $defaults['PHP_AUTH_PW'] = $components['pass'];
+ }
+
+ if (!isset($components['path'])) {
+ $components['path'] = '';
+ }
+
+ switch (strtoupper($method)) {
+ case 'POST':
+ case 'PUT':
+ case 'DELETE':
+ $defaults['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
+ case 'PATCH':
+ $request = $parameters;
+ $query = array();
+ break;
+ default:
+ $request = array();
+ $query = $parameters;
+ break;
+ }
+
+ if (isset($components['query'])) {
+ $queryString = html_entity_decode($components['query']);
+ parse_str($queryString, $qs);
+ if (is_array($qs)) {
+ $query = array_replace($qs, $query);
+ }
+ }
+ $queryString = http_build_query($query);
+
+ $uri = $components['path'].($queryString ? '?'.$queryString : '');
+
+ $server = array_replace($defaults, $server, array(
+ 'REQUEST_METHOD' => strtoupper($method),
+ 'PATH_INFO' => '',
+ 'REQUEST_URI' => $uri,
+ 'QUERY_STRING' => $queryString,
+ ));
+
+ return new static($query, $request, array(), $cookies, $files, $server, $content);
+ }
+
+ /**
+ * Clones a request and overrides some of its parameters.
+ *
+ * @param array $query The GET parameters
+ * @param array $request The POST parameters
+ * @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
+ * @param array $cookies The COOKIE parameters
+ * @param array $files The FILES parameters
+ * @param array $server The SERVER parameters
+ *
+ * @api
+ */
+ public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
+ {
+ $dup = clone $this;
+ if ($query !== null) {
+ $dup->query = new ParameterBag($query);
+ }
+ if ($request !== null) {
+ $dup->request = new ParameterBag($request);
+ }
+ if ($attributes !== null) {
+ $dup->attributes = new ParameterBag($attributes);
+ }
+ if ($cookies !== null) {
+ $dup->cookies = new ParameterBag($cookies);
+ }
+ if ($files !== null) {
+ $dup->files = new FileBag($files);
+ }
+ if ($server !== null) {
+ $dup->server = new ServerBag($server);
+ $dup->headers = new HeaderBag($dup->server->getHeaders());
+ }
+ $dup->languages = null;
+ $dup->charsets = null;
+ $dup->acceptableContentTypes = null;
+ $dup->pathInfo = null;
+ $dup->requestUri = null;
+ $dup->baseUrl = null;
+ $dup->basePath = null;
+ $dup->method = null;
+ $dup->format = null;
+
+ return $dup;
+ }
+
+ /**
+ * Clones the current request.
+ *
+ * Note that the session is not cloned as duplicated requests
+ * are most of the time sub-requests of the main one.
+ */
+ public function __clone()
+ {
+ $this->query = clone $this->query;
+ $this->request = clone $this->request;
+ $this->attributes = clone $this->attributes;
+ $this->cookies = clone $this->cookies;
+ $this->files = clone $this->files;
+ $this->server = clone $this->server;
+ $this->headers = clone $this->headers;
+ }
+
+ /**
+ * Returns the request as a string.
+ *
+ * @return string The request
+ */
+ public function __toString()
+ {
+ return
+ sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n".
+ $this->headers."\r\n".
+ $this->getContent();
+ }
+
+ /**
+ * Overrides the PHP global variables according to this request instance.
+ *
+ * It overrides $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE, and $_FILES.
+ *
+ * @api
+ */
+ public function overrideGlobals()
+ {
+ $_GET = $this->query->all();
+ $_POST = $this->request->all();
+ $_SERVER = $this->server->all();
+ $_COOKIE = $this->cookies->all();
+ // FIXME: populate $_FILES
+
+ foreach ($this->headers->all() as $key => $value) {
+ $key = strtoupper(str_replace('-', '_', $key));
+ if (in_array($key, array('CONTENT_TYPE', 'CONTENT_LENGTH'))) {
+ $_SERVER[$key] = implode(', ', $value);
+ } else {
+ $_SERVER['HTTP_'.$key] = implode(', ', $value);
+ }
+ }
+
+ // FIXME: should read variables_order and request_order
+ // to know which globals to merge and in which order
+ $_REQUEST = array_merge($_GET, $_POST);
+ }
+
+ /**
+ * Trusts $_SERVER entries coming from proxies.
+ *
+ * You should only call this method if your application
+ * is hosted behind a reverse proxy that you manage.
+ *
+ * @api
+ */
+ static public function trustProxyData()
+ {
+ self::$trustProxy = true;
+ }
+
+ /**
+ * Returns true if $_SERVER entries coming from proxies are trusted,
+ * false otherwise.
+ *
+ * @return boolean
+ */
+ static public function isProxyTrusted()
+ {
+ return self::$trustProxy;
+ }
+
+ /**
+ * Gets a "parameter" value.
+ *
+ * This method is mainly useful for libraries that want to provide some flexibility.
+ *
+ * Order of precedence: GET, PATH, POST, COOKIE
+ *
+ * Avoid using this method in controllers:
+ *
+ * * slow
+ * * prefer to get from a "named" source
+ *
+ * It is better to explicity get request parameters from the appropriate
+ * public property instead (query, request, attributes, ...).
+ *
+ * @param string $key the key
+ * @param mixed $default the default value
+ * @param type $deep is parameter deep in multidimensional array
+ *
+ * @return mixed
+ */
+ public function get($key, $default = null, $deep = false)
+ {
+ return $this->query->get($key, $this->attributes->get($key, $this->request->get($key, $default, $deep), $deep), $deep);
+ }
+
+ /**
+ * Gets the Session.
+ *
+ * @return SessionInterface|null The session
+ *
+ * @api
+ */
+ public function getSession()
+ {
+ return $this->session;
+ }
+
+ /**
+ * Whether the request contains a Session which was started in one of the
+ * previous requests.
+ *
+ * @return boolean
+ *
+ * @api
+ */
+ public function hasPreviousSession()
+ {
+ // the check for $this->session avoids malicious users trying to fake a session cookie with proper name
+ $sessionName = $this->hasSession() ? $this->session->getName() : null;
+
+ return $this->cookies->has($sessionName) && $this->hasSession();
+ }
+
+ /**
+ * Whether the request contains a Session object.
+ *
+ * @return boolean
+ *
+ * @api
+ */
+ public function hasSession()
+ {
+ return null !== $this->session;
+ }
+
+ /**
+ * Sets the Session.
+ *
+ * @param SessionInterface $session The Session
+ *
+ * @api
+ */
+ public function setSession(SessionInterface $session)
+ {
+ $this->session = $session;
+ }
+
+ /**
+ * Returns the client IP address.
+ *
+ * @return string The client IP address
+ *
+ * @api
+ */
+ public function getClientIp()
+ {
+ if (self::$trustProxy) {
+ if ($this->server->has('HTTP_CLIENT_IP')) {
+ return $this->server->get('HTTP_CLIENT_IP');
+ } elseif ($this->server->has('HTTP_X_FORWARDED_FOR')) {
+ $clientIp = explode(',', $this->server->get('HTTP_X_FORWARDED_FOR'), 2);
+
+ return isset($clientIp[0]) ? trim($clientIp[0]) : '';
+ }
+ }
+
+ return $this->server->get('REMOTE_ADDR');
+ }
+
+ /**
+ * Returns current script name.
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function getScriptName()
+ {
+ return $this->server->get('SCRIPT_NAME', $this->server->get('ORIG_SCRIPT_NAME', ''));
+ }
+
+ /**
+ * Returns the path being requested relative to the executed script.
+ *
+ * The path info always starts with a /.
+ *
+ * Suppose this request is instantiated from /mysite on localhost:
+ *
+ * * http://localhost/mysite returns an empty string
+ * * http://localhost/mysite/about returns '/about'
+ * * http://localhost/mysite/about?var=1 returns '/about'
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function getPathInfo()
+ {
+ if (null === $this->pathInfo) {
+ $this->pathInfo = $this->preparePathInfo();
+ }
+
+ return $this->pathInfo;
+ }
+
+ /**
+ * Returns the root path from which this request is executed.
+ *
+ * Suppose that an index.php file instantiates this request object:
+ *
+ * * http://localhost/index.php returns an empty string
+ * * http://localhost/index.php/page returns an empty string
+ * * http://localhost/web/index.php return '/web'
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function getBasePath()
+ {
+ if (null === $this->basePath) {
+ $this->basePath = $this->prepareBasePath();
+ }
+
+ return $this->basePath;
+ }
+
+ /**
+ * Returns the root url from which this request is executed.
+ *
+ * The base URL never ends with a /.
+ *
+ * This is similar to getBasePath(), except that it also includes the
+ * script filename (e.g. index.php) if one exists.
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function getBaseUrl()
+ {
+ if (null === $this->baseUrl) {
+ $this->baseUrl = $this->prepareBaseUrl();
+ }
+
+ return $this->baseUrl;
+ }
+
+ /**
+ * Gets the request's scheme.
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function getScheme()
+ {
+ return $this->isSecure() ? 'https' : 'http';
+ }
+
+ /**
+ * Returns the port on which the request is made.
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function getPort()
+ {
+ if (self::$trustProxy && $this->headers->has('X-Forwarded-Port')) {
+ return $this->headers->get('X-Forwarded-Port');
+ } else {
+ return $this->server->get('SERVER_PORT');
+ }
+ }
+
+ /**
+ * Returns the user.
+ *
+ * @return string|null
+ */
+ public function getUser()
+ {
+ return $this->server->get('PHP_AUTH_USER');
+ }
+
+ /**
+ * Returns the password.
+ *
+ * @return string|null
+ */
+ public function getPassword()
+ {
+ return $this->server->get('PHP_AUTH_PW');
+ }
+
+ /**
+ * Returns the HTTP host being requested.
+ *
+ * The port name will be appended to the host if it's non-standard.
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function getHttpHost()
+ {
+ $scheme = $this->getScheme();
+ $port = $this->getPort();
+
+ if (('http' == $scheme && $port == 80) || ('https' == $scheme && $port == 443)) {
+ return $this->getHost();
+ }
+
+ return $this->getHost().':'.$port;
+ }
+
+ /**
+ * Returns the requested URI.
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function getRequestUri()
+ {
+ if (null === $this->requestUri) {
+ $this->requestUri = $this->prepareRequestUri();
+ }
+
+ return $this->requestUri;
+ }
+
+ /**
+ * Generates a normalized URI for the Request.
+ *
+ * @return string A normalized URI for the Request
+ *
+ * @see getQueryString()
+ *
+ * @api
+ */
+ public function getUri()
+ {
+ $qs = $this->getQueryString();
+ if (null !== $qs) {
+ $qs = '?'.$qs;
+ }
+
+ $auth = '';
+ if ($user = $this->getUser()) {
+ $auth = $user;
+ }
+
+ if ($pass = $this->getPassword()) {
+ $auth .= ":$pass";
+ }
+
+ if ('' !== $auth) {
+ $auth .= '@';
+ }
+
+ return $this->getScheme().'://'.$auth.$this->getHttpHost().$this->getBaseUrl().$this->getPathInfo().$qs;
+ }
+
+ /**
+ * Generates a normalized URI for the given path.
+ *
+ * @param string $path A path to use instead of the current one
+ *
+ * @return string The normalized URI for the path
+ *
+ * @api
+ */
+ public function getUriForPath($path)
+ {
+ return $this->getScheme().'://'.$this->getHttpHost().$this->getBaseUrl().$path;
+ }
+
+ /**
+ * Generates the normalized query string for the Request.
+ *
+ * It builds a normalized query string, where keys/value pairs are alphabetized
+ * and have consistent escaping.
+ *
+ * @return string|null A normalized query string for the Request
+ *
+ * @api
+ */
+ public function getQueryString()
+ {
+ if (!$qs = $this->server->get('QUERY_STRING')) {
+ return null;
+ }
+
+ $parts = array();
+ $order = array();
+
+ foreach (explode('&', $qs) as $segment) {
+ if (false === strpos($segment, '=')) {
+ $parts[] = $segment;
+ $order[] = $segment;
+ } else {
+ $tmp = explode('=', rawurldecode($segment), 2);
+ $parts[] = rawurlencode($tmp[0]).'='.rawurlencode($tmp[1]);
+ $order[] = $tmp[0];
+ }
+ }
+ array_multisort($order, SORT_ASC, $parts);
+
+ return implode('&', $parts);
+ }
+
+ /**
+ * Checks whether the request is secure or not.
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isSecure()
+ {
+ return (
+ (strtolower($this->server->get('HTTPS')) == 'on' || $this->server->get('HTTPS') == 1)
+ ||
+ (self::$trustProxy && strtolower($this->headers->get('SSL_HTTPS')) == 'on' || $this->headers->get('SSL_HTTPS') == 1)
+ ||
+ (self::$trustProxy && strtolower($this->headers->get('X_FORWARDED_PROTO')) == 'https')
+ );
+ }
+
+ /**
+ * Returns the host name.
+ *
+ * @return string
+ *
+ * @api
+ */
+ public function getHost()
+ {
+ if (self::$trustProxy && $host = $this->headers->get('X_FORWARDED_HOST')) {
+ $elements = explode(',', $host);
+
+ $host = trim($elements[count($elements) - 1]);
+ } else {
+ if (!$host = $this->headers->get('HOST')) {
+ if (!$host = $this->server->get('SERVER_NAME')) {
+ $host = $this->server->get('SERVER_ADDR', '');
+ }
+ }
+ }
+
+ // Remove port number from host
+ $host = preg_replace('/:\d+$/', '', $host);
+
+ return trim($host);
+ }
+
+ /**
+ * Sets the request method.
+ *
+ * @param string $method
+ *
+ * @api
+ */
+ public function setMethod($method)
+ {
+ $this->method = null;
+ $this->server->set('REQUEST_METHOD', $method);
+ }
+
+ /**
+ * Gets the request method.
+ *
+ * The method is always an uppercased string.
+ *
+ * @return string The request method
+ *
+ * @api
+ */
+ public function getMethod()
+ {
+ if (null === $this->method) {
+ $this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
+ if ('POST' === $this->method) {
+ $this->method = strtoupper($this->headers->get('X-HTTP-METHOD-OVERRIDE', $this->request->get('_method', 'POST')));
+ }
+ }
+
+ return $this->method;
+ }
+
+ /**
+ * Gets the mime type associated with the format.
+ *
+ * @param string $format The format
+ *
+ * @return string The associated mime type (null if not found)
+ *
+ * @api
+ */
+ public function getMimeType($format)
+ {
+ if (null === static::$formats) {
+ static::initializeFormats();
+ }
+
+ return isset(static::$formats[$format]) ? static::$formats[$format][0] : null;
+ }
+
+ /**
+ * Gets the format associated with the mime type.
+ *
+ * @param string $mimeType The associated mime type
+ *
+ * @return string The format (null if not found)
+ *
+ * @api
+ */
+ public function getFormat($mimeType)
+ {
+ if (false !== $pos = strpos($mimeType, ';')) {
+ $mimeType = substr($mimeType, 0, $pos);
+ }
+
+ if (null === static::$formats) {
+ static::initializeFormats();
+ }
+
+ foreach (static::$formats as $format => $mimeTypes) {
+ if (in_array($mimeType, (array) $mimeTypes)) {
+ return $format;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Associates a format with mime types.
+ *
+ * @param string $format The format
+ * @param string|array $mimeTypes The associated mime types (the preferred one must be the first as it will be used as the content type)
+ *
+ * @api
+ */
+ public function setFormat($format, $mimeTypes)
+ {
+ if (null === static::$formats) {
+ static::initializeFormats();
+ }
+
+ static::$formats[$format] = is_array($mimeTypes) ? $mimeTypes : array($mimeTypes);
+ }
+
+ /**
+ * Gets the request format.
+ *
+ * Here is the process to determine the format:
+ *
+ * * format defined by the user (with setRequestFormat())
+ * * _format request parameter
+ * * $default
+ *
+ * @param string $default The default format
+ *
+ * @return string The request format
+ *
+ * @api
+ */
+ public function getRequestFormat($default = 'html')
+ {
+ if (null === $this->format) {
+ $this->format = $this->get('_format', $default);
+ }
+
+ return $this->format;
+ }
+
+ /**
+ * Sets the request format.
+ *
+ * @param string $format The request format.
+ *
+ * @api
+ */
+ public function setRequestFormat($format)
+ {
+ $this->format = $format;
+ }
+
+ /**
+ * Gets the format associated with the request.
+ *
+ * @return string The format (null if no content type is present)
+ *
+ * @api
+ */
+ public function getContentType()
+ {
+ return $this->getFormat($this->server->get('CONTENT_TYPE'));
+ }
+
+ /**
+ * Sets the default locale.
+ *
+ * @param string $locale
+ *
+ * @api
+ */
+ public function setDefaultLocale($locale)
+ {
+ $this->setPhpDefaultLocale($this->defaultLocale = $locale);
+ }
+
+ /**
+ * Sets the locale.
+ *
+ * @param string $locale
+ *
+ * @api
+ */
+ public function setLocale($locale)
+ {
+ $this->setPhpDefaultLocale($this->locale = $locale);
+ }
+
+ /**
+ * Get the locale.
+ *
+ * @return string
+ */
+ public function getLocale()
+ {
+ return null === $this->locale ? $this->defaultLocale : $this->locale;
+ }
+
+ /**
+ * Checks whether the method is safe or not.
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isMethodSafe()
+ {
+ return in_array($this->getMethod(), array('GET', 'HEAD'));
+ }
+
+ /**
+ * Returns the request body content.
+ *
+ * @param Boolean $asResource If true, a resource will be returned
+ *
+ * @return string|resource The request body content or a resource to read the body stream.
+ */
+ public function getContent($asResource = false)
+ {
+ if (false === $this->content || (true === $asResource && null !== $this->content)) {
+ throw new \LogicException('getContent() can only be called once when using the resource return type.');
+ }
+
+ if (true === $asResource) {
+ $this->content = false;
+
+ return fopen('php://input', 'rb');
+ }
+
+ if (null === $this->content) {
+ $this->content = file_get_contents('php://input');
+ }
+
+ return $this->content;
+ }
+
+ /**
+ * Gets the Etags.
+ *
+ * @return array The entity tags
+ */
+ public function getETags()
+ {
+ return preg_split('/\s*,\s*/', $this->headers->get('if_none_match'), null, PREG_SPLIT_NO_EMPTY);
+ }
+
+ public function isNoCache()
+ {
+ return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma');
+ }
+
+ /**
+ * Returns the preferred language.
+ *
+ * @param array $locales An array of ordered available locales
+ *
+ * @return string|null The preferred locale
+ *
+ * @api
+ */
+ public function getPreferredLanguage(array $locales = null)
+ {
+ $preferredLanguages = $this->getLanguages();
+
+ if (empty($locales)) {
+ return isset($preferredLanguages[0]) ? $preferredLanguages[0] : null;
+ }
+
+ if (!$preferredLanguages) {
+ return $locales[0];
+ }
+
+ $preferredLanguages = array_values(array_intersect($preferredLanguages, $locales));
+
+ return isset($preferredLanguages[0]) ? $preferredLanguages[0] : $locales[0];
+ }
+
+ /**
+ * Gets a list of languages acceptable by the client browser.
+ *
+ * @return array Languages ordered in the user browser preferences
+ *
+ * @api
+ */
+ public function getLanguages()
+ {
+ if (null !== $this->languages) {
+ return $this->languages;
+ }
+
+ $languages = $this->splitHttpAcceptHeader($this->headers->get('Accept-Language'));
+ $this->languages = array();
+ foreach ($languages as $lang => $q) {
+ if (strstr($lang, '-')) {
+ $codes = explode('-', $lang);
+ if ($codes[0] == 'i') {
+ // Language not listed in ISO 639 that are not variants
+ // of any listed language, which can be registered with the
+ // i-prefix, such as i-cherokee
+ if (count($codes) > 1) {
+ $lang = $codes[1];
+ }
+ } else {
+ for ($i = 0, $max = count($codes); $i < $max; $i++) {
+ if ($i == 0) {
+ $lang = strtolower($codes[0]);
+ } else {
+ $lang .= '_'.strtoupper($codes[$i]);
+ }
+ }
+ }
+ }
+
+ $this->languages[] = $lang;
+ }
+
+ return $this->languages;
+ }
+
+ /**
+ * Gets a list of charsets acceptable by the client browser.
+ *
+ * @return array List of charsets in preferable order
+ *
+ * @api
+ */
+ public function getCharsets()
+ {
+ if (null !== $this->charsets) {
+ return $this->charsets;
+ }
+
+ return $this->charsets = array_keys($this->splitHttpAcceptHeader($this->headers->get('Accept-Charset')));
+ }
+
+ /**
+ * Gets a list of content types acceptable by the client browser
+ *
+ * @return array List of content types in preferable order
+ *
+ * @api
+ */
+ public function getAcceptableContentTypes()
+ {
+ if (null !== $this->acceptableContentTypes) {
+ return $this->acceptableContentTypes;
+ }
+
+ return $this->acceptableContentTypes = array_keys($this->splitHttpAcceptHeader($this->headers->get('Accept')));
+ }
+
+ /**
+ * Returns true if the request is a XMLHttpRequest.
+ *
+ * It works if your JavaScript library set an X-Requested-With HTTP header.
+ * It is known to work with Prototype, Mootools, jQuery.
+ *
+ * @return Boolean true if the request is an XMLHttpRequest, false otherwise
+ *
+ * @api
+ */
+ public function isXmlHttpRequest()
+ {
+ return 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
+ }
+
+ /**
+ * Splits an Accept-* HTTP header.
+ *
+ * @param string $header Header to split
+ *
+ * @return array Array indexed by the values of the Accept-* header in preferred order
+ */
+ public function splitHttpAcceptHeader($header)
+ {
+ if (!$header) {
+ return array();
+ }
+
+ $values = array();
+ foreach (array_filter(explode(',', $header)) as $value) {
+ // Cut off any q-value that might come after a semi-colon
+ if (preg_match('/;\s*(q=.*$)/', $value, $match)) {
+ $q = (float) substr(trim($match[1]), 2);
+ $value = trim(substr($value, 0, -strlen($match[0])));
+ } else {
+ $q = 1;
+ }
+
+ if (0 < $q) {
+ $values[trim($value)] = $q;
+ }
+ }
+
+ arsort($values);
+ reset($values);
+
+ return $values;
+ }
+
+ /*
+ * The following methods are derived from code of the Zend Framework (1.10dev - 2010-01-24)
+ *
+ * Code subject to the new BSD license (http://framework.zend.com/license/new-bsd).
+ *
+ * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ */
+
+ protected function prepareRequestUri()
+ {
+ $requestUri = '';
+
+ if ($this->headers->has('X_REWRITE_URL') && false !== stripos(PHP_OS, 'WIN')) {
+ // check this first so IIS will catch
+ $requestUri = $this->headers->get('X_REWRITE_URL');
+ } elseif ($this->server->get('IIS_WasUrlRewritten') == '1' && $this->server->get('UNENCODED_URL') != '') {
+ // IIS7 with URL Rewrite: make sure we get the unencoded url (double slash problem)
+ $requestUri = $this->server->get('UNENCODED_URL');
+ } elseif ($this->server->has('REQUEST_URI')) {
+ $requestUri = $this->server->get('REQUEST_URI');
+ // HTTP proxy reqs setup request uri with scheme and host [and port] + the url path, only use url path
+ $schemeAndHttpHost = $this->getScheme().'://'.$this->getHttpHost();
+ if (strpos($requestUri, $schemeAndHttpHost) === 0) {
+ $requestUri = substr($requestUri, strlen($schemeAndHttpHost));
+ }
+ } elseif ($this->server->has('ORIG_PATH_INFO')) {
+ // IIS 5.0, PHP as CGI
+ $requestUri = $this->server->get('ORIG_PATH_INFO');
+ if ($this->server->get('QUERY_STRING')) {
+ $requestUri .= '?'.$this->server->get('QUERY_STRING');
+ }
+ }
+
+ return $requestUri;
+ }
+
+ /**
+ * Prepares the base URL.
+ *
+ * @return string
+ */
+ protected function prepareBaseUrl()
+ {
+ $filename = basename($this->server->get('SCRIPT_FILENAME'));
+
+ if (basename($this->server->get('SCRIPT_NAME')) === $filename) {
+ $baseUrl = $this->server->get('SCRIPT_NAME');
+ } elseif (basename($this->server->get('PHP_SELF')) === $filename) {
+ $baseUrl = $this->server->get('PHP_SELF');
+ } elseif (basename($this->server->get('ORIG_SCRIPT_NAME')) === $filename) {
+ $baseUrl = $this->server->get('ORIG_SCRIPT_NAME'); // 1and1 shared hosting compatibility
+ } else {
+ // Backtrack up the script_filename to find the portion matching
+ // php_self
+ $path = $this->server->get('PHP_SELF', '');
+ $file = $this->server->get('SCRIPT_FILENAME', '');
+ $segs = explode('/', trim($file, '/'));
+ $segs = array_reverse($segs);
+ $index = 0;
+ $last = count($segs);
+ $baseUrl = '';
+ do {
+ $seg = $segs[$index];
+ $baseUrl = '/'.$seg.$baseUrl;
+ ++$index;
+ } while (($last > $index) && (false !== ($pos = strpos($path, $baseUrl))) && (0 != $pos));
+ }
+
+ // Does the baseUrl have anything in common with the request_uri?
+ $requestUri = $this->getRequestUri();
+
+ if ($baseUrl && 0 === strpos($requestUri, $baseUrl)) {
+ // full $baseUrl matches
+ return $baseUrl;
+ }
+
+ if ($baseUrl && 0 === strpos($requestUri, dirname($baseUrl))) {
+ // directory portion of $baseUrl matches
+ return rtrim(dirname($baseUrl), '/');
+ }
+
+ $truncatedRequestUri = $requestUri;
+ if (($pos = strpos($requestUri, '?')) !== false) {
+ $truncatedRequestUri = substr($requestUri, 0, $pos);
+ }
+
+ $basename = basename($baseUrl);
+ if (empty($basename) || !strpos($truncatedRequestUri, $basename)) {
+ // no match whatsoever; set it blank
+ return '';
+ }
+
+ // If using mod_rewrite or ISAPI_Rewrite strip the script filename
+ // out of baseUrl. $pos !== 0 makes sure it is not matching a value
+ // from PATH_INFO or QUERY_STRING
+ if ((strlen($requestUri) >= strlen($baseUrl)) && ((false !== ($pos = strpos($requestUri, $baseUrl))) && ($pos !== 0))) {
+ $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
+ }
+
+ return rtrim($baseUrl, '/');
+ }
+
+ /**
+ * Prepares the base path.
+ *
+ * @return string base path
+ */
+ protected function prepareBasePath()
+ {
+ $filename = basename($this->server->get('SCRIPT_FILENAME'));
+ $baseUrl = $this->getBaseUrl();
+ if (empty($baseUrl)) {
+ return '';
+ }
+
+ if (basename($baseUrl) === $filename) {
+ $basePath = dirname($baseUrl);
+ } else {
+ $basePath = $baseUrl;
+ }
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $basePath = str_replace('\\', '/', $basePath);
+ }
+
+ return rtrim($basePath, '/');
+ }
+
+ /**
+ * Prepares the path info.
+ *
+ * @return string path info
+ */
+ protected function preparePathInfo()
+ {
+ $baseUrl = $this->getBaseUrl();
+
+ if (null === ($requestUri = $this->getRequestUri())) {
+ return '/';
+ }
+
+ $pathInfo = '/';
+
+ // Remove the query string from REQUEST_URI
+ if ($pos = strpos($requestUri, '?')) {
+ $requestUri = substr($requestUri, 0, $pos);
+ }
+
+ if ((null !== $baseUrl) && (false === ($pathInfo = substr(urldecode($requestUri), strlen(urldecode($baseUrl)))))) {
+ // If substr() returns false then PATH_INFO is set to an empty string
+ return '/';
+ } elseif (null === $baseUrl) {
+ return $requestUri;
+ }
+
+ return (string) $pathInfo;
+ }
+
+ /**
+ * Initializes HTTP request formats.
+ */
+ static protected function initializeFormats()
+ {
+ static::$formats = array(
+ 'html' => array('text/html', 'application/xhtml+xml'),
+ 'txt' => array('text/plain'),
+ 'js' => array('application/javascript', 'application/x-javascript', 'text/javascript'),
+ 'css' => array('text/css'),
+ 'json' => array('application/json', 'application/x-json'),
+ 'xml' => array('text/xml', 'application/xml', 'application/x-xml'),
+ 'rdf' => array('application/rdf+xml'),
+ 'atom' => array('application/atom+xml'),
+ 'rss' => array('application/rss+xml'),
+ );
+ }
+
+ /**
+ * Sets the default PHP locale.
+ *
+ * @param string $locale
+ */
+ private function setPhpDefaultLocale($locale)
+ {
+ // if either the class Locale doesn't exist, or an exception is thrown when
+ // setting the default locale, the intl module is not installed, and
+ // the call can be ignored:
+ try {
+ if (class_exists('Locale', false)) {
+ \Locale::setDefault($locale);
+ }
+ } catch (\Exception $e) {
+ }
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/RequestMatcher.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/RequestMatcher.php
new file mode 100755
index 000000000..0ca082d70
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/RequestMatcher.php
@@ -0,0 +1,221 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * RequestMatcher compares a pre-defined set of checks against a Request instance.
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class RequestMatcher implements RequestMatcherInterface
+{
+ /**
+ * @var string
+ */
+ private $path;
+
+ /**
+ * @var string
+ */
+ private $host;
+
+ /**
+ * @var string
+ */
+ private $methods;
+
+ /**
+ * @var string
+ */
+ private $ip;
+
+ /**
+ * Attributes.
+ *
+ * @var array
+ */
+ private $attributes;
+
+ public function __construct($path = null, $host = null, $methods = null, $ip = null, array $attributes = array())
+ {
+ $this->path = $path;
+ $this->host = $host;
+ $this->methods = $methods;
+ $this->ip = $ip;
+ $this->attributes = $attributes;
+ }
+
+ /**
+ * Adds a check for the URL host name.
+ *
+ * @param string $regexp A Regexp
+ */
+ public function matchHost($regexp)
+ {
+ $this->host = $regexp;
+ }
+
+ /**
+ * Adds a check for the URL path info.
+ *
+ * @param string $regexp A Regexp
+ */
+ public function matchPath($regexp)
+ {
+ $this->path = $regexp;
+ }
+
+ /**
+ * Adds a check for the client IP.
+ *
+ * @param string $ip A specific IP address or a range specified using IP/netmask like 192.168.1.0/24
+ */
+ public function matchIp($ip)
+ {
+ $this->ip = $ip;
+ }
+
+ /**
+ * Adds a check for the HTTP method.
+ *
+ * @param string|array $method An HTTP method or an array of HTTP methods
+ */
+ public function matchMethod($method)
+ {
+ $this->methods = array_map('strtoupper', is_array($method) ? $method : array($method));
+ }
+
+ /**
+ * Adds a check for request attribute.
+ *
+ * @param string $key The request attribute name
+ * @param string $regexp A Regexp
+ */
+ public function matchAttribute($key, $regexp)
+ {
+ $this->attributes[$key] = $regexp;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function matches(Request $request)
+ {
+ if (null !== $this->methods && !in_array($request->getMethod(), $this->methods)) {
+ return false;
+ }
+
+ foreach ($this->attributes as $key => $pattern) {
+ if (!preg_match('#'.str_replace('#', '\\#', $pattern).'#', $request->attributes->get($key))) {
+ return false;
+ }
+ }
+
+ if (null !== $this->path) {
+ $path = str_replace('#', '\\#', $this->path);
+
+ if (!preg_match('#'.$path.'#', $request->getPathInfo())) {
+ return false;
+ }
+ }
+
+ if (null !== $this->host && !preg_match('#'.str_replace('#', '\\#', $this->host).'#', $request->getHost())) {
+ return false;
+ }
+
+ if (null !== $this->ip && !$this->checkIp($request->getClientIp(), $this->ip)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Validates an IP address.
+ *
+ * @param string $requestIp
+ * @param string $ip
+ *
+ * @return boolean True valid, false if not.
+ */
+ protected function checkIp($requestIp, $ip)
+ {
+ // IPv6 address
+ if (false !== strpos($requestIp, ':')) {
+ return $this->checkIp6($requestIp, $ip);
+ } else {
+ return $this->checkIp4($requestIp, $ip);
+ }
+ }
+
+ /**
+ * Validates an IPv4 address.
+ *
+ * @param string $requestIp
+ * @param string $ip
+ *
+ * @return boolean True valid, false if not.
+ */
+ protected function checkIp4($requestIp, $ip)
+ {
+ if (false !== strpos($ip, '/')) {
+ list($address, $netmask) = explode('/', $ip, 2);
+
+ if ($netmask < 1 || $netmask > 32) {
+ return false;
+ }
+ } else {
+ $address = $ip;
+ $netmask = 32;
+ }
+
+ return 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask);
+ }
+
+ /**
+ * Validates an IPv6 address.
+ *
+ * @author David Soria Parra
+ * @see https://github.com/dsp/v6tools
+ *
+ * @param string $requestIp
+ * @param string $ip
+ *
+ * @return boolean True valid, false if not.
+ */
+ protected function checkIp6($requestIp, $ip)
+ {
+ if (!defined('AF_INET6')) {
+ throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".');
+ }
+
+ list($address, $netmask) = explode('/', $ip, 2);
+
+ $bytesAddr = unpack("n*", inet_pton($address));
+ $bytesTest = unpack("n*", inet_pton($requestIp));
+
+ for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; $i++) {
+ $left = $netmask - 16 * ($i-1);
+ $left = ($left <= 16) ? $left : 16;
+ $mask = ~(0xffff >> $left) & 0xffff;
+ if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/RequestMatcherInterface.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/RequestMatcherInterface.php
new file mode 100755
index 000000000..506ec7940
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/RequestMatcherInterface.php
@@ -0,0 +1,33 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * RequestMatcherInterface is an interface for strategies to match a Request.
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+interface RequestMatcherInterface
+{
+ /**
+ * Decides whether the rule(s) implemented by the strategy matches the supplied request.
+ *
+ * @param Request $request The request to check for a match
+ *
+ * @return Boolean true if the request matches, false otherwise
+ *
+ * @api
+ */
+ function matches(Request $request);
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Resources/stubs/SessionHandlerInterface.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Resources/stubs/SessionHandlerInterface.php
new file mode 100755
index 000000000..4378b814b
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Resources/stubs/SessionHandlerInterface.php
@@ -0,0 +1,98 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * SessionHandlerInterface
+ *
+ * Provides forward compatability with PHP 5.4
+ *
+ * Extensive documentation can be found at php.net, see links:
+ *
+ * @see http://php.net/sessionhandlerinterface
+ * @see http://php.net/session.customhandler
+ * @see http://php.net/session-set-save-handler
+ *
+ * @author Drak
+ */
+interface SessionHandlerInterface
+{
+ /**
+ * Open session.
+ *
+ * @see http://php.net/sessionhandlerinterface.open
+ *
+ * @param string $savePath Save path.
+ * @param string $sessionName Session Name.
+ *
+ * @throws \RuntimeException If something goes wrong starting the session.
+ *
+ * @return boolean
+ */
+ function open($savePath, $sessionName);
+
+ /**
+ * Close session.
+ *
+ * @see http://php.net/sessionhandlerinterface.close
+ *
+ * @return boolean
+ */
+ function close();
+
+ /**
+ * Read session.
+ *
+ * @see http://php.net/sessionhandlerinterface.read
+ *
+ * @throws \RuntimeException On fatal error but not "record not found".
+ *
+ * @return string String as stored in persistent storage or empty string in all other cases.
+ */
+ function read($sessionId);
+
+ /**
+ * Commit session to storage.
+ *
+ * @see http://php.net/sessionhandlerinterface.write
+ *
+ * @param string $sessionId Session ID.
+ * @param string $data Session serialized data to save.
+ *
+ * @return boolean
+ */
+ function write($sessionId, $data);
+
+ /**
+ * Destroys this session.
+ *
+ * @see http://php.net/sessionhandlerinterface.destroy
+ *
+ * @param string $sessionId Session ID.
+ *
+ * @throws \RuntimeException On fatal error.
+ *
+ * @return boolean
+ */
+ function destroy($sessionId);
+
+ /**
+ * Garbage collection for storage.
+ *
+ * @see http://php.net/sessionhandlerinterface.gc
+ *
+ * @param integer $lifetime Max lifetime in seconds to keep sessions stored.
+ *
+ * @throws \RuntimeException On fatal error.
+ *
+ * @return boolean
+ */
+ function gc($lifetime);
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Response.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Response.php
new file mode 100755
index 000000000..3a0a22e4a
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Response.php
@@ -0,0 +1,1112 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * Response represents an HTTP response.
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class Response
+{
+ /**
+ * @var \Symfony\Component\HttpFoundation\ResponseHeaderBag
+ */
+ public $headers;
+
+ /**
+ * @var string
+ */
+ protected $content;
+
+ /**
+ * @var string
+ */
+ protected $version;
+
+ /**
+ * @var integer
+ */
+ protected $statusCode;
+
+ /**
+ * @var string
+ */
+ protected $statusText;
+
+ /**
+ * @var string
+ */
+ protected $charset;
+
+ /**
+ * Status codes translation table.
+ *
+ * The list of codes is complete according to the
+ * {@link http://www.iana.org/assignments/http-status-codes/ Hypertext Transfer Protocol (HTTP) Status Code Registry}
+ * (last updated 2012-02-13).
+ *
+ * Unless otherwise noted, the status code is defined in RFC2616.
+ *
+ * @var array
+ */
+ static public $statusTexts = array(
+ 100 => 'Continue',
+ 101 => 'Switching Protocols',
+ 102 => 'Processing', // RFC2518
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+ 207 => 'Multi-Status', // RFC4918
+ 208 => 'Already Reported', // RFC5842
+ 226 => 'IM Used', // RFC3229
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Found',
+ 303 => 'See Other',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 306 => 'Reserved',
+ 307 => 'Temporary Redirect',
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Timeout',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Long',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Requested Range Not Satisfiable',
+ 417 => 'Expectation Failed',
+ 418 => 'I\'m a teapot',
+ 422 => 'Unprocessable Entity', // RFC4918
+ 423 => 'Locked', // RFC4918
+ 424 => 'Failed Dependency', // RFC4918
+ 425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817
+ 426 => 'Upgrade Required', // RFC2817
+ 428 => 'Precondition Required', // RFC-nottingham-http-new-status-04
+ 429 => 'Too Many Requests', // RFC-nottingham-http-new-status-04
+ 431 => 'Request Header Fields Too Large', // RFC-nottingham-http-new-status-04
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Timeout',
+ 505 => 'HTTP Version Not Supported',
+ 506 => 'Variant Also Negotiates (Experimental)', // [RFC2295]
+ 507 => 'Insufficient Storage', // RFC4918
+ 508 => 'Loop Detected', // RFC5842
+ 510 => 'Not Extended', // RFC2774
+ 511 => 'Network Authentication Required', // RFC-nottingham-http-new-status-04
+ );
+
+ /**
+ * Constructor.
+ *
+ * @param string $content The response content
+ * @param integer $status The response status code
+ * @param array $headers An array of response headers
+ *
+ * @api
+ */
+ public function __construct($content = '', $status = 200, $headers = array())
+ {
+ $this->headers = new ResponseHeaderBag($headers);
+ $this->setContent($content);
+ $this->setStatusCode($status);
+ $this->setProtocolVersion('1.0');
+ if (!$this->headers->has('Date')) {
+ $this->setDate(new \DateTime(null, new \DateTimeZone('UTC')));
+ }
+ }
+
+ /**
+ * Factory method for chainability
+ *
+ * Example:
+ *
+ * return Response::create($body, 200)
+ * ->setSharedMaxAge(300);
+ *
+ * @param string $content The response content
+ * @param integer $status The response status code
+ * @param array $headers An array of response headers
+ *
+ * @return Response
+ */
+ static public function create($content = '', $status = 200, $headers = array())
+ {
+ return new static($content, $status, $headers);
+ }
+
+ /**
+ * Returns the Response as an HTTP string.
+ *
+ * The string representation of the Resonse is the same as the
+ * one that will be sent to the client only if the prepare() method
+ * has been called before.
+ *
+ * @return string The Response as an HTTP string
+ *
+ * @see prepare()
+ */
+ public function __toString()
+ {
+ return
+ sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n".
+ $this->headers."\r\n".
+ $this->getContent();
+ }
+
+ /**
+ * Clones the current Response instance.
+ */
+ public function __clone()
+ {
+ $this->headers = clone $this->headers;
+ }
+
+ /**
+ * Prepares the Response before it is sent to the client.
+ *
+ * This method tweaks the Response to ensure that it is
+ * compliant with RFC 2616. Most of the changes are based on
+ * the Request that is "associated" with this Response.
+ *
+ * @param Request $request A Request instance
+ */
+ public function prepare(Request $request)
+ {
+ $headers = $this->headers;
+
+ if ($this->isInformational() || in_array($this->statusCode, array(204, 304))) {
+ $this->setContent('');
+ }
+
+ // Content-type based on the Request
+ if (!$headers->has('Content-Type')) {
+ $format = $request->getRequestFormat();
+ if (null !== $format && $mimeType = $request->getMimeType($format)) {
+ $headers->set('Content-Type', $mimeType);
+ }
+ }
+
+ // Fix Content-Type
+ $charset = $this->charset ?: 'UTF-8';
+ if (!$headers->has('Content-Type')) {
+ $headers->set('Content-Type', 'text/html; charset='.$charset);
+ } elseif (0 === strpos($headers->get('Content-Type'), 'text/') && false === strpos($headers->get('Content-Type'), 'charset')) {
+ // add the charset
+ $headers->set('Content-Type', $headers->get('Content-Type').'; charset='.$charset);
+ }
+
+ // Fix Content-Length
+ if ($headers->has('Transfer-Encoding')) {
+ $headers->remove('Content-Length');
+ }
+
+ if ('HEAD' === $request->getMethod()) {
+ // cf. RFC2616 14.13
+ $length = $headers->get('Content-Length');
+ $this->setContent('');
+ if ($length) {
+ $headers->set('Content-Length', $length);
+ }
+ }
+ }
+
+ /**
+ * Sends HTTP headers.
+ *
+ * @return Response
+ */
+ public function sendHeaders()
+ {
+ // headers have already been sent by the developer
+ if (headers_sent()) {
+ return $this;
+ }
+
+ // status
+ header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText));
+
+ // headers
+ foreach ($this->headers->all() as $name => $values) {
+ foreach ($values as $value) {
+ header($name.': '.$value, false);
+ }
+ }
+
+ // cookies
+ foreach ($this->headers->getCookies() as $cookie) {
+ setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
+ }
+
+ return $this;
+ }
+
+ /**
+ * Sends content for the current web response.
+ *
+ * @return Response
+ */
+ public function sendContent()
+ {
+ echo $this->content;
+
+ return $this;
+ }
+
+ /**
+ * Sends HTTP headers and content.
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function send()
+ {
+ $this->sendHeaders();
+ $this->sendContent();
+
+ if (function_exists('fastcgi_finish_request')) {
+ fastcgi_finish_request();
+ }
+
+ return $this;
+ }
+
+ /**
+ * Sets the response content.
+ *
+ * Valid types are strings, numbers, and objects that implement a __toString() method.
+ *
+ * @param mixed $content
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setContent($content)
+ {
+ if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable(array($content, '__toString'))) {
+ throw new \UnexpectedValueException('The Response content must be a string or object implementing __toString(), "'.gettype($content).'" given.');
+ }
+
+ $this->content = (string) $content;
+
+ return $this;
+ }
+
+ /**
+ * Gets the current response content.
+ *
+ * @return string Content
+ *
+ * @api
+ */
+ public function getContent()
+ {
+ return $this->content;
+ }
+
+ /**
+ * Sets the HTTP protocol version (1.0 or 1.1).
+ *
+ * @param string $version The HTTP protocol version
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setProtocolVersion($version)
+ {
+ $this->version = $version;
+
+ return $this;
+ }
+
+ /**
+ * Gets the HTTP protocol version.
+ *
+ * @return string The HTTP protocol version
+ *
+ * @api
+ */
+ public function getProtocolVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Sets the response status code.
+ *
+ * @param integer $code HTTP status code
+ * @param string $text HTTP status text
+ *
+ * @return Response
+ *
+ * @throws \InvalidArgumentException When the HTTP status code is not valid
+ *
+ * @api
+ */
+ public function setStatusCode($code, $text = null)
+ {
+ $this->statusCode = (int) $code;
+ if ($this->isInvalid()) {
+ throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code));
+ }
+
+ $this->statusText = false === $text ? '' : (null === $text ? self::$statusTexts[$this->statusCode] : $text);
+
+ return $this;
+ }
+
+ /**
+ * Retrieves the status code for the current web response.
+ *
+ * @return string Status code
+ *
+ * @api
+ */
+ public function getStatusCode()
+ {
+ return $this->statusCode;
+ }
+
+ /**
+ * Sets the response charset.
+ *
+ * @param string $charset Character set
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setCharset($charset)
+ {
+ $this->charset = $charset;
+
+ return $this;
+ }
+
+ /**
+ * Retrieves the response charset.
+ *
+ * @return string Character set
+ *
+ * @api
+ */
+ public function getCharset()
+ {
+ return $this->charset;
+ }
+
+ /**
+ * Returns true if the response is worth caching under any circumstance.
+ *
+ * Responses marked "private" with an explicit Cache-Control directive are
+ * considered uncacheable.
+ *
+ * Responses with neither a freshness lifetime (Expires, max-age) nor cache
+ * validator (Last-Modified, ETag) are considered uncacheable.
+ *
+ * @return Boolean true if the response is worth caching, false otherwise
+ *
+ * @api
+ */
+ public function isCacheable()
+ {
+ if (!in_array($this->statusCode, array(200, 203, 300, 301, 302, 404, 410))) {
+ return false;
+ }
+
+ if ($this->headers->hasCacheControlDirective('no-store') || $this->headers->getCacheControlDirective('private')) {
+ return false;
+ }
+
+ return $this->isValidateable() || $this->isFresh();
+ }
+
+ /**
+ * Returns true if the response is "fresh".
+ *
+ * Fresh responses may be served from cache without any interaction with the
+ * origin. A response is considered fresh when it includes a Cache-Control/max-age
+ * indicator or Expiration header and the calculated age is less than the freshness lifetime.
+ *
+ * @return Boolean true if the response is fresh, false otherwise
+ *
+ * @api
+ */
+ public function isFresh()
+ {
+ return $this->getTtl() > 0;
+ }
+
+ /**
+ * Returns true if the response includes headers that can be used to validate
+ * the response with the origin server using a conditional GET request.
+ *
+ * @return Boolean true if the response is validateable, false otherwise
+ *
+ * @api
+ */
+ public function isValidateable()
+ {
+ return $this->headers->has('Last-Modified') || $this->headers->has('ETag');
+ }
+
+ /**
+ * Marks the response as "private".
+ *
+ * It makes the response ineligible for serving other clients.
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setPrivate()
+ {
+ $this->headers->removeCacheControlDirective('public');
+ $this->headers->addCacheControlDirective('private');
+
+ return $this;
+ }
+
+ /**
+ * Marks the response as "public".
+ *
+ * It makes the response eligible for serving other clients.
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setPublic()
+ {
+ $this->headers->addCacheControlDirective('public');
+ $this->headers->removeCacheControlDirective('private');
+
+ return $this;
+ }
+
+ /**
+ * Returns true if the response must be revalidated by caches.
+ *
+ * This method indicates that the response must not be served stale by a
+ * cache in any circumstance without first revalidating with the origin.
+ * When present, the TTL of the response should not be overridden to be
+ * greater than the value provided by the origin.
+ *
+ * @return Boolean true if the response must be revalidated by a cache, false otherwise
+ *
+ * @api
+ */
+ public function mustRevalidate()
+ {
+ return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->has('must-proxy-revalidate');
+ }
+
+ /**
+ * Returns the Date header as a DateTime instance.
+ *
+ * @return \DateTime A \DateTime instance
+ *
+ * @throws \RuntimeException When the header is not parseable
+ *
+ * @api
+ */
+ public function getDate()
+ {
+ return $this->headers->getDate('Date');
+ }
+
+ /**
+ * Sets the Date header.
+ *
+ * @param \DateTime $date A \DateTime instance
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setDate(\DateTime $date)
+ {
+ $date->setTimezone(new \DateTimeZone('UTC'));
+ $this->headers->set('Date', $date->format('D, d M Y H:i:s').' GMT');
+
+ return $this;
+ }
+
+ /**
+ * Returns the age of the response.
+ *
+ * @return integer The age of the response in seconds
+ */
+ public function getAge()
+ {
+ if ($age = $this->headers->get('Age')) {
+ return $age;
+ }
+
+ return max(time() - $this->getDate()->format('U'), 0);
+ }
+
+ /**
+ * Marks the response stale by setting the Age header to be equal to the maximum age of the response.
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function expire()
+ {
+ if ($this->isFresh()) {
+ $this->headers->set('Age', $this->getMaxAge());
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the value of the Expires header as a DateTime instance.
+ *
+ * @return \DateTime A DateTime instance
+ *
+ * @api
+ */
+ public function getExpires()
+ {
+ return $this->headers->getDate('Expires');
+ }
+
+ /**
+ * Sets the Expires HTTP header with a DateTime instance.
+ *
+ * If passed a null value, it removes the header.
+ *
+ * @param \DateTime $date A \DateTime instance
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setExpires(\DateTime $date = null)
+ {
+ if (null === $date) {
+ $this->headers->remove('Expires');
+ } else {
+ $date = clone $date;
+ $date->setTimezone(new \DateTimeZone('UTC'));
+ $this->headers->set('Expires', $date->format('D, d M Y H:i:s').' GMT');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Sets the number of seconds after the time specified in the response's Date
+ * header when the the response should no longer be considered fresh.
+ *
+ * First, it checks for a s-maxage directive, then a max-age directive, and then it falls
+ * back on an expires header. It returns null when no maximum age can be established.
+ *
+ * @return integer|null Number of seconds
+ *
+ * @api
+ */
+ public function getMaxAge()
+ {
+ if ($age = $this->headers->getCacheControlDirective('s-maxage')) {
+ return $age;
+ }
+
+ if ($age = $this->headers->getCacheControlDirective('max-age')) {
+ return $age;
+ }
+
+ if (null !== $this->getExpires()) {
+ return $this->getExpires()->format('U') - $this->getDate()->format('U');
+ }
+
+ return null;
+ }
+
+ /**
+ * Sets the number of seconds after which the response should no longer be considered fresh.
+ *
+ * This methods sets the Cache-Control max-age directive.
+ *
+ * @param integer $value Number of seconds
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setMaxAge($value)
+ {
+ $this->headers->addCacheControlDirective('max-age', $value);
+
+ return $this;
+ }
+
+ /**
+ * Sets the number of seconds after which the response should no longer be considered fresh by shared caches.
+ *
+ * This methods sets the Cache-Control s-maxage directive.
+ *
+ * @param integer $value Number of seconds
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setSharedMaxAge($value)
+ {
+ $this->setPublic();
+ $this->headers->addCacheControlDirective('s-maxage', $value);
+
+ return $this;
+ }
+
+ /**
+ * Returns the response's time-to-live in seconds.
+ *
+ * It returns null when no freshness information is present in the response.
+ *
+ * When the responses TTL is <= 0, the response may not be served from cache without first
+ * revalidating with the origin.
+ *
+ * @return integer The TTL in seconds
+ *
+ * @api
+ */
+ public function getTtl()
+ {
+ if ($maxAge = $this->getMaxAge()) {
+ return $maxAge - $this->getAge();
+ }
+
+ return null;
+ }
+
+ /**
+ * Sets the response's time-to-live for shared caches.
+ *
+ * This method adjusts the Cache-Control/s-maxage directive.
+ *
+ * @param integer $seconds Number of seconds
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setTtl($seconds)
+ {
+ $this->setSharedMaxAge($this->getAge() + $seconds);
+
+ return $this;
+ }
+
+ /**
+ * Sets the response's time-to-live for private/client caches.
+ *
+ * This method adjusts the Cache-Control/max-age directive.
+ *
+ * @param integer $seconds Number of seconds
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setClientTtl($seconds)
+ {
+ $this->setMaxAge($this->getAge() + $seconds);
+
+ return $this;
+ }
+
+ /**
+ * Returns the Last-Modified HTTP header as a DateTime instance.
+ *
+ * @return \DateTime A DateTime instance
+ *
+ * @api
+ */
+ public function getLastModified()
+ {
+ return $this->headers->getDate('Last-Modified');
+ }
+
+ /**
+ * Sets the Last-Modified HTTP header with a DateTime instance.
+ *
+ * If passed a null value, it removes the header.
+ *
+ * @param \DateTime $date A \DateTime instance
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setLastModified(\DateTime $date = null)
+ {
+ if (null === $date) {
+ $this->headers->remove('Last-Modified');
+ } else {
+ $date = clone $date;
+ $date->setTimezone(new \DateTimeZone('UTC'));
+ $this->headers->set('Last-Modified', $date->format('D, d M Y H:i:s').' GMT');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the literal value of the ETag HTTP header.
+ *
+ * @return string The ETag HTTP header
+ *
+ * @api
+ */
+ public function getEtag()
+ {
+ return $this->headers->get('ETag');
+ }
+
+ /**
+ * Sets the ETag value.
+ *
+ * @param string $etag The ETag unique identifier
+ * @param Boolean $weak Whether you want a weak ETag or not
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setEtag($etag = null, $weak = false)
+ {
+ if (null === $etag) {
+ $this->headers->remove('Etag');
+ } else {
+ if (0 !== strpos($etag, '"')) {
+ $etag = '"'.$etag.'"';
+ }
+
+ $this->headers->set('ETag', (true === $weak ? 'W/' : '').$etag);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Sets the response's cache headers (validation and/or expiration).
+ *
+ * Available options are: etag, last_modified, max_age, s_maxage, private, and public.
+ *
+ * @param array $options An array of cache options
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setCache(array $options)
+ {
+ if ($diff = array_diff(array_keys($options), array('etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public'))) {
+ throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', array_values($diff))));
+ }
+
+ if (isset($options['etag'])) {
+ $this->setEtag($options['etag']);
+ }
+
+ if (isset($options['last_modified'])) {
+ $this->setLastModified($options['last_modified']);
+ }
+
+ if (isset($options['max_age'])) {
+ $this->setMaxAge($options['max_age']);
+ }
+
+ if (isset($options['s_maxage'])) {
+ $this->setSharedMaxAge($options['s_maxage']);
+ }
+
+ if (isset($options['public'])) {
+ if ($options['public']) {
+ $this->setPublic();
+ } else {
+ $this->setPrivate();
+ }
+ }
+
+ if (isset($options['private'])) {
+ if ($options['private']) {
+ $this->setPrivate();
+ } else {
+ $this->setPublic();
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Modifies the response so that it conforms to the rules defined for a 304 status code.
+ *
+ * This sets the status, removes the body, and discards any headers
+ * that MUST NOT be included in 304 responses.
+ *
+ * @return Response
+ *
+ * @see http://tools.ietf.org/html/rfc2616#section-10.3.5
+ *
+ * @api
+ */
+ public function setNotModified()
+ {
+ $this->setStatusCode(304);
+ $this->setContent(null);
+
+ // remove headers that MUST NOT be included with 304 Not Modified responses
+ foreach (array('Allow', 'Content-Encoding', 'Content-Language', 'Content-Length', 'Content-MD5', 'Content-Type', 'Last-Modified') as $header) {
+ $this->headers->remove($header);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns true if the response includes a Vary header.
+ *
+ * @return Boolean true if the response includes a Vary header, false otherwise
+ *
+ * @api
+ */
+ public function hasVary()
+ {
+ return (Boolean) $this->headers->get('Vary');
+ }
+
+ /**
+ * Returns an array of header names given in the Vary header.
+ *
+ * @return array An array of Vary names
+ *
+ * @api
+ */
+ public function getVary()
+ {
+ if (!$vary = $this->headers->get('Vary')) {
+ return array();
+ }
+
+ return is_array($vary) ? $vary : preg_split('/[\s,]+/', $vary);
+ }
+
+ /**
+ * Sets the Vary header.
+ *
+ * @param string|array $headers
+ * @param Boolean $replace Whether to replace the actual value of not (true by default)
+ *
+ * @return Response
+ *
+ * @api
+ */
+ public function setVary($headers, $replace = true)
+ {
+ $this->headers->set('Vary', $headers, $replace);
+
+ return $this;
+ }
+
+ /**
+ * Determines if the Response validators (ETag, Last-Modified) match
+ * a conditional value specified in the Request.
+ *
+ * If the Response is not modified, it sets the status code to 304 and
+ * removes the actual content by calling the setNotModified() method.
+ *
+ * @param Request $request A Request instance
+ *
+ * @return Boolean true if the Response validators match the Request, false otherwise
+ *
+ * @api
+ */
+ public function isNotModified(Request $request)
+ {
+ $lastModified = $request->headers->get('If-Modified-Since');
+ $notModified = false;
+ if ($etags = $request->getEtags()) {
+ $notModified = (in_array($this->getEtag(), $etags) || in_array('*', $etags)) && (!$lastModified || $this->headers->get('Last-Modified') == $lastModified);
+ } elseif ($lastModified) {
+ $notModified = $lastModified == $this->headers->get('Last-Modified');
+ }
+
+ if ($notModified) {
+ $this->setNotModified();
+ }
+
+ return $notModified;
+ }
+
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
+ /**
+ * Is response invalid?
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isInvalid()
+ {
+ return $this->statusCode < 100 || $this->statusCode >= 600;
+ }
+
+ /**
+ * Is response informative?
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isInformational()
+ {
+ return $this->statusCode >= 100 && $this->statusCode < 200;
+ }
+
+ /**
+ * Is response successful?
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isSuccessful()
+ {
+ return $this->statusCode >= 200 && $this->statusCode < 300;
+ }
+
+ /**
+ * Is the response a redirect?
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isRedirection()
+ {
+ return $this->statusCode >= 300 && $this->statusCode < 400;
+ }
+
+ /**
+ * Is there a client error?
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isClientError()
+ {
+ return $this->statusCode >= 400 && $this->statusCode < 500;
+ }
+
+ /**
+ * Was there a server side error?
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isServerError()
+ {
+ return $this->statusCode >= 500 && $this->statusCode < 600;
+ }
+
+ /**
+ * Is the response OK?
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isOk()
+ {
+ return 200 === $this->statusCode;
+ }
+
+ /**
+ * Is the reponse forbidden?
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isForbidden()
+ {
+ return 403 === $this->statusCode;
+ }
+
+ /**
+ * Is the response a not found error?
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isNotFound()
+ {
+ return 404 === $this->statusCode;
+ }
+
+ /**
+ * Is the response a redirect of some form?
+ *
+ * @param string $location
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isRedirect($location = null)
+ {
+ return in_array($this->statusCode, array(201, 301, 302, 303, 307)) && (null === $location ?: $location == $this->headers->get('Location'));
+ }
+
+ /**
+ * Is the response empty?
+ *
+ * @return Boolean
+ *
+ * @api
+ */
+ public function isEmpty()
+ {
+ return in_array($this->statusCode, array(201, 204, 304));
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/ResponseHeaderBag.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/ResponseHeaderBag.php
new file mode 100755
index 000000000..11615b96c
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/ResponseHeaderBag.php
@@ -0,0 +1,293 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * ResponseHeaderBag is a container for Response HTTP headers.
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class ResponseHeaderBag extends HeaderBag
+{
+ const COOKIES_FLAT = 'flat';
+ const COOKIES_ARRAY = 'array';
+
+ const DISPOSITION_ATTACHMENT = 'attachment';
+ const DISPOSITION_INLINE = 'inline';
+
+ /**
+ * @var array
+ */
+ protected $computedCacheControl = array();
+
+ /**
+ * @var array
+ */
+ protected $cookies = array();
+
+ /**
+ * Constructor.
+ *
+ * @param array $headers An array of HTTP headers
+ *
+ * @api
+ */
+ public function __construct(array $headers = array())
+ {
+ parent::__construct($headers);
+
+ if (!isset($this->headers['cache-control'])) {
+ $this->set('cache-control', '');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __toString()
+ {
+ $cookies = '';
+ foreach ($this->getCookies() as $cookie) {
+ $cookies .= 'Set-Cookie: '.$cookie."\r\n";
+ }
+
+ return parent::__toString().$cookies;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function replace(array $headers = array())
+ {
+ parent::replace($headers);
+
+ if (!isset($this->headers['cache-control'])) {
+ $this->set('cache-control', '');
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function set($key, $values, $replace = true)
+ {
+ parent::set($key, $values, $replace);
+
+ // ensure the cache-control header has sensible defaults
+ if (in_array(strtr(strtolower($key), '_', '-'), array('cache-control', 'etag', 'last-modified', 'expires'))) {
+ $computed = $this->computeCacheControlValue();
+ $this->headers['cache-control'] = array($computed);
+ $this->computedCacheControl = $this->parseCacheControl($computed);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @api
+ */
+ public function remove($key)
+ {
+ parent::remove($key);
+
+ if ('cache-control' === strtr(strtolower($key), '_', '-')) {
+ $this->computedCacheControl = array();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasCacheControlDirective($key)
+ {
+ return array_key_exists($key, $this->computedCacheControl);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheControlDirective($key)
+ {
+ return array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null;
+ }
+
+ /**
+ * Sets a cookie.
+ *
+ * @param Cookie $cookie
+ *
+ * @api
+ */
+ public function setCookie(Cookie $cookie)
+ {
+ $this->cookies[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie;
+ }
+
+ /**
+ * Removes a cookie from the array, but does not unset it in the browser
+ *
+ * @param string $name
+ * @param string $path
+ * @param string $domain
+ *
+ * @api
+ */
+ public function removeCookie($name, $path = '/', $domain = null)
+ {
+ if (null === $path) {
+ $path = '/';
+ }
+
+ unset($this->cookies[$domain][$path][$name]);
+
+ if (empty($this->cookies[$domain][$path])) {
+ unset($this->cookies[$domain][$path]);
+
+ if (empty($this->cookies[$domain])) {
+ unset($this->cookies[$domain]);
+ }
+ }
+ }
+
+ /**
+ * Returns an array with all cookies
+ *
+ * @param string $format
+ *
+ * @throws \InvalidArgumentException When the $format is invalid
+ *
+ * @return array
+ *
+ * @api
+ */
+ public function getCookies($format = self::COOKIES_FLAT)
+ {
+ if (!in_array($format, array(self::COOKIES_FLAT, self::COOKIES_ARRAY))) {
+ throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', array(self::COOKIES_FLAT, self::COOKIES_ARRAY))));
+ }
+
+ if (self::COOKIES_ARRAY === $format) {
+ return $this->cookies;
+ }
+
+ $flattenedCookies = array();
+ foreach ($this->cookies as $path) {
+ foreach ($path as $cookies) {
+ foreach ($cookies as $cookie) {
+ $flattenedCookies[] = $cookie;
+ }
+ }
+ }
+
+ return $flattenedCookies;
+ }
+
+ /**
+ * Clears a cookie in the browser
+ *
+ * @param string $name
+ * @param string $path
+ * @param string $domain
+ *
+ * @api
+ */
+ public function clearCookie($name, $path = '/', $domain = null)
+ {
+ $this->setCookie(new Cookie($name, null, 1, $path, $domain));
+ }
+
+ /**
+ * Generates a HTTP Content-Disposition field-value.
+ *
+ * @param string $disposition One of "inline" or "attachment"
+ * @param string $filename A unicode string
+ * @param string $filenameFallback A string containing only ASCII characters that
+ * is semantically equivalent to $filename. If the filename is already ASCII,
+ * it can be omitted, or just copied from $filename
+ *
+ * @return string A string suitable for use as a Content-Disposition field-value.
+ *
+ * @throws \InvalidArgumentException
+ * @see RFC 6266
+ */
+ public function makeDisposition($disposition, $filename, $filenameFallback = '')
+ {
+ if (!in_array($disposition, array(self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE))) {
+ throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE));
+ }
+
+ if (!$filenameFallback) {
+ $filenameFallback = $filename;
+ }
+
+ // filenameFallback is not ASCII.
+ if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) {
+ throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.');
+ }
+
+ // percent characters aren't safe in fallback.
+ if (false !== strpos($filenameFallback, '%')) {
+ throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.');
+ }
+
+ // path separators aren't allowed in either.
+ if (preg_match('#[/\\\\]#', $filename) || preg_match('#[/\\\\]#', $filenameFallback)) {
+ throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
+ }
+
+ $output = sprintf('%s; filename="%s"', $disposition, str_replace(array('\\', '"'), array('\\\\', '\\"'), $filenameFallback));
+
+ if ($filename != $filenameFallback) {
+ $output .= sprintf("; filename*=utf-8''%s", str_replace(array("'", '(', ')', '*'), array('%27', '%28', '%29', '%2A'), urlencode($filename)));
+ }
+
+ return $output;
+ }
+
+ /**
+ * Returns the calculated value of the cache-control header.
+ *
+ * This considers several other headers and calculates or modifies the
+ * cache-control header to a sensible, conservative value.
+ *
+ * @return string
+ */
+ protected function computeCacheControlValue()
+ {
+ if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) {
+ return 'no-cache';
+ }
+
+ if (!$this->cacheControl) {
+ // conservative by default
+ return 'private, must-revalidate';
+ }
+
+ $header = $this->getCacheControlHeader();
+ if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) {
+ return $header;
+ }
+
+ // public if s-maxage is defined, private otherwise
+ if (!isset($this->cacheControl['s-maxage'])) {
+ return $header.', private';
+ }
+
+ return $header;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/ServerBag.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/ServerBag.php
new file mode 100755
index 000000000..9b57f9ee0
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/ServerBag.php
@@ -0,0 +1,48 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * ServerBag is a container for HTTP headers from the $_SERVER variable.
+ *
+ * @author Fabien Potencier
+ * @author Bulat Shakirzyanov
+ */
+class ServerBag extends ParameterBag
+{
+ /**
+ * Gets the HTTP headers.
+ *
+ * @return string
+ */
+ public function getHeaders()
+ {
+ $headers = array();
+ foreach ($this->parameters as $key => $value) {
+ if (0 === strpos($key, 'HTTP_')) {
+ $headers[substr($key, 5)] = $value;
+ }
+ // CONTENT_* are not prefixed with HTTP_
+ elseif (in_array($key, array('CONTENT_LENGTH', 'CONTENT_MD5', 'CONTENT_TYPE'))) {
+ $headers[$key] = $this->parameters[$key];
+ }
+ }
+
+ // PHP_AUTH_USER/PHP_AUTH_PW
+ if (isset($this->parameters['PHP_AUTH_USER'])) {
+ $pass = isset($this->parameters['PHP_AUTH_PW']) ? $this->parameters['PHP_AUTH_PW'] : '';
+ $headers['AUTHORIZATION'] = 'Basic '.base64_encode($this->parameters['PHP_AUTH_USER'].':'.$pass);
+ }
+
+ return $headers;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBag.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBag.php
new file mode 100755
index 000000000..d1bcb0ffb
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBag.php
@@ -0,0 +1,137 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Attribute;
+
+/**
+ * This class relates to session attribute storage
+ */
+class AttributeBag implements AttributeBagInterface
+{
+ private $name = 'attributes';
+
+ /**
+ * @var string
+ */
+ private $storageKey;
+
+ /**
+ * @var array
+ */
+ protected $attributes = array();
+
+ /**
+ * Constructor.
+ *
+ * @param string $storageKey The key used to store flashes in the session.
+ */
+ public function __construct($storageKey = '_sf2_attributes')
+ {
+ $this->storageKey = $storageKey;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function initialize(array &$attributes)
+ {
+ $this->attributes = &$attributes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getStorageKey()
+ {
+ return $this->storageKey;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($name)
+ {
+ return array_key_exists($name, $this->attributes);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($name, $default = null)
+ {
+ return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($name, $value)
+ {
+ $this->attributes[$name] = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function all()
+ {
+ return $this->attributes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function replace(array $attributes)
+ {
+ $this->attributes = array();
+ foreach ($attributes as $key => $value) {
+ $this->set($key, $value);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function remove($name)
+ {
+ $retval = null;
+ if (array_key_exists($name, $this->attributes)) {
+ $retval = $this->attributes[$name];
+ unset($this->attributes[$name]);
+ }
+
+ return $retval;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ $return = $this->attributes;
+ $this->attributes = array();
+
+ return $return;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBagInterface.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBagInterface.php
new file mode 100755
index 000000000..ec6d93c02
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Attribute/AttributeBagInterface.php
@@ -0,0 +1,72 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Attribute;
+
+use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
+
+/**
+ * Attributes store.
+ *
+ * @author Drak
+ */
+interface AttributeBagInterface extends SessionBagInterface
+{
+ /**
+ * Checks if an attribute is defined.
+ *
+ * @param string $name The attribute name
+ *
+ * @return Boolean true if the attribute is defined, false otherwise
+ */
+ function has($name);
+
+ /**
+ * Returns an attribute.
+ *
+ * @param string $name The attribute name
+ * @param mixed $default The default value if not found.
+ *
+ * @return mixed
+ */
+ function get($name, $default = null);
+
+ /**
+ * Sets an attribute.
+ *
+ * @param string $name
+ * @param mixed $value
+ */
+ function set($name, $value);
+
+ /**
+ * Returns attributes.
+ *
+ * @return array Attributes
+ */
+ function all();
+
+ /**
+ * Sets attributes.
+ *
+ * @param array $attributes Attributes
+ */
+ function replace(array $attributes);
+
+ /**
+ * Removes an attribute.
+ *
+ * @param string $name
+ *
+ * @return mixed The removed value
+ */
+ function remove($name);
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php
new file mode 100755
index 000000000..138aa3614
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Attribute/NamespacedAttributeBag.php
@@ -0,0 +1,154 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Attribute;
+
+/**
+ * This class provides structured storage of session attributes using
+ * a name spacing character in the key.
+ *
+ * @author Drak
+ */
+class NamespacedAttributeBag extends AttributeBag
+{
+ /**
+ * Namespace character.
+ *
+ * @var string
+ */
+ private $namespaceCharacter;
+
+ /**
+ * Constructor.
+ *
+ * @param string $storageKey Session storage key.
+ * @param string $namespaceCharacter Namespace character to use in keys.
+ */
+ public function __construct($storageKey = '_sf2_attributes', $namespaceCharacter = '/')
+ {
+ $this->namespaceCharacter = $namespaceCharacter;
+ parent::__construct($storageKey);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($name)
+ {
+ $attributes = $this->resolveAttributePath($name);
+ $name = $this->resolveKey($name);
+
+ return array_key_exists($name, $attributes);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($name, $default = null)
+ {
+ $attributes = $this->resolveAttributePath($name);
+ $name = $this->resolveKey($name);
+
+ return array_key_exists($name, $attributes) ? $attributes[$name] : $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($name, $value)
+ {
+ $attributes = & $this->resolveAttributePath($name, true);
+ $name = $this->resolveKey($name);
+ $attributes[$name] = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function remove($name)
+ {
+ $retval = null;
+ $attributes = & $this->resolveAttributePath($name);
+ $name = $this->resolveKey($name);
+ if (array_key_exists($name, $attributes)) {
+ $retval = $attributes[$name];
+ unset($attributes[$name]);
+ }
+
+ return $retval;
+ }
+
+ /**
+ * Resolves a path in attributes property and returns it as a reference.
+ *
+ * This method allows structured namespacing of session attributes.
+ *
+ * @param string $name Key name
+ * @param boolean $writeContext Write context, default false
+ *
+ * @return array
+ */
+ protected function &resolveAttributePath($name, $writeContext = false)
+ {
+ $array = & $this->attributes;
+ $name = (strpos($name, $this->namespaceCharacter) === 0) ? substr($name, 1) : $name;
+
+ // Check if there is anything to do, else return
+ if (!$name) {
+ return $array;
+ }
+
+ $parts = explode($this->namespaceCharacter, $name);
+ if (count($parts) < 2) {
+ if (!$writeContext) {
+ return $array;
+ }
+
+ $array[$parts[0]] = array();
+
+ return $array;
+ }
+
+ unset($parts[count($parts)-1]);
+
+ foreach ($parts as $part) {
+ if (!array_key_exists($part, $array)) {
+ if (!$writeContext) {
+ return $array;
+ }
+
+ $array[$part] = array();
+ }
+
+ $array = & $array[$part];
+ }
+
+ return $array;
+ }
+
+ /**
+ * Resolves the key from the name.
+ *
+ * This is the last part in a dot separated string.
+ *
+ * @param string $name
+ *
+ * @return string
+ */
+ protected function resolveKey($name)
+ {
+ if (strpos($name, $this->namespaceCharacter) !== false) {
+ $name = substr($name, strrpos($name, $this->namespaceCharacter)+1, strlen($name));
+ }
+
+ return $name;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Flash/AutoExpireFlashBag.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Flash/AutoExpireFlashBag.php
new file mode 100755
index 000000000..10257847e
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Flash/AutoExpireFlashBag.php
@@ -0,0 +1,171 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Flash;
+
+/**
+ * AutoExpireFlashBag flash message container.
+ *
+ * @author Drak
+ */
+class AutoExpireFlashBag implements FlashBagInterface
+{
+ private $name = 'flashes';
+
+ /**
+ * Flash messages.
+ *
+ * @var array
+ */
+ private $flashes = array();
+
+ /**
+ * The storage key for flashes in the session
+ *
+ * @var string
+ */
+ private $storageKey;
+
+ /**
+ * Constructor.
+ *
+ * @param string $storageKey The key used to store flashes in the session.
+ */
+ public function __construct($storageKey = '_sf2_flashes')
+ {
+ $this->storageKey = $storageKey;
+ $this->flashes = array('display' => array(), 'new' => array());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function initialize(array &$flashes)
+ {
+ $this->flashes = &$flashes;
+
+ // The logic: messages from the last request will be stored in new, so we move them to previous
+ // This request we will show what is in 'display'. What is placed into 'new' this time round will
+ // be moved to display next time round.
+ $this->flashes['display'] = array_key_exists('new', $this->flashes) ? $this->flashes['new'] : array();
+ $this->flashes['new'] = array();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function peek($type, $default = null)
+ {
+ return $this->has($type) ? $this->flashes['display'][$type] : $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function peekAll()
+ {
+ return array_key_exists('display', $this->flashes) ? (array)$this->flashes['display'] : array();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($type, $default = null)
+ {
+ $return = $default;
+
+ if (!$this->has($type)) {
+ return $return;
+ }
+
+ if (isset($this->flashes['display'][$type])) {
+ $return = $this->flashes['display'][$type];
+ unset($this->flashes['display'][$type]);
+ }
+
+ return $return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function all()
+ {
+ $return = $this->flashes['display'];
+ $this->flashes = array('new' => array(), 'display' => array());
+
+ return $return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setAll(array $messages)
+ {
+ $this->flashes['new'] = $messages;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($type, $message)
+ {
+ $this->flashes['new'][$type] = $message;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($type)
+ {
+ return array_key_exists($type, $this->flashes['display']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function keys()
+ {
+ return array_keys($this->flashes['display']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getStorageKey()
+ {
+ return $this->storageKey;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ $return = $this->all();
+ $this->flashes = array('display' => array(), 'new' => array());
+
+ return $return;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php
new file mode 100755
index 000000000..c0b4ee57a
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Flash/FlashBag.php
@@ -0,0 +1,158 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Flash;
+
+/**
+ * FlashBag flash message container.
+ *
+ * @author Drak
+ */
+class FlashBag implements FlashBagInterface
+{
+ private $name = 'flashes';
+
+ /**
+ * Flash messages.
+ *
+ * @var array
+ */
+ private $flashes = array();
+
+ /**
+ * The storage key for flashes in the session
+ *
+ * @var string
+ */
+ private $storageKey;
+
+ /**
+ * Constructor.
+ *
+ * @param string $storageKey The key used to store flashes in the session.
+ */
+ public function __construct($storageKey = '_sf2_flashes')
+ {
+ $this->storageKey = $storageKey;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function initialize(array &$flashes)
+ {
+ $this->flashes = &$flashes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function peek($type, $default = null)
+ {
+ return $this->has($type) ? $this->flashes[$type] : $default;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function peekAll()
+ {
+ return $this->flashes;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($type, $default = null)
+ {
+ if (!$this->has($type)) {
+ return $default;
+ }
+
+ $return = $this->flashes[$type];
+
+ unset($this->flashes[$type]);
+
+ return $return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function all()
+ {
+ $return = $this->peekAll();
+ $this->flashes = array();
+
+ return $return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($type, $message)
+ {
+ $this->flashes[$type] = $message;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setAll(array $messages)
+ {
+ $this->flashes = $messages;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($type)
+ {
+ return array_key_exists($type, $this->flashes);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function keys()
+ {
+ return array_keys($this->flashes);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getStorageKey()
+ {
+ return $this->storageKey;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ return $this->all();
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php
new file mode 100755
index 000000000..0c45d74bb
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Flash/FlashBagInterface.php
@@ -0,0 +1,85 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Flash;
+
+use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
+
+/**
+ * FlashBagInterface.
+ *
+ * @author Drak
+ */
+interface FlashBagInterface extends SessionBagInterface
+{
+ /**
+ * Registers a message for a given type.
+ *
+ * @param string $type
+ * @param string $message
+ */
+ function set($type, $message);
+
+ /**
+ * Gets flash message for a given type.
+ *
+ * @param string $type Message category type.
+ * @param string $default Default value if $type doee not exist.
+ *
+ * @return string
+ */
+ function peek($type, $default = null);
+
+ /**
+ * Gets all flash messages.
+ *
+ * @return array
+ */
+ function peekAll();
+
+ /**
+ * Gets and clears flash from the stack.
+ *
+ * @param string $type
+ * @param string $default Default value if $type doee not exist.
+ *
+ * @return string
+ */
+ function get($type, $default = null);
+
+ /**
+ * Gets and clears flashes from the stack.
+ *
+ * @return array
+ */
+ function all();
+
+ /**
+ * Sets all flash messages.
+ */
+ function setAll(array $messages);
+
+ /**
+ * Has flash messages for a given type?
+ *
+ * @param string $type
+ *
+ * @return boolean
+ */
+ function has($type);
+
+ /**
+ * Returns a list of all defined types.
+ *
+ * @return array
+ */
+ function keys();
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Session.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Session.php
new file mode 100755
index 000000000..13c644887
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Session.php
@@ -0,0 +1,300 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session;
+
+use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface;
+use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
+use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface;
+use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
+use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
+use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
+use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
+
+/**
+ * Session.
+ *
+ * @author Fabien Potencier
+ * @author Drak
+ *
+ * @api
+ */
+class Session implements SessionInterface
+{
+ /**
+ * Storage driver.
+ *
+ * @var SessionStorageInterface
+ */
+ protected $storage;
+
+ /**
+ * @var string
+ */
+ private $flashName;
+
+ /**
+ * @var string
+ */
+ private $attributeName;
+
+ /**
+ * Constructor.
+ *
+ * @param SessionStorageInterface $storage A SessionStorageInterface instance.
+ * @param AttributeBagInterface $attributes An AttributeBagInterface instance, (defaults null for default AttributeBag)
+ * @param FlashBagInterface $flashes A FlashBagInterface instance (defaults null for default FlashBag)
+ */
+ public function __construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null)
+ {
+ $this->storage = $storage ?: new NativeSessionStorage();
+
+ $attributeBag = $attributes ?: new AttributeBag();
+ $this->attributeName = $attributeBag->getName();
+ $this->registerBag($attributeBag);
+
+ $flashBag = $flashes ?: new FlashBag();
+ $this->flashName = $flashBag->getName();
+ $this->registerBag($flashBag);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start()
+ {
+ return $this->storage->start();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function has($name)
+ {
+ return $this->storage->getBag($this->attributeName)->has($name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($name, $default = null)
+ {
+ return $this->storage->getBag($this->attributeName)->get($name, $default);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function set($name, $value)
+ {
+ $this->storage->getBag($this->attributeName)->set($name, $value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function all()
+ {
+ return $this->storage->getBag($this->attributeName)->all();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function replace(array $attributes)
+ {
+ $this->storage->getBag($this->attributeName)->replace($attributes);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function remove($name)
+ {
+ return $this->storage->getBag($this->attributeName)->remove($name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ $this->storage->getBag($this->attributeName)->clear();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function invalidate()
+ {
+ $this->storage->clear();
+
+ return $this->storage->regenerate(true);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function migrate($destroy = false)
+ {
+ return $this->storage->regenerate($destroy);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save()
+ {
+ $this->storage->save();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getId()
+ {
+ return $this->storage->getId();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setId($id)
+ {
+ $this->storage->setId($id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->storage->getName();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setName($name)
+ {
+ $this->storage->setName($name);
+ }
+
+ /**
+ * Registers a SessionBagInterface with the session.
+ *
+ * @param SessionBagInterface $bag
+ */
+ public function registerBag(SessionBagInterface $bag)
+ {
+ $this->storage->registerBag($bag);
+ }
+
+ /**
+ * Get's a bag instance.
+ *
+ * @param string $name
+ *
+ * @return SessionBagInterface
+ */
+ public function getBag($name)
+ {
+ return $this->storage->getBag($name);
+ }
+
+ /**
+ * Gets the flashbag interface.
+ *
+ * @return FlashBagInterface
+ */
+ public function getFlashBag()
+ {
+ return $this->getBag($this->flashName);
+ }
+
+ // the following methods are kept for compatibility with Symfony 2.0 (they will be removed for Symfony 2.3)
+
+ /**
+ * @return array
+ *
+ * @deprecated since 2.1, will be removed from 2.3
+ */
+ public function getFlashes()
+ {
+ return $this->getBag('flashes')->all();
+ }
+
+ /**
+ * @param array $values
+ *
+ * @deprecated since 2.1, will be removed from 2.3
+ */
+ public function setFlashes($values)
+ {
+ $this->getBag('flashes')->setAll($values);
+ }
+
+ /**
+ * @param string $name
+ * @param string $default
+ *
+ * @return string
+ *
+ * @deprecated since 2.1, will be removed from 2.3
+ */
+ public function getFlash($name, $default = null)
+ {
+ return $this->getBag('flashes')->get($name, $default);
+ }
+
+ /**
+ * @param string $name
+ * @param string $value
+ *
+ * @deprecated since 2.1, will be removed from 2.3
+ */
+ public function setFlash($name, $value)
+ {
+ $this->getBag('flashes')->set($name, $value);
+ }
+
+ /**
+ * @param string $name
+ *
+ * @return Boolean
+ *
+ * @deprecated since 2.1, will be removed from 2.3
+ */
+ public function hasFlash($name)
+ {
+ return $this->getBag('flashes')->has($name);
+ }
+
+ /**
+ * @param string $name
+ *
+ * @deprecated since 2.1, will be removed from 2.3
+ */
+ public function removeFlash($name)
+ {
+ $this->getBag('flashes')->get($name);
+ }
+
+ /**
+ * @return array
+ *
+ * @deprecated since 2.1, will be removed from 2.3
+ */
+ public function clearFlashes()
+ {
+ return $this->getBag('flashes')->clear();
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/SessionBagInterface.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/SessionBagInterface.php
new file mode 100755
index 000000000..50c2d4bd0
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/SessionBagInterface.php
@@ -0,0 +1,48 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session;
+
+/**
+ * Session Bag store.
+ *
+ * @author Drak
+ */
+interface SessionBagInterface
+{
+ /**
+ * Gets this bag's name
+ *
+ * @return string
+ */
+ function getName();
+
+ /**
+ * Initializes the Bag
+ *
+ * @param array $array
+ */
+ function initialize(array &$array);
+
+ /**
+ * Gets the storage key for this bag.
+ *
+ * @return string
+ */
+ function getStorageKey();
+
+ /**
+ * Clears out data from bag.
+ *
+ * @return mixed Whatever data was contained.
+ */
+ function clear();
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/SessionInterface.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/SessionInterface.php
new file mode 100755
index 000000000..4e4962de4
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/SessionInterface.php
@@ -0,0 +1,167 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session;
+
+/**
+ * Interface for the session.
+ *
+ * @author Drak
+ */
+interface SessionInterface
+{
+ /**
+ * Starts the session storage.
+ *
+ * @return Boolean True if session started.
+ *
+ * @throws \RuntimeException If session fails to start.
+ *
+ * @api
+ */
+ function start();
+
+ /**
+ * Returns the session ID.
+ *
+ * @return string The session ID.
+ *
+ * @api
+ */
+ function getId();
+
+ /**
+ * Sets the session ID
+ *
+ * @param string $id
+ *
+ * @api
+ */
+ function setId($id);
+
+ /**
+ * Returns the session name.
+ *
+ * @return mixed The session name.
+ *
+ * @api
+ */
+ function getName();
+
+ /**
+ * Sets the session name.
+ *
+ * @param string $name
+ *
+ * @api
+ */
+ function setName($name);
+
+ /**
+ * Invalidates the current session.
+ *
+ * Clears all session attributes and flashes and regenerates the
+ * session and deletes the old session from persistence.
+ *
+ * @return Boolean True if session invalidated, false if error.
+ *
+ * @api
+ */
+ function invalidate();
+
+ /**
+ * Migrates the current session to a new session id while maintaining all
+ * session attributes.
+ *
+ * @param Boolean $destroy Whether to delete the old session or leave it to garbage collection.
+ *
+ * @return Boolean True if session migrated, false if error.
+ *
+ * @api
+ */
+ function migrate($destroy = false);
+
+ /**
+ * Force the session to be saved and closed.
+ *
+ * This method is generally not required for real sessions as
+ * the session will be automatically saved at the end of
+ * code execution.
+ */
+ function save();
+
+ /**
+ * Checks if an attribute is defined.
+ *
+ * @param string $name The attribute name
+ *
+ * @return Boolean true if the attribute is defined, false otherwise
+ *
+ * @api
+ */
+ function has($name);
+
+ /**
+ * Returns an attribute.
+ *
+ * @param string $name The attribute name
+ * @param mixed $default The default value if not found.
+ *
+ * @return mixed
+ *
+ * @api
+ */
+ function get($name, $default = null);
+
+ /**
+ * Sets an attribute.
+ *
+ * @param string $name
+ * @param mixed $value
+ *
+ * @api
+ */
+ function set($name, $value);
+
+ /**
+ * Returns attributes.
+ *
+ * @return array Attributes
+ *
+ * @api
+ */
+ function all();
+
+ /**
+ * Sets attributes.
+ *
+ * @param array $attributes Attributes
+ */
+ function replace(array $attributes);
+
+ /**
+ * Removes an attribute.
+ *
+ * @param string $name
+ *
+ * @return mixed The removed value
+ *
+ * @api
+ */
+ function remove($name);
+
+ /**
+ * Clears all attributes.
+ *
+ * @api
+ */
+ function clear();
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcacheSessionHandler.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcacheSessionHandler.php
new file mode 100755
index 000000000..00488fd0d
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcacheSessionHandler.php
@@ -0,0 +1,139 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * MemcacheSessionHandler.
+ *
+ * @author Drak
+ */
+class MemcacheSessionHandler implements \SessionHandlerInterface
+{
+ /**
+ * Memcache driver.
+ *
+ * @var \Memcache
+ */
+ private $memcache;
+
+ /**
+ * Configuration options.
+ *
+ * @var array
+ */
+ private $memcacheOptions;
+
+ /**
+ * Key prefix for shared environments.
+ *
+ * @var string
+ */
+ private $prefix;
+
+ /**
+ * Constructor.
+ *
+ * @param \Memcache $memcache A \Memcache instance
+ * @param array $memcacheOptions An associative array of Memcache options
+ * @param array $options Session configuration options.
+ */
+ public function __construct(\Memcache $memcache, array $memcacheOptions = array(), array $options = array())
+ {
+ $this->memcache = $memcache;
+
+ // defaults
+ if (!isset($memcacheOptions['serverpool'])) {
+ $memcacheOptions['serverpool'] = array(array(
+ 'host' => '127.0.0.1',
+ 'port' => 11211,
+ 'timeout' => 1,
+ 'persistent' => false,
+ 'weight' => 1,
+ 'retry_interval' => 15,
+ ));
+ }
+
+ $memcacheOptions['expiretime'] = isset($memcacheOptions['expiretime']) ? (int)$memcacheOptions['expiretime'] : 86400;
+ $this->prefix = isset($memcacheOptions['prefix']) ? $memcacheOptions['prefix'] : 'sf2s';
+
+ $this->memcacheOptions = $memcacheOptions;
+ }
+
+ protected function addServer(array $server)
+ {
+ if (!array_key_exists('host', $server)) {
+ throw new \InvalidArgumentException('host key must be set');
+ }
+
+ $server['port'] = isset($server['port']) ? (int)$server['port'] : 11211;
+ $server['timeout'] = isset($server['timeout']) ? (int)$server['timeout'] : 1;
+ $server['persistent'] = isset($server['persistent']) ? (bool)$server['persistent'] : false;
+ $server['weight'] = isset($server['weight']) ? (int)$server['weight'] : 1;
+ $server['retry_interval'] = isset($server['retry_interval']) ? (int)$server['retry_interval'] : 15;
+
+ $this->memcache->addserver($server['host'], $server['port'], $server['persistent'],$server['weight'],$server['timeout'],$server['retry_interval']);
+
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function open($savePath, $sessionName)
+ {
+ foreach ($this->memcacheOptions['serverpool'] as $server) {
+ $this->addServer($server);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ return $this->memcache->close();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($sessionId)
+ {
+ return $this->memcache->get($this->prefix.$sessionId) ?: '';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($sessionId, $data)
+ {
+ return $this->memcache->set($this->prefix.$sessionId, $data, 0, $this->memcacheOptions['expiretime']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function destroy($sessionId)
+ {
+ return $this->memcache->delete($this->prefix.$sessionId);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gc($lifetime)
+ {
+ // not required here because memcache will auto expire the records anyhow.
+ return true;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php
new file mode 100755
index 000000000..71770dda8
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/MemcachedSessionHandler.php
@@ -0,0 +1,130 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * MemcachedSessionHandler.
+ *
+ * Memcached based session storage handler based on the Memcached class
+ * provided by the PHP memcached extension.
+ *
+ * @see http://php.net/memcached
+ *
+ * @author Drak
+ */
+class MemcachedSessionHandler implements \SessionHandlerInterface
+{
+ /**
+ * Memcached driver.
+ *
+ * @var \Memcached
+ */
+ private $memcached;
+
+ /**
+ * Configuration options.
+ *
+ * @var array
+ */
+ private $memcachedOptions;
+
+ /**
+ * Constructor.
+ *
+ * @param \Memcached $memcached A \Memcached instance
+ * @param array $memcachedOptions An associative array of Memcached options
+ * @param array $options Session configuration options.
+ */
+ public function __construct(\Memcached $memcached, array $memcachedOptions = array(), array $options = array())
+ {
+ $this->memcached = $memcached;
+
+ // defaults
+ if (!isset($memcachedOptions['serverpool'])) {
+ $memcachedOptions['serverpool'][] = array(
+ 'host' => '127.0.0.1',
+ 'port' => 11211,
+ 'weight' => 1);
+ }
+
+ $memcachedOptions['expiretime'] = isset($memcachedOptions['expiretime']) ? (int)$memcachedOptions['expiretime'] : 86400;
+
+ $this->memcached->setOption(\Memcached::OPT_PREFIX_KEY, isset($memcachedOptions['prefix']) ? $memcachedOptions['prefix'] : 'sf2s');
+
+ $this->memcachedOptions = $memcachedOptions;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function open($savePath, $sessionName)
+ {
+ return $this->memcached->addServers($this->memcachedOptions['serverpool']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($sessionId)
+ {
+ return $this->memcached->get($sessionId) ?: '';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($sessionId, $data)
+ {
+ return $this->memcached->set($sessionId, $data, $this->memcachedOptions['expiretime']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function destroy($sessionId)
+ {
+ return $this->memcached->delete($sessionId);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gc($lifetime)
+ {
+ // not required here because memcached will auto expire the records anyhow.
+ return true;
+ }
+
+ /**
+ * Adds a server to the memcached handler.
+ *
+ * @param array $server
+ */
+ protected function addServer(array $server)
+ {
+ if (array_key_exists('host', $server)) {
+ throw new \InvalidArgumentException('host key must be set');
+ }
+ $server['port'] = isset($server['port']) ? (int)$server['port'] : 11211;
+ $server['timeout'] = isset($server['timeout']) ? (int)$server['timeout'] : 1;
+ $server['presistent'] = isset($server['presistent']) ? (bool)$server['presistent'] : false;
+ $server['weight'] = isset($server['weight']) ? (bool)$server['weight'] : 1;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeFileSessionHandler.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeFileSessionHandler.php
new file mode 100755
index 000000000..422e3a79a
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeFileSessionHandler.php
@@ -0,0 +1,41 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * NativeFileSessionHandler.
+ *
+ * Native session handler using PHP's built in file storage.
+ *
+ * @author Drak
+ */
+class NativeFileSessionHandler extends NativeSessionHandler
+{
+ /**
+ * Constructor.
+ *
+ * @param string $savePath Path of directory to save session files. Default null will leave setting as defined by PHP.
+ */
+ public function __construct($savePath = null)
+ {
+ if (null === $savePath) {
+ $savePath = ini_get('session.save_path');
+ }
+
+ if ($savePath && !is_dir($savePath)) {
+ mkdir($savePath, 0777, true);
+ }
+
+ ini_set('session.save_handler', 'files');
+ ini_set('session.save_path', $savePath);
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeMemcacheSessionHandler.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeMemcacheSessionHandler.php
new file mode 100755
index 000000000..baacf2927
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeMemcacheSessionHandler.php
@@ -0,0 +1,65 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * NativeMemcacheSessionHandler.
+ *
+ * Driver for the memcache session save hadlers provided by the memcache PHP extension.
+ *
+ * @see http://php.net/memcache
+ *
+ * @author Drak
+ */
+class NativeMemcacheSessionHandler extends NativeSessionHandler
+{
+ /**
+ * Constructor.
+ *
+ * @param string $savePath Path of memcache server.
+ * @param array $options Session configuration options.
+ */
+ public function __construct($savePath = 'tcp://127.0.0.1:11211?persistent=0', array $options = array())
+ {
+ if (!extension_loaded('memcache')) {
+ throw new \RuntimeException('PHP does not have "memcache" session module registered');
+ }
+
+ if (null === $savePath) {
+ $savePath = ini_get('session.save_path');
+ }
+
+ ini_set('session.save_handler', 'memcache');
+ ini_set('session.save_path', $savePath);
+
+ $this->setOptions($options);
+ }
+
+ /**
+ * Set any memcached ini values.
+ *
+ * @see http://php.net/memcache.ini
+ */
+ protected function setOptions(array $options)
+ {
+ foreach ($options as $key => $value) {
+ if (in_array($key, array(
+ 'memcache.allow_failover', 'memcache.max_failover_attempts',
+ 'memcache.chunk_size', 'memcache.default_port', 'memcache.hash_strategy',
+ 'memcache.hash_function', 'memcache.protocol', 'memcache.redundancy',
+ 'memcache.session_redundancy', 'memcache.compress_threshold',
+ 'memcache.lock_timeout'))) {
+ ini_set($key, $value);
+ }
+ }
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeMemcachedSessionHandler.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeMemcachedSessionHandler.php
new file mode 100755
index 000000000..d84bdfbe6
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeMemcachedSessionHandler.php
@@ -0,0 +1,64 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * NativeMemcachedSessionHandler.
+ *
+ * Driver for the memcached session save hadlers provided by the memcached PHP extension.
+ *
+ * @see http://php.net/memcached.sessions
+ *
+ * @author Drak
+ */
+class NativeMemcachedSessionHandler extends NativeSessionHandler
+{
+ /**
+ * Constructor.
+ *
+ * @param string $savePath Comma separated list of servers: e.g. memcache1.example.com:11211,memcache2.example.com:11211
+ * @param array $options Session configuration options.
+ */
+ public function __construct($savePath = '127.0.0.1:11211', array $options = array())
+ {
+ if (!extension_loaded('memcached')) {
+ throw new \RuntimeException('PHP does not have "memcached" session module registered');
+ }
+
+ if (null === $savePath) {
+ $savePath = ini_get('session.save_path');
+ }
+
+ ini_set('session.save_handler', 'memcached');
+ ini_set('session.save_path', $savePath);
+
+ $this->setOptions($options);
+ }
+
+ /**
+ * Set any memcached ini values.
+ *
+ * @see https://github.com/php-memcached-dev/php-memcached/blob/master/memcached.ini
+ */
+ protected function setOptions(array $options)
+ {
+ foreach ($options as $key => $value) {
+ if (in_array($key, array(
+ 'memcached.sess_locking', 'memcached.sess_lock_wait',
+ 'memcached.sess_prefix', 'memcached.compression_type',
+ 'memcached.compression_factor', 'memcached.compression_threshold',
+ 'memcached.serializer'))) {
+ ini_set($key, $value);
+ }
+ }
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeSessionHandler.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeSessionHandler.php
new file mode 100755
index 000000000..1260ad0d2
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeSessionHandler.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * Adds SessionHandler functionality if available.
+ *
+ * @see http://php.net/sessionhandler
+ */
+
+if (version_compare(phpversion(), '5.4.0', '>=')) {
+ class NativeSessionHandler extends \SessionHandler {}
+} else {
+ class NativeSessionHandler {}
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeSqliteSessionHandler.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeSqliteSessionHandler.php
new file mode 100755
index 000000000..098cc8a68
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeSqliteSessionHandler.php
@@ -0,0 +1,58 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * NativeSqliteSessionHandler.
+ *
+ * Driver for the sqlite session save hadlers provided by the SQLite PHP extension.
+ *
+ * @author Drak
+ */
+class NativeSqliteSessionHandler extends NativeSessionHandler
+{
+ /**
+ * Constructor.
+ *
+ * @param string $savePath Path to SQLite database file itself.
+ * @param array $options Session configuration options.
+ */
+ public function __construct($savePath, array $options = array())
+ {
+ if (!extension_loaded('sqlite')) {
+ throw new \RuntimeException('PHP does not have "sqlite" session module registered');
+ }
+
+ if (null === $savePath) {
+ $savePath = ini_get('session.save_path');
+ }
+
+ ini_set('session.save_handler', 'sqlite');
+ ini_set('session.save_path', $savePath);
+
+ $this->setOptions($options);
+ }
+
+ /**
+ * Set any sqlite ini values.
+ *
+ * @see http://php.net/sqlite.configuration
+ */
+ protected function setOptions(array $options)
+ {
+ foreach ($options as $key => $value) {
+ if (in_array($key, array('sqlite.assoc_case'))) {
+ ini_set($key, $value);
+ }
+ }
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php
new file mode 100755
index 000000000..dd9f0c79a
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/NullSessionHandler.php
@@ -0,0 +1,72 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * NullSessionHandler.
+ *
+ * Can be used in unit testing or in a sitation where persisted sessions are not desired.
+ *
+ * @author Drak
+ *
+ * @api
+ */
+class NullSessionHandler implements \SessionHandlerInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function open($savePath, $sessionName)
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($sessionId)
+ {
+ return '';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($sessionId, $data)
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function destroy($sessionId)
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gc($lifetime)
+ {
+ return true;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php
new file mode 100755
index 000000000..28dccba80
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php
@@ -0,0 +1,221 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+
+/**
+ * PdoSessionHandler.
+ *
+ * @author Fabien Potencier
+ * @author Michael Williams
+ */
+class PdoSessionHandler implements \SessionHandlerInterface
+{
+ /**
+ * PDO instance.
+ *
+ * @var \PDO
+ */
+ private $pdo;
+
+ /**
+ * Database options.
+ *
+ *
+ * @var array
+ */
+ private $dbOptions;
+
+ /**
+ * Constructor.
+ *
+ * @param \PDO $pdo A \PDO instance
+ * @param array $dbOptions An associative array of DB options
+ * @param array $options Session configuration options
+ *
+ * @throws \InvalidArgumentException When "db_table" option is not provided
+ */
+ public function __construct(\PDO $pdo, array $dbOptions = array(), array $options = array())
+ {
+ if (!array_key_exists('db_table', $dbOptions)) {
+ throw new \InvalidArgumentException('You must provide the "db_table" option for a PdoSessionStorage.');
+ }
+
+ $this->pdo = $pdo;
+ $this->dbOptions = array_merge(array(
+ 'db_id_col' => 'sess_id',
+ 'db_data_col' => 'sess_data',
+ 'db_time_col' => 'sess_time',
+ ), $dbOptions);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function open($path, $name)
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function destroy($id)
+ {
+ // get table/column
+ $dbTable = $this->dbOptions['db_table'];
+ $dbIdCol = $this->dbOptions['db_id_col'];
+
+ // delete the record associated with this id
+ $sql = "DELETE FROM $dbTable WHERE $dbIdCol = :id";
+
+ try {
+ $stmt = $this->pdo->prepare($sql);
+ $stmt->bindParam(':id', $id, \PDO::PARAM_STR);
+ $stmt->execute();
+ } catch (\PDOException $e) {
+ throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s', $e->getMessage()), 0, $e);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gc($lifetime)
+ {
+ // get table/column
+ $dbTable = $this->dbOptions['db_table'];
+ $dbTimeCol = $this->dbOptions['db_time_col'];
+
+ // delete the session records that have expired
+ $sql = "DELETE FROM $dbTable WHERE $dbTimeCol < (:time - $lifetime)";
+
+ try {
+ $stmt = $this->pdo->prepare($sql);
+ $stmt->bindValue(':time', time(), \PDO::PARAM_INT);
+ $stmt->execute();
+ } catch (\PDOException $e) {
+ throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s', $e->getMessage()), 0, $e);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($id)
+ {
+ // get table/columns
+ $dbTable = $this->dbOptions['db_table'];
+ $dbDataCol = $this->dbOptions['db_data_col'];
+ $dbIdCol = $this->dbOptions['db_id_col'];
+
+ try {
+ $sql = "SELECT $dbDataCol FROM $dbTable WHERE $dbIdCol = :id";
+
+ $stmt = $this->pdo->prepare($sql);
+ $stmt->bindParam(':id', $id, \PDO::PARAM_STR);
+
+ $stmt->execute();
+ // it is recommended to use fetchAll so that PDO can close the DB cursor
+ // we anyway expect either no rows, or one row with one column. fetchColumn, seems to be buggy #4777
+ $sessionRows = $stmt->fetchAll(\PDO::FETCH_NUM);
+
+ if (count($sessionRows) == 1) {
+ return base64_decode($sessionRows[0][0]);
+ }
+
+ // session does not exist, create it
+ $this->createNewSession($id);
+
+ return '';
+ } catch (\PDOException $e) {
+ throw new \RuntimeException(sprintf('PDOException was thrown when trying to read the session data: %s', $e->getMessage()), 0, $e);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($id, $data)
+ {
+ // get table/column
+ $dbTable = $this->dbOptions['db_table'];
+ $dbDataCol = $this->dbOptions['db_data_col'];
+ $dbIdCol = $this->dbOptions['db_id_col'];
+ $dbTimeCol = $this->dbOptions['db_time_col'];
+
+ $sql = ('mysql' === $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME))
+ ? "INSERT INTO $dbTable ($dbIdCol, $dbDataCol, $dbTimeCol) VALUES (:id, :data, :time) "
+ ."ON DUPLICATE KEY UPDATE $dbDataCol = VALUES($dbDataCol), $dbTimeCol = CASE WHEN $dbTimeCol = :time THEN (VALUES($dbTimeCol) + 1) ELSE VALUES($dbTimeCol) END"
+ : "UPDATE $dbTable SET $dbDataCol = :data, $dbTimeCol = :time WHERE $dbIdCol = :id";
+
+ try {
+ //session data can contain non binary safe characters so we need to encode it
+ $encoded = base64_encode($data);
+ $stmt = $this->pdo->prepare($sql);
+ $stmt->bindParam(':id', $id, \PDO::PARAM_STR);
+ $stmt->bindParam(':data', $encoded, \PDO::PARAM_STR);
+ $stmt->bindValue(':time', time(), \PDO::PARAM_INT);
+ $stmt->execute();
+
+ if (!$stmt->rowCount()) {
+ // No session exists in the database to update. This happens when we have called
+ // session_regenerate_id()
+ $this->createNewSession($id, $data);
+ }
+ } catch (\PDOException $e) {
+ throw new \RuntimeException(sprintf('PDOException was thrown when trying to write the session data: %s', $e->getMessage()), 0, $e);
+ }
+
+ return true;
+ }
+
+ /**
+ * Creates a new session with the given $id and $data
+ *
+ * @param string $id
+ * @param string $data
+ *
+ * @return boolean True.
+ */
+ private function createNewSession($id, $data = '')
+ {
+ // get table/column
+ $dbTable = $this->dbOptions['db_table'];
+ $dbDataCol = $this->dbOptions['db_data_col'];
+ $dbIdCol = $this->dbOptions['db_id_col'];
+ $dbTimeCol = $this->dbOptions['db_time_col'];
+
+ $sql = "INSERT INTO $dbTable ($dbIdCol, $dbDataCol, $dbTimeCol) VALUES (:id, :data, :time)";
+
+ //session data can contain non binary safe characters so we need to encode it
+ $encoded = base64_encode($data);
+ $stmt = $this->pdo->prepare($sql);
+ $stmt->bindParam(':id', $id, \PDO::PARAM_STR);
+ $stmt->bindParam(':data', $encoded, \PDO::PARAM_STR);
+ $stmt->bindValue(':time', time(), \PDO::PARAM_INT);
+ $stmt->execute();
+
+ return true;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php
new file mode 100755
index 000000000..6f1e279f4
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/MockArraySessionStorage.php
@@ -0,0 +1,218 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage;
+
+use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
+
+/**
+ * MockArraySessionStorage mocks the session for unit tests.
+ *
+ * No PHP session is actually started since a session can be initialized
+ * and shutdown only once per PHP execution cycle.
+ *
+ * When doing functional testing, you should use MockFileSessionStorage instead.
+ *
+ * @author Fabien Potencier
+ * @author Bulat Shakirzyanov
+ * @author Drak
+ */
+class MockArraySessionStorage implements SessionStorageInterface
+{
+ /**
+ * @var string
+ */
+ protected $id = '';
+
+ /**
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * @var boolean
+ */
+ protected $started = false;
+
+ /**
+ * @var boolean
+ */
+ protected $closed = false;
+
+ /**
+ * @var array
+ */
+ protected $data = array();
+
+ /**
+ * Constructor.
+ *
+ * @param string $name Session name
+ */
+ public function __construct($name = 'MOCKSESSID')
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Sets the session data.
+ *
+ * @param array $array
+ */
+ public function setSessionData(array $array)
+ {
+ $this->data = $array;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start()
+ {
+ if ($this->started && !$this->closed) {
+ return true;
+ }
+
+ if (empty($this->id)) {
+ $this->id = $this->generateId();
+ }
+
+ $this->loadSession();
+
+ return true;
+ }
+
+
+ /**
+ * {@inheritdoc}
+ */
+ public function regenerate($destroy = false)
+ {
+ if (!$this->started) {
+ $this->start();
+ }
+
+ $this->id = $this->generateId();
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setId($id)
+ {
+ if ($this->started) {
+ throw new \LogicException('Cannot set session ID after the session has started.');
+ }
+
+ $this->id = $id;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save()
+ {
+ // nothing to do since we don't persist the session data
+ $this->closed = false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ // clear out the bags
+ foreach ($this->bags as $bag) {
+ $bag->clear();
+ }
+
+ // clear out the session
+ $this->data = array();
+
+ // reconnect the bags to the session
+ $this->loadSession();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function registerBag(SessionBagInterface $bag)
+ {
+ $this->bags[$bag->getName()] = $bag;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBag($name)
+ {
+ if (!isset($this->bags[$name])) {
+ throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
+ }
+
+ if (!$this->started) {
+ $this->start();
+ }
+
+ return $this->bags[$name];
+ }
+
+ /**
+ * Generates a session ID.
+ *
+ * This doesn't need to be particularly cryptographically secure since this is just
+ * a mock.
+ *
+ * @return string
+ */
+ protected function generateId()
+ {
+ return sha1(uniqid(mt_rand()));
+ }
+
+ protected function loadSession()
+ {
+ foreach ($this->bags as $bag) {
+ $key = $bag->getStorageKey();
+ $this->data[$key] = isset($this->data[$key]) ? $this->data[$key] : array();
+ $bag->initialize($this->data[$key]);
+ }
+
+ $this->started = true;
+ $this->closed = false;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorage.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorage.php
new file mode 100755
index 000000000..24457319f
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/MockFileSessionStorage.php
@@ -0,0 +1,126 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage;
+
+/**
+ * MockFileSessionStorage is used to mock sessions for
+ * functional testing when done in a single PHP process.
+ *
+ * No PHP session is actually started since a session can be initialized
+ * and shutdown only once per PHP execution cycle and this class does
+ * not pollute any session related globals, including session_*() functions
+ * or session.* PHP ini directives.
+ *
+ * @author Drak
+ */
+class MockFileSessionStorage extends MockArraySessionStorage
+{
+ /**
+ * @var string
+ */
+ private $savePath;
+
+ /**
+ * Constructor.
+ *
+ * @param string $savePath Path of directory to save session files.
+ * @param string $name Session name.
+ */
+ public function __construct($savePath = null, $name = 'MOCKSESSID')
+ {
+ if (null === $savePath) {
+ $savePath = sys_get_temp_dir();
+ }
+
+ if (!is_dir($savePath)) {
+ mkdir($savePath, 0777, true);
+ }
+
+ $this->savePath = $savePath;
+
+ parent::__construct($name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start()
+ {
+ if ($this->started) {
+ return true;
+ }
+
+ if (!$this->id) {
+ $this->id = $this->generateId();
+ }
+
+ $this->read();
+
+ $this->started = true;
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function regenerate($destroy = false)
+ {
+ if ($destroy) {
+ $this->destroy();
+ }
+
+ $this->id = $this->generateId();
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save()
+ {
+ file_put_contents($this->getFilePath(), serialize($this->data));
+ }
+
+ /**
+ * Deletes a session from persistent storage.
+ * Deliberately leaves session data in memory intact.
+ */
+ private function destroy()
+ {
+ if (is_file($this->getFilePath())) {
+ unlink($this->getFilePath());
+ }
+ }
+
+ /**
+ * Calculate path to file.
+ *
+ * @return string File path
+ */
+ private function getFilePath()
+ {
+ return $this->savePath.'/'.$this->id.'.mocksess';
+ }
+
+ /**
+ * Reads session from storage and loads session.
+ */
+ private function read()
+ {
+ $filePath = $this->getFilePath();
+ $this->data = is_readable($filePath) && is_file($filePath) ? unserialize(file_get_contents($filePath)) : array();
+
+ $this->loadSession();
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php
new file mode 100755
index 000000000..5252bf55f
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.php
@@ -0,0 +1,347 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage;
+
+use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
+use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
+use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
+use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
+
+/**
+ * This provides a base class for session attribute storage.
+ *
+ * @author Drak
+ */
+class NativeSessionStorage implements SessionStorageInterface
+{
+ /**
+ * Array of SessionBagInterface
+ *
+ * @var array
+ */
+ protected $bags;
+
+ /**
+ * @var boolean
+ */
+ protected $started = false;
+
+ /**
+ * @var boolean
+ */
+ protected $closed = false;
+
+ /**
+ * @var AbstractProxy
+ */
+ protected $saveHandler;
+
+ /**
+ * Constructor.
+ *
+ * Depending on how you want the storage driver to behave you probably
+ * want top override this constructor entirely.
+ *
+ * List of options for $options array with their defaults.
+ * @see http://php.net/session.configuration for options
+ * but we omit 'session.' from the beginning of the keys for convenience.
+ *
+ * auto_start, "0"
+ * cache_limiter, "nocache" (use "0" to prevent headers from being sent entirely).
+ * cookie_domain, ""
+ * cookie_httponly, ""
+ * cookie_lifetime, "0"
+ * cookie_path, "/"
+ * cookie_secure, ""
+ * entropy_file, ""
+ * entropy_length, "0"
+ * gc_divisor, "100"
+ * gc_maxlifetime, "1440"
+ * gc_probability, "1"
+ * hash_bits_per_character, "4"
+ * hash_function, "0"
+ * name, "PHPSESSID"
+ * referer_check, ""
+ * serialize_handler, "php"
+ * use_cookies, "1"
+ * use_only_cookies, "1"
+ * use_trans_sid, "0"
+ * upload_progress.enabled, "1"
+ * upload_progress.cleanup, "1"
+ * upload_progress.prefix, "upload_progress_"
+ * upload_progress.name, "PHP_SESSION_UPLOAD_PROGRESS"
+ * upload_progress.freq, "1%"
+ * upload_progress.min-freq, "1"
+ * url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset="
+ *
+ * @param array $options Session configuration options.
+ * @param object $handler SessionHandlerInterface.
+ */
+ public function __construct(array $options = array(), $handler = null)
+ {
+ // sensible defaults
+ ini_set('session.auto_start', 0); // by default we prefer to explicitly start the session using the class.
+ ini_set('session.cache_limiter', ''); // disable by default because it's managed by HeaderBag (if used)
+ ini_set('session.use_cookies', 1);
+
+ if (version_compare(phpversion(), '5.4.0', '>=')) {
+ session_register_shutdown();
+ } else {
+ register_shutdown_function('session_write_close');
+ }
+
+ $this->setOptions($options);
+ $this->setSaveHandler($handler);
+ }
+
+ /**
+ * Gets the save handler instance.
+ *
+ * @return AbstractProxy
+ */
+ public function getSaveHandler()
+ {
+ return $this->saveHandler;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start()
+ {
+ if ($this->started && !$this->closed) {
+ return true;
+ }
+
+ // catch condition where session was started automatically by PHP
+ if (!$this->started && !$this->closed && $this->saveHandler->isActive()
+ && $this->saveHandler->isSessionHandlerInterface()) {
+ $this->loadSession();
+
+ return true;
+ }
+
+ if (ini_get('session.use_cookies') && headers_sent()) {
+ throw new \RuntimeException('Failed to start the session because headers have already been sent.');
+ }
+
+ // start the session
+ if (!session_start()) {
+ throw new \RuntimeException('Failed to start the session');
+ }
+
+ $this->loadSession();
+
+ if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
+ $this->saveHandler->setActive(false);
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getId()
+ {
+ if (!$this->started) {
+ return ''; // returning empty is consistent with session_id() behaviour
+ }
+
+ return $this->saveHandler->getId();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setId($id)
+ {
+ return $this->saveHandler->setId($id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return $this->saveHandler->getName();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setName($name)
+ {
+ $this->saveHandler->setName($name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function regenerate($destroy = false)
+ {
+ return session_regenerate_id($destroy);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save()
+ {
+ session_write_close();
+
+ if (!$this->saveHandler->isWrapper() && !$this->getSaveHandler()->isSessionHandlerInterface()) {
+ $this->saveHandler->setActive(false);
+ }
+
+ $this->closed = true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clear()
+ {
+ // clear out the bags
+ foreach ($this->bags as $bag) {
+ $bag->clear();
+ }
+
+ // clear out the session
+ $_SESSION = array();
+
+ // reconnect the bags to the session
+ $this->loadSession();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function registerBag(SessionBagInterface $bag)
+ {
+ $this->bags[$bag->getName()] = $bag;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBag($name)
+ {
+ if (!isset($this->bags[$name])) {
+ throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
+ }
+
+ if (ini_get('session.auto_start') && !$this->started) {
+ $this->start();
+ } elseif ($this->saveHandler->isActive() && !$this->started) {
+ $this->loadSession();
+ }
+
+ return $this->bags[$name];
+ }
+
+ /**
+ * Sets session.* ini variables.
+ *
+ * For convenience we omit 'session.' from the beginning of the keys.
+ * Explicitly ignores other ini keys.
+ *
+ * @param array $options Session ini directives array(key => value).
+ *
+ * @see http://php.net/session.configuration
+ */
+ public function setOptions(array $options)
+ {
+ foreach ($options as $key => $value) {
+ if (in_array($key, array(
+ 'auto_start', 'cache_limiter', 'cookie_domain', 'cookie_httponly',
+ 'cookie_lifetime', 'cookie_path', 'cookie_secure',
+ 'entropy_file', 'entropy_length', 'gc_divisor',
+ 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character',
+ 'hash_function', 'name', 'referer_check',
+ 'serialize_handler', 'use_cookies',
+ 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled',
+ 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name',
+ 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags'))) {
+ ini_set('session.'.$key, $value);
+ }
+ }
+ }
+
+ /**
+ * Registers save handler as a PHP session handler.
+ *
+ * To use internal PHP session save handlers, override this method using ini_set with
+ * session.save_handlers and session.save_path e.g.
+ *
+ * ini_set('session.save_handlers', 'files');
+ * ini_set('session.save_path', /tmp');
+ *
+ * @see http://php.net/session-set-save-handler
+ * @see http://php.net/sessionhandlerinterface
+ * @see http://php.net/sessionhandler
+ *
+ * @param object $saveHandler Default null means NativeProxy.
+ */
+ public function setSaveHandler($saveHandler = null)
+ {
+ // Wrap $saveHandler in proxy
+ if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
+ $saveHandler = new SessionHandlerProxy($saveHandler);
+ } elseif (!$saveHandler instanceof AbstractProxy) {
+ $saveHandler = new NativeProxy($saveHandler);
+ }
+
+ $this->saveHandler = $saveHandler;
+
+ if ($this->saveHandler instanceof \SessionHandlerInterface) {
+ if (version_compare(phpversion(), '5.4.0', '>=')) {
+ session_set_save_handler($this->saveHandler, false);
+ } else {
+ session_set_save_handler(
+ array($this->saveHandler, 'open'),
+ array($this->saveHandler, 'close'),
+ array($this->saveHandler, 'read'),
+ array($this->saveHandler, 'write'),
+ array($this->saveHandler, 'destroy'),
+ array($this->saveHandler, 'gc')
+ );
+ }
+ }
+ }
+
+ /**
+ * Load the session with attributes.
+ *
+ * After starting the session, PHP retrieves the session from whatever handlers
+ * are set to (either PHP's internal, or a custom save handler set with session_set_save_handler()).
+ * PHP takes the return value from the read() handler, unserializes it
+ * and populates $_SESSION with the result automatically.
+ *
+ * @param array|null $session
+ */
+ protected function loadSession(array &$session = null)
+ {
+ if (null === $session) {
+ $session = &$_SESSION;
+ }
+
+ foreach ($this->bags as $bag) {
+ $key = $bag->getStorageKey();
+ $session[$key] = isset($session[$key]) ? $session[$key] : array();
+ $bag->initialize($session[$key]);
+ }
+
+ $this->started = true;
+ $this->closed = false;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Proxy/AbstractProxy.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Proxy/AbstractProxy.php
new file mode 100755
index 000000000..09f9efa09
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Proxy/AbstractProxy.php
@@ -0,0 +1,135 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;
+
+/**
+ * AbstractProxy.
+ *
+ * @author Drak
+ */
+abstract class AbstractProxy
+{
+ /**
+ * Flag if handler wraps an internal PHP session handler (using \SessionHandler).
+ *
+ * @var boolean
+ */
+ protected $wrapper = false;
+
+ /**
+ * @var boolean
+ */
+ protected $active = false;
+
+ /**
+ * @var string
+ */
+ protected $saveHandlerName;
+
+ /**
+ * Gets the session.save_handler name.
+ *
+ * @return string
+ */
+ public function getSaveHandlerName()
+ {
+ return $this->saveHandlerName;
+ }
+
+ /**
+ * Is this proxy handler and instance of \SessionHandlerInterface.
+ *
+ * @return boolean
+ */
+ public function isSessionHandlerInterface()
+ {
+ return ($this instanceof \SessionHandlerInterface);
+ }
+
+ /**
+ * Returns true if this handler wraps an internal PHP session save handler using \SessionHandler.
+ *
+ * @return bool
+ */
+ public function isWrapper()
+ {
+ return $this->wrapper;
+ }
+
+ /**
+ * Has a session started?
+ *
+ * @return bool
+ */
+ public function isActive()
+ {
+ return $this->active;
+ }
+
+ /**
+ * Sets the active flag.
+ *
+ * @param bool $flag
+ */
+ public function setActive($flag)
+ {
+ $this->active = (bool) $flag;
+ }
+
+ /**
+ * Gets the session ID.
+ *
+ * @return string
+ */
+ public function getId()
+ {
+ return session_id();
+ }
+
+ /**
+ * Sets the session ID.
+ *
+ * @param string $id
+ */
+ public function setId($id)
+ {
+ if ($this->isActive()) {
+ throw new \LogicException('Cannot change the ID of an active session');
+ }
+
+ session_id($id);
+ }
+
+ /**
+ * Gets the session name.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return session_name();
+ }
+
+ /**
+ * Sets the session name.
+ *
+ * @param string $name
+ */
+ public function setName($name)
+ {
+ if ($this->isActive()) {
+ throw new \LogicException('Cannot change the name of an active session');
+ }
+
+ session_name($name);
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Proxy/NativeProxy.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Proxy/NativeProxy.php
new file mode 100755
index 000000000..5bb2c712e
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Proxy/NativeProxy.php
@@ -0,0 +1,41 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;
+
+/**
+ * NativeProxy.
+ *
+ * This proxy is built-in session handlers in PHP 5.3.x
+ *
+ * @author Drak
+ */
+class NativeProxy extends AbstractProxy
+{
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ // this makes an educated guess as to what the handler is since it should already be set.
+ $this->saveHandlerName = ini_get('session.save_handler');
+ }
+
+ /**
+ * Returns true if this handler wraps an internal PHP session save handler using \SessionHandler.
+ *
+ * @return bool False.
+ */
+ public function isWrapper()
+ {
+ return false;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php
new file mode 100755
index 000000000..e925d628d
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Proxy/SessionHandlerProxy.php
@@ -0,0 +1,95 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage\Proxy;
+
+/**
+ * SessionHandler proxy.
+ *
+ * @author Drak
+ */
+class SessionHandlerProxy extends AbstractProxy implements \SessionHandlerInterface
+{
+ /**
+ * @var \SessionHandlerInterface
+ */
+ protected $handler;
+
+ /**
+ * Constructor.
+ *
+ * @param \SessionHandlerInterface $handler
+ */
+ public function __construct(\SessionHandlerInterface $handler)
+ {
+ $this->handler = $handler;
+ $this->wrapper = ($handler instanceof \SessionHandler);
+ $this->saveHandlerName = $this->wrapper ? ini_get('session.save_handler') : 'user';
+ }
+
+ // \SessionHandlerInterface
+
+ /**
+ * {@inheritdoc}
+ */
+ public function open($savePath, $sessionName)
+ {
+ $return = (bool)$this->handler->open($savePath, $sessionName);
+
+ if (true === $return) {
+ $this->active = true;
+ }
+
+ return $return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ $this->active = false;
+
+ return (bool) $this->handler->close();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read($id)
+ {
+ return (string) $this->handler->read($id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($id, $data)
+ {
+ return (bool) $this->handler->write($id, $data);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function destroy($id)
+ {
+ return (bool) $this->handler->destroy($id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function gc($maxlifetime)
+ {
+ return (bool) $this->handler->gc($maxlifetime);
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageInterface.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageInterface.php
new file mode 100755
index 000000000..8bf2e5d32
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/SessionStorageInterface.php
@@ -0,0 +1,126 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation\Session\Storage;
+
+use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
+
+/**
+ * StorageInterface.
+ *
+ * @author Fabien Potencier
+ * @author Drak
+ *
+ * @api
+ */
+interface SessionStorageInterface
+{
+ /**
+ * Starts the session.
+ *
+ * @throws \RuntimeException If something goes wrong starting the session.
+ *
+ * @return boolean True if started.
+ *
+ * @api
+ */
+ function start();
+
+ /**
+ * Returns the session ID
+ *
+ * @return string The session ID or empty.
+ *
+ * @api
+ */
+ function getId();
+
+ /**
+ * Sets the session ID
+ *
+ * @param string $id
+ *
+ * @api
+ */
+ function setId($id);
+
+ /**
+ * Returns the session name
+ *
+ * @return mixed The session name.
+ *
+ * @api
+ */
+ function getName();
+
+ /**
+ * Sets the session name
+ *
+ * @param string $name
+ *
+ * @api
+ */
+ function setName($name);
+
+ /**
+ * Regenerates id that represents this storage.
+ *
+ * This method must invoke session_regenerate_id($destroy) unless
+ * this interface is used for a storage object designed for unit
+ * or functional testing where a real PHP session would interfere
+ * with testing.
+ *
+ * Note regenerate+destroy should not clear the session data in memory
+ * only delete the session data from persistent storage.
+ *
+ * @param Boolean $destroy Destroy session when regenerating?
+ *
+ * @return Boolean True if session regenerated, false if error
+ *
+ * @throws \RuntimeException If an error occurs while regenerating this storage
+ *
+ * @api
+ */
+ function regenerate($destroy = false);
+
+ /**
+ * Force the session to be saved and closed.
+ *
+ * This method must invoke session_write_close() unless this interface is
+ * used for a storage object design for unit or functional testing where
+ * a real PHP session would interfere with testing, in which case it
+ * it should actually persist the session data if required.
+ */
+ function save();
+
+ /**
+ * Clear all session data in memory.
+ */
+ function clear();
+
+ /**
+ * Gets a SessionBagInterface by name.
+ *
+ * @param string $name
+ *
+ * @return SessionBagInterface
+ *
+ * @throws \InvalidArgumentException If the bag does not exist
+ */
+ function getBag($name);
+
+ /**
+ * Registers a SessionBagInterface for use.
+ *
+ * @param SessionBagInterface $bag
+ */
+ function registerBag(SessionBagInterface $bag);
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/StreamedResponse.php b/app/laravel/vendor/Symfony/Component/HttpFoundation/StreamedResponse.php
new file mode 100755
index 000000000..1952a848b
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/StreamedResponse.php
@@ -0,0 +1,129 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * StreamedResponse represents a streamed HTTP response.
+ *
+ * A StreamedResponse uses a callback for its content.
+ *
+ * The callback should use the standard PHP functions like echo
+ * to stream the response back to the client. The flush() method
+ * can also be used if needed.
+ *
+ * @see flush()
+ *
+ * @author Fabien Potencier
+ *
+ * @api
+ */
+class StreamedResponse extends Response
+{
+ protected $callback;
+ protected $streamed;
+
+ /**
+ * Constructor.
+ *
+ * @param mixed $callback A valid PHP callback
+ * @param integer $status The response status code
+ * @param array $headers An array of response headers
+ *
+ * @api
+ */
+ public function __construct($callback = null, $status = 200, $headers = array())
+ {
+ parent::__construct(null, $status, $headers);
+
+ if (null !== $callback) {
+ $this->setCallback($callback);
+ }
+ $this->streamed = false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public static function create($callback = null, $status = 200, $headers = array())
+ {
+ return new static($callback, $status, $headers);
+ }
+
+ /**
+ * Sets the PHP callback associated with this Response.
+ *
+ * @param mixed $callback A valid PHP callback
+ */
+ public function setCallback($callback)
+ {
+ if (!is_callable($callback)) {
+ throw new \LogicException('The Response callback must be a valid PHP callable.');
+ }
+ $this->callback = $callback;
+ }
+
+ /**
+ * @{inheritdoc}
+ */
+ public function prepare(Request $request)
+ {
+ if ('1.0' != $request->server->get('SERVER_PROTOCOL')) {
+ $this->setProtocolVersion('1.1');
+ }
+
+ $this->headers->set('Cache-Control', 'no-cache');
+
+ parent::prepare($request);
+ }
+
+ /**
+ * @{inheritdoc}
+ *
+ * This method only sends the content once.
+ */
+ public function sendContent()
+ {
+ if ($this->streamed) {
+ return;
+ }
+
+ $this->streamed = true;
+
+ if (null === $this->callback) {
+ throw new \LogicException('The Response callback must not be null.');
+ }
+
+ call_user_func($this->callback);
+ }
+
+ /**
+ * @{inheritdoc}
+ *
+ * @throws \LogicException when the content is not null
+ */
+ public function setContent($content)
+ {
+ if (null !== $content) {
+ throw new \LogicException('The content cannot be set on a StreamedResponse instance.');
+ }
+ }
+
+ /**
+ * @{inheritdoc}
+ *
+ * @return false
+ */
+ public function getContent()
+ {
+ return false;
+ }
+}
diff --git a/app/laravel/vendor/Symfony/Component/HttpFoundation/composer.json b/app/laravel/vendor/Symfony/Component/HttpFoundation/composer.json
new file mode 100755
index 000000000..d0f1015c0
--- /dev/null
+++ b/app/laravel/vendor/Symfony/Component/HttpFoundation/composer.json
@@ -0,0 +1,33 @@
+{
+ "name": "symfony/http-foundation",
+ "type": "library",
+ "description": "Symfony HttpFoundation Component",
+ "keywords": [],
+ "homepage": "http://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "http://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "autoload": {
+ "psr-0": {
+ "Symfony\\Component\\HttpFoundation": "",
+ "SessionHandlerInterface": "Symfony/Component/HttpFoundation/Resources/stubs"
+ }
+ },
+ "target-dir": "Symfony/Component/HttpFoundation",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1-dev"
+ }
+ }
+}
diff --git a/app/laravel/view.php b/app/laravel/view.php
index 76d8d40d8..b9854d2a0 100644
--- a/app/laravel/view.php
+++ b/app/laravel/view.php
@@ -37,6 +37,27 @@ class View implements ArrayAccess {
*/
public static $names = array();
+ /**
+ * The cache content of loaded view files.
+ *
+ * @var array
+ */
+ public static $cache = array();
+
+ /**
+ * THe last view to be rendered.
+ *
+ * @var string
+ */
+ public static $last;
+
+ /**
+ * The render operations taking place.
+ *
+ * @var int
+ */
+ public static $render_count = 0;
+
/**
* The Laravel view loader event name.
*
@@ -103,13 +124,19 @@ public function __construct($view, $data = array())
}
/**
- * Get the path to a given view on disk.
+ * Determine if the given view exists.
*
- * @param string $view
- * @return string
+ * @param string $view
+ * @param boolean $return_path
+ * @return string|bool
*/
- protected function path($view)
+ public static function exists($view, $return_path = false)
{
+ if (starts_with($view, 'name: ') and array_key_exists($name = substr($view, 6), static::$names))
+ {
+ $view = static::$names[$name];
+ }
+
list($bundle, $view) = Bundle::parse($view);
$view = str_replace('.', '/', $view);
@@ -117,9 +144,25 @@ protected function path($view)
// We delegate the determination of view paths to the view loader event
// so that the developer is free to override and manage the loading
// of views in any way they see fit for their application.
- $path = Event::first(static::loader, array($bundle, $view));
+ $path = Event::until(static::loader, array($bundle, $view));
if ( ! is_null($path))
+ {
+ return $return_path ? $path : true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the path to a given view on disk.
+ *
+ * @param string $view
+ * @return string
+ */
+ protected function path($view)
+ {
+ if ($path = $this->exists($view,true))
{
return $path;
}
@@ -139,7 +182,7 @@ public static function file($bundle, $view, $directory)
{
$directory = str_finish($directory, DS);
- // Views may have either the default PHP file extension of the "Blade"
+ // Views may have either the default PHP file extension or the "Blade"
// extension, so we will need to check for both in the view path
// and return the first one we find for the given view.
if (file_exists($path = $directory.$view.EXT))
@@ -226,13 +269,18 @@ public static function name($view, $name)
* });
*
*
- * @param string $view
- * @param Closure $composer
+ * @param string|array $views
+ * @param Closure $composer
* @return void
*/
- public static function composer($view, $composer)
+ public static function composer($views, $composer)
{
- Event::listen("laravel.composing: {$view}", $composer);
+ $views = (array) $views;
+
+ foreach ($views as $view)
+ {
+ Event::listen("laravel.composing: {$view}", $composer);
+ }
}
/**
@@ -262,7 +310,7 @@ public static function render_each($view, array $data, $iterator, $empty = 'raw|
}
// If there is no data in the array, we will render the contents of
- // the "empty" view. Alternative, the "empty view" can be a raw
+ // the "empty" view. Alternatively, the "empty view" can be a raw
// string that is prefixed with "raw|" for convenience.
else
{
@@ -286,24 +334,32 @@ public static function render_each($view, array $data, $iterator, $empty = 'raw|
*/
public function render()
{
- // To allow bundles or other pieces of the application to modify the
- // view before it is rendered, we'll fire an event, passing in the
- // view instance so it can modified.
- $composer = "laravel.composing: {$this->view}";
+ static::$render_count++;
+
+ Event::fire("laravel.composing: {$this->view}", array($this));
- Event::fire($composer, array($this));
+ $contents = null;
// If there are listeners to the view engine event, we'll pass them
// the view so they can render it according to their needs, which
// allows easy attachment of other view parsers.
if (Event::listeners(static::engine))
{
- $result = Event::first(static::engine, array($this));
+ $result = Event::until(static::engine, array($this));
- if ($result !== false) return $result;
+ if ( ! is_null($result)) $contents = $result;
}
- return $this->get();
+ if (is_null($contents)) $contents = $this->get();
+
+ static::$render_count--;
+
+ if (static::$render_count == 0)
+ {
+ Section::$sections = array();
+ }
+
+ return $contents;
}
/**
@@ -315,6 +371,11 @@ public function get()
{
$__data = $this->data();
+ // The contents of each view file is cached in an array for the
+ // request since partial views may be rendered inside of for
+ // loops which could incur performance penalties.
+ $__contents = $this->load();
+
ob_start() and extract($__data, EXTR_SKIP);
// We'll include the view contents for parsing within a catcher
@@ -322,18 +383,47 @@ public function get()
// will throw it out to the exception handler.
try
{
- include $this->path;
+ eval('?>'.$__contents);
}
// If we caught an exception, we'll silently flush the output
// buffer so that no partially rendered views get thrown out
- // to the client and confuse the user.
+ // to the client and confuse the user with junk.
catch (\Exception $e)
{
ob_get_clean(); throw $e;
}
- return ob_get_clean();
+ $content = ob_get_clean();
+
+ // The view filter event gives us a last chance to modify the
+ // evaluated contents of the view and return them. This lets
+ // us do something like run the contents through Jade, etc.
+ if (Event::listeners('view.filter'))
+ {
+ return Event::first('view.filter', array($content, $this->path));
+ }
+
+ return $content;
+ }
+
+ /**
+ * Get the contents of the view file from disk.
+ *
+ * @return string
+ */
+ protected function load()
+ {
+ static::$last = array('name' => $this->view, 'path' => $this->path);
+
+ if (isset(static::$cache[$this->path]))
+ {
+ return static::$cache[$this->path];
+ }
+ else
+ {
+ return static::$cache[$this->path] = file_get_contents($this->path);
+ }
}
/**
@@ -500,4 +590,20 @@ public function __toString()
return $this->render();
}
+ /**
+ * Magic Method for handling dynamic functions.
+ *
+ * This method handles calls to dynamic with helpers.
+ */
+ public function __call($method, $parameters)
+ {
+ if (strpos($method, 'with_') === 0)
+ {
+ $key = substr($method, 5);
+ return $this->with($key, $parameters[0]);
+ }
+
+ throw new \Exception("Method [$method] is not defined on the View class.");
+ }
+
}
\ No newline at end of file
diff --git a/app/paths.php b/app/paths.php
index 0f434320b..9d0dd842f 100644
--- a/app/paths.php
+++ b/app/paths.php
@@ -3,66 +3,77 @@
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
- * @version 3.1.5
+ * @version 3.2.0
* @author Taylor Otwell