diff --git a/.env.example b/.env.example
index d3cf77234..91e59f966 100644
--- a/.env.example
+++ b/.env.example
@@ -14,14 +14,28 @@ CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
+# Storage
+STORAGE_TYPE=local
+# Amazon S3 Config
+STORAGE_S3_KEY=false
+STORAGE_S3_SECRET=false
+STORAGE_S3_REGION=false
+STORAGE_S3_BUCKET=false
+# Storage URL
+# Used to prefix image urls for when using custom domains/cdns
+STORAGE_URL=false
+
# Social Authentication information. Defaults as off.
GITHUB_APP_ID=false
GITHUB_APP_SECRET=false
GOOGLE_APP_ID=false
GOOGLE_APP_SECRET=false
-# URL for social login redirects, NO TRAILING SLASH
+# URL used for social login redirects, NO TRAILING SLASH
APP_URL=http://bookstack.dev
+# External services
+USE_GRAVATAR=true
+
# Mail settings
MAIL_DRIVER=smtp
MAIL_HOST=localhost
diff --git a/app/Entity.php b/app/Entity.php
index 977b02e77..5ccc016a3 100644
--- a/app/Entity.php
+++ b/app/Entity.php
@@ -7,23 +7,7 @@ use Illuminate\Database\Eloquent\Model;
abstract class Entity extends Model
{
- /**
- * Relation for the user that created this entity.
- * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
- */
- public function createdBy()
- {
- return $this->belongsTo('BookStack\User', 'created_by');
- }
-
- /**
- * Relation for the user that updated this entity.
- * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
- */
- public function updatedBy()
- {
- return $this->belongsTo('BookStack\User', 'updated_by');
- }
+ use Ownable;
/**
* Compares this entity to another given entity.
@@ -97,18 +81,29 @@ abstract class Entity extends Model
*/
public static function isA($type)
{
- return static::getName() === strtolower($type);
+ return static::getClassName() === strtolower($type);
}
/**
* Gets the class name.
* @return string
*/
- public static function getName()
+ public static function getClassName()
{
return strtolower(array_slice(explode('\\', static::class), -1, 1)[0]);
}
+ /**
+ *Gets a limited-length version of the entities name.
+ * @param int $length
+ * @return string
+ */
+ public function getShortName($length = 25)
+ {
+ if(strlen($this->name) <= $length) return $this->name;
+ return substr($this->name, 0, $length-3) . '...';
+ }
+
/**
* Perform a full-text search on this entity.
* @param string[] $fieldsToSearch
@@ -123,20 +118,20 @@ abstract class Entity extends Model
$termString .= $term . '* ';
}
$fields = implode(',', $fieldsToSearch);
- $search = static::whereRaw('MATCH(' . $fields . ') AGAINST(? IN BOOLEAN MODE)', [$termString]);
+ $termStringEscaped = \DB::connection()->getPdo()->quote($termString);
+ $search = static::addSelect(\DB::raw('*, MATCH(name) AGAINST('.$termStringEscaped.' IN BOOLEAN MODE) AS title_relevance'));
+ $search = $search->whereRaw('MATCH(' . $fields . ') AGAINST(? IN BOOLEAN MODE)', [$termString]);
+
+ // Add additional where terms
foreach ($wheres as $whereTerm) {
$search->where($whereTerm[0], $whereTerm[1], $whereTerm[2]);
}
- if (!static::isA('book')) {
- $search = $search->with('book');
- }
+ // Load in relations
+ if (!static::isA('book')) $search = $search->with('book');
+ if (static::isA('page')) $search = $search->with('chapter');
- if (static::isA('page')) {
- $search = $search->with('chapter');
- }
-
- return $search->get();
+ return $search->orderBy('title_relevance', 'desc')->get();
}
/**
diff --git a/app/Http/Controllers/BookController.php b/app/Http/Controllers/BookController.php
index 6b2d6928d..a4365d605 100644
--- a/app/Http/Controllers/BookController.php
+++ b/app/Http/Controllers/BookController.php
@@ -42,8 +42,10 @@ class BookController extends Controller
public function index()
{
$books = $this->bookRepo->getAllPaginated(10);
- $recents = $this->signedIn ? $this->bookRepo->getRecentlyViewed(10, 0) : false;
- return view('books/index', ['books' => $books, 'recents' => $recents]);
+ $recents = $this->signedIn ? $this->bookRepo->getRecentlyViewed(4, 0) : false;
+ $popular = $this->bookRepo->getPopular(4, 0);
+ $this->setPageTitle('Books');
+ return view('books/index', ['books' => $books, 'recents' => $recents, 'popular' => $popular]);
}
/**
@@ -54,6 +56,7 @@ class BookController extends Controller
public function create()
{
$this->checkPermission('book-create');
+ $this->setPageTitle('Create New Book');
return view('books/create');
}
@@ -88,8 +91,9 @@ class BookController extends Controller
public function show($slug)
{
$book = $this->bookRepo->getBySlug($slug);
- Views::add($book);
$bookChildren = $this->bookRepo->getChildren($book);
+ Views::add($book);
+ $this->setPageTitle($book->getShortName());
return view('books/show', ['book' => $book, 'current' => $book, 'bookChildren' => $bookChildren]);
}
@@ -103,6 +107,7 @@ class BookController extends Controller
{
$this->checkPermission('book-update');
$book = $this->bookRepo->getBySlug($slug);
+ $this->setPageTitle('Edit Book ' . $book->getShortName());
return view('books/edit', ['book' => $book, 'current' => $book]);
}
@@ -138,6 +143,7 @@ class BookController extends Controller
{
$this->checkPermission('book-delete');
$book = $this->bookRepo->getBySlug($bookSlug);
+ $this->setPageTitle('Delete Book ' . $book->getShortName());
return view('books/delete', ['book' => $book, 'current' => $book]);
}
@@ -152,9 +158,16 @@ class BookController extends Controller
$book = $this->bookRepo->getBySlug($bookSlug);
$bookChildren = $this->bookRepo->getChildren($book);
$books = $this->bookRepo->getAll();
+ $this->setPageTitle('Sort Book ' . $book->getShortName());
return view('books/sort', ['book' => $book, 'current' => $book, 'books' => $books, 'bookChildren' => $bookChildren]);
}
+ /**
+ * Shows the sort box for a single book.
+ * Used via AJAX when loading in extra books to a sort.
+ * @param $bookSlug
+ * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+ */
public function getSortItem($bookSlug)
{
$book = $this->bookRepo->getBySlug($bookSlug);
diff --git a/app/Http/Controllers/ChapterController.php b/app/Http/Controllers/ChapterController.php
index 1fe1e8b3e..fc13e8b58 100644
--- a/app/Http/Controllers/ChapterController.php
+++ b/app/Http/Controllers/ChapterController.php
@@ -40,6 +40,7 @@ class ChapterController extends Controller
{
$this->checkPermission('chapter-create');
$book = $this->bookRepo->getBySlug($bookSlug);
+ $this->setPageTitle('Create New Chapter');
return view('chapters/create', ['book' => $book, 'current' => $book]);
}
@@ -79,6 +80,7 @@ class ChapterController extends Controller
$chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
$sidebarTree = $this->bookRepo->getChildren($book);
Views::add($chapter);
+ $this->setPageTitle($chapter->getShortName());
return view('chapters/show', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter, 'sidebarTree' => $sidebarTree]);
}
@@ -93,6 +95,7 @@ class ChapterController extends Controller
$this->checkPermission('chapter-update');
$book = $this->bookRepo->getBySlug($bookSlug);
$chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
+ $this->setPageTitle('Edit Chapter' . $chapter->getShortName());
return view('chapters/edit', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]);
}
@@ -127,6 +130,7 @@ class ChapterController extends Controller
$this->checkPermission('chapter-delete');
$book = $this->bookRepo->getBySlug($bookSlug);
$chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
+ $this->setPageTitle('Delete Chapter' . $chapter->getShortName());
return view('chapters/delete', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]);
}
diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php
index 4cc865d29..5dc79eb02 100644
--- a/app/Http/Controllers/Controller.php
+++ b/app/Http/Controllers/Controller.php
@@ -42,6 +42,15 @@ abstract class Controller extends BaseController
$this->signedIn = auth()->check();
}
+ /**
+ * Adds the page title into the view.
+ * @param $title
+ */
+ public function setPageTitle($title)
+ {
+ view()->share('pageTitle', $title);
+ }
+
/**
* Checks for a permission.
*
diff --git a/app/Http/Controllers/ImageController.php b/app/Http/Controllers/ImageController.php
index fd7901570..146dd0c05 100644
--- a/app/Http/Controllers/ImageController.php
+++ b/app/Http/Controllers/ImageController.php
@@ -2,6 +2,7 @@
namespace BookStack\Http\Controllers;
+use BookStack\Repos\ImageRepo;
use Illuminate\Filesystem\Filesystem as File;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@@ -14,125 +15,78 @@ class ImageController extends Controller
{
protected $image;
protected $file;
+ protected $imageRepo;
/**
* ImageController constructor.
- * @param Image $image
- * @param File $file
+ * @param Image $image
+ * @param File $file
+ * @param ImageRepo $imageRepo
*/
- public function __construct(Image $image, File $file)
+ public function __construct(Image $image, File $file, ImageRepo $imageRepo)
{
$this->image = $image;
$this->file = $file;
+ $this->imageRepo = $imageRepo;
parent::__construct();
}
/**
- * Get all images, Paginated
+ * Get all images for a specific type, Paginated
* @param int $page
* @return \Illuminate\Http\JsonResponse
*/
- public function getAll($page = 0)
+ public function getAllByType($type, $page = 0)
{
- $pageSize = 30;
- $images = $this->image->orderBy('created_at', 'desc')
- ->skip($page * $pageSize)->take($pageSize)->get();
- foreach ($images as $image) {
- $this->loadSizes($image);
- }
- $hasMore = $this->image->orderBy('created_at', 'desc')
- ->skip(($page + 1) * $pageSize)->take($pageSize)->count() > 0;
- return response()->json([
- 'images' => $images,
- 'hasMore' => $hasMore
- ]);
+ $imgData = $this->imageRepo->getPaginatedByType($type, $page);
+ return response()->json($imgData);
}
/**
- * Loads the standard thumbnail sizes for an image.
- * @param Image $image
+ * Get all images for a user.
+ * @param int $page
+ * @return \Illuminate\Http\JsonResponse
*/
- private function loadSizes(Image $image)
+ public function getAllForUserType($page = 0)
{
- $image->thumbnail = $this->getThumbnail($image, 150, 150);
- $image->display = $this->getThumbnail($image, 840, 0, true);
+ $imgData = $this->imageRepo->getPaginatedByType('user', $page, 24, $this->currentUser->id);
+ return response()->json($imgData);
}
- /**
- * Get the thumbnail for an image.
- * If $keepRatio is true only the width will be used.
- * @param $image
- * @param int $width
- * @param int $height
- * @param bool $keepRatio
- * @return string
- */
- public function getThumbnail($image, $width = 220, $height = 220, $keepRatio = false)
- {
- $explodedPath = explode('/', $image->url);
- $dirPrefix = $keepRatio ? 'scaled-' : 'thumbs-';
- array_splice($explodedPath, 4, 0, [$dirPrefix . $width . '-' . $height]);
- $thumbPath = implode('/', $explodedPath);
- $thumbFilePath = public_path() . $thumbPath;
-
- // Return the thumbnail url path if already exists
- if (file_exists($thumbFilePath)) {
- return $thumbPath;
- }
-
- // Otherwise create the thumbnail
- $thumb = ImageTool::make(public_path() . $image->url);
- if($keepRatio) {
- $thumb->resize($width, null, function ($constraint) {
- $constraint->aspectRatio();
- $constraint->upsize();
- });
- } else {
- $thumb->fit($width, $height);
- }
-
- // Create thumbnail folder if it does not exist
- if (!file_exists(dirname($thumbFilePath))) {
- mkdir(dirname($thumbFilePath), 0775, true);
- }
-
- //Save Thumbnail
- $thumb->save($thumbFilePath);
- return $thumbPath;
- }
/**
* Handles image uploads for use on pages.
+ * @param string $type
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
- public function upload(Request $request)
+ public function uploadByType($type, Request $request)
{
$this->checkPermission('image-create');
$this->validate($request, [
'file' => 'image|mimes:jpeg,gif,png'
]);
- $imageUpload = $request->file('file');
- $name = str_replace(' ', '-', $imageUpload->getClientOriginalName());
- $storageName = substr(sha1(time()), 0, 10) . '-' . $name;
- $imagePath = '/uploads/images/' . Date('Y-m-M') . '/';
- $storagePath = public_path() . $imagePath;
- $fullPath = $storagePath . $storageName;
- while (file_exists($fullPath)) {
- $storageName = substr(sha1(rand()), 0, 3) . $storageName;
- $fullPath = $storagePath . $storageName;
- }
- $imageUpload->move($storagePath, $storageName);
- // Create and save image object
- $this->image->name = $name;
- $this->image->url = $imagePath . $storageName;
- $this->image->created_by = auth()->user()->id;
- $this->image->updated_by = auth()->user()->id;
- $this->image->save();
- $this->loadSizes($this->image);
- return response()->json($this->image);
+ $imageUpload = $request->file('file');
+ $image = $this->imageRepo->saveNew($imageUpload, $type);
+ return response()->json($image);
+ }
+
+ /**
+ * Generate a sized thumbnail for an image.
+ * @param $id
+ * @param $width
+ * @param $height
+ * @param $crop
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function getThumbnail($id, $width, $height, $crop)
+ {
+ $this->checkPermission('image-create');
+ $image = $this->imageRepo->getById($id);
+ $thumbnailUrl = $this->imageRepo->getThumbnail($image, $width, $height, $crop == 'false');
+ return response()->json(['url' => $thumbnailUrl]);
}
/**
@@ -147,13 +101,12 @@ class ImageController extends Controller
$this->validate($request, [
'name' => 'required|min:2|string'
]);
- $image = $this->image->findOrFail($imageId);
- $image->fill($request->all());
- $image->save();
- $this->loadSizes($image);
- return response()->json($this->image);
+ $image = $this->imageRepo->getById($imageId);
+ $image = $this->imageRepo->updateImageDetails($image, $request->all());
+ return response()->json($image);
}
+
/**
* Deletes an image and all thumbnail/image files
* @param PageRepo $pageRepo
@@ -164,41 +117,18 @@ class ImageController extends Controller
public function destroy(PageRepo $pageRepo, Request $request, $id)
{
$this->checkPermission('image-delete');
- $image = $this->image->findOrFail($id);
+ $image = $this->imageRepo->getById($id);
// Check if this image is used on any pages
- $pageSearch = $pageRepo->searchForImage($image->url);
$isForced = ($request->has('force') && ($request->get('force') === 'true') || $request->get('force') === true);
- if ($pageSearch !== false && !$isForced) {
- return response()->json($pageSearch, 400);
- }
-
- // Delete files
- $folder = public_path() . dirname($image->url);
- $fileName = basename($image->url);
-
- // Delete thumbnails
- foreach (glob($folder . '/*') as $file) {
- if (is_dir($file)) {
- $thumbName = $file . '/' . $fileName;
- if (file_exists($file)) {
- unlink($thumbName);
- }
- // Remove thumb folder if empty
- if (count(glob($file . '/*')) === 0) {
- rmdir($file);
- }
+ if (!$isForced) {
+ $pageSearch = $pageRepo->searchForImage($image->url);
+ if ($pageSearch !== false) {
+ return response()->json($pageSearch, 400);
}
}
- // Delete file and database entry
- unlink($folder . '/' . $fileName);
- $image->delete();
-
- // Delete parent folder if empty
- if (count(glob($folder . '/*')) === 0) {
- rmdir($folder);
- }
+ $this->imageRepo->destroyImage($image);
return response()->json('Image Deleted');
}
diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php
index d9d53178e..2002fbdf0 100644
--- a/app/Http/Controllers/PageController.php
+++ b/app/Http/Controllers/PageController.php
@@ -46,6 +46,7 @@ class PageController extends Controller
$this->checkPermission('page-create');
$book = $this->bookRepo->getBySlug($bookSlug);
$chapter = $chapterSlug ? $this->chapterRepo->getBySlug($chapterSlug, $book->id) : false;
+ $this->setPageTitle('Create New Page');
return view('pages/create', ['book' => $book, 'chapter' => $chapter]);
}
@@ -89,6 +90,7 @@ class PageController extends Controller
$page = $this->pageRepo->getBySlug($pageSlug, $book->id);
$sidebarTree = $this->bookRepo->getChildren($book);
Views::add($page);
+ $this->setPageTitle($page->getShortName());
return view('pages/show', ['page' => $page, 'book' => $book, 'current' => $page, 'sidebarTree' => $sidebarTree]);
}
@@ -104,6 +106,7 @@ class PageController extends Controller
$this->checkPermission('page-update');
$book = $this->bookRepo->getBySlug($bookSlug);
$page = $this->pageRepo->getBySlug($pageSlug, $book->id);
+ $this->setPageTitle('Editing Page ' . $page->getShortName());
return view('pages/edit', ['page' => $page, 'book' => $book, 'current' => $page]);
}
@@ -148,6 +151,7 @@ class PageController extends Controller
$this->checkPermission('page-delete');
$book = $this->bookRepo->getBySlug($bookSlug);
$page = $this->pageRepo->getBySlug($pageSlug, $book->id);
+ $this->setPageTitle('Delete Page ' . $page->getShortName());
return view('pages/delete', ['book' => $book, 'page' => $page, 'current' => $page]);
}
@@ -179,6 +183,7 @@ class PageController extends Controller
{
$book = $this->bookRepo->getBySlug($bookSlug);
$page = $this->pageRepo->getBySlug($pageSlug, $book->id);
+ $this->setPageTitle('Revisions For ' . $page->getShortName());
return view('pages/revisions', ['page' => $page, 'book' => $book, 'current' => $page]);
}
@@ -195,6 +200,7 @@ class PageController extends Controller
$page = $this->pageRepo->getBySlug($pageSlug, $book->id);
$revision = $this->pageRepo->getRevisionById($revisionId);
$page->fill($revision->toArray());
+ $this->setPageTitle('Page Revision For ' . $page->getShortName());
return view('pages/revision', ['page' => $page, 'book' => $book]);
}
diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php
index c6222156d..c9ca1f09f 100644
--- a/app/Http/Controllers/SearchController.php
+++ b/app/Http/Controllers/SearchController.php
@@ -45,6 +45,7 @@ class SearchController extends Controller
$pages = $this->pageRepo->getBySearch($searchTerm);
$books = $this->bookRepo->getBySearch($searchTerm);
$chapters = $this->chapterRepo->getBySearch($searchTerm);
+ $this->setPageTitle('Search For ' . $searchTerm);
return view('search/all', ['pages' => $pages, 'books' => $books, 'chapters' => $chapters, 'searchTerm' => $searchTerm]);
}
diff --git a/app/Http/Controllers/SettingController.php b/app/Http/Controllers/SettingController.php
index 3e96de62e..bca48807f 100644
--- a/app/Http/Controllers/SettingController.php
+++ b/app/Http/Controllers/SettingController.php
@@ -18,6 +18,7 @@ class SettingController extends Controller
public function index()
{
$this->checkPermission('settings-update');
+ $this->setPageTitle('Settings');
return view('settings/index');
}
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
index dacb91a7b..3f41b2d0e 100644
--- a/app/Http/Controllers/UserController.php
+++ b/app/Http/Controllers/UserController.php
@@ -4,7 +4,7 @@ namespace BookStack\Http\Controllers;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Hash;
+use Illuminate\Http\Response;
use BookStack\Http\Requests;
use BookStack\Repos\UserRepo;
use BookStack\Services\SocialAuthService;
@@ -18,7 +18,8 @@ class UserController extends Controller
/**
* UserController constructor.
- * @param $user
+ * @param User $user
+ * @param UserRepo $userRepo
*/
public function __construct(User $user, UserRepo $userRepo)
{
@@ -29,18 +30,17 @@ class UserController extends Controller
/**
* Display a listing of the users.
- *
* @return Response
*/
public function index()
{
$users = $this->user->all();
+ $this->setPageTitle('Users');
return view('users/index', ['users' => $users]);
}
/**
* Show the form for creating a new user.
- *
* @return Response
*/
public function create()
@@ -51,7 +51,6 @@ class UserController extends Controller
/**
* Store a newly created user in storage.
- *
* @param Request $request
* @return Response
*/
@@ -60,7 +59,7 @@ class UserController extends Controller
$this->checkPermission('user-create');
$this->validate($request, [
'name' => 'required',
- 'email' => 'required|email',
+ 'email' => 'required|email|unique:users,email',
'password' => 'required|min:5',
'password-confirm' => 'required|same:password',
'role' => 'required|exists:roles,id'
@@ -71,13 +70,20 @@ class UserController extends Controller
$user->save();
$user->attachRoleId($request->get('role'));
+
+ // Get avatar from gravatar and save
+ if (!env('DISABLE_EXTERNAL_SERVICES', false)) {
+ $avatar = \Images::saveUserGravatar($user);
+ $user->avatar()->associate($avatar);
+ $user->save();
+ }
+
return redirect('/users');
}
/**
* Show the form for editing the specified user.
- *
* @param int $id
* @param SocialAuthService $socialAuthService
* @return Response
@@ -90,12 +96,12 @@ class UserController extends Controller
$user = $this->user->findOrFail($id);
$activeSocialDrivers = $socialAuthService->getActiveDrivers();
+ $this->setPageTitle('User Profile');
return view('users/edit', ['user' => $user, 'activeSocialDrivers' => $activeSocialDrivers]);
}
/**
* Update the specified user in storage.
- *
* @param Request $request
* @param int $id
* @return Response
@@ -139,12 +145,12 @@ class UserController extends Controller
return $this->currentUser->id == $id;
});
$user = $this->user->findOrFail($id);
+ $this->setPageTitle('Delete User ' . $user->name);
return view('users/delete', ['user' => $user]);
}
/**
* Remove the specified user from storage.
- *
* @param int $id
* @return Response
*/
@@ -153,14 +159,14 @@ class UserController extends Controller
$this->checkPermissionOr('user-delete', function () use ($id) {
return $this->currentUser->id == $id;
});
+
$user = $this->userRepo->getById($id);
- // Delete social accounts
- if($this->userRepo->isOnlyAdmin($user)) {
+ if ($this->userRepo->isOnlyAdmin($user)) {
session()->flash('error', 'You cannot delete the only admin');
return redirect($user->getEditUrl());
}
- $user->socialAccounts()->delete();
- $user->delete();
+ $this->userRepo->destroy($user);
+
return redirect('/users');
}
}
diff --git a/app/Http/routes.php b/app/Http/routes.php
index e605dbee1..23d4c33ab 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -45,8 +45,6 @@ Route::group(['middleware' => 'auth'], function () {
});
- // Uploads
- Route::post('/upload/image', 'ImageController@upload');
// Users
Route::get('/users', 'UserController@index');
@@ -58,10 +56,18 @@ Route::group(['middleware' => 'auth'], function () {
Route::delete('/users/{id}', 'UserController@destroy');
// Image routes
- Route::get('/images/all', 'ImageController@getAll');
- Route::put('/images/update/{imageId}', 'ImageController@update');
- Route::delete('/images/{imageId}', 'ImageController@destroy');
- Route::get('/images/all/{page}', 'ImageController@getAll');
+ Route::group(['prefix' => 'images'], function() {
+ // Get for user images
+ Route::get('/user/all', 'ImageController@getAllForUserType');
+ Route::get('/user/all/{page}', 'ImageController@getAllForUserType');
+ // Standard get, update and deletion for all types
+ Route::get('/thumb/{id}/{width}/{height}/{crop}', 'ImageController@getThumbnail');
+ Route::put('/update/{imageId}', 'ImageController@update');
+ Route::post('/{type}/upload', 'ImageController@uploadByType');
+ Route::get('/{type}/all', 'ImageController@getAllByType');
+ Route::get('/{type}/all/{page}', 'ImageController@getAllByType');
+ Route::delete('/{imageId}', 'ImageController@destroy');
+ });
// Links
Route::get('/link/{id}', 'PageController@redirectFromLink');
diff --git a/app/Image.php b/app/Image.php
index 7c77440f9..3ac084d8f 100644
--- a/app/Image.php
+++ b/app/Image.php
@@ -3,22 +3,24 @@
namespace BookStack;
-class Image extends Entity
+use Illuminate\Database\Eloquent\Model;
+use Images;
+
+class Image extends Model
{
+ use Ownable;
protected $fillable = ['name'];
- public function getFilePath()
- {
- return storage_path() . $this->url;
- }
-
/**
- * Get the url for this item.
+ * Get a thumbnail for this image.
+ * @param int $width
+ * @param int $height
+ * @param bool|false $keepRatio
* @return string
*/
- public function getUrl()
+ public function getThumb($width, $height, $keepRatio = false)
{
- return public_path() . $this->url;
+ return Images::getThumbnail($this, $width, $height, $keepRatio);
}
}
diff --git a/app/Ownable.php b/app/Ownable.php
new file mode 100644
index 000000000..d6505b746
--- /dev/null
+++ b/app/Ownable.php
@@ -0,0 +1,23 @@
+belongsTo('BookStack\User', 'created_by');
+ }
+
+ /**
+ * Relation for the user that updated this entity.
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function updatedBy()
+ {
+ return $this->belongsTo('BookStack\User', 'updated_by');
+ }
+}
\ No newline at end of file
diff --git a/app/Page.php b/app/Page.php
index feedb1eae..bd5f3bafe 100644
--- a/app/Page.php
+++ b/app/Page.php
@@ -32,7 +32,6 @@ class Page extends Entity
return $this->chapter()->count() > 0;
}
-
public function revisions()
{
return $this->hasMany('BookStack\PageRevision')->orderBy('created_at', 'desc');
@@ -40,7 +39,6 @@ class Page extends Entity
public function getUrl()
{
- // TODO - Extract this and share with chapters
$bookSlug = $this->getAttribute('bookSlug') ? $this->getAttribute('bookSlug') : $this->book->slug;
return '/books/' . $bookSlug . '/page/' . $this->slug;
}
diff --git a/app/Providers/CustomFacadeProvider.php b/app/Providers/CustomFacadeProvider.php
index bd4b2b515..1df14a076 100644
--- a/app/Providers/CustomFacadeProvider.php
+++ b/app/Providers/CustomFacadeProvider.php
@@ -2,6 +2,7 @@
namespace BookStack\Providers;
+use BookStack\Services\ImageService;
use BookStack\Services\ViewService;
use Illuminate\Support\ServiceProvider;
use BookStack\Services\ActivityService;
@@ -40,5 +41,12 @@ class CustomFacadeProvider extends ServiceProvider
$this->app->make('Illuminate\Contracts\Cache\Repository')
);
});
+ $this->app->bind('images', function() {
+ return new ImageService(
+ $this->app->make('Intervention\Image\ImageManager'),
+ $this->app->make('Illuminate\Contracts\Filesystem\Factory'),
+ $this->app->make('Illuminate\Contracts\Cache\Repository')
+ );
+ });
}
}
diff --git a/app/Repos/BookRepo.php b/app/Repos/BookRepo.php
index 9be77defe..469fdb31d 100644
--- a/app/Repos/BookRepo.php
+++ b/app/Repos/BookRepo.php
@@ -77,6 +77,17 @@ class BookRepo
return Views::getUserRecentlyViewed($count, $page, $this->book);
}
+ /**
+ * Gets the most viewed books.
+ * @param int $count
+ * @param int $page
+ * @return mixed
+ */
+ public function getPopular($count = 10, $page = 0)
+ {
+ return Views::getPopular($count, $page, $this->book);
+ }
+
/**
* Get a book by slug
* @param $slug
diff --git a/app/Repos/ImageRepo.php b/app/Repos/ImageRepo.php
new file mode 100644
index 000000000..d41909ac5
--- /dev/null
+++ b/app/Repos/ImageRepo.php
@@ -0,0 +1,137 @@
+image = $image;
+ $this->imageService = $imageService;
+ }
+
+
+ /**
+ * Get an image with the given id.
+ * @param $id
+ * @return mixed
+ */
+ public function getById($id)
+ {
+ return $this->image->findOrFail($id);
+ }
+
+
+ /**
+ * Gets a load images paginated, filtered by image type.
+ * @param string $type
+ * @param int $page
+ * @param int $pageSize
+ * @param bool|int $userFilter
+ * @return array
+ */
+ public function getPaginatedByType($type, $page = 0, $pageSize = 24, $userFilter = false)
+ {
+ $images = $this->image->where('type', '=', strtolower($type));
+
+ if ($userFilter !== false) {
+ $images = $images->where('created_by', '=', $userFilter);
+ }
+
+ $images = $images->orderBy('created_at', 'desc')->skip($pageSize * $page)->take($pageSize + 1)->get();
+ $hasMore = count($images) > $pageSize;
+
+ $returnImages = $images->take(24);
+ $returnImages->each(function ($image) {
+ $this->loadThumbs($image);
+ });
+
+ return [
+ 'images' => $returnImages,
+ 'hasMore' => $hasMore
+ ];
+ }
+
+ /**
+ * Save a new image into storage and return the new image.
+ * @param UploadedFile $uploadFile
+ * @param string $type
+ * @return Image
+ */
+ public function saveNew(UploadedFile $uploadFile, $type)
+ {
+ $image = $this->imageService->saveNewFromUpload($uploadFile, $type);
+ $this->loadThumbs($image);
+ return $image;
+ }
+
+ /**
+ * Update the details of an image via an array of properties.
+ * @param Image $image
+ * @param array $updateDetails
+ * @return Image
+ */
+ public function updateImageDetails(Image $image, $updateDetails)
+ {
+ $image->fill($updateDetails);
+ $image->save();
+ $this->loadThumbs($image);
+ return $image;
+ }
+
+
+ /**
+ * Destroys an Image object along with its files and thumbnails.
+ * @param Image $image
+ * @return bool
+ */
+ public function destroyImage(Image $image)
+ {
+ $this->imageService->destroyImage($image);
+ return true;
+ }
+
+
+ /**
+ * Load thumbnails onto an image object.
+ * @param Image $image
+ */
+ private function loadThumbs(Image $image)
+ {
+ $image->thumbs = [
+ 'gallery' => $this->getThumbnail($image, 150, 150),
+ 'display' => $this->getThumbnail($image, 840, 0, true)
+ ];
+ }
+
+ /**
+ * Get the thumbnail for an image.
+ * If $keepRatio is true only the width will be used.
+ * Checks the cache then storage to avoid creating / accessing the filesystem on every check.
+ *
+ * @param Image $image
+ * @param int $width
+ * @param int $height
+ * @param bool $keepRatio
+ * @return string
+ */
+ public function getThumbnail(Image $image, $width = 220, $height = 220, $keepRatio = false)
+ {
+ return $this->imageService->getThumbnail($image, $width, $height, $keepRatio);
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/Repos/PageRepo.php b/app/Repos/PageRepo.php
index a52cecad3..f7b48efdc 100644
--- a/app/Repos/PageRepo.php
+++ b/app/Repos/PageRepo.php
@@ -269,7 +269,7 @@ class PageRepo
* @param Page $page
* @return $this
*/
- private function saveRevision(Page $page)
+ public function saveRevision(Page $page)
{
$revision = $this->pageRevision->fill($page->toArray());
$revision->page_id = $page->id;
diff --git a/app/Repos/UserRepo.php b/app/Repos/UserRepo.php
index 5122aac77..fecd7c88b 100644
--- a/app/Repos/UserRepo.php
+++ b/app/Repos/UserRepo.php
@@ -46,16 +46,21 @@ class UserRepo
public function registerNew(array $data)
{
$user = $this->create($data);
- $roleId = \Setting::get('registration-role');
-
- if ($roleId === false) {
- $roleId = $this->role->getDefault()->id;
- }
-
- $user->attachRoleId($roleId);
+ $this->attachDefaultRole($user);
return $user;
}
+ /**
+ * Give a user the default role. Used when creating a new user.
+ * @param $user
+ */
+ public function attachDefaultRole($user)
+ {
+ $roleId = \Setting::get('registration-role');
+ if ($roleId === false) $roleId = $this->role->getDefault()->id;
+ $user->attachRoleId($roleId);
+ }
+
/**
* Checks if the give user is the only admin.
* @param User $user
@@ -88,4 +93,14 @@ class UserRepo
'password' => bcrypt($data['password'])
]);
}
+
+ /**
+ * Remove the given user from storage, Delete all related content.
+ * @param User $user
+ */
+ public function destroy(User $user)
+ {
+ $user->socialAccounts()->delete();
+ $user->delete();
+ }
}
\ No newline at end of file
diff --git a/app/Services/Facades/Images.php b/app/Services/Facades/Images.php
new file mode 100644
index 000000000..219f069a0
--- /dev/null
+++ b/app/Services/Facades/Images.php
@@ -0,0 +1,14 @@
+imageTool = $imageTool;
+ $this->fileSystem = $fileSystem;
+ $this->cache = $cache;
+ }
+
+ /**
+ * Saves a new image from an upload.
+ * @param UploadedFile $uploadedFile
+ * @param string $type
+ * @return mixed
+ */
+ public function saveNewFromUpload(UploadedFile $uploadedFile, $type)
+ {
+ $imageName = $uploadedFile->getClientOriginalName();
+ $imageData = file_get_contents($uploadedFile->getRealPath());
+ return $this->saveNew($imageName, $imageData, $type);
+ }
+
+
+ /**
+ * Gets an image from url and saves it to the database.
+ * @param $url
+ * @param string $type
+ * @param bool|string $imageName
+ * @return mixed
+ * @throws \Exception
+ */
+ private function saveNewFromUrl($url, $type, $imageName = false)
+ {
+ $imageName = $imageName ? $imageName : basename($url);
+ $imageData = file_get_contents($url);
+ if($imageData === false) throw new \Exception('Cannot get image from ' . $url);
+ return $this->saveNew($imageName, $imageData, $type);
+ }
+
+ /**
+ * Saves a new image
+ * @param string $imageName
+ * @param string $imageData
+ * @param string $type
+ * @return Image
+ */
+ private function saveNew($imageName, $imageData, $type)
+ {
+ $storage = $this->getStorage();
+ $secureUploads = Setting::get('app-secure-images');
+ $imageName = str_replace(' ', '-', $imageName);
+
+ if ($secureUploads) $imageName = str_random(16) . '-' . $imageName;
+
+ $imagePath = '/uploads/images/' . $type . '/' . Date('Y-m-M') . '/';
+ while ($storage->exists($imagePath . $imageName)) {
+ $imageName = str_random(3) . $imageName;
+ }
+ $fullPath = $imagePath . $imageName;
+
+ $storage->put($fullPath, $imageData);
+
+ $userId = auth()->user()->id;
+ $image = Image::forceCreate([
+ 'name' => $imageName,
+ 'path' => $fullPath,
+ 'url' => $this->getPublicUrl($fullPath),
+ 'type' => $type,
+ 'created_by' => $userId,
+ 'updated_by' => $userId
+ ]);
+
+ return $image;
+ }
+
+ /**
+ * Get the thumbnail for an image.
+ * If $keepRatio is true only the width will be used.
+ * Checks the cache then storage to avoid creating / accessing the filesystem on every check.
+ *
+ * @param Image $image
+ * @param int $width
+ * @param int $height
+ * @param bool $keepRatio
+ * @return string
+ */
+ public function getThumbnail(Image $image, $width = 220, $height = 220, $keepRatio = false)
+ {
+ $thumbDirName = '/' . ($keepRatio ? 'scaled-' : 'thumbs-') . $width . '-' . $height . '/';
+ $thumbFilePath = dirname($image->path) . $thumbDirName . basename($image->path);
+
+ if ($this->cache->has('images-' . $image->id . '-' . $thumbFilePath) && $this->cache->get('images-' . $thumbFilePath)) {
+ return $this->getPublicUrl($thumbFilePath);
+ }
+
+ $storage = $this->getStorage();
+
+ if ($storage->exists($thumbFilePath)) {
+ return $this->getPublicUrl($thumbFilePath);
+ }
+
+ // Otherwise create the thumbnail
+ $thumb = $this->imageTool->make($storage->get($image->path));
+ if ($keepRatio) {
+ $thumb->resize($width, null, function ($constraint) {
+ $constraint->aspectRatio();
+ $constraint->upsize();
+ });
+ } else {
+ $thumb->fit($width, $height);
+ }
+
+ $thumbData = (string)$thumb->encode();
+ $storage->put($thumbFilePath, $thumbData);
+ $this->cache->put('images-' . $image->id . '-' . $thumbFilePath, $thumbFilePath, 60 * 72);
+
+ return $this->getPublicUrl($thumbFilePath);
+ }
+
+ /**
+ * Destroys an Image object along with its files and thumbnails.
+ * @param Image $image
+ * @return bool
+ */
+ public function destroyImage(Image $image)
+ {
+ $storage = $this->getStorage();
+
+ $imageFolder = dirname($image->path);
+ $imageFileName = basename($image->path);
+ $allImages = collect($storage->allFiles($imageFolder));
+
+ $imagesToDelete = $allImages->filter(function ($imagePath) use ($imageFileName) {
+ $expectedIndex = strlen($imagePath) - strlen($imageFileName);
+ return strpos($imagePath, $imageFileName) === $expectedIndex;
+ });
+
+ $storage->delete($imagesToDelete->all());
+
+ // Cleanup of empty folders
+ foreach ($storage->directories($imageFolder) as $directory) {
+ if ($this->isFolderEmpty($directory)) $storage->deleteDirectory($directory);
+ }
+ if ($this->isFolderEmpty($imageFolder)) $storage->deleteDirectory($imageFolder);
+
+ $image->delete();
+ return true;
+ }
+
+ /**
+ * Save a gravatar image and set a the profile image for a user.
+ * @param User $user
+ * @param int $size
+ * @return mixed
+ */
+ public function saveUserGravatar(User $user, $size = 500)
+ {
+ $emailHash = md5(strtolower(trim($user->email)));
+ $url = 'http://www.gravatar.com/avatar/' . $emailHash . '?s=' . $size . '&d=identicon';
+ $imageName = str_replace(' ', '-', $user->name . '-gravatar.png');
+ $image = $this->saveNewFromUrl($url, 'user', $imageName);
+ $image->created_by = $user->id;
+ $image->save();
+ return $image;
+ }
+
+ /**
+ * Get the storage that will be used for storing images.
+ * @return FileSystemInstance
+ */
+ private function getStorage()
+ {
+ if ($this->storageInstance !== null) return $this->storageInstance;
+
+ $storageType = env('STORAGE_TYPE');
+ $this->storageInstance = $this->fileSystem->disk($storageType);
+
+ return $this->storageInstance;
+ }
+
+ /**
+ * Check whether or not a folder is empty.
+ * @param $path
+ * @return int
+ */
+ private function isFolderEmpty($path)
+ {
+ $files = $this->getStorage()->files($path);
+ $folders = $this->getStorage()->directories($path);
+ return count($files) === 0 && count($folders) === 0;
+ }
+
+ /**
+ * Gets a public facing url for an image by checking relevant environment variables.
+ * @param $filePath
+ * @return string
+ */
+ private function getPublicUrl($filePath)
+ {
+ if ($this->storageUrl === null) {
+ $storageUrl = env('STORAGE_URL');
+
+ // Get the standard public s3 url if s3 is set as storage type
+ if ($storageUrl == false && env('STORAGE_TYPE') === 's3') {
+ $storageDetails = config('filesystems.disks.s3');
+ $storageUrl = 'https://s3-' . $storageDetails['region'] . '.amazonaws.com/' . $storageDetails['bucket'];
+ }
+
+ $this->storageUrl = $storageUrl;
+ }
+
+ return ($this->storageUrl == false ? '' : rtrim($this->storageUrl, '/')) . $filePath;
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/Services/ViewService.php b/app/Services/ViewService.php
index 475500927..5b800d939 100644
--- a/app/Services/ViewService.php
+++ b/app/Services/ViewService.php
@@ -44,6 +44,29 @@ class ViewService
return 1;
}
+
+ /**
+ * Get the entities with the most views.
+ * @param int $count
+ * @param int $page
+ * @param bool|false $filterModel
+ */
+ public function getPopular($count = 10, $page = 0, $filterModel = false)
+ {
+ $skipCount = $count * $page;
+ $query = $this->view->select('id', 'viewable_id', 'viewable_type', \DB::raw('SUM(views) as view_count'))
+ ->groupBy('viewable_id', 'viewable_type')
+ ->orderBy('view_count', 'desc');
+
+ if($filterModel) $query->where('viewable_type', '=', get_class($filterModel));
+
+ $views = $query->with('viewable')->skip($skipCount)->take($count)->get();
+ $viewedEntities = $views->map(function ($item) {
+ return $item->viewable()->getResults();
+ });
+ return $viewedEntities;
+ }
+
/**
* Get all recently viewed entities for the current user.
* @param int $count
diff --git a/app/User.php b/app/User.php
index 570789f37..1be98c3c4 100644
--- a/app/User.php
+++ b/app/User.php
@@ -24,7 +24,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
*
* @var array
*/
- protected $fillable = ['name', 'email', 'password'];
+ protected $fillable = ['name', 'email', 'password', 'image_id'];
/**
* The attributes excluded from the model's JSON form.
@@ -145,8 +145,17 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
*/
public function getAvatar($size = 50)
{
- $emailHash = md5(strtolower(trim($this->email)));
- return '//www.gravatar.com/avatar/' . $emailHash . '?s=' . $size . '&d=identicon';
+ if ($this->image_id === 0 || $this->image_id === '0' || $this->image_id === null) return '/user_avatar.png';
+ return $this->avatar->getThumb($size, $size, false);
+ }
+
+ /**
+ * Get the avatar for the user.
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function avatar()
+ {
+ return $this->belongsTo('BookStack\Image', 'image_id');
}
/**
diff --git a/app/helpers.php b/app/helpers.php
new file mode 100644
index 000000000..f25a8f765
--- /dev/null
+++ b/app/helpers.php
@@ -0,0 +1,30 @@
+=5.5.9",
"laravel/framework": "5.1.*",
"intervention/image": "^2.3",
- "laravel/socialite": "^2.0"
+ "laravel/socialite": "^2.0",
+ "barryvdh/laravel-ide-helper": "^2.1",
+ "barryvdh/laravel-debugbar": "^2.0",
+ "league/flysystem-aws-s3-v3": "^1.0"
},
"require-dev": {
"fzaninotto/faker": "~1.4",
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "~4.0",
- "phpspec/phpspec": "~2.1",
- "barryvdh/laravel-ide-helper": "^2.1",
- "barryvdh/laravel-debugbar": "^2.0"
+ "phpspec/phpspec": "~2.1"
},
"autoload": {
"classmap": [
@@ -24,7 +25,10 @@
],
"psr-4": {
"BookStack\\": "app/"
- }
+ },
+ "files": [
+ "app/helpers.php"
+ ]
},
"autoload-dev": {
"classmap": [
diff --git a/composer.lock b/composer.lock
index 485ee353c..23d2d50b6 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,9 +4,87 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "c216d0bcb72b4f2008d7fa8067da2f77",
- "content-hash": "3c421ae5b8e5c11792249142cb96ff25",
+ "hash": "19725116631f01881caafa33052eecb9",
+ "content-hash": "f1dbd776f0ae13ec99e4e6d99510cd8e",
"packages": [
+ {
+ "name": "aws/aws-sdk-php",
+ "version": "3.11.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/aws/aws-sdk-php.git",
+ "reference": "2524c78e0fa1ed049719b8b6b0696f0b6dfb1ca2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2524c78e0fa1ed049719b8b6b0696f0b6dfb1ca2",
+ "reference": "2524c78e0fa1ed049719b8b6b0696f0b6dfb1ca2",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/guzzle": "~5.3|~6.0.1|~6.1",
+ "guzzlehttp/promises": "~1.0",
+ "guzzlehttp/psr7": "~1.0",
+ "mtdowling/jmespath.php": "~2.2",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "andrewsville/php-token-reflection": "^1.4",
+ "aws/aws-php-sns-message-validator": "~1.0",
+ "behat/behat": "~3.0",
+ "doctrine/cache": "~1.4",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-openssl": "*",
+ "ext-pcre": "*",
+ "ext-simplexml": "*",
+ "ext-spl": "*",
+ "nette/neon": "^2.3",
+ "phpunit/phpunit": "~4.0"
+ },
+ "suggest": {
+ "doctrine/cache": "To use the DoctrineCacheAdapter",
+ "ext-curl": "To send requests using cURL",
+ "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Aws\\": "src/"
+ },
+ "files": [
+ "src/functions.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "Amazon Web Services",
+ "homepage": "http://aws.amazon.com"
+ }
+ ],
+ "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project",
+ "homepage": "http://aws.amazon.com/sdkforphp",
+ "keywords": [
+ "amazon",
+ "aws",
+ "cloud",
+ "dynamodb",
+ "ec2",
+ "glacier",
+ "s3",
+ "sdk"
+ ],
+ "time": "2015-12-04 01:19:53"
+ },
{
"name": "barryvdh/laravel-debugbar",
"version": "v2.0.6",
@@ -126,29 +204,29 @@
},
{
"name": "classpreloader/classpreloader",
- "version": "2.0.0",
+ "version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/ClassPreloader/ClassPreloader.git",
- "reference": "8c3c14b10309e3b40bce833913a6c0c0b8c8f962"
+ "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/8c3c14b10309e3b40bce833913a6c0c0b8c8f962",
- "reference": "8c3c14b10309e3b40bce833913a6c0c0b8c8f962",
+ "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/9b10b913c2bdf90c3d2e0d726b454fb7f77c552a",
+ "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a",
"shasum": ""
},
"require": {
- "nikic/php-parser": "~1.3",
+ "nikic/php-parser": "^1.0|^2.0",
"php": ">=5.5.9"
},
"require-dev": {
- "phpunit/phpunit": "~4.0"
+ "phpunit/phpunit": "^4.8|^5.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0-dev"
+ "dev-master": "3.0-dev"
}
},
"autoload": {
@@ -176,7 +254,7 @@
"class",
"preload"
],
- "time": "2015-06-28 21:39:13"
+ "time": "2015-11-09 22:51:51"
},
{
"name": "danielstjules/stringy",
@@ -269,16 +347,16 @@
},
{
"name": "doctrine/inflector",
- "version": "v1.0.1",
+ "version": "v1.1.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/inflector.git",
- "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604"
+ "reference": "90b2128806bfde671b6952ab8bea493942c1fdae"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/inflector/zipball/0bcb2e79d8571787f18b7eb036ed3d004908e604",
- "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604",
+ "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae",
+ "reference": "90b2128806bfde671b6952ab8bea493942c1fdae",
"shasum": ""
},
"require": {
@@ -290,7 +368,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "1.1.x-dev"
}
},
"autoload": {
@@ -332,7 +410,7 @@
"singularize",
"string"
],
- "time": "2014-12-20 21:24:13"
+ "time": "2015-11-06 14:35:42"
},
{
"name": "guzzle/guzzle",
@@ -431,16 +509,16 @@
},
{
"name": "guzzlehttp/guzzle",
- "version": "6.0.2",
+ "version": "6.1.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
- "reference": "a8dfeff00eb84616a17fea7a4d72af35e750410f"
+ "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a8dfeff00eb84616a17fea7a4d72af35e750410f",
- "reference": "a8dfeff00eb84616a17fea7a4d72af35e750410f",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/c6851d6e48f63b69357cbfa55bca116448140e0c",
+ "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c",
"shasum": ""
},
"require": {
@@ -456,7 +534,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "6.0-dev"
+ "dev-master": "6.1-dev"
}
},
"autoload": {
@@ -489,20 +567,20 @@
"rest",
"web service"
],
- "time": "2015-07-04 20:09:24"
+ "time": "2015-11-23 00:47:50"
},
{
"name": "guzzlehttp/promises",
- "version": "1.0.2",
+ "version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
- "reference": "97fe7210def29451ec74923b27e552238defd75a"
+ "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/promises/zipball/97fe7210def29451ec74923b27e552238defd75a",
- "reference": "97fe7210def29451ec74923b27e552238defd75a",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/b1e1c0d55f8083c71eda2c28c12a228d708294ea",
+ "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea",
"shasum": ""
},
"require": {
@@ -540,20 +618,20 @@
"keywords": [
"promise"
],
- "time": "2015-08-15 19:37:21"
+ "time": "2015-10-15 22:28:00"
},
{
"name": "guzzlehttp/psr7",
- "version": "1.2.0",
+ "version": "1.2.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
- "reference": "4ef919b0cf3b1989523138b60163bbcb7ba1ff7e"
+ "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/4ef919b0cf3b1989523138b60163bbcb7ba1ff7e",
- "reference": "4ef919b0cf3b1989523138b60163bbcb7ba1ff7e",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/4d0bdbe1206df7440219ce14c972aa57cc5e4982",
+ "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982",
"shasum": ""
},
"require": {
@@ -598,20 +676,20 @@
"stream",
"uri"
],
- "time": "2015-08-15 19:32:36"
+ "time": "2015-11-03 01:34:55"
},
{
"name": "intervention/image",
- "version": "2.3.1",
+ "version": "2.3.4",
"source": {
"type": "git",
"url": "https://github.com/Intervention/image.git",
- "reference": "156f9d6f8a186c68b92f0c50084718f02dae1b5f"
+ "reference": "a67ee32df0c6820cc6e861ad4144ee0ef9c74aa3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Intervention/image/zipball/156f9d6f8a186c68b92f0c50084718f02dae1b5f",
- "reference": "156f9d6f8a186c68b92f0c50084718f02dae1b5f",
+ "url": "https://api.github.com/repos/Intervention/image/zipball/a67ee32df0c6820cc6e861ad4144ee0ef9c74aa3",
+ "reference": "a67ee32df0c6820cc6e861ad4144ee0ef9c74aa3",
"shasum": ""
},
"require": {
@@ -660,7 +738,7 @@
"thumbnail",
"watermark"
],
- "time": "2015-07-10 15:03:58"
+ "time": "2015-11-30 17:03:21"
},
{
"name": "jakub-onderka/php-console-color",
@@ -809,20 +887,20 @@
},
{
"name": "laravel/framework",
- "version": "v5.1.10",
+ "version": "v5.1.25",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
- "reference": "d47ccc8de10ccb6f328cc90f901ca5e47e077c93"
+ "reference": "53979acc664debc401bfcb61086c4fc4f196b22d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/framework/zipball/d47ccc8de10ccb6f328cc90f901ca5e47e077c93",
- "reference": "d47ccc8de10ccb6f328cc90f901ca5e47e077c93",
+ "url": "https://api.github.com/repos/laravel/framework/zipball/53979acc664debc401bfcb61086c4fc4f196b22d",
+ "reference": "53979acc664debc401bfcb61086c4fc4f196b22d",
"shasum": ""
},
"require": {
- "classpreloader/classpreloader": "~2.0",
+ "classpreloader/classpreloader": "~2.0|~3.0",
"danielstjules/stringy": "~1.8",
"doctrine/inflector": "~1.0",
"ext-mbstring": "*",
@@ -832,8 +910,9 @@
"monolog/monolog": "~1.11",
"mtdowling/cron-expression": "~1.0",
"nesbot/carbon": "~1.19",
+ "paragonie/random_compat": "~1.1",
"php": ">=5.5.9",
- "psy/psysh": "~0.5.1",
+ "psy/psysh": "0.6.*",
"swiftmailer/swiftmailer": "~5.1",
"symfony/console": "2.7.*",
"symfony/css-selector": "2.7.*",
@@ -882,7 +961,7 @@
"require-dev": {
"aws/aws-sdk-php": "~3.0",
"iron-io/iron_mq": "~2.0",
- "mockery/mockery": "~0.9.1",
+ "mockery/mockery": "~0.9.2",
"pda/pheanstalk": "~3.0",
"phpunit/phpunit": "~4.0",
"predis/predis": "~1.0"
@@ -933,20 +1012,20 @@
"framework",
"laravel"
],
- "time": "2015-08-12 18:16:08"
+ "time": "2015-11-30 19:24:36"
},
{
"name": "laravel/socialite",
- "version": "v2.0.12",
+ "version": "v2.0.14",
"source": {
"type": "git",
"url": "https://github.com/laravel/socialite.git",
- "reference": "0bb08c8666f4c01e55e3b3b0e42f2b5075be6a6e"
+ "reference": "b15f4be0ac739405120d74b837af423aa71502d9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/socialite/zipball/0bb08c8666f4c01e55e3b3b0e42f2b5075be6a6e",
- "reference": "0bb08c8666f4c01e55e3b3b0e42f2b5075be6a6e",
+ "url": "https://api.github.com/repos/laravel/socialite/zipball/b15f4be0ac739405120d74b837af423aa71502d9",
+ "reference": "b15f4be0ac739405120d74b837af423aa71502d9",
"shasum": ""
},
"require": {
@@ -987,25 +1066,28 @@
"laravel",
"oauth"
],
- "time": "2015-08-30 01:12:56"
+ "time": "2015-10-16 15:39:46"
},
{
"name": "league/flysystem",
- "version": "1.0.11",
+ "version": "1.0.15",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
- "reference": "c16222fdc02467eaa12cb6d6d0e65527741f6040"
+ "reference": "31525caf9e8772683672fefd8a1ca0c0736020f4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/c16222fdc02467eaa12cb6d6d0e65527741f6040",
- "reference": "c16222fdc02467eaa12cb6d6d0e65527741f6040",
+ "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/31525caf9e8772683672fefd8a1ca0c0736020f4",
+ "reference": "31525caf9e8772683672fefd8a1ca0c0736020f4",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
+ "conflict": {
+ "league/flysystem-sftp": "<1.0.6"
+ },
"require-dev": {
"ext-fileinfo": "*",
"mockery/mockery": "~0.9",
@@ -1068,20 +1150,67 @@
"sftp",
"storage"
],
- "time": "2015-07-28 20:41:58"
+ "time": "2015-09-30 22:26:59"
},
{
- "name": "league/oauth1-client",
- "version": "1.6.0",
+ "name": "league/flysystem-aws-s3-v3",
+ "version": "1.0.9",
"source": {
"type": "git",
- "url": "https://github.com/thephpleague/oauth1-client.git",
- "reference": "4d4edd9b6014f882e319231a9b3351e3a1dfdc81"
+ "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git",
+ "reference": "595e24678bf78f8107ebc9355d8376ae0eb712c6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/4d4edd9b6014f882e319231a9b3351e3a1dfdc81",
- "reference": "4d4edd9b6014f882e319231a9b3351e3a1dfdc81",
+ "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/595e24678bf78f8107ebc9355d8376ae0eb712c6",
+ "reference": "595e24678bf78f8107ebc9355d8376ae0eb712c6",
+ "shasum": ""
+ },
+ "require": {
+ "aws/aws-sdk-php": "^3.0.0",
+ "league/flysystem": "~1.0",
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "henrikbjorn/phpspec-code-coverage": "~1.0.1",
+ "phpspec/phpspec": "^2.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "League\\Flysystem\\AwsS3v3\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Frank de Jonge",
+ "email": "info@frenky.net"
+ }
+ ],
+ "description": "Flysystem adapter for the AWS S3 SDK v3.x",
+ "time": "2015-11-19 08:44:16"
+ },
+ {
+ "name": "league/oauth1-client",
+ "version": "1.6.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thephpleague/oauth1-client.git",
+ "reference": "cef3ceda13c78f89c323e4d5e6301c0eb7cea422"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/cef3ceda13c78f89c323e4d5e6301c0eb7cea422",
+ "reference": "cef3ceda13c78f89c323e4d5e6301c0eb7cea422",
"shasum": ""
},
"require": {
@@ -1131,7 +1260,7 @@
"tumblr",
"twitter"
],
- "time": "2015-08-22 09:49:14"
+ "time": "2015-10-23 04:02:07"
},
{
"name": "maximebf/debugbar",
@@ -1191,16 +1320,16 @@
},
{
"name": "monolog/monolog",
- "version": "1.16.0",
+ "version": "1.17.2",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
- "reference": "c0c0b4bee3aabce7182876b0d912ef2595563db7"
+ "reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c0c0b4bee3aabce7182876b0d912ef2595563db7",
- "reference": "c0c0b4bee3aabce7182876b0d912ef2595563db7",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bee7f0dc9c3e0b69a6039697533dca1e845c8c24",
+ "reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24",
"shasum": ""
},
"require": {
@@ -1214,10 +1343,11 @@
"aws/aws-sdk-php": "^2.4.9",
"doctrine/couchdb": "~1.0@dev",
"graylog2/gelf-php": "~1.0",
+ "jakub-onderka/php-parallel-lint": "0.9",
"php-console/php-console": "^3.1.3",
"phpunit/phpunit": "~4.5",
"phpunit/phpunit-mock-objects": "2.3.0",
- "raven/raven": "~0.8",
+ "raven/raven": "^0.13",
"ruflin/elastica": ">=0.90 <3.0",
"swiftmailer/swiftmailer": "~5.3",
"videlalvaro/php-amqplib": "~2.4"
@@ -1263,7 +1393,7 @@
"logging",
"psr-3"
],
- "time": "2015-08-09 17:44:44"
+ "time": "2015-10-14 12:51:02"
},
{
"name": "mtdowling/cron-expression",
@@ -1310,17 +1440,72 @@
"time": "2015-01-11 23:07:46"
},
{
- "name": "nesbot/carbon",
- "version": "1.20.0",
+ "name": "mtdowling/jmespath.php",
+ "version": "2.2.0",
"source": {
"type": "git",
- "url": "https://github.com/briannesbitt/Carbon.git",
- "reference": "bfd3eaba109c9a2405c92174c8e17f20c2b9caf3"
+ "url": "https://github.com/jmespath/jmespath.php.git",
+ "reference": "a7d99d0c836e69d27b7bfca1d33ca2759fba3289"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bfd3eaba109c9a2405c92174c8e17f20c2b9caf3",
- "reference": "bfd3eaba109c9a2405c92174c8e17f20c2b9caf3",
+ "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/a7d99d0c836e69d27b7bfca1d33ca2759fba3289",
+ "reference": "a7d99d0c836e69d27b7bfca1d33ca2759fba3289",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "bin": [
+ "bin/jp.php"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "JmesPath\\": "src/"
+ },
+ "files": [
+ "src/JmesPath.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Declaratively specify how to extract elements from a JSON document",
+ "keywords": [
+ "json",
+ "jsonpath"
+ ],
+ "time": "2015-05-27 17:21:31"
+ },
+ {
+ "name": "nesbot/carbon",
+ "version": "1.21.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/briannesbitt/Carbon.git",
+ "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7b08ec6f75791e130012f206e3f7b0e76e18e3d7",
+ "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7",
"shasum": ""
},
"require": {
@@ -1328,12 +1513,12 @@
"symfony/translation": "~2.6|~3.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.0"
+ "phpunit/phpunit": "~4.0|~5.0"
},
"type": "library",
"autoload": {
- "psr-0": {
- "Carbon": "src"
+ "psr-4": {
+ "Carbon\\": "src/Carbon/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1354,20 +1539,20 @@
"datetime",
"time"
],
- "time": "2015-06-25 04:19:39"
+ "time": "2015-11-04 20:07:17"
},
{
"name": "nikic/php-parser",
- "version": "v1.4.0",
+ "version": "v1.4.1",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "196f177cfefa0f1f7166c0a05d8255889be12418"
+ "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/196f177cfefa0f1f7166c0a05d8255889be12418",
- "reference": "196f177cfefa0f1f7166c0a05d8255889be12418",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51",
+ "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51",
"shasum": ""
},
"require": {
@@ -1399,7 +1584,55 @@
"parser",
"php"
],
- "time": "2015-07-14 17:31:05"
+ "time": "2015-09-19 14:15:08"
+ },
+ {
+ "name": "paragonie/random_compat",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "a208865a5aeffc2dbbef2a5b3409887272d93f32"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/a208865a5aeffc2dbbef2a5b3409887272d93f32",
+ "reference": "a208865a5aeffc2dbbef2a5b3409887272d93f32",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "lib/random.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "pseudorandom",
+ "random"
+ ],
+ "time": "2015-12-01 02:52:15"
},
{
"name": "phpdocumentor/reflection-docblock",
@@ -1539,29 +1772,29 @@
},
{
"name": "psy/psysh",
- "version": "v0.5.2",
+ "version": "v0.6.1",
"source": {
"type": "git",
"url": "https://github.com/bobthecow/psysh.git",
- "reference": "aaf8772ade08b5f0f6830774a5d5c2f800415975"
+ "reference": "0f04df0b23663799a8941fae13cd8e6299bde3ed"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/bobthecow/psysh/zipball/aaf8772ade08b5f0f6830774a5d5c2f800415975",
- "reference": "aaf8772ade08b5f0f6830774a5d5c2f800415975",
+ "url": "https://api.github.com/repos/bobthecow/psysh/zipball/0f04df0b23663799a8941fae13cd8e6299bde3ed",
+ "reference": "0f04df0b23663799a8941fae13cd8e6299bde3ed",
"shasum": ""
},
"require": {
"dnoegel/php-xdg-base-dir": "0.1",
"jakub-onderka/php-console-highlighter": "0.3.*",
- "nikic/php-parser": "^1.2.1",
+ "nikic/php-parser": "^1.2.1|~2.0",
"php": ">=5.3.9",
"symfony/console": "~2.3.10|^2.4.2|~3.0",
"symfony/var-dumper": "~2.7|~3.0"
},
"require-dev": {
"fabpot/php-cs-fixer": "~1.5",
- "phpunit/phpunit": "~3.7|~4.0",
+ "phpunit/phpunit": "~3.7|~4.0|~5.0",
"squizlabs/php_codesniffer": "~2.0",
"symfony/finder": "~2.1|~3.0"
},
@@ -1577,15 +1810,15 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-develop": "0.6.x-dev"
+ "dev-develop": "0.7.x-dev"
}
},
"autoload": {
"files": [
"src/Psy/functions.php"
],
- "psr-0": {
- "Psy\\": "src/"
+ "psr-4": {
+ "Psy\\": "src/Psy/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1607,7 +1840,7 @@
"interactive",
"shell"
],
- "time": "2015-07-16 15:26:57"
+ "time": "2015-11-12 16:18:56"
},
{
"name": "swiftmailer/swiftmailer",
@@ -1664,35 +1897,37 @@
},
{
"name": "symfony/class-loader",
- "version": "v2.7.3",
+ "version": "v2.8.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/class-loader.git",
- "reference": "2fccbc544997340808801a7410cdcb96dd12edc4"
+ "reference": "51f83451bf0ddfc696e47e4642d6cd10fcfce160"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/class-loader/zipball/2fccbc544997340808801a7410cdcb96dd12edc4",
- "reference": "2fccbc544997340808801a7410cdcb96dd12edc4",
+ "url": "https://api.github.com/repos/symfony/class-loader/zipball/51f83451bf0ddfc696e47e4642d6cd10fcfce160",
+ "reference": "51f83451bf0ddfc696e47e4642d6cd10fcfce160",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"require-dev": {
- "symfony/finder": "~2.0,>=2.0.5",
- "symfony/phpunit-bridge": "~2.7"
+ "symfony/finder": "~2.0,>=2.0.5|~3.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.7-dev"
+ "dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\ClassLoader\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -1710,20 +1945,20 @@
],
"description": "Symfony ClassLoader Component",
"homepage": "https://symfony.com",
- "time": "2015-06-25 12:52:11"
+ "time": "2015-11-26 07:00:59"
},
{
"name": "symfony/console",
- "version": "v2.7.3",
+ "version": "v2.7.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e"
+ "reference": "16bb1cb86df43c90931df65f529e7ebd79636750"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/d6cf02fe73634c96677e428f840704bfbcaec29e",
- "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e",
+ "url": "https://api.github.com/repos/symfony/console/zipball/16bb1cb86df43c90931df65f529e7ebd79636750",
+ "reference": "16bb1cb86df43c90931df65f529e7ebd79636750",
"shasum": ""
},
"require": {
@@ -1732,7 +1967,6 @@
"require-dev": {
"psr/log": "~1.0",
"symfony/event-dispatcher": "~2.1",
- "symfony/phpunit-bridge": "~2.7",
"symfony/process": "~2.1"
},
"suggest": {
@@ -1749,7 +1983,10 @@
"autoload": {
"psr-4": {
"Symfony\\Component\\Console\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -1767,28 +2004,25 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2015-07-28 15:18:12"
+ "time": "2015-11-18 09:54:26"
},
{
"name": "symfony/css-selector",
- "version": "v2.7.3",
+ "version": "v2.7.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092"
+ "reference": "abb47717fb88aebd9437da2fc8bb01a50a36679f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/0b5c07b516226b7dd32afbbc82fe547a469c5092",
- "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/abb47717fb88aebd9437da2fc8bb01a50a36679f",
+ "reference": "abb47717fb88aebd9437da2fc8bb01a50a36679f",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7"
- },
"type": "library",
"extra": {
"branch-alias": {
@@ -1798,7 +2032,10 @@
"autoload": {
"psr-4": {
"Symfony\\Component\\CssSelector\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -1820,20 +2057,20 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "time": "2015-05-15 13:33:16"
+ "time": "2015-10-30 20:10:21"
},
{
"name": "symfony/debug",
- "version": "v2.7.3",
+ "version": "v2.7.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
- "reference": "9daa1bf9f7e615fa2fba30357e479a90141222e3"
+ "reference": "0dbc119596f4afc82d9b2eb2a7e6a4af1ee763fa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/9daa1bf9f7e615fa2fba30357e479a90141222e3",
- "reference": "9daa1bf9f7e615fa2fba30357e479a90141222e3",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/0dbc119596f4afc82d9b2eb2a7e6a4af1ee763fa",
+ "reference": "0dbc119596f4afc82d9b2eb2a7e6a4af1ee763fa",
"shasum": ""
},
"require": {
@@ -1845,13 +2082,7 @@
},
"require-dev": {
"symfony/class-loader": "~2.2",
- "symfony/http-foundation": "~2.1",
- "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2",
- "symfony/phpunit-bridge": "~2.7"
- },
- "suggest": {
- "symfony/http-foundation": "",
- "symfony/http-kernel": ""
+ "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2"
},
"type": "library",
"extra": {
@@ -1862,7 +2093,10 @@
"autoload": {
"psr-4": {
"Symfony\\Component\\Debug\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -1880,28 +2114,27 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
- "time": "2015-07-09 16:07:40"
+ "time": "2015-10-30 20:10:21"
},
{
"name": "symfony/dom-crawler",
- "version": "v2.7.3",
+ "version": "v2.7.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
- "reference": "9dabece63182e95c42b06967a0d929a5df78bc35"
+ "reference": "b33593cbfe1d81b50d48353f338aca76a08658d8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/9dabece63182e95c42b06967a0d929a5df78bc35",
- "reference": "9dabece63182e95c42b06967a0d929a5df78bc35",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b33593cbfe1d81b50d48353f338aca76a08658d8",
+ "reference": "b33593cbfe1d81b50d48353f338aca76a08658d8",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"require-dev": {
- "symfony/css-selector": "~2.3",
- "symfony/phpunit-bridge": "~2.7"
+ "symfony/css-selector": "~2.3"
},
"suggest": {
"symfony/css-selector": ""
@@ -1915,7 +2148,10 @@
"autoload": {
"psr-4": {
"Symfony\\Component\\DomCrawler\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -1933,20 +2169,20 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
- "time": "2015-07-09 16:07:40"
+ "time": "2015-11-02 20:20:53"
},
{
"name": "symfony/event-dispatcher",
- "version": "v2.7.3",
+ "version": "v2.8.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3"
+ "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9310b5f9a87ec2ea75d20fec0b0017c77c66dac3",
- "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5eb815363c0388e83247e7e9853e5dbc14999cc",
+ "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc",
"shasum": ""
},
"require": {
@@ -1954,11 +2190,10 @@
},
"require-dev": {
"psr/log": "~1.0",
- "symfony/config": "~2.0,>=2.0.5",
- "symfony/dependency-injection": "~2.6",
- "symfony/expression-language": "~2.6",
- "symfony/phpunit-bridge": "~2.7",
- "symfony/stopwatch": "~2.3"
+ "symfony/config": "~2.0,>=2.0.5|~3.0.0",
+ "symfony/dependency-injection": "~2.6|~3.0.0",
+ "symfony/expression-language": "~2.6|~3.0.0",
+ "symfony/stopwatch": "~2.3|~3.0.0"
},
"suggest": {
"symfony/dependency-injection": "",
@@ -1967,13 +2202,16 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.7-dev"
+ "dev-master": "2.8-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\EventDispatcher\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -1991,28 +2229,25 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2015-06-18 19:21:56"
+ "time": "2015-10-30 20:15:42"
},
{
"name": "symfony/finder",
- "version": "v2.7.3",
+ "version": "v2.7.7",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Finder.git",
- "reference": "ae0f363277485094edc04c9f3cbe595b183b78e4"
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "a06a0c0ff7db3736a50d530c908cca547bf13da9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Finder/zipball/ae0f363277485094edc04c9f3cbe595b183b78e4",
- "reference": "ae0f363277485094edc04c9f3cbe595b183b78e4",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/a06a0c0ff7db3736a50d530c908cca547bf13da9",
+ "reference": "a06a0c0ff7db3736a50d530c908cca547bf13da9",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7"
- },
"type": "library",
"extra": {
"branch-alias": {
@@ -2022,7 +2257,10 @@
"autoload": {
"psr-4": {
"Symfony\\Component\\Finder\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2040,28 +2278,27 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2015-07-09 16:07:40"
+ "time": "2015-10-30 20:10:21"
},
{
"name": "symfony/http-foundation",
- "version": "v2.7.3",
+ "version": "v2.7.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "863af6898081b34c65d42100c370b9f3c51b70ca"
+ "reference": "e83a3d105ddaf5a113e803c904fdec552d1f1c35"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/863af6898081b34c65d42100c370b9f3c51b70ca",
- "reference": "863af6898081b34c65d42100c370b9f3c51b70ca",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e83a3d105ddaf5a113e803c904fdec552d1f1c35",
+ "reference": "e83a3d105ddaf5a113e803c904fdec552d1f1c35",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"require-dev": {
- "symfony/expression-language": "~2.4",
- "symfony/phpunit-bridge": "~2.7"
+ "symfony/expression-language": "~2.4"
},
"type": "library",
"extra": {
@@ -2075,6 +2312,9 @@
},
"classmap": [
"Resources/stubs"
+ ],
+ "exclude-from-classmap": [
+ "/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -2093,20 +2333,20 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
- "time": "2015-07-22 10:11:00"
+ "time": "2015-11-20 17:41:18"
},
{
"name": "symfony/http-kernel",
- "version": "v2.7.3",
+ "version": "v2.7.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "405d3e7a59ff7a28ec469441326a0ac79065ea98"
+ "reference": "5570de31e8fbc03777a8c61eb24f9b626e5e5941"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/405d3e7a59ff7a28ec469441326a0ac79065ea98",
- "reference": "405d3e7a59ff7a28ec469441326a0ac79065ea98",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/5570de31e8fbc03777a8c61eb24f9b626e5e5941",
+ "reference": "5570de31e8fbc03777a8c61eb24f9b626e5e5941",
"shasum": ""
},
"require": {
@@ -2129,7 +2369,6 @@
"symfony/dom-crawler": "~2.0,>=2.0.5",
"symfony/expression-language": "~2.4",
"symfony/finder": "~2.0,>=2.0.5",
- "symfony/phpunit-bridge": "~2.7",
"symfony/process": "~2.0,>=2.0.5",
"symfony/routing": "~2.2",
"symfony/stopwatch": "~2.3",
@@ -2155,7 +2394,10 @@
"autoload": {
"psr-4": {
"Symfony\\Component\\HttpKernel\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2173,28 +2415,25 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
- "time": "2015-07-31 13:24:45"
+ "time": "2015-11-23 11:57:49"
},
{
"name": "symfony/process",
- "version": "v2.7.3",
+ "version": "v2.7.7",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Process.git",
- "reference": "48aeb0e48600321c272955132d7606ab0a49adb3"
+ "url": "https://github.com/symfony/process.git",
+ "reference": "f6290983c8725d0afa29bdc3e5295879de3e58f5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Process/zipball/48aeb0e48600321c272955132d7606ab0a49adb3",
- "reference": "48aeb0e48600321c272955132d7606ab0a49adb3",
+ "url": "https://api.github.com/repos/symfony/process/zipball/f6290983c8725d0afa29bdc3e5295879de3e58f5",
+ "reference": "f6290983c8725d0afa29bdc3e5295879de3e58f5",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7"
- },
"type": "library",
"extra": {
"branch-alias": {
@@ -2204,7 +2443,10 @@
"autoload": {
"psr-4": {
"Symfony\\Component\\Process\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2222,20 +2464,20 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2015-07-01 11:25:50"
+ "time": "2015-11-19 16:11:24"
},
{
"name": "symfony/routing",
- "version": "v2.7.3",
+ "version": "v2.7.7",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Routing.git",
- "reference": "ea9134f277162b02e5f80ac058b75a77637b0d26"
+ "url": "https://github.com/symfony/routing.git",
+ "reference": "7450f6196711b124fb8b04a12286d01a0401ddfe"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Routing/zipball/ea9134f277162b02e5f80ac058b75a77637b0d26",
- "reference": "ea9134f277162b02e5f80ac058b75a77637b0d26",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/7450f6196711b124fb8b04a12286d01a0401ddfe",
+ "reference": "7450f6196711b124fb8b04a12286d01a0401ddfe",
"shasum": ""
},
"require": {
@@ -2251,7 +2493,6 @@
"symfony/config": "~2.7",
"symfony/expression-language": "~2.4",
"symfony/http-foundation": "~2.3",
- "symfony/phpunit-bridge": "~2.7",
"symfony/yaml": "~2.0,>=2.0.5"
},
"suggest": {
@@ -2269,7 +2510,10 @@
"autoload": {
"psr-4": {
"Symfony\\Component\\Routing\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2293,20 +2537,20 @@
"uri",
"url"
],
- "time": "2015-07-09 16:07:40"
+ "time": "2015-11-18 13:41:01"
},
{
"name": "symfony/translation",
- "version": "v2.7.3",
+ "version": "v2.7.7",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Translation.git",
- "reference": "c8dc34cc936152c609cdd722af317e4239d10dd6"
+ "url": "https://github.com/symfony/translation.git",
+ "reference": "e4ecb9c3ba1304eaf24de15c2d7a428101c1982f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Translation/zipball/c8dc34cc936152c609cdd722af317e4239d10dd6",
- "reference": "c8dc34cc936152c609cdd722af317e4239d10dd6",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/e4ecb9c3ba1304eaf24de15c2d7a428101c1982f",
+ "reference": "e4ecb9c3ba1304eaf24de15c2d7a428101c1982f",
"shasum": ""
},
"require": {
@@ -2318,8 +2562,7 @@
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~2.7",
- "symfony/intl": "~2.3",
- "symfony/phpunit-bridge": "~2.7",
+ "symfony/intl": "~2.4",
"symfony/yaml": "~2.2"
},
"suggest": {
@@ -2336,7 +2579,10 @@
"autoload": {
"psr-4": {
"Symfony\\Component\\Translation\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2354,28 +2600,25 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
- "time": "2015-07-09 16:07:40"
+ "time": "2015-11-18 13:41:01"
},
{
"name": "symfony/var-dumper",
- "version": "v2.7.3",
+ "version": "v2.7.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "e8903ebba5eb019f5886ffce739ea9e3b7519579"
+ "reference": "72bcb27411780eaee9469729aace73c0d46fb2b8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e8903ebba5eb019f5886ffce739ea9e3b7519579",
- "reference": "e8903ebba5eb019f5886ffce739ea9e3b7519579",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/72bcb27411780eaee9469729aace73c0d46fb2b8",
+ "reference": "72bcb27411780eaee9469729aace73c0d46fb2b8",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7"
- },
"suggest": {
"ext-symfony_debug": ""
},
@@ -2391,7 +2634,10 @@
],
"psr-4": {
"Symfony\\Component\\VarDumper\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2413,7 +2659,7 @@
"debug",
"dump"
],
- "time": "2015-07-28 15:18:12"
+ "time": "2015-11-18 13:41:01"
},
{
"name": "vlucas/phpdotenv",
@@ -2715,36 +2961,36 @@
},
{
"name": "phpspec/phpspec",
- "version": "2.2.1",
+ "version": "2.4.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/phpspec.git",
- "reference": "e9a40577323e67f1de2e214abf32976a0352d8f8"
+ "reference": "1d3938e6d9ffb1bd4805ea8ddac62ea48767f358"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/phpspec/zipball/e9a40577323e67f1de2e214abf32976a0352d8f8",
- "reference": "e9a40577323e67f1de2e214abf32976a0352d8f8",
+ "url": "https://api.github.com/repos/phpspec/phpspec/zipball/1d3938e6d9ffb1bd4805ea8ddac62ea48767f358",
+ "reference": "1d3938e6d9ffb1bd4805ea8ddac62ea48767f358",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.1",
+ "ext-tokenizer": "*",
"php": ">=5.3.3",
"phpspec/php-diff": "~1.0.0",
"phpspec/prophecy": "~1.4",
"sebastian/exporter": "~1.0",
- "symfony/console": "~2.3",
- "symfony/event-dispatcher": "~2.1",
- "symfony/finder": "~2.1",
- "symfony/process": "~2.1",
- "symfony/yaml": "~2.1"
+ "symfony/console": "~2.3|~3.0",
+ "symfony/event-dispatcher": "~2.1|~3.0",
+ "symfony/finder": "~2.1|~3.0",
+ "symfony/process": "^2.6|~3.0",
+ "symfony/yaml": "~2.1|~3.0"
},
"require-dev": {
"behat/behat": "^3.0.11",
"bossa/phpspec2-expect": "~1.0",
"phpunit/phpunit": "~4.4",
- "symfony/filesystem": "~2.1",
- "symfony/process": "~2.1"
+ "symfony/filesystem": "~2.1|~3.0"
},
"suggest": {
"phpspec/nyan-formatters": "~1.0 – Adds Nyan formatters"
@@ -2789,7 +3035,7 @@
"testing",
"tests"
],
- "time": "2015-05-30 15:21:40"
+ "time": "2015-11-29 02:03:49"
},
{
"name": "phpspec/prophecy",
@@ -2853,16 +3099,16 @@
},
{
"name": "phpunit/php-code-coverage",
- "version": "2.2.2",
+ "version": "2.2.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c"
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2d7c03c0e4e080901b8f33b2897b0577be18a13c",
- "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
"shasum": ""
},
"require": {
@@ -2911,7 +3157,7 @@
"testing",
"xunit"
],
- "time": "2015-08-04 03:42:39"
+ "time": "2015-10-06 15:47:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -3044,16 +3290,16 @@
},
{
"name": "phpunit/php-token-stream",
- "version": "1.4.6",
+ "version": "1.4.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b"
+ "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3ab72c62e550370a6cd5dc873e1a04ab57562f5b",
- "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
+ "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
"shasum": ""
},
"require": {
@@ -3089,20 +3335,20 @@
"keywords": [
"tokenizer"
],
- "time": "2015-08-16 08:51:00"
+ "time": "2015-09-15 10:49:45"
},
{
"name": "phpunit/phpunit",
- "version": "4.8.4",
+ "version": "4.8.19",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "55bf1d6092b0e13a1f26bd5eaffeef3d8ad85ea7"
+ "reference": "b2caaf8947aba5e002d42126723e9d69795f32b4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/55bf1d6092b0e13a1f26bd5eaffeef3d8ad85ea7",
- "reference": "55bf1d6092b0e13a1f26bd5eaffeef3d8ad85ea7",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b2caaf8947aba5e002d42126723e9d69795f32b4",
+ "reference": "b2caaf8947aba5e002d42126723e9d69795f32b4",
"shasum": ""
},
"require": {
@@ -3161,24 +3407,24 @@
"testing",
"xunit"
],
- "time": "2015-08-15 04:21:23"
+ "time": "2015-11-30 08:18:59"
},
{
"name": "phpunit/phpunit-mock-objects",
- "version": "2.3.6",
+ "version": "2.3.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
- "reference": "18dfbcb81d05e2296c0bcddd4db96cade75e6f42"
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/18dfbcb81d05e2296c0bcddd4db96cade75e6f42",
- "reference": "18dfbcb81d05e2296c0bcddd4db96cade75e6f42",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
"shasum": ""
},
"require": {
- "doctrine/instantiator": "~1.0,>=1.0.2",
+ "doctrine/instantiator": "^1.0.2",
"php": ">=5.3.3",
"phpunit/php-text-template": "~1.2",
"sebastian/exporter": "~1.2"
@@ -3217,7 +3463,7 @@
"mock",
"xunit"
],
- "time": "2015-07-10 06:54:24"
+ "time": "2015-10-02 06:51:40"
},
{
"name": "sebastian/comparator",
@@ -3337,16 +3583,16 @@
},
{
"name": "sebastian/environment",
- "version": "1.3.2",
+ "version": "1.3.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
- "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44"
+ "reference": "6e7133793a8e5a5714a551a8324337374be209df"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44",
- "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e7133793a8e5a5714a551a8324337374be209df",
+ "reference": "6e7133793a8e5a5714a551a8324337374be209df",
"shasum": ""
},
"require": {
@@ -3383,7 +3629,7 @@
"environment",
"hhvm"
],
- "time": "2015-08-03 06:14:51"
+ "time": "2015-12-02 08:37:27"
},
{
"name": "sebastian/exporter",
@@ -3453,16 +3699,16 @@
},
{
"name": "sebastian/global-state",
- "version": "1.0.0",
+ "version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01"
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01",
- "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
"shasum": ""
},
"require": {
@@ -3500,7 +3746,7 @@
"keywords": [
"global state"
],
- "time": "2014-10-06 09:23:50"
+ "time": "2015-10-12 03:26:01"
},
{
"name": "sebastian/recursion-context",
@@ -3592,34 +3838,34 @@
},
{
"name": "symfony/yaml",
- "version": "v2.7.3",
+ "version": "v3.0.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Yaml.git",
- "reference": "71340e996171474a53f3d29111d046be4ad8a0ff"
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Yaml/zipball/71340e996171474a53f3d29111d046be4ad8a0ff",
- "reference": "71340e996171474a53f3d29111d046be4ad8a0ff",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002",
+ "reference": "177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002",
"shasum": ""
},
"require": {
- "php": ">=5.3.9"
- },
- "require-dev": {
- "symfony/phpunit-bridge": "~2.7"
+ "php": ">=5.5.9"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.7-dev"
+ "dev-master": "3.0-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
- }
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -3637,7 +3883,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2015-07-28 14:07:07"
+ "time": "2015-11-30 12:36:17"
}
],
"aliases": [],
diff --git a/config/app.php b/config/app.php
index aa7c0b561..b9c207632 100644
--- a/config/app.php
+++ b/config/app.php
@@ -13,7 +13,7 @@ return [
|
*/
- 'debug' => env('APP_DEBUG', false),
+ 'debug' => env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------
@@ -26,7 +26,7 @@ return [
|
*/
- 'url' => env('APP_URL', 'http://localhost'),
+ 'url' => env('APP_URL', 'http://localhost'),
/*
|--------------------------------------------------------------------------
@@ -39,7 +39,7 @@ return [
|
*/
- 'timezone' => 'UTC',
+ 'timezone' => 'UTC',
/*
|--------------------------------------------------------------------------
@@ -52,7 +52,7 @@ return [
|
*/
- 'locale' => 'en',
+ 'locale' => 'en',
/*
|--------------------------------------------------------------------------
@@ -78,9 +78,9 @@ return [
|
*/
- 'key' => env('APP_KEY', 'AbAZchsay4uBTU33RubBzLKw203yqSqr'),
+ 'key' => env('APP_KEY', 'AbAZchsay4uBTU33RubBzLKw203yqSqr'),
- 'cipher' => 'AES-256-CBC',
+ 'cipher' => 'AES-256-CBC',
/*
|--------------------------------------------------------------------------
@@ -95,7 +95,7 @@ return [
|
*/
- 'log' => 'single',
+ 'log' => 'single',
/*
|--------------------------------------------------------------------------
@@ -108,7 +108,7 @@ return [
|
*/
- 'providers' => [
+ 'providers' => [
/*
* Laravel Framework Service Providers...
@@ -167,7 +167,7 @@ return [
|
*/
- 'aliases' => [
+ 'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
@@ -208,15 +208,16 @@ return [
*/
'ImageTool' => Intervention\Image\Facades\Image::class,
- 'Debugbar' => Barryvdh\Debugbar\Facade::class,
+ 'Debugbar' => Barryvdh\Debugbar\Facade::class,
/**
* Custom
*/
- 'Activity' => BookStack\Services\Facades\Activity::class,
- 'Setting' => BookStack\Services\Facades\Setting::class,
- 'Views' => BookStack\Services\Facades\Views::class,
+ 'Activity' => BookStack\Services\Facades\Activity::class,
+ 'Setting' => BookStack\Services\Facades\Setting::class,
+ 'Views' => BookStack\Services\Facades\Views::class,
+ 'Images' => \BookStack\Services\Facades\Images::class,
],
diff --git a/config/filesystems.php b/config/filesystems.php
index 3fffcf0a2..5fd3df6df 100644
--- a/config/filesystems.php
+++ b/config/filesystems.php
@@ -45,7 +45,7 @@ return [
'local' => [
'driver' => 'local',
- 'root' => storage_path('app'),
+ 'root' => public_path(),
],
'ftp' => [
@@ -64,10 +64,10 @@ return [
's3' => [
'driver' => 's3',
- 'key' => 'your-key',
- 'secret' => 'your-secret',
- 'region' => 'your-region',
- 'bucket' => 'your-bucket',
+ 'key' => env('STORAGE_S3_KEY', 'your-key'),
+ 'secret' => env('STORAGE_S3_SECRET', 'your-secret'),
+ 'region' => env('STORAGE_S3_REGION', 'your-region'),
+ 'bucket' => env('STORAGE_S3_BUCKET', 'your-bucket'),
],
'rackspace' => [
diff --git a/database/migrations/2015_12_05_145049_fulltext_weighting.php b/database/migrations/2015_12_05_145049_fulltext_weighting.php
new file mode 100644
index 000000000..cef43f604
--- /dev/null
+++ b/database/migrations/2015_12_05_145049_fulltext_weighting.php
@@ -0,0 +1,37 @@
+dropIndex('name_search');
+ });
+ Schema::table('books', function(Blueprint $table) {
+ $table->dropIndex('name_search');
+ });
+ Schema::table('chapters', function(Blueprint $table) {
+ $table->dropIndex('name_search');
+ });
+ }
+}
diff --git a/database/migrations/2015_12_07_195238_add_image_upload_types.php b/database/migrations/2015_12_07_195238_add_image_upload_types.php
new file mode 100644
index 000000000..eed937611
--- /dev/null
+++ b/database/migrations/2015_12_07_195238_add_image_upload_types.php
@@ -0,0 +1,41 @@
+string('path', 400);
+ $table->string('type')->index();
+ });
+
+ Image::all()->each(function($image) {
+ $image->path = $image->url;
+ $image->type = 'gallery';
+ $image->save();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('images', function (Blueprint $table) {
+ $table->dropColumn('type');
+ $table->dropColumn('path');
+ });
+
+ }
+}
diff --git a/database/migrations/2015_12_09_195748_add_user_avatars.php b/database/migrations/2015_12_09_195748_add_user_avatars.php
new file mode 100644
index 000000000..47cb027fa
--- /dev/null
+++ b/database/migrations/2015_12_09_195748_add_user_avatars.php
@@ -0,0 +1,31 @@
+integer('image_id')->default(0);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('users', function (Blueprint $table) {
+ $table->dropColumn('image_id');
+ });
+ }
+}
diff --git a/database/seeds/DummyContentSeeder.php b/database/seeds/DummyContentSeeder.php
index d8ab91d22..d2ccc7960 100644
--- a/database/seeds/DummyContentSeeder.php
+++ b/database/seeds/DummyContentSeeder.php
@@ -23,7 +23,9 @@ class DummyContentSeeder extends Seeder
$pages = factory(\BookStack\Page::class, 10)->make(['created_by' => $user->id, 'updated_by' => $user->id, 'book_id' => $book->id]);
$chapter->pages()->saveMany($pages);
});
+ $pages = factory(\BookStack\Page::class, 3)->make(['created_by' => $user->id, 'updated_by' => $user->id]);
$book->chapters()->saveMany($chapters);
+ $book->pages()->saveMany($pages);
});
}
}
diff --git a/gulpfile.js b/gulpfile.js
index 621e665be..439618739 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -1,8 +1,26 @@
var elixir = require('laravel-elixir');
+// Custom extensions
+var gulp = require('gulp');
+var Task = elixir.Task;
+var fs = require('fs');
+
+elixir.extend('queryVersion', function(inputFiles) {
+ new Task('queryVersion', function() {
+ var manifestObject = {};
+ var uidString = Date.now().toString(16).slice(4);
+ for (var i = 0; i < inputFiles.length; i++) {
+ var file = inputFiles[i];
+ manifestObject[file] = file + '?version=' + uidString;
+ }
+ var fileContents = JSON.stringify(manifestObject, null, 1);
+ fs.writeFileSync('public/build/manifest.json', fileContents);
+ }).watch(['./public/css/*.css', './public/js/*.js']);
+});
+
elixir(function(mix) {
mix.sass('styles.scss')
.sass('print-styles.scss')
.browserify(['jquery-extensions.js', 'global.js'], 'public/js/common.js')
- .version(['css/styles.css', 'css/print-styles.css', 'js/common.js']);
+ .queryVersion(['css/styles.css', 'css/print-styles.css', 'js/common.js']);
});
diff --git a/package.json b/package.json
index af2cbae58..e33ad170e 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"private": true,
"devDependencies": {
- "gulp": "^3.8.8",
+ "gulp": "^3.9.0",
"insert-css": "^0.2.0"
},
"dependencies": {
diff --git a/phpunit.xml b/phpunit.xml
index 0884937af..d86aacd00 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -26,5 +26,6 @@