diff --git a/laravel/asset.php b/laravel/asset.php index dea2451..8b6f930 100644 --- a/laravel/asset.php +++ b/laravel/asset.php @@ -78,7 +78,6 @@ class Asset_Container { * Create a new asset container instance. * * @param string $name - * @param HTML $html * @return void */ public function __construct($name) diff --git a/laravel/autoloader.php b/laravel/autoloader.php index e997555..036585d 100644 --- a/laravel/autoloader.php +++ b/laravel/autoloader.php @@ -183,8 +183,8 @@ public static function psr($directory) /** * Map namespaces to directories. * - * @param string $namespace - * @param string $path + * @param array $mappings + * @return void */ public static function namespaces($mappings) { diff --git a/laravel/bundle.php b/laravel/bundle.php index dd0f9e5..825b31f 100644 --- a/laravel/bundle.php +++ b/laravel/bundle.php @@ -27,8 +27,7 @@ class Bundle { * Register a bundle for the application. * * @param string $bundle - * @param string $location - * @param string $handles + * @param mixed $config Array of 'location', 'handles' and 'auto'; or string of location. * @return void */ public static function register($bundle, $config = array()) @@ -111,7 +110,7 @@ public static function routes($bundle) * * If no bundle is assigned to handle the URI, the default bundle is returned. * - * @param string $bundle + * @param string $uri * @return string */ public static function handles($uri) diff --git a/laravel/cache.php b/laravel/cache.php index a27db04..261bbdd 100644 --- a/laravel/cache.php +++ b/laravel/cache.php @@ -23,7 +23,7 @@ class Cache { * * * @param string $driver - * @return Cache\Driver + * @return Cache\Drivers\Driver */ public static function driver($driver = null) { @@ -41,7 +41,7 @@ public static function driver($driver = null) * Create a new cache driver instance. * * @param string $driver - * @return Driver + * @return Cache\Drivers\Driver */ protected static function factory($driver) { diff --git a/laravel/cache/drivers/database.php b/laravel/cache/drivers/database.php index 85e8b13..3edd18d 100644 --- a/laravel/cache/drivers/database.php +++ b/laravel/cache/drivers/database.php @@ -101,7 +101,7 @@ public function forget($key) /** * Get a query builder for the database table. * - * @return Query + * @return Laravel\Database\Query */ protected function table() { diff --git a/laravel/cache/drivers/driver.php b/laravel/cache/drivers/driver.php index d12de53..b74ebe0 100644 --- a/laravel/cache/drivers/driver.php +++ b/laravel/cache/drivers/driver.php @@ -23,7 +23,6 @@ abstract public function has($key); * * @param string $key * @param mixed $default - * @param string $driver * @return mixed */ public function get($key, $default = null) diff --git a/laravel/cache/drivers/redis.php b/laravel/cache/drivers/redis.php index cc3c621..2ed3cac 100644 --- a/laravel/cache/drivers/redis.php +++ b/laravel/cache/drivers/redis.php @@ -5,14 +5,14 @@ class Redis extends Driver { /** * The Redis database instance. * - * @var Redis + * @var Laravel\Redis */ protected $redis; /** * Create a new Redis cache driver instance. * - * @param Redis $redis + * @param Laravel\Redis $redis * @return void */ public function __construct(\Laravel\Redis $redis) diff --git a/laravel/cli/console.php b/laravel/cli/console.php index 1512aaa..0591f93 100644 --- a/laravel/cli/console.php +++ b/laravel/cli/console.php @@ -6,7 +6,7 @@ class Console { * Parse the command line arguments and return the results. * * @param array $argv - * @param array + * @return array */ public static function options($argv) { diff --git a/laravel/cli/dependencies.php b/laravel/cli/dependencies.php index 2a665b8..3c6acc4 100644 --- a/laravel/cli/dependencies.php +++ b/laravel/cli/dependencies.php @@ -22,7 +22,9 @@ */ IoC::register('task: bundle', function() { - return new Tasks\Bundle\Bundler; + $repository = IoC::resolve('bundle.repository'); + + return new Tasks\Bundle\Bundler($repository); }); /** diff --git a/laravel/cli/tasks/bundle/bundler.php b/laravel/cli/tasks/bundle/bundler.php index b154fd1..156fa34 100644 --- a/laravel/cli/tasks/bundle/bundler.php +++ b/laravel/cli/tasks/bundle/bundler.php @@ -1,11 +1,30 @@ repository = $repository; + } + /** * Install the given bundles into the application. * @@ -16,7 +35,7 @@ public function install($bundles) { foreach ($this->get($bundles) as $bundle) { - if (is_dir(path('bundle').$bundle['name'])) + if (Bundle::exists($bundle['name'])) { echo "Bundle {$bundle['name']} is already installed."; @@ -30,9 +49,58 @@ public function install($bundles) // Each bundle provider implements the Provider interface and // is repsonsible for retrieving the bundle source from its // hosting party and installing it into the application. - $provider = "bundle.provider: {$bundle['provider']}"; + $path = path('bundle').$this->path($bundle); + + $this->download($bundle, $path); + + echo "Bundle [{$bundle['name']}] has been installed!".PHP_EOL; + } + } + + /** + * Upgrade the given bundles for the application. + * + * @param array $bundles + * @return void + */ + public function upgrade($bundles) + { + if (count($bundles) == 0) $bundles = Bundle::names(); + + foreach ($bundles as $name) + { + if ( ! Bundle::exists($name)) + { + echo "Bundle [{$name}] is not installed!"; + + continue; + } + + // First we want to retrieve the information for the bundle, + // such as where it is currently installed. This will let + // us upgrade the bundle into the same path in which it + // is already installed. + $bundle = Bundle::get($name); + + // If the bundle exists, we will grab the data about the + // bundle from the API so we can make the right bundle + // provider for the bundle, since we have no way of + // knowing which provider was used to install. + $response = $this->retrieve($name); + + if ($response['status'] == 'not-found') + { + continue; + } + + // Once we have the bundle information from the API, + // we'll simply recursively delete the bundle and + // then re-download it using the provider. + File::rmdir($bundle->location); - IoC::resolve($provider)->install($bundle); + $this->download($response['bundle'], $bundle->location); + + echo "Bundle [{$name}] has been upgraded!".PHP_EOL; } } @@ -44,9 +112,9 @@ public function install($bundles) */ public function publish($bundles) { - // If no bundles are passed to the command, we'll just gather all - // of the installed bundle names and publish the assets for each - // of the bundles to the public directory. + // If no bundles are passed to the command, we'll just gather + // all of the installed bundle names and publish the assets + // for each of the bundles to the public directory. if (count($bundles) == 0) $bundles = Bundle::names(); $publisher = IoC::resolve('bundle.publisher'); @@ -67,20 +135,13 @@ protected function get($bundles) { $responses = array(); - $repository = IoC::resolve('bundle.repository'); - foreach ($bundles as $bundle) { // First we'll call the bundle repository to gather the bundle data // array, which contains all of the information needed to install // the bundle into the application. We'll verify that the bundle // exists and the API is responding for each bundle. - $response = $repository->get($bundle); - - if ( ! $response) - { - throw new \Exception("The bundle API is not responding."); - } + $response = $this->retrieve($bundle); if ($response['status'] == 'not-found') { @@ -95,10 +156,55 @@ protected function get($bundles) $responses[] = $bundle; - $responses = array_merge($responses, $this->get($bundle['dependencies'])); + $dependencies = $this->get($bundle['dependencies']); + + $responses = array_merge($responses, $dependencies); } return $responses; } + /** + * Install a bundle using a provider. + * + * @param string $bundle + * @param string $path + * @return void + */ + protected function download($bundle, $path) + { + $provider = "bundle.provider: {$bundle['provider']}"; + + IoC::resolve($provider)->install($bundle, $path); + } + + /** + * Retrieve a bundle from the repository. + * + * @param string $bundle + * @return array + */ + protected function retrieve($bundle) + { + $response = $this->repository->get($bundle); + + if ( ! $response) + { + throw new \Exception("The bundle API is not responding."); + } + + return $response; + } + + /** + * Return the path for a given bundle. + * + * @param array $bundle + * @return string + */ + protected function path($bundle) + { + return array_get($bundle, 'path', $bundle['name']); + } + } \ No newline at end of file diff --git a/laravel/cli/tasks/bundle/providers/github.php b/laravel/cli/tasks/bundle/providers/github.php index 9dd90da..7aa3462 100644 --- a/laravel/cli/tasks/bundle/providers/github.php +++ b/laravel/cli/tasks/bundle/providers/github.php @@ -1,6 +1,4 @@ -$method($bundle); - } - - /** - * Install a Github hosted bundle from Zip. - * - * @param string $bundle - * @return void - */ - protected function zipball($bundle) + public function install($bundle, $path) { $url = "http://nodeload.github.com/{$bundle['location']}/zipball/master"; - parent::zipball($bundle, $url, true); - - echo "Bundle [{$bundle['name']}] has been installed!".PHP_EOL; - } - - /** - * Install a Github hosted bundle using submodules. - * - * @param string $bundle - * @return void - */ - protected function submodule($bundle) - { - $repository = "git@github.com:{$bundle['location']}.git"; - - $this->directory($bundle); - - // We need to just extract the basename of the bundle path when - // adding the submodule. Of course, we can't add a submodule to - // a location outside of the Git repository, so we don't need - // the full bundle path. - $root = basename(path('bundle')).'/'; - - passthru('git submodule add '.$repository.' '.$root.$this->path($bundle)); - - passthru('git submodule update'); - } - - /** - * Create the path to the bundle's dirname. - * - * @param array $bundle - * @return void - */ - protected function directory($bundle) - { - // If the installation target directory doesn't exist, we will create - // it recursively so that we can properly install the bundle to the - // correct path in the application. - $target = dirname(path('bundle').$this->path($bundle)); - - if ( ! is_dir($target)) - { - mkdir($target, 0777, true); - } + parent::zipball($url, $bundle, $path); } } \ No newline at end of file diff --git a/laravel/cli/tasks/bundle/providers/provider.php b/laravel/cli/tasks/bundle/providers/provider.php index 8007371..5309e5c 100644 --- a/laravel/cli/tasks/bundle/providers/provider.php +++ b/laravel/cli/tasks/bundle/providers/provider.php @@ -8,23 +8,27 @@ abstract class Provider { * Install the given bundle into the application. * * @param string $bundle + * @param string $path * @return void */ - abstract public function install($bundle); + abstract public function install($bundle, $path); /** * Install a bundle from by downloading a Zip. * - * @param array $bundle * @param string $url + * @param array $bundle + * @param string $path * @return void */ - protected function zipball($bundle, $url) + protected function zipball($url, $bundle, $path) { + $work = path('storage').'work/'; + // When installing a bundle from a Zip archive, we'll first clone // down the bundle zip into the bundles "working" directory so // we have a spot to do all of our bundle extration work. - $target = path('storage').'work/laravel-bundle.zip'; + $target = $work.'laravel-bundle.zip'; File::put($target, file_get_contents($url)); @@ -36,31 +40,18 @@ protected function zipball($bundle, $url) // into the working directory. By convention, we expect the // archive to contain one root directory, and all of the // bundle contents should be stored in that directory. - $zip->extractTo(path('storage').'work'); + $zip->extractTo($work); - $latest = File::latest(dirname($target)); + $latest = File::latest($work)->getRealPath(); - @chmod($latest->getRealPath(), 0777); + @chmod($latest, 0777); // Once we have the latest modified directory, we should be // able to move its contents over into the bundles folder // so the bundle will be usable by the develoepr. - $path = $this->path($bundle); - - File::mvdir($latest->getRealPath(), path('bundle').$path); + File::mvdir($latest, $path); @unlink($target); } - /** - * Return the path for a given bundle. - * - * @param array $bundle - * @return string - */ - protected function path($bundle) - { - return array_get($bundle, 'path', $bundle['name']); - } - } \ No newline at end of file diff --git a/laravel/cli/tasks/migrate/database.php b/laravel/cli/tasks/migrate/database.php index 29bfb15..a6aae9d 100644 --- a/laravel/cli/tasks/migrate/database.php +++ b/laravel/cli/tasks/migrate/database.php @@ -74,7 +74,7 @@ public function batch() /** * Get a database query instance for the migration table. * - * @return Query + * @return Laravel\Database\Query */ protected function table() { diff --git a/laravel/cli/tasks/migrate/resolver.php b/laravel/cli/tasks/migrate/resolver.php index 67e5323..f139195 100644 --- a/laravel/cli/tasks/migrate/resolver.php +++ b/laravel/cli/tasks/migrate/resolver.php @@ -14,7 +14,7 @@ class Resolver { /** * Create a new instance of the migration resolver. * - * @param Database $datbase + * @param Database $database * @return void */ public function __construct(Database $database) diff --git a/laravel/cli/tasks/test/runner.php b/laravel/cli/tasks/test/runner.php index 06066c2..dbddf0f 100644 --- a/laravel/cli/tasks/test/runner.php +++ b/laravel/cli/tasks/test/runner.php @@ -41,7 +41,7 @@ public function core() /** * Run the tests for a given bundle. * - * @param array $arguments + * @param array $bundles * @return void */ public function bundle($bundles = array()) diff --git a/laravel/cookie.php b/laravel/cookie.php index e5c5db9..fd60583 100644 --- a/laravel/cookie.php +++ b/laravel/cookie.php @@ -113,7 +113,7 @@ public static function get($name, $default = null) * @param string $path * @param string $domain * @param bool $secure - * @return bool + * @return void */ public static function put($name, $value, $minutes = 0, $path = '/', $domain = null, $secure = false) { diff --git a/laravel/database.php b/laravel/database.php index ef2389a..447fa76 100644 --- a/laravel/database.php +++ b/laravel/database.php @@ -26,7 +26,7 @@ class Database { * * * @param string $connection - * @return Connection + * @return Database\Connection */ public static function connection($connection = null) { @@ -62,7 +62,7 @@ protected static function connect($config) * Create a new database connector instance. * * @param string $driver - * @return Connector + * @return Database\Connectors\Connector */ protected static function connector($driver) { @@ -90,7 +90,7 @@ protected static function connector($driver) * * @param string $table * @param string $connection - * @return Queries\Query + * @return Database\Query */ public static function table($table, $connection = null) { diff --git a/laravel/database/query.php b/laravel/database/query.php index 6c7dbcd..d3363a4 100644 --- a/laravel/database/query.php +++ b/laravel/database/query.php @@ -625,7 +625,7 @@ public function get($columns = array('*')) /** * Get an aggregate value. * - * @param string $aggregate + * @param string $aggregator * @param string $column * @return mixed */ diff --git a/laravel/database/query/grammars/sqlserver.php b/laravel/database/query/grammars/sqlserver.php index 15efafe..6b3c812 100644 --- a/laravel/database/query/grammars/sqlserver.php +++ b/laravel/database/query/grammars/sqlserver.php @@ -124,7 +124,7 @@ protected function ansi_offset(Query $query, $components) */ protected function limit(Query $query) { - return; + return ''; } /** @@ -135,7 +135,7 @@ protected function limit(Query $query) */ protected function offset(Query $query) { - return; + return ''; } } \ No newline at end of file diff --git a/laravel/database/schema/table.php b/laravel/database/schema/table.php index 8151679..9eee0cc 100644 --- a/laravel/database/schema/table.php +++ b/laravel/database/schema/table.php @@ -99,7 +99,9 @@ public function fulltext($columns, $name) /** * Create a new index on the table. * - * @param string|array + * @param string|array $columns + * @param string $name + * @return Fluent */ public function index($columns, $name) { @@ -237,7 +239,6 @@ public function integer($name, $increment = false) * Add a float column to the table. * * @param string $name - * @param bool $increment * @return Fluent */ public function float($name) diff --git a/laravel/file.php b/laravel/file.php index 7466427..4bb0293 100644 --- a/laravel/file.php +++ b/laravel/file.php @@ -93,7 +93,7 @@ public static function type($path) /** * Get the file size of a given file. * - * @param string $file + * @param string $path * @return int */ public static function size($path) @@ -149,7 +149,7 @@ public static function mime($extension, $default = 'application/octet-stream') * $image = File::is(array('jpg', 'png', 'gif'), 'path/to/file'); * * - * @param array|string $extension + * @param array|string $extensions * @param string $path * @return bool */ @@ -241,6 +241,36 @@ public static function cpdir($source, $destination, $delete = false, $options = if ($delete) rmdir($source); } + /** + * Recursively delete a directory. + * + * @param string $directory + * @return void + */ + public static function rmdir($directory) + { + if ( ! is_dir($directory)) return; + + $items = new fIterator($directory); + + foreach ($items as $item) + { + // If the item is a directory, we can just recurse into the + // function and delete that sub-directory, otherwise we'll + // just deleete the file and keep going! + if ($item->isDir()) + { + static::rmdir($item->getRealPath()); + } + else + { + @unlink($item->getRealPath()); + } + } + + @rmdir($directory); + } + /** * Get the most recently modified file in a directory. * diff --git a/laravel/form.php b/laravel/form.php index 6b3f310..1fd97ca 100644 --- a/laravel/form.php +++ b/laravel/form.php @@ -186,6 +186,7 @@ public static function label($name, $value, $attributes = array()) * echo Form::input('text', 'email', 'example@gmail.com'); * * + * @param string $type * @param string $name * @param mixed $value * @param array $attributes @@ -389,7 +390,7 @@ public static function select($name, $options = array(), $selected = null, $attr * * @param string $value * @param string $display - * @return string $selected + * @param string $selected * @return string */ protected static function option($value, $display, $selected) @@ -506,6 +507,7 @@ public static function reset($value, $attributes = array()) * * * @param string $url + * @param string $name * @param array $attributes * @return string */ @@ -519,7 +521,6 @@ public static function image($url, $name = null, $attributes = array()) /** * Create a HTML button element. * - * @param string $name * @param string $value * @param array $attributes * @return string diff --git a/laravel/helpers.php b/laravel/helpers.php index dc88731..0700e55 100644 --- a/laravel/helpers.php +++ b/laravel/helpers.php @@ -26,7 +26,7 @@ function __($key, $replacements = array(), $language = null) return Laravel\Lang::line($key, $replacements, $language); } -/**a +/** * Get an item from an array using "dot" notation. * * @@ -362,4 +362,15 @@ function str_contains($haystack, $needle) function value($value) { return ($value instanceof Closure) ? call_user_func($value) : $value; +} + +/** + * Short-cut for constructor method chaining. + * + * @param mixed $object + * @return mixed + */ +function with($object) +{ + return $object; } \ No newline at end of file diff --git a/laravel/html.php b/laravel/html.php index 7644731..9d5a914 100644 --- a/laravel/html.php +++ b/laravel/html.php @@ -173,6 +173,7 @@ public static function link_to_secure_asset($url, $title, $attributes = array()) * @param string $title * @param array $parameters * @param array $attributes + * @param bool $https * @return string */ public static function link_to_route($name, $title, $parameters = array(), $attributes = array(), $https = false) diff --git a/laravel/ioc.php b/laravel/ioc.php index 0c3e168..2c59646 100644 --- a/laravel/ioc.php +++ b/laravel/ioc.php @@ -21,6 +21,7 @@ class IoC { * * @param string $name * @param Closure $resolver + * @param bool $singleton * @return void */ public static function register($name, Closure $resolver, $singleton = false) diff --git a/laravel/laravel.php b/laravel/laravel.php index 0d9253a..0ba4f4d 100644 --- a/laravel/laravel.php +++ b/laravel/laravel.php @@ -149,27 +149,38 @@ } /** - * Route the request to the proper route in the application. If a - * route is found, the route will be called via the request class - * static property. If no route is found, the 404 response will - * be returned to the browser. + * If the requset URI has too many segments, we will bomb out of + * the request. This is too avoid potential DDoS attacks against + * the framework by overloading the controller lookup method + * with thousands of segments. */ +$uri = URI::current(); + if (count(URI::$segments) > 15) { throw new \Exception("Invalid request. Too many URI segments."); } -Request::$route = Routing\Router::route(Request::method(), URI::current()); +/** + * Route the request to the proper route in the application. If a + * route is found, the route will be called via the request class + * static property. If no route is found, the 404 response will + * be returned to the browser. + */ +Request::$route = Routing\Router::route(Request::method(), $uri); -if ( ! is_null(Request::$route)) -{ - $response = Request::$route->call(); -} -else +if (is_null(Request::$route)) { + Request::$route = new Routing\Route('GET /404', array(function() + { + return Response::error('404'); + })); + $response = Response::error('404'); } +$response = Request::$route->call(); + /** * Close the session and write the active payload to persistent * storage. The session cookie will also be written and if the diff --git a/laravel/memcached.php b/laravel/memcached.php index d073737..548e298 100644 --- a/laravel/memcached.php +++ b/laravel/memcached.php @@ -5,7 +5,7 @@ class Memcached { /** * The Memcached connection instance. * - * @var Memcache + * @var Memcached */ protected static $connection; @@ -20,7 +20,7 @@ class Memcached { * Memcached::connection()->set('name', 'Taylor'); * * - * @return Memcache + * @return Memcached */ public static function connection() { @@ -36,7 +36,7 @@ public static function connection() * Create a new Memcached connection instance. * * @param array $servers - * @return Memcache + * @return Memcached */ protected static function connect($servers) { diff --git a/laravel/messages.php b/laravel/messages.php index 4b49972..f0c449f 100644 --- a/laravel/messages.php +++ b/laravel/messages.php @@ -12,6 +12,7 @@ class Messages { /** * Create a new Messages instance. * + * @param array $messages * @return void */ public function __construct($messages = array()) diff --git a/laravel/paginator.php b/laravel/paginator.php index c194231..a3176e6 100644 --- a/laravel/paginator.php +++ b/laravel/paginator.php @@ -71,10 +71,10 @@ class Paginator { * Create a new Paginator instance. * * @param array $results - * @param int $last * @param int $page * @param int $total * @param int $per_page + * @param int $last * @return void */ protected function __construct($results, $page, $total, $per_page, $last) @@ -246,6 +246,7 @@ public function slider($adjacent = 3) * echo $paginator->previous('Go Back'); * * + * @param string $text * @return string */ public function previous($text = null) @@ -266,6 +267,7 @@ public function previous($text = null) * echo $paginator->next('Skip Forwards'); * * + * @param string $text * @return string */ public function next($text = null) @@ -364,7 +366,7 @@ protected function range($start, $end) * * @param int $page * @param string $text - * @param string $attributes + * @param string $class * @return string */ protected function link($page, $text, $class) diff --git a/laravel/redirect.php b/laravel/redirect.php index 2f19fa7..7dd606e 100644 --- a/laravel/redirect.php +++ b/laravel/redirect.php @@ -28,7 +28,7 @@ public static function to($url, $status = 302, $https = false) * * @param string $url * @param int $status - * @return Response + * @return Redirect */ public static function to_secure($url, $status = 302) { @@ -82,7 +82,7 @@ public static function to_secure_route($route, $parameters = array(), $status = * * @param string $key * @param mixed $value - * @return Response + * @return Redirect */ public function with($key, $value) { diff --git a/laravel/routing/filter.php b/laravel/routing/filter.php index 86d71bc..61e3def 100644 --- a/laravel/routing/filter.php +++ b/laravel/routing/filter.php @@ -155,6 +155,7 @@ class Filter_Collection { * * @param string|array $filters * @param mixed $parameters + * @return void */ public function __construct($filters, $parameters = null) { diff --git a/laravel/routing/route.php b/laravel/routing/route.php index 4d0ce72..3150499 100644 --- a/laravel/routing/route.php +++ b/laravel/routing/route.php @@ -53,7 +53,6 @@ public function __construct($key, $action, $parameters = array()) { $this->key = $key; $this->action = $action; - $this->parameters = $parameters; // Extract each URI from the route key. Since the route key has the request // method, we will extract that from the string. If the URI points to the @@ -67,6 +66,8 @@ public function __construct($key, $action, $parameters = array()) // the bundle so we know if we need to run a bundle's global filters // when executing the route. $this->bundle = Bundle::resolve(head(explode('/', $this->uris[0]))); + + $this->parameters = array_map('urldecode', $parameters); } /** @@ -141,7 +142,7 @@ public function response() * * If the route belongs to a bundle, the bundle's global filters are returned too. * - * @param string $filter + * @param string $event * @return array */ protected function filters($event) diff --git a/laravel/routing/router.php b/laravel/routing/router.php index c5112ed..3623f6d 100644 --- a/laravel/routing/router.php +++ b/laravel/routing/router.php @@ -36,6 +36,13 @@ class Router { '/(:any?)' => '(?:/([a-zA-Z0-9\.\-_%]+)', ); + /** + * An array of HTTP request methods. + * + * @var array + */ + public static $methods = array('GET', 'POST', 'PUT', 'DELETE'); + /** * Register a route with the router. * @@ -48,13 +55,20 @@ class Router { * * * @param string|array $route - * @param string $action + * @param mixed $action * @return void */ public static function register($route, $action) { foreach ((array) $route as $uri) { + if (starts_with($uri, '*')) + { + static::universal(substr($uri, 2), $action); + + continue; + } + // If the action is a string, it is a pointer to a controller, so we // need to add it to the action array as a "uses" clause, which will // indicate to the route to call the controller when the route is @@ -78,6 +92,30 @@ public static function register($route, $action) } } + /** + * Register a route for all HTTP verbs. + * + * @param string $route + * @param mixed $action + * @return void + */ + protected static function universal($route, $action) + { + $count = count(static::$methods); + + $routes = array_fill(0, $count, $route); + + // When registering a universal route, we'll iterate through all of the + // verbs supported by the router and prepend each one of the URIs with + // one of the request verbs, then we'll register the routes. + for ($i = 0; $i < $count; $i++) + { + $routes[$i] = static::$methods[$i].' '.$routes[$i]; + } + + static::register($routes, $action); + } + /** * Find a route by the route's assigned name. * @@ -254,8 +292,8 @@ protected static function controller($bundle, $method, $destination, $segments) /** * Locate the URI segment matching a controller name. * - * @param string $directory * @param array $segments + * @param string $directory * @return int */ protected static function locate($segments, $directory) diff --git a/laravel/session.php b/laravel/session.php index 817e32a..ee99777 100644 --- a/laravel/session.php +++ b/laravel/session.php @@ -5,7 +5,7 @@ class Session { /** * The session singleton instance for the request. * - * @var Payload + * @var Session\Payload */ public static $instance; @@ -31,7 +31,7 @@ public static function start($driver) * Create a new session driver instance. * * @param string $driver - * @return Driver + * @return Session\Drivers\Driver */ public static function factory($driver) { @@ -71,7 +71,7 @@ public static function factory($driver) * Session::instance()->put('name', 'Taylor'); * * - * @return Payload + * @return Session\Payload */ public static function instance() { diff --git a/laravel/session/drivers/apc.php b/laravel/session/drivers/apc.php index 61f7bcf..a45efaa 100644 --- a/laravel/session/drivers/apc.php +++ b/laravel/session/drivers/apc.php @@ -5,14 +5,14 @@ class APC implements Driver { /** * The APC cache driver instance. * - * @var Cache\Drivers\APC + * @var Laravel\Cache\Drivers\APC */ private $apc; /** * Create a new APC session driver instance. * - * @param Cache\Drivers\APC $apc + * @param Laravel\Cache\Drivers\APC $apc * @return void */ public function __construct(\Laravel\Cache\Drivers\APC $apc) diff --git a/laravel/session/drivers/memcached.php b/laravel/session/drivers/memcached.php index 3c7a130..f6c73e5 100644 --- a/laravel/session/drivers/memcached.php +++ b/laravel/session/drivers/memcached.php @@ -5,14 +5,14 @@ class Memcached implements Driver { /** * The Memcache cache driver instance. * - * @var Cache\Drivers\Memcached + * @var Laravel\Cache\Drivers\Memcached */ private $memcached; /** * Create a new Memcached session driver instance. * - * @param Memcached $memcached + * @param Laravel\Cache\Drivers\Memcached $memcached * @return void */ public function __construct(\Laravel\Cache\Drivers\Memcached $memcached) diff --git a/laravel/session/drivers/redis.php b/laravel/session/drivers/redis.php index a45b9a1..1f93fea 100644 --- a/laravel/session/drivers/redis.php +++ b/laravel/session/drivers/redis.php @@ -5,14 +5,14 @@ class Redis implements Driver { /** * The Redis cache driver instance. * - * @var Cache\Drivers\Redis + * @var Laravel\Cache\Drivers\Redis */ protected $redis; /** * Create a new Redis session driver. * - * @param Cache\Drivers\Redis $redis + * @param Laravel\Cache\Drivers\Redis $redis * @return void */ public function __construct(\Laravel\Cache\Drivers\Redis $redis) diff --git a/laravel/session/payload.php b/laravel/session/payload.php index a640a96..5269816 100644 --- a/laravel/session/payload.php +++ b/laravel/session/payload.php @@ -202,7 +202,7 @@ public function reflash() * Session::keep(array('name', 'email')); * * - * @param string|array $key + * @param string|array $keys * @return void */ public function keep($keys) diff --git a/laravel/str.php b/laravel/str.php index 80fb038..8f46282 100644 --- a/laravel/str.php +++ b/laravel/str.php @@ -154,6 +154,7 @@ public static function singular($value) * * * @param string $value + * @param int $count * @return string */ public static function plural($value, $count = 2) @@ -177,7 +178,7 @@ public static function plural($value, $count = 2) * * * @param string $value - * @param int $length + * @param int $words * @param string $end * @return string */ diff --git a/laravel/uri.php b/laravel/uri.php index e94b16a..e86eae9 100644 --- a/laravel/uri.php +++ b/laravel/uri.php @@ -33,22 +33,14 @@ public static function current() $uri = static::remove($uri, parse_url(URL::base(), PHP_URL_PATH)); // We'll also remove the application's index page as it is not used for at - // all for routing and is totally unnecessary as far as the framework is - // concerned. It is only in the URI when mod_rewrite is not available. + // all for routing and is totally unnecessary as far as the routing of + // incoming requests to the framework is concerned. if (($index = '/'.Config::get('application.index')) !== '/') { $uri = static::remove($uri, $index); } - static::$uri = static::format($uri); - - // Cache the URI segments. This allows us to avoid having to explode - // the segments every time the developer requests one of them. The - // extra slashes have already been stripped off of the URI so no - // extraneous elements should be present in the segment array. - $segments = explode('/', trim(static::$uri, '/')); - - static::$segments = array_diff($segments, array('')); + static::segments(static::$uri = static::format($uri)); return static::$uri; } @@ -75,6 +67,19 @@ public static function segment($index, $default = null) return array_get(static::$segments, $index - 1, $default); } + /** + * Set the URI segments for the request. + * + * @param string $uri + * @return void + */ + protected static function segments($uri) + { + $segments = explode('/', trim($uri, '/')); + + static::$segments = array_diff($segments, array('')); + } + /** * Remove a given value from the URI. * diff --git a/laravel/url.php b/laravel/url.php index 30f8321..11b142d 100644 --- a/laravel/url.php +++ b/laravel/url.php @@ -2,6 +2,13 @@ class URL { + /** + * The cached base URL. + * + * @var string + */ + public static $base; + /** * Get the base URL of the application. * @@ -9,7 +16,17 @@ class URL { */ public static function base() { - if (($base = Config::get('application.url')) !== '') return $base; + if (isset(static::$base)) return static::$base; + + $base = 'http://localhost'; + + // If the application URL configuration is set, we will just use + // that instead of trying to guess the URL based on the $_SERVER + // array's host and script name. + if (($url = Config::get('application.url')) !== '') + { + $base = $url; + } if (isset($_SERVER['HTTP_HOST'])) { @@ -21,10 +38,10 @@ public static function base() // construct the base URL to the application. $path = str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']); - return rtrim($protocol.$_SERVER['HTTP_HOST'].$path, '/'); + $base = rtrim($protocol.$_SERVER['HTTP_HOST'].$path, '/'); } - return 'http://localhost'; + return static::$base = $base; } /** diff --git a/laravel/validator.php b/laravel/validator.php index 73e1b20..73baebf 100644 --- a/laravel/validator.php +++ b/laravel/validator.php @@ -58,13 +58,6 @@ class Validator { */ protected $size_rules = array('size', 'between', 'min', 'max'); - /** - * The inclusion related validation rules. - * - * @var array - */ - protected $inclusion_rules = array('in', 'not_in', 'mimes'); - /** * The numeric related validation rules. * @@ -253,9 +246,7 @@ protected function validate_required($attribute, $value) */ protected function validate_confirmed($attribute, $value) { - $confirmed = $attribute.'_confirmation'; - - return isset($this->attributes[$confirmed]) and $value == $this->attributes[$confirmed]; + return $this->validate_same($attribute, $value, array($attribute.'_confirmation')); } /** @@ -272,6 +263,36 @@ protected function validate_accepted($attribute, $value) return $this->validate_required($attribute, $value) and ($value == 'yes' or $value == '1'); } + /** + * Validate that an attribute is the same as another attribute. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validate_same($attribute, $value, $parameters) + { + $other = $parameters[0]; + + return isset($this->attributes[$other]) and $value == $this->attributes[$other]; + } + + /** + * Validate that an attribute is different from another attribute. + * + * @param string $attribute + * @param mixed $value + * @param array $parameters + * @return bool + */ + protected function validate_different($attribute, $value, $parameters) + { + $other = $parameters[0]; + + return isset($this->attributes[$other]) and $value != $this->attributes[$other]; + } + /** * Validate that an attribute is numeric. * @@ -686,28 +707,138 @@ protected function replace($message, $attribute, $rule, $parameters) { $message = str_replace(':attribute', $this->attribute($attribute), $message); - if (in_array($rule, $this->size_rules)) + if (method_exists($this, $replacer = 'replace_'.$rule)) { - // Even though every size rule will not have a place-holder for min, max, - // and size, we will go ahead and make replacements for all of them just - // for convenience. Except for "between", every replacement should be - // the first parameter in the array. - $max = ($rule == 'between') ? $parameters[1] : $parameters[0]; + $message = $this->$replacer($message, $attribute, $rule, $parameters); + } - $replace = array($parameters[0], $parameters[0], $max); + return $message; + } - $message = str_replace(array(':size', ':min', ':max'), $replace, $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_between($message, $attribute, $rule, $parameters) + { + return str_replace(array(':min', ':max'), $parameters, $message); + } - // The :values place-holder is used for rules that accept a list of - // values, such as "in" and "not_in". The place-holder value will - // be replaced with a comma delimited list of the values. - elseif (in_array($rule, $this->inclusion_rules)) - { - $message = str_replace(':values', implode(', ', $parameters), $message); - } + /** + * Replace all place-holders for the size rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replace_size($message, $attribute, $rule, $parameters) + { + return str_replace(':size', $parameters[0], $message); + } - return $message; + /** + * Replace all place-holders for the min rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replace_min($message, $attribute, $rule, $parameters) + { + return str_replace(':min', $parameters[0], $message); + } + + /** + * Replace all place-holders for the max rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replace_max($message, $attribute, $rule, $parameters) + { + return str_replace(':max', $parameters[0], $message); + } + + /** + * Replace all place-holders for the in rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replace_in($message, $attribute, $rule, $parameters) + { + return str_replace(':values', implode(', ', $parameters), $message); + } + + /** + * Replace all place-holders for the not_in rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replace_not_in($message, $attribute, $rule, $parameters) + { + return str_replace(':values', implode(', ', $parameters), $message); + } + + /** + * Replace all place-holders for the not_in rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replace_mimes($message, $attribute, $rule, $parameters) + { + return str_replace(':values', implode(', ', $parameters), $message); + } + + /** + * Replace all place-holders for the same rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replace_same($message, $attribute, $rule, $parameters) + { + return str_replace(':other', $parameters[0], $message); + } + + /** + * Replace all place-holders for the different rule. + * + * @param string $message + * @param string $attribute + * @param string $rule + * @param array $parameters + * @return string + */ + protected function replace_different($message, $attribute, $rule, $parameters) + { + return str_replace(':other', $parameters[0], $message); } /** @@ -727,7 +858,9 @@ protected function attribute($attribute) // If no language line has been specified for the attribute, all of // the underscores will be removed from the attribute name and that // will be used as the attribtue name in the message. - $display = Lang::line("{$bundle}validation.attributes.{$attribute}")->get($this->language); + $line = "{$bundle}validation.attributes.{$attribute}"; + + $display = Lang::line($line)->get($this->language); return (is_null($display)) ? str_replace('_', ' ', $attribute) : $display; } @@ -813,7 +946,7 @@ public function connection(Database\Connection $connection) /** * Get the database connection for the Validator. * - * @return Connection + * @return Database\Connection */ protected function db() { diff --git a/laravel/view.php b/laravel/view.php index 3aa3f73..1b153d5 100644 --- a/laravel/view.php +++ b/laravel/view.php @@ -183,7 +183,7 @@ public static function name($view, $name) * * * @param string $view - * @param Closure + * @param Closure $composer * @return void */ public static function composer($view, $composer) diff --git a/paths.php b/paths.php index f4b0f45..b18b067 100644 --- a/paths.php +++ b/paths.php @@ -68,17 +68,28 @@ $GLOBALS['laravel_paths'][$name] = realpath($path).DS; } -// -------------------------------------------------------------- -// Define a global path helper function. -// -------------------------------------------------------------- +/** + * A global path helper function. + * + * + * $storage = path('storage'); + * + * + * @param string $path + * @return string + */ function path($path) { return $GLOBALS['laravel_paths'][$path]; } -// -------------------------------------------------------------- -// Define a global path setter function. -// -------------------------------------------------------------- +/** + * A global path setter function. + * + * @param string $path + * @param string $value + * @return void + */ function set_path($path, $value) { $GLOBALS['laravel_paths'][$path] = $value;