diff --git a/app/controllers/Api/Web/DashboardController.php b/app/controllers/Api/Web/DashboardController.php index e444ee61..343b2ef6 100644 --- a/app/controllers/Api/Web/DashboardController.php +++ b/app/controllers/Api/Web/DashboardController.php @@ -7,6 +7,7 @@ use Commands\UploadTrackCommand; use Cover; use Entities\Image; + use Entities\News; use Entities\Track; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Input; @@ -20,7 +21,7 @@ ->explicitFilter() ->published() ->orderBy('published_at', 'desc') - ->take(20); + ->take(30); $recentTracks = []; @@ -30,6 +31,13 @@ return Response::json([ 'recent_tracks' => $recentTracks, - 'popular_tracks' => Track::popular(30, Auth::check() && Auth::user()->can_see_explicit_content)], 200); + 'popular_tracks' => Track::popular(30, Auth::check() && Auth::user()->can_see_explicit_content), + 'news' => News::getNews(0, 10)], 200); + } + + public function postReadNews() { + News::markPostAsRead(Input::get('url')); + return Response::json([ + ]); } } \ No newline at end of file diff --git a/app/controllers/TracksController.php b/app/controllers/TracksController.php index 2863740a..d89772f0 100644 --- a/app/controllers/TracksController.php +++ b/app/controllers/TracksController.php @@ -66,16 +66,29 @@ return Redirect::action('TracksController@getTrack', [$id, $track->slug]); } - public function getStream($id) { + public function getStream($id, $extension) { $track = Track::find($id); if (!$track || !$track->canView(Auth::user())) App::abort(404); - $format = Track::$Formats['MP3']; + $format = null; + $formatName = null; + + foreach (Track::$Formats as $name => $item) { + if ($item['extension'] == $extension) { + $format = $item; + $formatName = $name; + break; + } + } + + if ($format == null) + App::abort(404); + ResourceLogItem::logItem('track', $id, ResourceLogItem::PLAY, $format['index']); $response = Response::make('', 200); - $filename = $track->getFileFor('MP3'); + $filename = $track->getFileFor($formatName); if (Config::get('app.sendfile')) { $response->header('X-Sendfile', $filename); diff --git a/app/database/migrations/2013_09_01_232520_create_news_table.php b/app/database/migrations/2013_09_01_232520_create_news_table.php new file mode 100644 index 00000000..d6e9aa73 --- /dev/null +++ b/app/database/migrations/2013_09_01_232520_create_news_table.php @@ -0,0 +1,21 @@ +increments('id'); + $table->integer('user_id')->unsigned()->index(); + $table->string('post_hash', 32)->index(); + $table->timestamps(); + + $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); + }); + } + + public function down() { + Schema::drop('news'); + } + +} \ No newline at end of file diff --git a/app/filters.php b/app/filters.php index 0456d3a0..9c739444 100644 --- a/app/filters.php +++ b/app/filters.php @@ -38,11 +38,11 @@ Log::listen(function($level, $message, $context) use ($profiler) { $profiler->log($level, $message, $context); }); - } - App::error(function($exception) { - return Response::view('errors.404', array(), 404); - }); + App::error(function($exception) { + // return Response::view('errors.500', array(), 404); + }); + } App::missing(function($exception) { return Response::view('errors.404', array(), 404); diff --git a/app/models/Entities/News.php b/app/models/Entities/News.php new file mode 100644 index 00000000..bb0435aa --- /dev/null +++ b/app/models/Entities/News.php @@ -0,0 +1,59 @@ +cache = false; + $feed->set_feed_url('http://mlpforums.com/blog/rss/404-ponyfm-development-blog/'); + $feed->init(); + $feed->handle_content_type(); + + $posts = $feed->get_items($start, $end); + $postHashes = []; + + foreach ($posts as $post) { + $postHashes[] = self::calculateHash($post->get_permalink()); + } + + $seenRecords = Auth::check() ? self::where('user_id', '=', Auth::user()->id)->whereIn('post_hash', $postHashes)->get() : []; + $seenHashes = []; + + foreach ($seenRecords as $record) { + $seenHashes[$record->post_hash] = 1; + } + + $postsReturn = []; + + // This date is around when the last blog post was posted as of now. + // I put in a cutoff so that blog posts made before this update is pushed are always marked as 'read' + $readCutoffDate = mktime(null, null, null, 4, 28, 2013); + + foreach ($posts as $post) { + $autoRead = $post->get_date('U') < $readCutoffDate; + $postsReturn[] = [ + 'title' => $post->get_title(), + 'date' => $post->get_date('j F Y g:i a'), + 'url' => $post->get_permalink(), + 'read' => $autoRead || isset($seenHashes[self::calculateHash($post->get_permalink())])]; + } + + return $postsReturn; + } + + public static function markPostAsRead($postUrl) { + $postHash = self::calculateHash($postUrl); + $news = new News(); + $news->user_id = Auth::user()->id; + $news->post_hash = $postHash; + $news->save(); + } + + private static function calculateHash($postPermalink) { + return md5($postPermalink); + } + } \ No newline at end of file diff --git a/app/models/Entities/Track.php b/app/models/Entities/Track.php index 13a9ae3e..2fab16aa 100644 --- a/app/models/Entities/Track.php +++ b/app/models/Entities/Track.php @@ -8,6 +8,7 @@ use Helpers; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Cache; + use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\URL; @@ -54,7 +55,7 @@ } public static function popular($count, $allowExplicit = false) { - $trackIds = Cache::remember('popular_tracks-' . ($allowExplicit ? 'explicit' : 'safe'), 5, function() use ($allowExplicit) { + $trackIds = Cache::remember('popular_tracks' . $count . '-' . ($allowExplicit ? 'explicit' : 'safe'), 5, function() use ($allowExplicit, $count) { $query = static ::published() ->join(DB::raw(' @@ -65,7 +66,7 @@ 'tracks.id', '=', 'ranged_plays.track_id') ->groupBy('id') ->orderBy('plays', 'desc') - ->take(20); + ->take($count); if (!$allowExplicit) $query->whereIsExplicit(false); @@ -197,7 +198,9 @@ 'normal' => $track->getCoverUrl(Image::NORMAL) ], 'streams' => [ - 'mp3' => $track->getStreamUrl('MP3') + 'mp3' => $track->getStreamUrl('MP3'), + 'aac' => (!Config::get('app.debug') || is_file($track->getFileFor('AAC')) ) ? $track->getStreamUrl('AAC') : null, + 'ogg' => ( Config::get('app.debug') || is_file($track->getFileFor('OGG Vorbis'))) ? $track->getStreamUrl('OGG Vorbis') : null ], 'user_data' => $userData, 'permissions' => [ @@ -350,8 +353,8 @@ return $this->cover->getUrl($type); } - public function getStreamUrl() { - return URL::to('/t' . $this->id . '/stream'); + public function getStreamUrl($format = 'MP3') { + return URL::to('/t' . $this->id . '/stream.' . self::$Formats[$format]['extension']); } public function getDirectory() { diff --git a/app/routes.php b/app/routes.php index 0a0ae864..70292be1 100644 --- a/app/routes.php +++ b/app/routes.php @@ -23,7 +23,7 @@ Route::get('tracks/{id}-{slug}', 'TracksController@getTrack'); Route::get('t{id}', 'TracksController@getShortlink' ); Route::get('t{id}/embed', 'TracksController@getEmbed' ); - Route::get('t{id}/stream', 'TracksController@getStream' ); + Route::get('t{id}/stream.{extension}', 'TracksController@getStream' ); Route::get('t{id}/dl.{extension}', 'TracksController@getDownload' ); Route::get('albums', 'AlbumsController@getIndex'); @@ -92,6 +92,8 @@ Route::post('/favourites/toggle', 'Api\Web\FavouritesController@postToggle'); Route::post('/follow/toggle', 'Api\Web\FollowController@postToggle'); + + Route::post('/dashboard/read-news', 'Api\Web\DashboardController@postReadNews'); }); Route::group(['before' => 'auth'], function() { diff --git a/bootstrap/compiled.php b/bootstrap/compiled.php index 77fc2c3c..bdd50c2f 100644 --- a/bootstrap/compiled.php +++ b/bootstrap/compiled.php @@ -183,7 +183,7 @@ class Container implements ArrayAccess if (is_null($dependency)) { $dependencies[] = $this->resolveNonClass($parameter); } else { - $dependencies[] = $this->make($dependency->name); + $dependencies[] = $this->resolveClass($parameter); } } return (array) $dependencies; @@ -197,6 +197,18 @@ class Container implements ArrayAccess throw new BindingResolutionException($message); } } + protected function resolveClass(ReflectionParameter $parameter) + { + try { + return $this->make($parameter->getClass()->name); + } catch (BindingResolutionException $e) { + if ($parameter->isOptional()) { + return $parameter->getDefaultValue(); + } else { + throw $e; + } + } + } public function resolving(Closure $callback) { $this->resolvingCallbacks[] = $callback; @@ -290,7 +302,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpFoundation\RedirectResponse as SymfonyRedirect; class Application extends Container implements HttpKernelInterface, ResponsePreparerInterface { - const VERSION = '4.0.2'; + const VERSION = '4.0.6'; protected $booted = false; protected $bootingCallbacks = array(); protected $bootedCallbacks = array(); @@ -298,6 +310,7 @@ class Application extends Container implements HttpKernelInterface, ResponsePrep protected $serviceProviders = array(); protected $loadedProviders = array(); protected $deferredServices = array(); + protected static $requestClass = 'Illuminate\\Http\\Request'; public function __construct(Request $request = null) { $this['request'] = $this->createRequest($request); @@ -307,12 +320,13 @@ class Application extends Container implements HttpKernelInterface, ResponsePrep } protected function createRequest(Request $request = null) { - return $request ?: Request::createFromGlobals(); + return $request ?: static::onRequest('createFromGlobals'); } public function setRequestForConsoleEnvironment() { $url = $this['config']->get('app.url', 'http://localhost'); - $this->instance('request', Request::create($url, 'GET', array(), array(), array(), $_SERVER)); + $parameters = array($url, 'GET', array(), array(), array(), $_SERVER); + $this->instance('request', static::onRequest('create', $parameters)); } public function redirectIfTrailingSlash() { @@ -476,10 +490,11 @@ class Application extends Container implements HttpKernelInterface, ResponsePrep { if ($this->isDownForMaintenance()) { $response = $this['events']->until('illuminate.app.down'); - return $this->prepareResponse($response, $request); - } else { - return $this['router']->dispatch($this->prepareRequest($request)); + if (!is_null($response)) { + return $this->prepareResponse($response, $request); + } } + return $this['router']->dispatch($this->prepareRequest($request)); } public function handle(SymfonyRequest $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) { @@ -553,7 +568,7 @@ class Application extends Container implements HttpKernelInterface, ResponsePrep { $this['exception']->error($callback); } - public function pushError(Closure $closure) + public function pushError(Closure $callback) { $this['exception']->pushError($callback); } @@ -586,6 +601,17 @@ class Application extends Container implements HttpKernelInterface, ResponsePrep { $this->deferredServices = $services; } + public static function requestClass($class = null) + { + if (!is_null($class)) { + static::$requestClass = $class; + } + return static::$requestClass; + } + public static function onRequest($method, $parameters = array()) + { + return forward_static_call_array(array(static::requestClass(), $method), $parameters); + } public function __get($key) { return $this[$key]; @@ -665,7 +691,7 @@ class Request extends \Symfony\Component\HttpFoundation\Request } return true; } - if (is_array($this->input($key))) { + if (is_bool($this->input($key)) or is_array($this->input($key))) { return true; } return trim((string) $this->input($key)) !== ''; @@ -782,6 +808,15 @@ class Request extends \Symfony\Component\HttpFoundation\Request $acceptable = $this->getAcceptableContentTypes(); return isset($acceptable[0]) and $acceptable[0] == 'application/json'; } + public function format($default = 'html') + { + foreach ($this->getAcceptableContentTypes() as $type) { + if ($format = $this->getFormat($type)) { + return $format; + } + } + return $default; + } public function getSessionStore() { if (!isset($this->sessionStore)) { @@ -808,6 +843,8 @@ class Request const HEADER_CLIENT_PROTO = 'client_proto'; const HEADER_CLIENT_PORT = 'client_port'; protected static $trustedProxies = array(); + protected static $trustedHostPatterns = array(); + protected static $trustedHosts = array(); protected static $trustedHeaders = array(self::HEADER_CLIENT_IP => 'X_FORWARDED_FOR', self::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST', self::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO', self::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT'); protected static $httpMethodParameterOverride = false; public $attributes; @@ -952,6 +989,9 @@ class Request $dup->basePath = null; $dup->method = null; $dup->format = null; + if (!$dup->get('_format')) { + $dup->setRequestFormat($this->getRequestFormat()); + } return $dup; } public function __clone() @@ -1000,6 +1040,17 @@ class Request { return self::$trustedProxies; } + public static function setTrustedHosts(array $hostPatterns) + { + self::$trustedHostPatterns = array_map(function ($hostPattern) { + return sprintf('{%s}i', str_replace('}', '\\}', $hostPattern)); + }, $hostPatterns); + self::$trustedHosts = array(); + } + public static function getTrustedHosts() + { + return self::$trustedHostPatterns; + } public static function setTrustedHeaderName($key, $value) { if (!array_key_exists($key, self::$trustedHeaders)) { @@ -1199,7 +1250,19 @@ class Request } $host = strtolower(preg_replace('/:\\d+$/', '', trim($host))); if ($host && !preg_match('/^\\[?(?:[a-zA-Z0-9-:\\]_]+\\.?)+$/', $host)) { - throw new \UnexpectedValueException('Invalid Host'); + throw new \UnexpectedValueException('Invalid Host "' . $host . '"'); + } + if (count(self::$trustedHostPatterns) > 0) { + if (in_array($host, self::$trustedHosts)) { + return $host; + } + foreach (self::$trustedHostPatterns as $pattern) { + if (preg_match($pattern, $host)) { + self::$trustedHosts[] = $host; + return $host; + } + } + throw new \UnexpectedValueException('Untrusted Host "' . $host . '"'); } return $host; } @@ -2152,7 +2215,18 @@ class NativeSessionStorage implements SessionStorageInterface if ($destroy) { $this->metadataBag->stampNew(); } - return session_regenerate_id($destroy); + $ret = session_regenerate_id($destroy); + if ('files' === $this->getSaveHandler()->getSaveHandlerName()) { + session_write_close(); + if (isset($_SESSION)) { + $backup = $_SESSION; + session_start(); + $_SESSION = $backup; + } else { + session_start(); + } + } + return $ret; } public function save() { @@ -2902,8 +2976,7 @@ class ExceptionHandler

%d/%d %s: %s

-
    -', $ind, $total, $class, $message); +
      ', $ind, $total, $class, $message); foreach ($e['trace'] as $trace) { $content .= '
    1. '; if ($trace['function']) { @@ -2932,7 +3005,7 @@ class ExceptionHandler } } } - return "
      \r\n

      {$title}

      \r\n {$content}\r\n
      "; + return "
      \n

      {$title}

      \n {$content}\n
      "; } public function getStylesheet(FlattenException $exception) { @@ -2989,7 +3062,7 @@ class ExceptionHandler } private function decorate($content, $css) { - return "\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n {$content}\r\n \r\n"; + return "\n\n \n \n \n \n \n \n {$content}\n \n"; } private function abbrClass($class) { @@ -3067,7 +3140,7 @@ abstract class ServiceProvider } protected function getClassChain(ReflectionClass $reflect) { - $lastName = null; + $classes = array(); while ($reflect !== false) { $classes[] = $reflect; $reflect = $reflect->getParentClass(); @@ -3081,9 +3154,9 @@ abstract class ServiceProvider } return $namespace; } - public function commands() + public function commands($commands) { - $commands = func_get_args(); + $commands = is_array($commands) ? $commands : func_get_args(); $events = $this->app['events']; $events->listen('artisan.start', function ($artisan) use($commands) { $artisan->resolveCommands($commands); @@ -3398,6 +3471,10 @@ class Str } return rtrim($matches[0]) . $end; } + public static function parseCallback($callback, $default) + { + return static::contains($callback, '@') ? explode('@', $callback, 2) : array($callback, $default); + } public static function plural($value, $count = 2) { return Pluralizer::plural($value, $count); @@ -3522,6 +3599,9 @@ class ErrorHandler return true; } if ($this->displayErrors && error_reporting() & $level && $this->level & $level) { + if (!class_exists('Symfony\\Component\\Debug\\Exception\\ContextErrorException')) { + require 'F:\\Nelson\\My Documents - Personal\\Visual Studio 2010\\Projects\\Poniverse\\spa.pony.fm\\vendor\\symfony\\debug\\Symfony\\Component\\Debug' . '/Exception/ContextErrorException.php'; + } throw new ContextErrorException(sprintf('%s: %s in %s line %d', isset($this->levels[$level]) ? $this->levels[$level] : $level, $message, $file, $line), 0, $level, $file, $line, $context); } return false; @@ -3582,7 +3662,7 @@ class Repository extends NamespacedItemResolver implements ArrayAccess public function has($key) { $default = microtime(true); - return $this->get($key, $default) != $default; + return $this->get($key, $default) !== $default; } public function hasGroup($key) { @@ -3923,7 +4003,7 @@ class Filesystem } public function lastModified($path) { - return filemtime(realpath($path)); + return filemtime($path); } public function isDirectory($directory) { @@ -3959,7 +4039,7 @@ class Filesystem { $directories = array(); foreach (Finder::create()->in($directory)->directories()->depth(0) as $dir) { - $directories[] = $dir->getRealPath(); + $directories[] = $dir->getPathname(); } return $directories; } @@ -3980,12 +4060,12 @@ class Filesystem foreach ($items as $item) { $target = $destination . '/' . $item->getBasename(); if ($item->isDir()) { - $path = $item->getRealPath(); + $path = $item->getPathname(); if (!$this->copyDirectory($path, $target, $options)) { return false; } } else { - if (!$this->copy($item->getRealPath(), $target)) { + if (!$this->copy($item->getPathname(), $target)) { return false; } } @@ -4000,9 +4080,9 @@ class Filesystem $items = new FilesystemIterator($directory); foreach ($items as $item) { if ($item->isDir()) { - $this->deleteDirectory($item->getRealPath()); + $this->deleteDirectory($item->getPathname()); } else { - $this->delete($item->getRealPath()); + $this->delete($item->getPathname()); } } if (!$preserve) { @@ -4248,8 +4328,7 @@ class SessionServiceProvider extends ServiceProvider } protected function registerSessionEvents() { - $app = $this->app; - $config = $app['config']['session']; + $config = $this->app['config']['session']; if (!is_null($config['driver'])) { $this->registerBootingEvent(); $this->registerCloseEvent(); @@ -4257,8 +4336,7 @@ class SessionServiceProvider extends ServiceProvider } protected function registerBootingEvent() { - $app = $this->app; - $this->app->booting(function ($app) use($app) { + $this->app->booting(function ($app) { $app['session']->start(); }); } @@ -4286,7 +4364,7 @@ class SessionServiceProvider extends ServiceProvider { $config = $this->app['config']['session']; $expire = $this->getExpireTime($config); - setcookie($config['cookie'], session_id(), $expire, $config['path'], $config['domain']); + setcookie($config['cookie'], session_id(), $expire, $config['path'], $config['domain'], false, true); } protected function getExpireTime($config) { @@ -4829,21 +4907,21 @@ class Router $this->patternFilters[$pattern][] = compact('name', 'methods'); } } - public function findPatternFilters(Request $request) + public function findPatternFilters($method, $path) { $results = array(); foreach ($this->patternFilters as $pattern => $filters) { - if (str_is('/' . $pattern, $request->getPathInfo())) { - $merge = $this->filterPatternsByMethod($request, $filters); + if (str_is('/' . $pattern, $path)) { + $merge = $this->filterPatternsByMethod($method, $filters); $results = array_merge($results, $merge); } } return $results; } - protected function filterPatternsByMethod(Request $request, $filters) + protected function filterPatternsByMethod($method, $filters) { $results = array(); - $method = strtolower($request->getMethod()); + $method = strtolower($method); foreach ($filters as $filter) { if (is_null($filter['methods']) or in_array($method, $filter['methods'])) { $results[] = $filter['name']; @@ -5154,7 +5232,7 @@ class Dispatcher protected $sorted = array(); public function __construct(Container $container = null) { - $this->container = $container; + $this->container = $container ?: new Container(); } public function listen($event, $listener, $priority = 0) { @@ -5166,7 +5244,7 @@ class Dispatcher } protected function setupWildcardListen($event, $listener, $priority) { - $this->wildcards[$event][] = $listener; + $this->wildcards[$event][] = $this->makeListener($listener); } public function hasListeners($eventName) { @@ -5300,6 +5378,7 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa protected $relations = array(); protected $hidden = array(); protected $visible = array(); + protected $appends = array(); protected $fillable = array(); protected $guarded = array('*'); protected $touches = array(); @@ -5376,6 +5455,10 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa $model->save(); return $model; } + public static function query() + { + return with(new static())->newQuery(); + } public static function on($connection = null) { $instance = new static(); @@ -5526,7 +5609,8 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa { $query = $this->newQuery()->where($this->getKeyName(), $this->getKey()); if ($this->softDelete) { - $query->update(array(static::DELETED_AT => new DateTime())); + $this->{static::DELETED_AT} = $time = $this->freshTimestamp(); + $query->update(array(static::DELETED_AT => $this->fromDateTime($time))); } else { $query->delete(); } @@ -5534,8 +5618,13 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa public function restore() { if ($this->softDelete) { + if ($this->fireModelEvent('restoring') === false) { + return false; + } $this->{static::DELETED_AT} = null; - return $this->save(); + $result = $this->save(); + $this->fireModelEvent('restored', false); + return $result; } } public static function saving($callback) @@ -5570,6 +5659,14 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa { static::registerModelEvent('deleted', $callback); } + public static function restoring($callback) + { + static::registerModelEvent('restoring', $callback); + } + public static function restored($callback) + { + static::registerModelEvent('restored', $callback); + } public static function flushEventListeners() { if (!isset(static::$dispatcher)) { @@ -5589,7 +5686,7 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa } public function getObservableEvents() { - return array('creating', 'created', 'updating', 'updated', 'deleting', 'deleted', 'saving', 'saved'); + return array('creating', 'created', 'updating', 'updated', 'deleting', 'deleted', 'saving', 'saved', 'restoring', 'restored'); } protected function increment($column, $amount = 1) { @@ -5758,6 +5855,10 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa { return new DateTime(); } + public function freshTimestampString() + { + return $this->fromDateTime($this->freshTimestamp()); + } public function newQuery($excludeDeleted = true) { $builder = new Builder($this->newBaseQueryBuilder()); @@ -5800,7 +5901,7 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa if (isset($this->table)) { return $this->table; } - return str_replace('\\', '', snake_case(str_plural(get_class($this)))); + return str_replace('\\', '', snake_case(str_plural(class_basename($this)))); } public function setTable($table) { @@ -5860,6 +5961,10 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa { $this->visible = $visible; } + public function setAppends(array $appends) + { + $this->appends = $appends; + } public function getFillable() { return $this->fillable; @@ -5941,26 +6046,26 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa } public function attributesToArray() { - $attributes = $this->getAccessibleAttributes(); + $attributes = $this->getArrayableAttributes(); foreach ($this->getMutatedAttributes() as $key) { if (!array_key_exists($key, $attributes)) { continue; } $attributes[$key] = $this->mutateAttribute($key, $attributes[$key]); } + foreach ($this->appends as $key) { + $attributes[$key] = $this->mutateAttribute($key, null); + } return $attributes; } - protected function getAccessibleAttributes() + protected function getArrayableAttributes() { - if (count($this->visible) > 0) { - return array_intersect_key($this->attributes, array_flip($this->visible)); - } - return array_diff_key($this->attributes, array_flip($this->hidden)); + return $this->getArrayableItems($this->attributes); } public function relationsToArray() { $attributes = array(); - foreach ($this->relations as $key => $value) { + foreach ($this->getArrayableRelations() as $key => $value) { if (in_array($key, $this->hidden)) { continue; } @@ -5972,12 +6077,23 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa if (static::$snakeAttributes) { $key = snake_case($key); } - if (isset($relation)) { + if (isset($relation) or is_null($value)) { $attributes[$key] = $relation; } } return $attributes; } + protected function getArrayableRelations() + { + return $this->getArrayableItems($this->relations); + } + protected function getArrayableItems(array $values) + { + if (count($this->visible) > 0) { + return array_intersect_key($values, array_flip($this->visible)); + } + return array_diff_key($values, array_flip($this->hidden)); + } public function getAttribute($key) { $inAttributes = array_key_exists($key, $this->attributes); @@ -6039,7 +6155,7 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa { return array(static::CREATED_AT, static::UPDATED_AT, static::DELETED_AT); } - protected function fromDateTime($value) + public function fromDateTime($value) { $format = $this->getDateFormat(); if ($value instanceof DateTime) { @@ -6109,6 +6225,10 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa } return $dirty; } + public function getRelations() + { + return $this->relations; + } public function getRelation($relation) { return $this->relations[$relation]; @@ -6134,6 +6254,7 @@ abstract class Model implements ArrayAccess, ArrayableInterface, JsonableInterfa public function setConnection($name) { $this->connection = $name; + return $this; } public static function resolveConnection($connection = null) { @@ -6256,6 +6377,7 @@ class DatabaseManager implements ConnectionResolverInterface } public function reconnect($name = null) { + $name = $name ?: $this->getDefaultConnection(); unset($this->connections[$name]); return $this->connection($name); } @@ -6265,6 +6387,10 @@ class DatabaseManager implements ConnectionResolverInterface if (isset($this->extensions[$name])) { return call_user_func($this->extensions[$name], $config); } + $driver = $config['driver']; + if (isset($this->extensions[$driver])) { + return call_user_func($this->extensions[$driver], $config); + } return $this->factory->make($config, $name); } protected function prepare(Connection $connection) @@ -6409,7 +6535,7 @@ class Store extends SymfonySession { return array_get($this->all(), $name, $default); } - public function hasOldInput($key) + public function hasOldInput($key = null) { return !is_null($this->getOldInput($key)); } @@ -6543,13 +6669,18 @@ class SessionManager extends Manager } protected function createRedisDriver() { - return $this->createCacheBased('redis'); + $handler = $this->createCacheHandler('redis'); + $handler->getCache()->getStore()->setConnection($this->app['config']['session.connection']); + return $this->buildSession($handler); } protected function createCacheBased($driver) + { + return $this->buildSession($this->createCacheHandler($driver)); + } + protected function createCacheHandler($driver) { $minutes = $this->app['config']['session.lifetime']; - $handler = new CacheBasedSessionHandler($this->app['cache']->driver($driver), $minutes); - return $this->buildSession($handler); + return new CacheBasedSessionHandler($this->app['cache']->driver($driver), $minutes); } protected function buildSession($handler) { @@ -6728,11 +6859,15 @@ class Encrypter if (!$payload or $this->invalidPayload($payload)) { throw new DecryptException('Invalid data.'); } - if ($payload['mac'] !== $this->hash($payload['iv'], $payload['value'])) { + if (!$this->validMac($payload)) { throw new DecryptException('MAC is invalid.'); } return $payload; } + protected function validMac(array $payload) + { + return $payload['mac'] == $this->hash($payload['iv'], $payload['value']); + } protected function hash($iv, $value) { return hash_hmac('sha256', $iv . $value, $this->key); @@ -6915,6 +7050,7 @@ class Logger implements LoggerInterface const CRITICAL = 500; const ALERT = 550; const EMERGENCY = 600; + const API = 1; protected static $levels = array(100 => 'DEBUG', 200 => 'INFO', 250 => 'NOTICE', 300 => 'WARNING', 400 => 'ERROR', 500 => 'CRITICAL', 550 => 'ALERT', 600 => 'EMERGENCY'); protected static $timezone; protected $name; @@ -7141,6 +7277,7 @@ abstract class AbstractHandler implements HandlerInterface throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), ' . var_export($callback, true) . ' given'); } array_unshift($this->processors, $callback); + return $this; } public function popProcessor() { @@ -7152,6 +7289,7 @@ abstract class AbstractHandler implements HandlerInterface public function setFormatter(FormatterInterface $formatter) { $this->formatter = $formatter; + return $this; } public function getFormatter() { @@ -7163,6 +7301,7 @@ abstract class AbstractHandler implements HandlerInterface public function setLevel($level) { $this->level = $level; + return $this; } public function getLevel() { @@ -7171,6 +7310,7 @@ abstract class AbstractHandler implements HandlerInterface public function setBubble($bubble) { $this->bubble = $bubble; + return $this; } public function getBubble() { @@ -7303,18 +7443,16 @@ class RotatingFileHandler extends StreamHandler if (!empty($fileInfo['extension'])) { $glob .= '.' . $fileInfo['extension']; } - $iterator = new \GlobIterator($glob); - $count = $iterator->count(); - if ($this->maxFiles >= $count) { + $logFiles = glob($glob); + if ($this->maxFiles >= count($logFiles)) { return; } - $array = iterator_to_array($iterator); - usort($array, function ($a, $b) { - return strcmp($b->getFilename(), $a->getFilename()); + usort($logFiles, function ($a, $b) { + return strcmp($b, $a); }); - foreach (array_slice($array, $this->maxFiles) as $file) { - if ($file->isWritable()) { - unlink($file->getRealPath()); + foreach (array_slice($logFiles, $this->maxFiles) as $file) { + if (is_writable($file)) { + unlink($file); } } } @@ -7819,7 +7957,8 @@ class Route extends BaseRoute protected function getAllBeforeFilters(Request $request) { $before = $this->getBeforeFilters(); - return array_merge($before, $this->router->findPatternFilters($request)); + $patterns = $this->router->findPatternFilters($request->getMethod(), $request->getPathInfo()); + return array_merge($before, $patterns); } protected function callAfterFilters(Request $request, $response) { @@ -7935,7 +8074,7 @@ class Route extends BaseRoute } public function setBeforeFilters($value) { - $filters = is_string($value) ? explode('|', $value) : (array) $value; + $filters = $this->parseFilterValue($value); $this->setOption('_before', array_merge($this->getBeforeFilters(), $filters)); } public function getAfterFilters() @@ -7944,9 +8083,17 @@ class Route extends BaseRoute } public function setAfterFilters($value) { - $filters = is_string($value) ? explode('|', $value) : (array) $value; + $filters = $this->parseFilterValue($value); $this->setOption('_after', array_merge($this->getAfterFilters(), $filters)); } + protected function parseFilterValue($value) + { + $results = array(); + foreach ((array) $value as $filters) { + $results = array_merge($results, explode('|', $filters)); + } + return $results; + } public function setParameters($parameters) { $this->parameters = $parameters; @@ -8109,7 +8256,8 @@ class Environment { $path = $this->finder->find($view); $data = array_merge($mergeData, $this->parseData($data)); - return new View($this, $this->getEngineFromPath($path), $view, $path, $data); + $this->callCreator($view = new View($this, $this->getEngineFromPath($path), $view, $path, $data)); + return $view; } protected function parseData($data) { @@ -8170,47 +8318,64 @@ class Environment $this->share($innerKey, $innerValue); } } + public function creator($views, $callback) + { + $creators = array(); + foreach ((array) $views as $view) { + $creators[] = $this->addViewEvent($view, $callback, 'creating: '); + } + return $creators; + } public function composer($views, $callback) { $composers = array(); foreach ((array) $views as $view) { - $composers[] = $this->addComposer($view, $callback); + $composers[] = $this->addViewEvent($view, $callback); } return $composers; } - protected function addComposer($view, $callback) + protected function addViewEvent($view, $callback, $prefix = 'composing: ') { if ($callback instanceof Closure) { - $this->events->listen('composing: ' . $view, $callback); + $this->events->listen($prefix . $view, $callback); return $callback; } elseif (is_string($callback)) { - return $this->addClassComposer($view, $callback); + return $this->addClassEvent($view, $callback, $prefix); } } - protected function addClassComposer($view, $class) + protected function addClassEvent($view, $class, $prefix) { - $name = 'composing: ' . $view; - $callback = $this->buildClassComposerCallback($class); + $name = $prefix . $view; + $callback = $this->buildClassEventCallback($class, $prefix); $this->events->listen($name, $callback); return $callback; } - protected function buildClassComposerCallback($class) + protected function buildClassEventCallback($class, $prefix) { $container = $this->container; - list($class, $method) = $this->parseClassComposer($class); + list($class, $method) = $this->parseClassEvent($class, $prefix); return function () use($class, $method, $container) { $callable = array($container->make($class), $method); return call_user_func_array($callable, func_get_args()); }; } - protected function parseClassComposer($class) + protected function parseClassEvent($class, $prefix) { - return str_contains($class, '@') ? explode('@', $class) : array($class, 'compose'); + if (str_contains($class, '@')) { + return explode('@', $class); + } else { + $method = str_contains($prefix, 'composing') ? 'compose' : 'create'; + return array($class, $method); + } } public function callComposer(View $view) { $this->events->fire('composing: ' . $view->getName(), array($view)); } + public function callCreator(View $view) + { + $this->events->fire('creating: ' . $view->getName(), array($view)); + } public function startSection($section, $content = '') { if ($content === '') { @@ -8246,9 +8411,9 @@ class Environment $this->sections[$section] = $content; } } - public function yieldContent($section) + public function yieldContent($section, $default = '') { - return isset($this->sections[$section]) ? $this->sections[$section] : ''; + return isset($this->sections[$section]) ? $this->sections[$section] : $default; } public function flushSections() { @@ -8300,6 +8465,10 @@ class Environment { return $this->events; } + public function setDispatcher(Dispatcher $events) + { + $this->events = $events; + } public function getContainer() { return $this->container; @@ -8414,6 +8583,11 @@ class MessageBag implements ArrayableInterface, Countable, JsonableInterface, Me public function setFormat($format = ':message') { $this->format = $format; + return $this; + } + public function isEmpty() + { + return !$this->any(); } public function any() { @@ -9119,8 +9293,16 @@ class Response $obStatus = ob_get_status(1); while (($level = ob_get_level()) > 0 && $level !== $previous) { $previous = $level; - if ($obStatus[$level - 1] && isset($obStatus[$level - 1]['del']) && $obStatus[$level - 1]['del']) { - ob_end_flush(); + if ($obStatus[$level - 1]) { + if (version_compare(PHP_VERSION, '5.4', '>=')) { + if (isset($obStatus[$level - 1]['flags']) && $obStatus[$level - 1]['flags'] & PHP_OUTPUT_HANDLER_REMOVABLE) { + ob_end_flush(); + } + } else { + if (isset($obStatus[$level - 1]['del']) && $obStatus[$level - 1]['del']) { + ob_end_flush(); + } + } } } flush(); @@ -9837,15 +10019,18 @@ class Run } } $output = ob_get_clean(); - if ($this->allowQuit()) { - echo $output; - die; - } else { - if ($this->writeToOutput()) { - echo $output; + if ($this->writeToOutput()) { + if ($handlerResponse == Handler::QUIT && $this->allowQuit()) { + while (ob_get_level() > 0) { + ob_end_clean(); + } } - return $output; + echo $output; } + if ($handlerResponse == Handler::QUIT && $this->allowQuit()) { + die; + } + return $output; } public function handleError($level, $message, $file = null, $line = null) { diff --git a/composer.json b/composer.json index 5b223f3c..d1769950 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,8 @@ "require": { "laravel/framework": "4.0.*", "kriswallsmith/assetic": "1.2.*@dev", - "codescale/ffmpeg-php": "2.7.0" + "codescale/ffmpeg-php": "2.7.0", + "simplepie/simplepie": "1.3.1" }, "autoload": { "classmap": [ diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 9057ac30..00000000 --- a/composer.lock +++ /dev/null @@ -1,2303 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" - ], - "hash": "c97b33f82a1e14bf632925de72277467", - "packages": [ - { - "name": "cboden/ratchet", - "version": "0.3.x-dev", - "source": { - "type": "git", - "url": "https://github.com/cboden/Ratchet.git", - "reference": "f4ddea5f44bc64c06016acea9da80e5e87830a7a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/cboden/Ratchet/zipball/f4ddea5f44bc64c06016acea9da80e5e87830a7a", - "reference": "f4ddea5f44bc64c06016acea9da80e5e87830a7a", - "shasum": "" - }, - "require": { - "guzzle/http": ">=3.0,<4.0", - "php": ">=5.3.9", - "react/socket": ">=0.2,<1.0", - "symfony/http-foundation": ">=2.2,<3.0", - "symfony/routing": ">=2.2,<3.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Ratchet\\Tests": "tests", - "Ratchet": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Boden", - "email": "cboden@gmail.com", - "homepage": "http://res.im", - "role": "Developer" - } - ], - "description": "PHP WebSocket library", - "homepage": "http://socketo.me", - "keywords": [ - "Ratchet", - "WebSockets", - "server", - "sockets" - ], - "time": "2013-05-29 11:51:33" - }, - { - "name": "classpreloader/classpreloader", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/mtdowling/ClassPreloader.git", - "reference": "62c99d52ce2f1b0b8449c61e2d94f48d918222eb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mtdowling/ClassPreloader/zipball/62c99d52ce2f1b0b8449c61e2d94f48d918222eb", - "reference": "62c99d52ce2f1b0b8449c61e2d94f48d918222eb", - "shasum": "" - }, - "require": { - "nikic/php-parser": "*", - "php": ">=5.3.3", - "symfony/console": ">2.0", - "symfony/filesystem": ">2.0", - "symfony/finder": ">2.0" - }, - "bin": [ - "classpreloader.php" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.0-dev" - } - }, - "autoload": { - "psr-0": { - "ClassPreloader": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case", - "keywords": [ - "autoload", - "class", - "preload" - ], - "time": "2013-05-26 16:10:36" - }, - { - "name": "codescale/ffmpeg-php", - "version": "2.7.0", - "source": { - "type": "git", - "url": "https://github.com/CodeScaleInc/ffmpeg-php.git", - "reference": "2.7.0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/CodeScaleInc/ffmpeg-php/zipball/2.7.0", - "reference": "2.7.0", - "shasum": "" - }, - "require": { - "php": ">=5.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "." - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "New BSD" - ], - "authors": [ - { - "name": "char0n (Vladimír Gorej, CodeScale s.r.o.)", - "email": "gorej@codescale.net", - "homepage": "http://www.codescale.net/", - "role": "Development lead" - } - ], - "description": "PHP wrapper for FFmpeg application", - "homepage": "http://freecode.com/projects/ffmpegphp", - "keywords": [ - "audio", - "ffmpeg", - "video" - ], - "time": "2013-05-05 09:10:04" - }, - { - "name": "doctrine/annotations", - "version": "v1.1.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "v1.1.1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/v1.1.1", - "reference": "v1.1.1", - "shasum": "" - }, - "require": { - "doctrine/lexer": "1.*", - "php": ">=5.3.2" - }, - "require-dev": { - "doctrine/cache": "1.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Annotations\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com", - "homepage": "http://www.jwage.com/" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com", - "homepage": "http://www.instaclick.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh", - "role": "Developer of wrapped JMSSerializerBundle" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "time": "2013-04-20 08:30:17" - }, - { - "name": "doctrine/cache", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/doctrine/cache.git", - "reference": "45123145f70dd79618963a72a5271b4f389712e4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/45123145f70dd79618963a72a5271b4f389712e4", - "reference": "45123145f70dd79618963a72a5271b4f389712e4", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "conflict": { - "doctrine/common": ">2.2,<2.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Cache\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jonathan H. Wage", - "email": "jonwage@gmail.com", - "homepage": "http://www.jwage.com/" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com", - "homepage": "http://www.instaclick.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", - "role": "Developer of wrapped JMSSerializerBundle" - } - ], - "description": "Caching library offering an object-oriented API for many cache backends", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "cache", - "caching" - ], - "time": "2013-05-13 02:51:07" - }, - { - "name": "doctrine/collections", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/doctrine/collections.git", - "reference": "3db3ab843ff76774bee4679d4cb3a10cffb0a935" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/3db3ab843ff76774bee4679d4cb3a10cffb0a935", - "reference": "3db3ab843ff76774bee4679d4cb3a10cffb0a935", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Collections\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com", - "homepage": "http://www.jwage.com/" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com", - "homepage": "http://www.instaclick.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh", - "role": "Developer of wrapped JMSSerializerBundle" - } - ], - "description": "Collections Abstraction library", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "array", - "collections", - "iterator" - ], - "time": "2013-05-26 05:21:22" - }, - { - "name": "doctrine/common", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/doctrine/common.git", - "reference": "2169b0ce1d253d448c60b7d40bbe4e4b5afe22fe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/2169b0ce1d253d448c60b7d40bbe4e4b5afe22fe", - "reference": "2169b0ce1d253d448c60b7d40bbe4e4b5afe22fe", - "shasum": "" - }, - "require": { - "doctrine/annotations": "1.*", - "doctrine/cache": "1.*", - "doctrine/collections": "1.*", - "doctrine/inflector": "1.*", - "doctrine/lexer": "1.*", - "php": ">=5.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.4.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com", - "homepage": "http://www.jwage.com/" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com", - "homepage": "http://www.instaclick.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "http://jmsyst.com", - "role": "Developer of wrapped JMSSerializerBundle" - } - ], - "description": "Common Library for Doctrine projects", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "annotations", - "collections", - "eventmanager", - "persistence", - "spl" - ], - "time": "2013-05-27 19:11:46" - }, - { - "name": "doctrine/dbal", - "version": "2.3.x-dev", - "source": { - "type": "git", - "url": "https://github.com/doctrine/dbal.git", - "reference": "6a62fefefde6b2c0d8b3df70151d6a81fc028d28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/6a62fefefde6b2c0d8b3df70151d6a81fc028d28", - "reference": "6a62fefefde6b2c0d8b3df70151d6a81fc028d28", - "shasum": "" - }, - "require": { - "doctrine/common": ">=2.3.0,<2.5-dev", - "php": ">=5.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\DBAL": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com", - "homepage": "http://www.jwage.com/" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com", - "homepage": "http://www.instaclick.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - } - ], - "description": "Database Abstraction Layer", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "database", - "dbal", - "persistence", - "queryobject" - ], - "time": "2013-05-21 05:53:02" - }, - { - "name": "doctrine/inflector", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/doctrine/inflector.git", - "reference": "8b4b3ccec7aafc596e2fc1e593c9f2e78f939c8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/8b4b3ccec7aafc596e2fc1e593c9f2e78f939c8c", - "reference": "8b4b3ccec7aafc596e2fc1e593c9f2e78f939c8c", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Inflector\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com", - "homepage": "http://www.jwage.com/" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com", - "homepage": "http://www.instaclick.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh", - "role": "Developer of wrapped JMSSerializerBundle" - } - ], - "description": "Common String Manipulations with regard to casing and singular/plural rules.", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "inflection", - "pluralize", - "singularize", - "string" - ], - "time": "2013-04-10 16:14:30" - }, - { - "name": "doctrine/lexer", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "bc0e1f0cc285127a38c6c8ea88bc5dba2fd53e94" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/bc0e1f0cc285127a38c6c8ea88bc5dba2fd53e94", - "reference": "bc0e1f0cc285127a38c6c8ea88bc5dba2fd53e94", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Lexer\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com", - "homepage": "http://www.instaclick.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh", - "role": "Developer of wrapped JMSSerializerBundle" - } - ], - "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "http://www.doctrine-project.org", - "keywords": [ - "lexer", - "parser" - ], - "time": "2013-03-07 12:15:25" - }, - { - "name": "evenement/evenement", - "version": "1.0.x-dev", - "source": { - "type": "git", - "url": "https://github.com/igorw/evenement.git", - "reference": "8b0918f8374327dfed4408fe467980ab41d556dd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/igorw/evenement/zipball/8b0918f8374327dfed4408fe467980ab41d556dd", - "reference": "8b0918f8374327dfed4408fe467980ab41d556dd", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "psr-0": { - "Evenement": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Igor Wiedler", - "email": "igor@wiedler.ch", - "homepage": "http://wiedler.ch/igor/" - } - ], - "description": "Événement is a very simple event dispatching library for PHP 5.3", - "keywords": [ - "event-dispatcher" - ], - "time": "2012-12-29 17:04:52" - }, - { - "name": "filp/whoops", - "version": "1.0.6", - "source": { - "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "1.0.6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/1.0.6", - "reference": "1.0.6", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "mockery/mockery": "dev-master", - "silex/silex": "1.0.*@dev" - }, - "type": "library", - "autoload": { - "psr-0": { - "Whoops": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Filipe Dobreira", - "homepage": "https://github.com/filp", - "role": "Developer" - } - ], - "description": "php error handling for cool kids", - "homepage": "https://github.com/filp/whoops", - "keywords": [ - "error", - "exception", - "handling", - "library", - "silex-provider", - "whoops", - "zf2" - ], - "time": "2013-05-10 22:13:22" - }, - { - "name": "guzzle/common", - "version": "dev-master", - "target-dir": "Guzzle/Common", - "source": { - "type": "git", - "url": "https://github.com/guzzle/common.git", - "reference": "v3.6.0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/common/zipball/v3.6.0", - "reference": "v3.6.0", - "shasum": "" - }, - "require": { - "php": ">=5.3.2", - "symfony/event-dispatcher": ">=2.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.6-dev" - } - }, - "autoload": { - "psr-0": { - "Guzzle\\Common": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Common libraries used by Guzzle", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "collection", - "common", - "event", - "exception" - ], - "time": "2013-05-30 07:01:25" - }, - { - "name": "guzzle/http", - "version": "dev-master", - "target-dir": "Guzzle/Http", - "source": { - "type": "git", - "url": "https://github.com/guzzle/http.git", - "reference": "v3.6.0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/http/zipball/v3.6.0", - "reference": "v3.6.0", - "shasum": "" - }, - "require": { - "guzzle/common": "self.version", - "guzzle/parser": "self.version", - "guzzle/stream": "self.version", - "php": ">=5.3.2" - }, - "suggest": { - "ext-curl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.6-dev" - } - }, - "autoload": { - "psr-0": { - "Guzzle\\Http": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "HTTP libraries used by Guzzle", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "Guzzle", - "client", - "curl", - "http", - "http client" - ], - "time": "2013-05-30 07:01:25" - }, - { - "name": "guzzle/parser", - "version": "dev-master", - "target-dir": "Guzzle/Parser", - "source": { - "type": "git", - "url": "https://github.com/guzzle/parser.git", - "reference": "v3.6.0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/parser/zipball/v3.6.0", - "reference": "v3.6.0", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.6-dev" - } - }, - "autoload": { - "psr-0": { - "Guzzle\\Parser": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Interchangeable parsers used by Guzzle", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "URI Template", - "cookie", - "http", - "message", - "url" - ], - "time": "2013-05-30 07:01:25" - }, - { - "name": "guzzle/stream", - "version": "dev-master", - "target-dir": "Guzzle/Stream", - "source": { - "type": "git", - "url": "https://github.com/guzzle/stream.git", - "reference": "v3.6.0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/stream/zipball/v3.6.0", - "reference": "v3.6.0", - "shasum": "" - }, - "require": { - "guzzle/common": "self.version", - "php": ">=5.3.2" - }, - "suggest": { - "guzzle/http": "To convert Guzzle request objects to PHP streams" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.6-dev" - } - }, - "autoload": { - "psr-0": { - "Guzzle\\Stream": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle stream wrapper component", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "Guzzle", - "component", - "stream" - ], - "time": "2013-05-30 07:01:25" - }, - { - "name": "ircmaxell/password-compat", - "version": "1.0.x-dev", - "source": { - "type": "git", - "url": "https://github.com/ircmaxell/password_compat.git", - "reference": "v1.0.3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/v1.0.3", - "reference": "v1.0.3", - "shasum": "" - }, - "type": "library", - "autoload": { - "files": [ - "lib/password.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Anthony Ferrara", - "email": "ircmaxell@php.net", - "homepage": "http://blog.ircmaxell.com" - } - ], - "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", - "homepage": "https://github.com/ircmaxell/password_compat", - "keywords": [ - "hashing", - "password" - ], - "time": "2013-04-30 19:58:08" - }, - { - "name": "kriswallsmith/assetic", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/kriswallsmith/assetic.git", - "reference": "d5311bf231ecf8a1e4b8ae00dcb15651b63dfed5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/kriswallsmith/assetic/zipball/d5311bf231ecf8a1e4b8ae00dcb15651b63dfed5", - "reference": "d5311bf231ecf8a1e4b8ae00dcb15651b63dfed5", - "shasum": "" - }, - "require": { - "php": ">=5.3.1", - "symfony/process": ">=2.1,<3.0" - }, - "require-dev": { - "cssmin/cssmin": "*", - "joliclic/javascript-packer": "*", - "kamicane/packager": "*", - "leafo/lessphp": "*", - "leafo/scssphp": "*", - "leafo/scssphp-compass": "*", - "mrclay/minify": "*", - "phpunit/phpunit": ">=3.7,<4.0", - "ptachoire/cssembed": "*", - "twig/twig": ">=1.6,<2.0" - }, - "suggest": { - "leafo/lessphp": "Assetic provides the integration with the lessphp LESS compiler", - "leafo/scssphp": "Assetic provides the integration with the scssphp SCSS compiler", - "leafo/scssphp-compass": "Assetic provides the integration with the SCSS compass plugin", - "ptachoire/cssembed": "Assetic provides the integration with phpcssembed to embed data uris", - "twig/twig": "Assetic provides the integration with the Twig templating engine" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "psr-0": { - "Assetic": "src/" - }, - "files": [ - "src/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kris Wallsmith", - "email": "kris.wallsmith@gmail.com", - "homepage": "http://kriswallsmith.net/" - } - ], - "description": "Asset Management for PHP", - "homepage": "https://github.com/kriswallsmith/assetic", - "keywords": [ - "assets", - "compression", - "minification" - ], - "time": "2013-06-04 14:31:31" - }, - { - "name": "laravel/framework", - "version": "4.0.x-dev", - "source": { - "type": "git", - "url": "https://github.com/laravel/framework.git", - "reference": "444dbc5d02fa1e10737fcb06dd7124731f88a819" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/444dbc5d02fa1e10737fcb06dd7124731f88a819", - "reference": "444dbc5d02fa1e10737fcb06dd7124731f88a819", - "shasum": "" - }, - "require": { - "classpreloader/classpreloader": "1.0.*", - "doctrine/dbal": "2.3.x", - "filp/whoops": "1.0.6", - "ircmaxell/password-compat": "1.0.*", - "monolog/monolog": "1.5.*", - "nesbot/carbon": "1.*", - "patchwork/utf8": "1.1.*", - "php": ">=5.3.0", - "predis/predis": "0.8.*", - "swiftmailer/swiftmailer": "5.0.*", - "symfony/browser-kit": "2.3.*", - "symfony/console": "2.3.*", - "symfony/css-selector": "2.3.*", - "symfony/debug": "2.3.*", - "symfony/dom-crawler": "2.3.*", - "symfony/event-dispatcher": "2.3.*", - "symfony/finder": "2.3.*", - "symfony/http-foundation": "2.3.*", - "symfony/http-kernel": "2.3.*", - "symfony/process": "2.3.*", - "symfony/routing": "2.3.*", - "symfony/translation": "2.3.*" - }, - "replace": { - "illuminate/auth": "self.version", - "illuminate/cache": "self.version", - "illuminate/config": "self.version", - "illuminate/console": "self.version", - "illuminate/container": "self.version", - "illuminate/cookie": "self.version", - "illuminate/database": "self.version", - "illuminate/encryption": "self.version", - "illuminate/events": "self.version", - "illuminate/exception": "self.version", - "illuminate/filesystem": "self.version", - "illuminate/foundation": "self.version", - "illuminate/hashing": "self.version", - "illuminate/html": "self.version", - "illuminate/http": "self.version", - "illuminate/log": "self.version", - "illuminate/mail": "self.version", - "illuminate/pagination": "self.version", - "illuminate/queue": "self.version", - "illuminate/redis": "self.version", - "illuminate/routing": "self.version", - "illuminate/session": "self.version", - "illuminate/support": "self.version", - "illuminate/translation": "self.version", - "illuminate/validation": "self.version", - "illuminate/view": "self.version", - "illuminate/workbench": "self.version" - }, - "require-dev": { - "aws/aws-sdk-php": "2.2.*", - "iron-io/iron_mq": "1.4.4", - "mockery/mockery": "0.7.2", - "pda/pheanstalk": "2.0.*", - "phpunit/phpunit": "3.7.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - [ - "src/Illuminate/Queue/IlluminateQueueClosure.php" - ] - ], - "files": [ - "src/Illuminate/Support/helpers.php" - ], - "psr-0": { - "Illuminate": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "The Laravel Framework.", - "keywords": [ - "framework", - "laravel" - ], - "time": "2013-06-04 21:58:42" - }, - { - "name": "monolog/monolog", - "version": "1.5.0", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "1.5.0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/1.5.0", - "reference": "1.5.0", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "psr/log": ">=1.0,<2.0" - }, - "require-dev": { - "doctrine/couchdb": "dev-master", - "mlehner/gelf-php": "1.0.*", - "raven/raven": "0.3.*" - }, - "suggest": { - "doctrine/couchdb": "Allow sending log messages to a CouchDB server", - "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", - "ext-mongo": "Allow sending log messages to a MongoDB server", - "mlehner/gelf-php": "Allow sending log messages to a GrayLog2 server", - "raven/raven": "Allow sending log messages to a Sentry server" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "psr-0": { - "Monolog": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be", - "role": "Developer" - } - ], - "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "http://github.com/Seldaek/monolog", - "keywords": [ - "log", - "logging", - "psr-3" - ], - "time": "2013-04-23 10:09:48" - }, - { - "name": "nesbot/carbon", - "version": "1.2.0", - "source": { - "type": "git", - "url": "git://github.com/briannesbitt/Carbon.git", - "reference": "1.2.0" - }, - "dist": { - "type": "zip", - "url": "https://github.com/briannesbitt/Carbon/zipball/1.2.0", - "reference": "1.2.0", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Carbon": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Brian Nesbitt", - "email": "brian@nesbot.com", - "homepage": "http://nesbot.com" - } - ], - "description": "A simple API extension for DateTime.", - "homepage": "https://github.com/briannesbitt/Carbon", - "keywords": [ - "date", - "datetime", - "time" - ], - "time": "2012-10-14 17:41:18" - }, - { - "name": "nikic/php-parser", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "5ccf6196d6925e66568e3b8460c262e9512e4b92" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/5ccf6196d6925e66568e3b8460c262e9512e4b92", - "reference": "5ccf6196d6925e66568e3b8460c262e9512e4b92", - "shasum": "" - }, - "require": { - "php": ">=5.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.9-dev" - } - }, - "autoload": { - "psr-0": { - "PHPParser": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "time": "2013-05-23 13:17:59" - }, - { - "name": "patchwork/utf8", - "version": "v1.1.8", - "source": { - "type": "git", - "url": "https://github.com/nicolas-grekas/Patchwork-UTF8.git", - "reference": "v1.1.8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nicolas-grekas/Patchwork-UTF8/zipball/v1.1.8", - "reference": "v1.1.8", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Patchwork": "class/", - "Normalizer": "class/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "(Apache-2.0 or GPL-2.0)" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com", - "role": "Developer" - } - ], - "description": "UTF-8 strings handling for PHP 5.3: portable, performant and extended", - "homepage": "https://github.com/nicolas-grekas/Patchwork-UTF8", - "keywords": [ - "i18n", - "unicode", - "utf-8", - "utf8" - ], - "time": "2013-05-24 12:11:22" - }, - { - "name": "predis/predis", - "version": "0.8.x-dev", - "source": { - "type": "git", - "url": "https://github.com/nrk/predis.git", - "reference": "aa458a1922a99611d7f81795bedff88459bc8753" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nrk/predis/zipball/aa458a1922a99611d7f81795bedff88459bc8753", - "reference": "aa458a1922a99611d7f81795bedff88459bc8753", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "suggest": { - "ext-curl": "Allows access to Webdis when paired with phpiredis", - "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol" - }, - "type": "library", - "autoload": { - "psr-0": { - "Predis": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniele Alessandri", - "email": "suppakilla@gmail.com", - "homepage": "http://clorophilla.net" - } - ], - "description": "Flexible and feature-complete PHP client library for Redis", - "homepage": "http://github.com/nrk/predis", - "keywords": [ - "nosql", - "predis", - "redis" - ], - "time": "2013-06-03 10:04:10" - }, - { - "name": "psr/log", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log", - "reference": "1.0.0" - }, - "dist": { - "type": "zip", - "url": "https://github.com/php-fig/log/archive/1.0.0.zip", - "reference": "1.0.0", - "shasum": "" - }, - "type": "library", - "autoload": { - "psr-0": { - "Psr\\Log\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "time": "2012-12-21 11:40:51" - }, - { - "name": "react/event-loop", - "version": "dev-master", - "target-dir": "React/EventLoop", - "source": { - "type": "git", - "url": "https://github.com/reactphp/event-loop.git", - "reference": "v0.3.2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/event-loop/zipball/v0.3.2", - "reference": "v0.3.2", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-libev": "*", - "ext-libevent": ">=0.0.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.3-dev" - } - }, - "autoload": { - "psr-0": { - "React\\EventLoop": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Event loop abstraction layer that libraries can use for evented I/O.", - "keywords": [ - "event-loop" - ], - "time": "2013-01-14 23:11:47" - }, - { - "name": "react/socket", - "version": "dev-master", - "target-dir": "React/Socket", - "source": { - "type": "git", - "url": "https://github.com/reactphp/socket.git", - "reference": "v0.3.2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/socket/zipball/v0.3.2", - "reference": "v0.3.2", - "shasum": "" - }, - "require": { - "evenement/evenement": "1.0.*", - "php": ">=5.3.3", - "react/event-loop": "0.3.*", - "react/stream": "0.3.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.3-dev" - } - }, - "autoload": { - "psr-0": { - "React\\Socket": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Library for building an evented socket server.", - "keywords": [ - "Socket" - ], - "time": "2013-04-26 20:23:10" - }, - { - "name": "react/stream", - "version": "dev-master", - "target-dir": "React/Stream", - "source": { - "type": "git", - "url": "https://github.com/reactphp/stream.git", - "reference": "v0.3.2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/stream/zipball/v0.3.2", - "reference": "v0.3.2", - "shasum": "" - }, - "require": { - "evenement/evenement": "1.0.*", - "php": ">=5.3.3" - }, - "suggest": { - "react/event-loop": "0.3.*", - "react/promise": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.3-dev" - } - }, - "autoload": { - "psr-0": { - "React\\Stream": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Basic readable and writable stream interfaces that support piping.", - "keywords": [ - "pipe", - "stream" - ], - "time": "2013-05-10 15:12:22" - }, - { - "name": "swiftmailer/swiftmailer", - "version": "v5.0.0", - "source": { - "type": "git", - "url": "https://github.com/swiftmailer/swiftmailer.git", - "reference": "v5.0.0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/v5.0.0", - "reference": "v5.0.0", - "shasum": "" - }, - "require": { - "php": ">=5.2.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "files": [ - "lib/swift_required.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Chris Corbyn" - } - ], - "description": "Swiftmailer, free feature-rich PHP mailer", - "homepage": "http://swiftmailer.org", - "keywords": [ - "mail", - "mailer" - ], - "time": "2013-04-30 17:35:30" - }, - { - "name": "symfony/browser-kit", - "version": "2.3.x-dev", - "target-dir": "Symfony/Component/BrowserKit", - "source": { - "type": "git", - "url": "https://github.com/symfony/BrowserKit.git", - "reference": "v2.3.0-RC1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/v2.3.0-RC1", - "reference": "v2.3.0-RC1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/dom-crawler": ">=2.0,<3.0" - }, - "require-dev": { - "symfony/css-selector": ">=2.0,<3.0", - "symfony/process": ">=2.0,<3.0" - }, - "suggest": { - "symfony/process": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\BrowserKit\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony BrowserKit Component", - "homepage": "http://symfony.com", - "time": "2013-05-15 15:16:47" - }, - { - "name": "symfony/console", - "version": "2.3.x-dev", - "target-dir": "Symfony/Component/Console", - "source": { - "type": "git", - "url": "https://github.com/symfony/Console.git", - "reference": "v2.3.0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/v2.3.0", - "reference": "v2.3.0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/event-dispatcher": ">=2.1,<3.0" - }, - "suggest": { - "symfony/event-dispatcher": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Console\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Console Component", - "homepage": "http://symfony.com", - "time": "2013-05-30 05:11:26" - }, - { - "name": "symfony/css-selector", - "version": "2.3.x-dev", - "target-dir": "Symfony/Component/CssSelector", - "source": { - "type": "git", - "url": "https://github.com/symfony/CssSelector.git", - "reference": "v2.3.0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/CssSelector/zipball/v2.3.0", - "reference": "v2.3.0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\CssSelector\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - } - ], - "description": "Symfony CssSelector Component", - "homepage": "http://symfony.com", - "time": "2013-05-19 18:59:12" - }, - { - "name": "symfony/debug", - "version": "2.3.x-dev", - "target-dir": "Symfony/Component/Debug", - "source": { - "type": "git", - "url": "https://github.com/symfony/Debug.git", - "reference": "v2.3.0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Debug/zipball/v2.3.0", - "reference": "v2.3.0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/http-foundation": ">=2.1,<3.0", - "symfony/http-kernel": ">=2.1,<3.0" - }, - "suggest": { - "symfony/class-loader": "", - "symfony/http-foundation": "", - "symfony/http-kernel": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Debug\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Debug Component", - "homepage": "http://symfony.com", - "time": "2013-06-02 11:58:44" - }, - { - "name": "symfony/dom-crawler", - "version": "2.3.x-dev", - "target-dir": "Symfony/Component/DomCrawler", - "source": { - "type": "git", - "url": "https://github.com/symfony/DomCrawler.git", - "reference": "3cf81e7a021853183aa303181afc6e6868bf48ce" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/3cf81e7a021853183aa303181afc6e6868bf48ce", - "reference": "3cf81e7a021853183aa303181afc6e6868bf48ce", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/css-selector": ">=2.0,<3.0" - }, - "suggest": { - "symfony/css-selector": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\DomCrawler\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony DomCrawler Component", - "homepage": "http://symfony.com", - "time": "2013-05-19 19:00:48" - }, - { - "name": "symfony/event-dispatcher", - "version": "2.3.x-dev", - "target-dir": "Symfony/Component/EventDispatcher", - "source": { - "type": "git", - "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "v2.3.0-RC1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.3.0-RC1", - "reference": "v2.3.0-RC1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/dependency-injection": ">=2.0,<3.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\EventDispatcher\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "http://symfony.com", - "time": "2013-05-13 14:36:40" - }, - { - "name": "symfony/filesystem", - "version": "dev-master", - "target-dir": "Symfony/Component/Filesystem", - "source": { - "type": "git", - "url": "https://github.com/symfony/Filesystem.git", - "reference": "3567f5f48305098044c6d6a383f5cefec9c45efa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/3567f5f48305098044c6d6a383f5cefec9c45efa", - "reference": "3567f5f48305098044c6d6a383f5cefec9c45efa", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.4-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Filesystem\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Filesystem Component", - "homepage": "http://symfony.com", - "time": "2013-05-16 07:54:39" - }, - { - "name": "symfony/finder", - "version": "2.3.x-dev", - "target-dir": "Symfony/Component/Finder", - "source": { - "type": "git", - "url": "https://github.com/symfony/Finder.git", - "reference": "v2.3.0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.3.0", - "reference": "v2.3.0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Finder\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Finder Component", - "homepage": "http://symfony.com", - "time": "2013-06-02 12:05:51" - }, - { - "name": "symfony/http-foundation", - "version": "2.3.x-dev", - "target-dir": "Symfony/Component/HttpFoundation", - "source": { - "type": "git", - "url": "https://github.com/symfony/HttpFoundation.git", - "reference": "v2.3.0-RC1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/v2.3.0-RC1", - "reference": "v2.3.0-RC1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "classmap": [ - "Symfony/Component/HttpFoundation/Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony HttpFoundation Component", - "homepage": "http://symfony.com", - "time": "2013-05-10 06:00:03" - }, - { - "name": "symfony/http-kernel", - "version": "2.3.x-dev", - "target-dir": "Symfony/Component/HttpKernel", - "source": { - "type": "git", - "url": "https://github.com/symfony/HttpKernel.git", - "reference": "4f0f6485abe0e2e8b8a94369fb98b8447fb1e3cc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/4f0f6485abe0e2e8b8a94369fb98b8447fb1e3cc", - "reference": "4f0f6485abe0e2e8b8a94369fb98b8447fb1e3cc", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "psr/log": ">=1.0,<2.0", - "symfony/debug": ">=2.3,<3.0", - "symfony/event-dispatcher": ">=2.1,<3.0", - "symfony/http-foundation": ">=2.2,<3.0" - }, - "require-dev": { - "symfony/browser-kit": "2.2.*", - "symfony/class-loader": ">=2.1,<3.0", - "symfony/config": ">=2.0,<3.0", - "symfony/console": "2.2.*", - "symfony/dependency-injection": ">=2.0,<3.0", - "symfony/finder": ">=2.0,<3.0", - "symfony/process": ">=2.0,<3.0", - "symfony/routing": ">=2.2,<3.0", - "symfony/stopwatch": ">=2.2,<3.0" - }, - "suggest": { - "symfony/browser-kit": "", - "symfony/class-loader": "", - "symfony/config": "", - "symfony/console": "", - "symfony/dependency-injection": "", - "symfony/finder": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\HttpKernel\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony HttpKernel Component", - "homepage": "http://symfony.com", - "time": "2013-06-03 15:11:57" - }, - { - "name": "symfony/process", - "version": "2.3.x-dev", - "target-dir": "Symfony/Component/Process", - "source": { - "type": "git", - "url": "https://github.com/symfony/Process.git", - "reference": "v2.3.0-RC1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Process/zipball/v2.3.0-RC1", - "reference": "v2.3.0-RC1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Process\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Process Component", - "homepage": "http://symfony.com", - "time": "2013-05-06 20:03:44" - }, - { - "name": "symfony/routing", - "version": "2.3.x-dev", - "target-dir": "Symfony/Component/Routing", - "source": { - "type": "git", - "url": "https://github.com/symfony/Routing.git", - "reference": "v2.3.0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Routing/zipball/v2.3.0", - "reference": "v2.3.0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "doctrine/common": ">=2.2,<3.0", - "psr/log": ">=1.0,<2.0", - "symfony/config": ">=2.2,<3.0", - "symfony/yaml": ">=2.0,<3.0" - }, - "suggest": { - "doctrine/common": "", - "symfony/config": "", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Routing\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Routing Component", - "homepage": "http://symfony.com", - "time": "2013-05-20 08:57:26" - }, - { - "name": "symfony/translation", - "version": "2.3.x-dev", - "target-dir": "Symfony/Component/Translation", - "source": { - "type": "git", - "url": "https://github.com/symfony/Translation.git", - "reference": "v2.3.0-RC1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/v2.3.0-RC1", - "reference": "v2.3.0-RC1", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/config": ">=2.0,<3.0", - "symfony/yaml": ">=2.2,<3.0" - }, - "suggest": { - "symfony/config": "", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Translation\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Translation Component", - "homepage": "http://symfony.com", - "time": "2013-05-13 14:36:40" - } - ], - "packages-dev": [ - - ], - "aliases": [ - - ], - "minimum-stability": "dev", - "stability-flags": { - "kriswallsmith/assetic": 20 - }, - "platform": [ - - ], - "platform-dev": [ - - ] -} diff --git a/public/scripts/app/controllers/dashboard.coffee b/public/scripts/app/controllers/dashboard.coffee index cf97cc84..1e7014bf 100644 --- a/public/scripts/app/controllers/dashboard.coffee +++ b/public/scripts/app/controllers/dashboard.coffee @@ -4,12 +4,19 @@ window.pfm.preloaders['dashboard'] = [ ] angular.module('ponyfm').controller "dashboard", [ - '$scope', 'dashboard' - ($scope, dashboard) -> + '$scope', 'dashboard', 'auth', '$http' + ($scope, dashboard, auth, $http) -> $scope.recentTracks = null $scope.popularTracks = null + $scope.news = null dashboard.refresh().done (res) -> $scope.recentTracks = res.recent_tracks $scope.popularTracks = res.popular_tracks + $scope.news = res.news + + $scope.markAsRead = (post) -> + if auth.data.isLogged + $http.post('/api/web/dashboard/read-news', {url: post.url, _token: window.pfm.token}).success -> + post.read = true ] \ No newline at end of file diff --git a/public/scripts/app/controllers/home.coffee b/public/scripts/app/controllers/home.coffee index aedb8829..d9ca38ea 100644 --- a/public/scripts/app/controllers/home.coffee +++ b/public/scripts/app/controllers/home.coffee @@ -8,8 +8,10 @@ angular.module('ponyfm').controller "home", [ ($scope, dashboard) -> $scope.recentTracks = null $scope.popularTracks = null + $scope.news = null dashboard.refresh().done (res) -> $scope.recentTracks = res.recent_tracks $scope.popularTracks = res.popular_tracks + $scope.news = res.news ] \ No newline at end of file diff --git a/public/scripts/app/directives/src-loader.coffee b/public/scripts/app/directives/src-loader.coffee index 1655aa28..b244f90d 100644 --- a/public/scripts/app/directives/src-loader.coffee +++ b/public/scripts/app/directives/src-loader.coffee @@ -1,17 +1,22 @@ angular.module('ponyfm').directive 'pfmSrcLoader', () -> (scope, element, attrs) -> size = attrs.pfmSrcSize || 'normal' - url = attrs.pfmSrcLoader + element.css {opacity: .5} - element.attr 'src', '/images/icons/loading_' + size + '.png' + update = (val) -> + element.attr 'src', '/images/icons/loading_' + size + '.png' - image = element.clone() - image.removeAttr 'pfm-src-loader' - image.removeAttr 'pfm-src-size' + image = element.clone() + image.removeAttr 'pfm-src-loader' + image.removeAttr 'pfm-src-size' - image[0].onload = -> - element.replaceWith image - image.css {opacity: 0} - image.animate {opacity: 1}, 250 + image[0].onload = -> + element.attr 'src', val + element.css {opacity: 0} + element.animate {opacity: 1}, 250 - image[0].src = url \ No newline at end of file + image[0].src = val + + update scope.$eval attrs.pfmSrcLoader + + scope.$watch attrs.pfmSrcLoader, update \ No newline at end of file diff --git a/public/scripts/app/services/player.coffee b/public/scripts/app/services/player.coffee index b231a3ec..31c94fd4 100644 --- a/public/scripts/app/services/player.coffee +++ b/public/scripts/app/services/player.coffee @@ -6,8 +6,18 @@ angular.module('ponyfm').factory('player', [ play = (track) -> self.currentTrack = track $rootScope.$broadcast 'player-starting-track', track + + streams = [] + streams.push track.streams.mp3 + streams.push track.streams.ogg if track.streams.ogg + streams.push track.streams.aac if track.streams.aac + + track.progress = 0 + track.progressSeconds = 0 + track.loadingProgress = 0 + self.currentSound = soundManager.createSound - url: track.streams.mp3, + url: streams, volume: self.volume whileloading: () -> $rootScope.safeApply -> @@ -83,7 +93,8 @@ angular.module('ponyfm').factory('player', [ self.currentSound.stop() if self.currentSound != null self.playlistIndex-- - if self.playlistIndex <= 0 + + if self.playlistIndex < 0 self.playlist.length = 0 self.currentTrack = null self.currentSong = null diff --git a/public/styles/content.less b/public/styles/content.less index 4ab5f5eb..ec387d00 100644 --- a/public/styles/content.less +++ b/public/styles/content.less @@ -342,7 +342,7 @@ html { line-height: normal; padding: 0px; - margin: 5px 0px; + padding: 5px 0px; padding-right: 10px; position: relative; @@ -384,6 +384,10 @@ html { margin-top: 5px; } + .artist { + .ellipsis(); + } + .artist, .stats, .genre, .stats-expanded { color: #777; font-size: 80%; diff --git a/public/styles/dashboard.less b/public/styles/dashboard.less index 6d47c386..9fa4b3a6 100644 --- a/public/styles/dashboard.less +++ b/public/styles/dashboard.less @@ -1,23 +1,116 @@ @import-once "base/bootstrap/bootstrap"; -.recent-tracks { +.dashboard { h1 { - a { - display: block; - float: right; - font-size: 10pt; + background: @pfm-purple; + color: #fff; + font-size: 10pt; + padding: 5px; + margin: 0px; + margin-bottom: 5px; + } +} - margin-top: 8px; +@media (max-width: 1300px) and (min-width: 720px) { + html .dashboard { + .recent-tracks { + width: 50%; + + .tracks-listing > li:nth-child(1n+15) { + display: none; + } + } + + .popular-tracks { + width: 50%; + float: right; + } + + .news { + width: 50%; + clear: left; + } + } +} + +@media (max-width: 720px) { + html .dashboard { + section { + float: none !important; + width: auto !important; } } } .dashboard { + h1 { + a { + color: #fff; + display: block; + float: right; + font-size: 10pt; + background: darken(@pfm-purple, 20%); + margin: -5px; + margin-left: 0px; + padding: 5px; + } + } + section { .box-sizing(border-box); - float: left; - width: 50%; padding: 5px; + float: left; } -} \ No newline at end of file + + .recent-tracks { + width: 37.5%; + } + + .popular-tracks { + width: 37.5%; + } + + .news { + width: 25%; + + ul { + list-style: none; + padding: 0px; + margin: 0px; + + li { + margin: 0px; + padding: 0px; + + &.read { + a { + background: #eee; + border-left-color: #ddd; + } + } + + a { + .ellipsis(); + + color: #000; + display: block; + padding: 5px; + font-size: 10pt; + background: lighten(@pfm-purple, 30%); + border-left: 5px solid @pfm-purple; + margin: 5px 0px; + overflow: hidden; + + em { + display: block; + color: #444; + float: right; + font-size: 8pt; + font-style: normal; + } + } + } + } + } +} diff --git a/public/styles/layout.less b/public/styles/layout.less index f951a84b..9e640ec4 100644 --- a/public/styles/layout.less +++ b/public/styles/layout.less @@ -9,6 +9,7 @@ html body { height: 100%; background: #444; font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + padding: 0px !important; } header { diff --git a/public/styles/player.less b/public/styles/player.less index 2bb4bf88..46b344d9 100644 --- a/public/styles/player.less +++ b/public/styles/player.less @@ -14,13 +14,39 @@ body.is-logged { float: left; width: 43px; height: 43px; + position: relative; + overflow: hidden; + padding: 1px; img { .img-polaroid(); + .box-shadow(none); + display: block; - width: 100%; + width: 40px; + height: 40px; padding: 1px; } + + .loader { + .transition(top 250ms linear); + + z-index: 1000; + background: rgba(0, 0, 0, .6); + color: #fff; + position: absolute; + top: -50px; + left: 2px; + width: 42px; + height: 42px; + line-height: 43px; + text-align: center; + font-size: 16px; + + &.showing { + top: 2px; + } + } } .inner { @@ -51,7 +77,7 @@ body.is-logged { } .transport { - background: @pfm-light-grey; + background: #aaa; height: 8px; position: relative; cursor: pointer; diff --git a/public/templates/account/albums.html b/public/templates/account/albums.html index d415b844..2fb1cddf 100644 --- a/public/templates/account/albums.html +++ b/public/templates/account/albums.html @@ -12,7 +12,7 @@