Showing
60 changed files
with
1671 additions
and
535 deletions
| ... | @@ -14,14 +14,28 @@ CACHE_DRIVER=file | ... | @@ -14,14 +14,28 @@ CACHE_DRIVER=file |
| 14 | SESSION_DRIVER=file | 14 | SESSION_DRIVER=file |
| 15 | QUEUE_DRIVER=sync | 15 | QUEUE_DRIVER=sync |
| 16 | 16 | ||
| 17 | +# Storage | ||
| 18 | +STORAGE_TYPE=local | ||
| 19 | +# Amazon S3 Config | ||
| 20 | +STORAGE_S3_KEY=false | ||
| 21 | +STORAGE_S3_SECRET=false | ||
| 22 | +STORAGE_S3_REGION=false | ||
| 23 | +STORAGE_S3_BUCKET=false | ||
| 24 | +# Storage URL | ||
| 25 | +# Used to prefix image urls for when using custom domains/cdns | ||
| 26 | +STORAGE_URL=false | ||
| 27 | + | ||
| 17 | # Social Authentication information. Defaults as off. | 28 | # Social Authentication information. Defaults as off. |
| 18 | GITHUB_APP_ID=false | 29 | GITHUB_APP_ID=false |
| 19 | GITHUB_APP_SECRET=false | 30 | GITHUB_APP_SECRET=false |
| 20 | GOOGLE_APP_ID=false | 31 | GOOGLE_APP_ID=false |
| 21 | GOOGLE_APP_SECRET=false | 32 | GOOGLE_APP_SECRET=false |
| 22 | -# URL for social login redirects, NO TRAILING SLASH | 33 | +# URL used for social login redirects, NO TRAILING SLASH |
| 23 | APP_URL=http://bookstack.dev | 34 | APP_URL=http://bookstack.dev |
| 24 | 35 | ||
| 36 | +# External services | ||
| 37 | +USE_GRAVATAR=true | ||
| 38 | + | ||
| 25 | # Mail settings | 39 | # Mail settings |
| 26 | MAIL_DRIVER=smtp | 40 | MAIL_DRIVER=smtp |
| 27 | MAIL_HOST=localhost | 41 | MAIL_HOST=localhost | ... | ... |
| ... | @@ -7,23 +7,7 @@ use Illuminate\Database\Eloquent\Model; | ... | @@ -7,23 +7,7 @@ use Illuminate\Database\Eloquent\Model; |
| 7 | abstract class Entity extends Model | 7 | abstract class Entity extends Model |
| 8 | { | 8 | { |
| 9 | 9 | ||
| 10 | - /** | 10 | + use Ownable; |
| 11 | - * Relation for the user that created this entity. | ||
| 12 | - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||
| 13 | - */ | ||
| 14 | - public function createdBy() | ||
| 15 | - { | ||
| 16 | - return $this->belongsTo('BookStack\User', 'created_by'); | ||
| 17 | - } | ||
| 18 | - | ||
| 19 | - /** | ||
| 20 | - * Relation for the user that updated this entity. | ||
| 21 | - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||
| 22 | - */ | ||
| 23 | - public function updatedBy() | ||
| 24 | - { | ||
| 25 | - return $this->belongsTo('BookStack\User', 'updated_by'); | ||
| 26 | - } | ||
| 27 | 11 | ||
| 28 | /** | 12 | /** |
| 29 | * Compares this entity to another given entity. | 13 | * Compares this entity to another given entity. |
| ... | @@ -97,19 +81,30 @@ abstract class Entity extends Model | ... | @@ -97,19 +81,30 @@ abstract class Entity extends Model |
| 97 | */ | 81 | */ |
| 98 | public static function isA($type) | 82 | public static function isA($type) |
| 99 | { | 83 | { |
| 100 | - return static::getName() === strtolower($type); | 84 | + return static::getClassName() === strtolower($type); |
| 101 | } | 85 | } |
| 102 | 86 | ||
| 103 | /** | 87 | /** |
| 104 | * Gets the class name. | 88 | * Gets the class name. |
| 105 | * @return string | 89 | * @return string |
| 106 | */ | 90 | */ |
| 107 | - public static function getName() | 91 | + public static function getClassName() |
| 108 | { | 92 | { |
| 109 | return strtolower(array_slice(explode('\\', static::class), -1, 1)[0]); | 93 | return strtolower(array_slice(explode('\\', static::class), -1, 1)[0]); |
| 110 | } | 94 | } |
| 111 | 95 | ||
| 112 | /** | 96 | /** |
| 97 | + *Gets a limited-length version of the entities name. | ||
| 98 | + * @param int $length | ||
| 99 | + * @return string | ||
| 100 | + */ | ||
| 101 | + public function getShortName($length = 25) | ||
| 102 | + { | ||
| 103 | + if(strlen($this->name) <= $length) return $this->name; | ||
| 104 | + return substr($this->name, 0, $length-3) . '...'; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + /** | ||
| 113 | * Perform a full-text search on this entity. | 108 | * Perform a full-text search on this entity. |
| 114 | * @param string[] $fieldsToSearch | 109 | * @param string[] $fieldsToSearch |
| 115 | * @param string[] $terms | 110 | * @param string[] $terms |
| ... | @@ -123,20 +118,20 @@ abstract class Entity extends Model | ... | @@ -123,20 +118,20 @@ abstract class Entity extends Model |
| 123 | $termString .= $term . '* '; | 118 | $termString .= $term . '* '; |
| 124 | } | 119 | } |
| 125 | $fields = implode(',', $fieldsToSearch); | 120 | $fields = implode(',', $fieldsToSearch); |
| 126 | - $search = static::whereRaw('MATCH(' . $fields . ') AGAINST(? IN BOOLEAN MODE)', [$termString]); | 121 | + $termStringEscaped = \DB::connection()->getPdo()->quote($termString); |
| 122 | + $search = static::addSelect(\DB::raw('*, MATCH(name) AGAINST('.$termStringEscaped.' IN BOOLEAN MODE) AS title_relevance')); | ||
| 123 | + $search = $search->whereRaw('MATCH(' . $fields . ') AGAINST(? IN BOOLEAN MODE)', [$termString]); | ||
| 124 | + | ||
| 125 | + // Add additional where terms | ||
| 127 | foreach ($wheres as $whereTerm) { | 126 | foreach ($wheres as $whereTerm) { |
| 128 | $search->where($whereTerm[0], $whereTerm[1], $whereTerm[2]); | 127 | $search->where($whereTerm[0], $whereTerm[1], $whereTerm[2]); |
| 129 | } | 128 | } |
| 130 | 129 | ||
| 131 | - if (!static::isA('book')) { | 130 | + // Load in relations |
| 132 | - $search = $search->with('book'); | 131 | + if (!static::isA('book')) $search = $search->with('book'); |
| 133 | - } | 132 | + if (static::isA('page')) $search = $search->with('chapter'); |
| 134 | - | ||
| 135 | - if (static::isA('page')) { | ||
| 136 | - $search = $search->with('chapter'); | ||
| 137 | - } | ||
| 138 | 133 | ||
| 139 | - return $search->get(); | 134 | + return $search->orderBy('title_relevance', 'desc')->get(); |
| 140 | } | 135 | } |
| 141 | 136 | ||
| 142 | /** | 137 | /** | ... | ... |
| ... | @@ -42,8 +42,10 @@ class BookController extends Controller | ... | @@ -42,8 +42,10 @@ class BookController extends Controller |
| 42 | public function index() | 42 | public function index() |
| 43 | { | 43 | { |
| 44 | $books = $this->bookRepo->getAllPaginated(10); | 44 | $books = $this->bookRepo->getAllPaginated(10); |
| 45 | - $recents = $this->signedIn ? $this->bookRepo->getRecentlyViewed(10, 0) : false; | 45 | + $recents = $this->signedIn ? $this->bookRepo->getRecentlyViewed(4, 0) : false; |
| 46 | - return view('books/index', ['books' => $books, 'recents' => $recents]); | 46 | + $popular = $this->bookRepo->getPopular(4, 0); |
| 47 | + $this->setPageTitle('Books'); | ||
| 48 | + return view('books/index', ['books' => $books, 'recents' => $recents, 'popular' => $popular]); | ||
| 47 | } | 49 | } |
| 48 | 50 | ||
| 49 | /** | 51 | /** |
| ... | @@ -54,6 +56,7 @@ class BookController extends Controller | ... | @@ -54,6 +56,7 @@ class BookController extends Controller |
| 54 | public function create() | 56 | public function create() |
| 55 | { | 57 | { |
| 56 | $this->checkPermission('book-create'); | 58 | $this->checkPermission('book-create'); |
| 59 | + $this->setPageTitle('Create New Book'); | ||
| 57 | return view('books/create'); | 60 | return view('books/create'); |
| 58 | } | 61 | } |
| 59 | 62 | ||
| ... | @@ -88,8 +91,9 @@ class BookController extends Controller | ... | @@ -88,8 +91,9 @@ class BookController extends Controller |
| 88 | public function show($slug) | 91 | public function show($slug) |
| 89 | { | 92 | { |
| 90 | $book = $this->bookRepo->getBySlug($slug); | 93 | $book = $this->bookRepo->getBySlug($slug); |
| 91 | - Views::add($book); | ||
| 92 | $bookChildren = $this->bookRepo->getChildren($book); | 94 | $bookChildren = $this->bookRepo->getChildren($book); |
| 95 | + Views::add($book); | ||
| 96 | + $this->setPageTitle($book->getShortName()); | ||
| 93 | return view('books/show', ['book' => $book, 'current' => $book, 'bookChildren' => $bookChildren]); | 97 | return view('books/show', ['book' => $book, 'current' => $book, 'bookChildren' => $bookChildren]); |
| 94 | } | 98 | } |
| 95 | 99 | ||
| ... | @@ -103,6 +107,7 @@ class BookController extends Controller | ... | @@ -103,6 +107,7 @@ class BookController extends Controller |
| 103 | { | 107 | { |
| 104 | $this->checkPermission('book-update'); | 108 | $this->checkPermission('book-update'); |
| 105 | $book = $this->bookRepo->getBySlug($slug); | 109 | $book = $this->bookRepo->getBySlug($slug); |
| 110 | + $this->setPageTitle('Edit Book ' . $book->getShortName()); | ||
| 106 | return view('books/edit', ['book' => $book, 'current' => $book]); | 111 | return view('books/edit', ['book' => $book, 'current' => $book]); |
| 107 | } | 112 | } |
| 108 | 113 | ||
| ... | @@ -138,6 +143,7 @@ class BookController extends Controller | ... | @@ -138,6 +143,7 @@ class BookController extends Controller |
| 138 | { | 143 | { |
| 139 | $this->checkPermission('book-delete'); | 144 | $this->checkPermission('book-delete'); |
| 140 | $book = $this->bookRepo->getBySlug($bookSlug); | 145 | $book = $this->bookRepo->getBySlug($bookSlug); |
| 146 | + $this->setPageTitle('Delete Book ' . $book->getShortName()); | ||
| 141 | return view('books/delete', ['book' => $book, 'current' => $book]); | 147 | return view('books/delete', ['book' => $book, 'current' => $book]); |
| 142 | } | 148 | } |
| 143 | 149 | ||
| ... | @@ -152,9 +158,16 @@ class BookController extends Controller | ... | @@ -152,9 +158,16 @@ class BookController extends Controller |
| 152 | $book = $this->bookRepo->getBySlug($bookSlug); | 158 | $book = $this->bookRepo->getBySlug($bookSlug); |
| 153 | $bookChildren = $this->bookRepo->getChildren($book); | 159 | $bookChildren = $this->bookRepo->getChildren($book); |
| 154 | $books = $this->bookRepo->getAll(); | 160 | $books = $this->bookRepo->getAll(); |
| 161 | + $this->setPageTitle('Sort Book ' . $book->getShortName()); | ||
| 155 | return view('books/sort', ['book' => $book, 'current' => $book, 'books' => $books, 'bookChildren' => $bookChildren]); | 162 | return view('books/sort', ['book' => $book, 'current' => $book, 'books' => $books, 'bookChildren' => $bookChildren]); |
| 156 | } | 163 | } |
| 157 | 164 | ||
| 165 | + /** | ||
| 166 | + * Shows the sort box for a single book. | ||
| 167 | + * Used via AJAX when loading in extra books to a sort. | ||
| 168 | + * @param $bookSlug | ||
| 169 | + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View | ||
| 170 | + */ | ||
| 158 | public function getSortItem($bookSlug) | 171 | public function getSortItem($bookSlug) |
| 159 | { | 172 | { |
| 160 | $book = $this->bookRepo->getBySlug($bookSlug); | 173 | $book = $this->bookRepo->getBySlug($bookSlug); | ... | ... |
| ... | @@ -40,6 +40,7 @@ class ChapterController extends Controller | ... | @@ -40,6 +40,7 @@ class ChapterController extends Controller |
| 40 | { | 40 | { |
| 41 | $this->checkPermission('chapter-create'); | 41 | $this->checkPermission('chapter-create'); |
| 42 | $book = $this->bookRepo->getBySlug($bookSlug); | 42 | $book = $this->bookRepo->getBySlug($bookSlug); |
| 43 | + $this->setPageTitle('Create New Chapter'); | ||
| 43 | return view('chapters/create', ['book' => $book, 'current' => $book]); | 44 | return view('chapters/create', ['book' => $book, 'current' => $book]); |
| 44 | } | 45 | } |
| 45 | 46 | ||
| ... | @@ -79,6 +80,7 @@ class ChapterController extends Controller | ... | @@ -79,6 +80,7 @@ class ChapterController extends Controller |
| 79 | $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); | 80 | $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); |
| 80 | $sidebarTree = $this->bookRepo->getChildren($book); | 81 | $sidebarTree = $this->bookRepo->getChildren($book); |
| 81 | Views::add($chapter); | 82 | Views::add($chapter); |
| 83 | + $this->setPageTitle($chapter->getShortName()); | ||
| 82 | return view('chapters/show', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter, 'sidebarTree' => $sidebarTree]); | 84 | return view('chapters/show', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter, 'sidebarTree' => $sidebarTree]); |
| 83 | } | 85 | } |
| 84 | 86 | ||
| ... | @@ -93,6 +95,7 @@ class ChapterController extends Controller | ... | @@ -93,6 +95,7 @@ class ChapterController extends Controller |
| 93 | $this->checkPermission('chapter-update'); | 95 | $this->checkPermission('chapter-update'); |
| 94 | $book = $this->bookRepo->getBySlug($bookSlug); | 96 | $book = $this->bookRepo->getBySlug($bookSlug); |
| 95 | $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); | 97 | $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); |
| 98 | + $this->setPageTitle('Edit Chapter' . $chapter->getShortName()); | ||
| 96 | return view('chapters/edit', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]); | 99 | return view('chapters/edit', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]); |
| 97 | } | 100 | } |
| 98 | 101 | ||
| ... | @@ -127,6 +130,7 @@ class ChapterController extends Controller | ... | @@ -127,6 +130,7 @@ class ChapterController extends Controller |
| 127 | $this->checkPermission('chapter-delete'); | 130 | $this->checkPermission('chapter-delete'); |
| 128 | $book = $this->bookRepo->getBySlug($bookSlug); | 131 | $book = $this->bookRepo->getBySlug($bookSlug); |
| 129 | $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); | 132 | $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); |
| 133 | + $this->setPageTitle('Delete Chapter' . $chapter->getShortName()); | ||
| 130 | return view('chapters/delete', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]); | 134 | return view('chapters/delete', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]); |
| 131 | } | 135 | } |
| 132 | 136 | ... | ... |
| ... | @@ -43,6 +43,15 @@ abstract class Controller extends BaseController | ... | @@ -43,6 +43,15 @@ abstract class Controller extends BaseController |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | /** | 45 | /** |
| 46 | + * Adds the page title into the view. | ||
| 47 | + * @param $title | ||
| 48 | + */ | ||
| 49 | + public function setPageTitle($title) | ||
| 50 | + { | ||
| 51 | + view()->share('pageTitle', $title); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + /** | ||
| 46 | * Checks for a permission. | 55 | * Checks for a permission. |
| 47 | * | 56 | * |
| 48 | * @param $permissionName | 57 | * @param $permissionName | ... | ... |
| ... | @@ -2,6 +2,7 @@ | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | ||
| 3 | namespace BookStack\Http\Controllers; | 3 | namespace BookStack\Http\Controllers; |
| 4 | 4 | ||
| 5 | +use BookStack\Repos\ImageRepo; | ||
| 5 | use Illuminate\Filesystem\Filesystem as File; | 6 | use Illuminate\Filesystem\Filesystem as File; |
| 6 | use Illuminate\Http\Request; | 7 | use Illuminate\Http\Request; |
| 7 | use Illuminate\Support\Facades\Auth; | 8 | use Illuminate\Support\Facades\Auth; |
| ... | @@ -14,125 +15,78 @@ class ImageController extends Controller | ... | @@ -14,125 +15,78 @@ class ImageController extends Controller |
| 14 | { | 15 | { |
| 15 | protected $image; | 16 | protected $image; |
| 16 | protected $file; | 17 | protected $file; |
| 18 | + protected $imageRepo; | ||
| 17 | 19 | ||
| 18 | /** | 20 | /** |
| 19 | * ImageController constructor. | 21 | * ImageController constructor. |
| 20 | - * @param Image $image | 22 | + * @param Image $image |
| 21 | - * @param File $file | 23 | + * @param File $file |
| 24 | + * @param ImageRepo $imageRepo | ||
| 22 | */ | 25 | */ |
| 23 | - public function __construct(Image $image, File $file) | 26 | + public function __construct(Image $image, File $file, ImageRepo $imageRepo) |
| 24 | { | 27 | { |
| 25 | $this->image = $image; | 28 | $this->image = $image; |
| 26 | $this->file = $file; | 29 | $this->file = $file; |
| 30 | + $this->imageRepo = $imageRepo; | ||
| 27 | parent::__construct(); | 31 | parent::__construct(); |
| 28 | } | 32 | } |
| 29 | 33 | ||
| 30 | 34 | ||
| 31 | /** | 35 | /** |
| 32 | - * Get all images, Paginated | 36 | + * Get all images for a specific type, Paginated |
| 33 | * @param int $page | 37 | * @param int $page |
| 34 | * @return \Illuminate\Http\JsonResponse | 38 | * @return \Illuminate\Http\JsonResponse |
| 35 | */ | 39 | */ |
| 36 | - public function getAll($page = 0) | 40 | + public function getAllByType($type, $page = 0) |
| 37 | { | 41 | { |
| 38 | - $pageSize = 30; | 42 | + $imgData = $this->imageRepo->getPaginatedByType($type, $page); |
| 39 | - $images = $this->image->orderBy('created_at', 'desc') | 43 | + return response()->json($imgData); |
| 40 | - ->skip($page * $pageSize)->take($pageSize)->get(); | ||
| 41 | - foreach ($images as $image) { | ||
| 42 | - $this->loadSizes($image); | ||
| 43 | - } | ||
| 44 | - $hasMore = $this->image->orderBy('created_at', 'desc') | ||
| 45 | - ->skip(($page + 1) * $pageSize)->take($pageSize)->count() > 0; | ||
| 46 | - return response()->json([ | ||
| 47 | - 'images' => $images, | ||
| 48 | - 'hasMore' => $hasMore | ||
| 49 | - ]); | ||
| 50 | } | 44 | } |
| 51 | 45 | ||
| 52 | /** | 46 | /** |
| 53 | - * Loads the standard thumbnail sizes for an image. | 47 | + * Get all images for a user. |
| 54 | - * @param Image $image | 48 | + * @param int $page |
| 49 | + * @return \Illuminate\Http\JsonResponse | ||
| 55 | */ | 50 | */ |
| 56 | - private function loadSizes(Image $image) | 51 | + public function getAllForUserType($page = 0) |
| 57 | { | 52 | { |
| 58 | - $image->thumbnail = $this->getThumbnail($image, 150, 150); | 53 | + $imgData = $this->imageRepo->getPaginatedByType('user', $page, 24, $this->currentUser->id); |
| 59 | - $image->display = $this->getThumbnail($image, 840, 0, true); | 54 | + return response()->json($imgData); |
| 60 | } | 55 | } |
| 61 | 56 | ||
| 62 | - /** | ||
| 63 | - * Get the thumbnail for an image. | ||
| 64 | - * If $keepRatio is true only the width will be used. | ||
| 65 | - * @param $image | ||
| 66 | - * @param int $width | ||
| 67 | - * @param int $height | ||
| 68 | - * @param bool $keepRatio | ||
| 69 | - * @return string | ||
| 70 | - */ | ||
| 71 | - public function getThumbnail($image, $width = 220, $height = 220, $keepRatio = false) | ||
| 72 | - { | ||
| 73 | - $explodedPath = explode('/', $image->url); | ||
| 74 | - $dirPrefix = $keepRatio ? 'scaled-' : 'thumbs-'; | ||
| 75 | - array_splice($explodedPath, 4, 0, [$dirPrefix . $width . '-' . $height]); | ||
| 76 | - $thumbPath = implode('/', $explodedPath); | ||
| 77 | - $thumbFilePath = public_path() . $thumbPath; | ||
| 78 | - | ||
| 79 | - // Return the thumbnail url path if already exists | ||
| 80 | - if (file_exists($thumbFilePath)) { | ||
| 81 | - return $thumbPath; | ||
| 82 | - } | ||
| 83 | - | ||
| 84 | - // Otherwise create the thumbnail | ||
| 85 | - $thumb = ImageTool::make(public_path() . $image->url); | ||
| 86 | - if($keepRatio) { | ||
| 87 | - $thumb->resize($width, null, function ($constraint) { | ||
| 88 | - $constraint->aspectRatio(); | ||
| 89 | - $constraint->upsize(); | ||
| 90 | - }); | ||
| 91 | - } else { | ||
| 92 | - $thumb->fit($width, $height); | ||
| 93 | - } | ||
| 94 | - | ||
| 95 | - // Create thumbnail folder if it does not exist | ||
| 96 | - if (!file_exists(dirname($thumbFilePath))) { | ||
| 97 | - mkdir(dirname($thumbFilePath), 0775, true); | ||
| 98 | - } | ||
| 99 | - | ||
| 100 | - //Save Thumbnail | ||
| 101 | - $thumb->save($thumbFilePath); | ||
| 102 | - return $thumbPath; | ||
| 103 | - } | ||
| 104 | 57 | ||
| 105 | /** | 58 | /** |
| 106 | * Handles image uploads for use on pages. | 59 | * Handles image uploads for use on pages. |
| 60 | + * @param string $type | ||
| 107 | * @param Request $request | 61 | * @param Request $request |
| 108 | * @return \Illuminate\Http\JsonResponse | 62 | * @return \Illuminate\Http\JsonResponse |
| 109 | */ | 63 | */ |
| 110 | - public function upload(Request $request) | 64 | + public function uploadByType($type, Request $request) |
| 111 | { | 65 | { |
| 112 | $this->checkPermission('image-create'); | 66 | $this->checkPermission('image-create'); |
| 113 | $this->validate($request, [ | 67 | $this->validate($request, [ |
| 114 | 'file' => 'image|mimes:jpeg,gif,png' | 68 | 'file' => 'image|mimes:jpeg,gif,png' |
| 115 | ]); | 69 | ]); |
| 70 | + | ||
| 116 | $imageUpload = $request->file('file'); | 71 | $imageUpload = $request->file('file'); |
| 72 | + $image = $this->imageRepo->saveNew($imageUpload, $type); | ||
| 73 | + return response()->json($image); | ||
| 74 | + } | ||
| 117 | 75 | ||
| 118 | - $name = str_replace(' ', '-', $imageUpload->getClientOriginalName()); | 76 | + /** |
| 119 | - $storageName = substr(sha1(time()), 0, 10) . '-' . $name; | 77 | + * Generate a sized thumbnail for an image. |
| 120 | - $imagePath = '/uploads/images/' . Date('Y-m-M') . '/'; | 78 | + * @param $id |
| 121 | - $storagePath = public_path() . $imagePath; | 79 | + * @param $width |
| 122 | - $fullPath = $storagePath . $storageName; | 80 | + * @param $height |
| 123 | - while (file_exists($fullPath)) { | 81 | + * @param $crop |
| 124 | - $storageName = substr(sha1(rand()), 0, 3) . $storageName; | 82 | + * @return \Illuminate\Http\JsonResponse |
| 125 | - $fullPath = $storagePath . $storageName; | 83 | + */ |
| 126 | - } | 84 | + public function getThumbnail($id, $width, $height, $crop) |
| 127 | - $imageUpload->move($storagePath, $storageName); | 85 | + { |
| 128 | - // Create and save image object | 86 | + $this->checkPermission('image-create'); |
| 129 | - $this->image->name = $name; | 87 | + $image = $this->imageRepo->getById($id); |
| 130 | - $this->image->url = $imagePath . $storageName; | 88 | + $thumbnailUrl = $this->imageRepo->getThumbnail($image, $width, $height, $crop == 'false'); |
| 131 | - $this->image->created_by = auth()->user()->id; | 89 | + return response()->json(['url' => $thumbnailUrl]); |
| 132 | - $this->image->updated_by = auth()->user()->id; | ||
| 133 | - $this->image->save(); | ||
| 134 | - $this->loadSizes($this->image); | ||
| 135 | - return response()->json($this->image); | ||
| 136 | } | 90 | } |
| 137 | 91 | ||
| 138 | /** | 92 | /** |
| ... | @@ -147,13 +101,12 @@ class ImageController extends Controller | ... | @@ -147,13 +101,12 @@ class ImageController extends Controller |
| 147 | $this->validate($request, [ | 101 | $this->validate($request, [ |
| 148 | 'name' => 'required|min:2|string' | 102 | 'name' => 'required|min:2|string' |
| 149 | ]); | 103 | ]); |
| 150 | - $image = $this->image->findOrFail($imageId); | 104 | + $image = $this->imageRepo->getById($imageId); |
| 151 | - $image->fill($request->all()); | 105 | + $image = $this->imageRepo->updateImageDetails($image, $request->all()); |
| 152 | - $image->save(); | 106 | + return response()->json($image); |
| 153 | - $this->loadSizes($image); | ||
| 154 | - return response()->json($this->image); | ||
| 155 | } | 107 | } |
| 156 | 108 | ||
| 109 | + | ||
| 157 | /** | 110 | /** |
| 158 | * Deletes an image and all thumbnail/image files | 111 | * Deletes an image and all thumbnail/image files |
| 159 | * @param PageRepo $pageRepo | 112 | * @param PageRepo $pageRepo |
| ... | @@ -164,41 +117,18 @@ class ImageController extends Controller | ... | @@ -164,41 +117,18 @@ class ImageController extends Controller |
| 164 | public function destroy(PageRepo $pageRepo, Request $request, $id) | 117 | public function destroy(PageRepo $pageRepo, Request $request, $id) |
| 165 | { | 118 | { |
| 166 | $this->checkPermission('image-delete'); | 119 | $this->checkPermission('image-delete'); |
| 167 | - $image = $this->image->findOrFail($id); | 120 | + $image = $this->imageRepo->getById($id); |
| 168 | 121 | ||
| 169 | // Check if this image is used on any pages | 122 | // Check if this image is used on any pages |
| 170 | - $pageSearch = $pageRepo->searchForImage($image->url); | ||
| 171 | $isForced = ($request->has('force') && ($request->get('force') === 'true') || $request->get('force') === true); | 123 | $isForced = ($request->has('force') && ($request->get('force') === 'true') || $request->get('force') === true); |
| 172 | - if ($pageSearch !== false && !$isForced) { | 124 | + if (!$isForced) { |
| 173 | - return response()->json($pageSearch, 400); | 125 | + $pageSearch = $pageRepo->searchForImage($image->url); |
| 174 | - } | 126 | + if ($pageSearch !== false) { |
| 175 | - | 127 | + return response()->json($pageSearch, 400); |
| 176 | - // Delete files | ||
| 177 | - $folder = public_path() . dirname($image->url); | ||
| 178 | - $fileName = basename($image->url); | ||
| 179 | - | ||
| 180 | - // Delete thumbnails | ||
| 181 | - foreach (glob($folder . '/*') as $file) { | ||
| 182 | - if (is_dir($file)) { | ||
| 183 | - $thumbName = $file . '/' . $fileName; | ||
| 184 | - if (file_exists($file)) { | ||
| 185 | - unlink($thumbName); | ||
| 186 | - } | ||
| 187 | - // Remove thumb folder if empty | ||
| 188 | - if (count(glob($file . '/*')) === 0) { | ||
| 189 | - rmdir($file); | ||
| 190 | - } | ||
| 191 | } | 128 | } |
| 192 | } | 129 | } |
| 193 | 130 | ||
| 194 | - // Delete file and database entry | 131 | + $this->imageRepo->destroyImage($image); |
| 195 | - unlink($folder . '/' . $fileName); | ||
| 196 | - $image->delete(); | ||
| 197 | - | ||
| 198 | - // Delete parent folder if empty | ||
| 199 | - if (count(glob($folder . '/*')) === 0) { | ||
| 200 | - rmdir($folder); | ||
| 201 | - } | ||
| 202 | return response()->json('Image Deleted'); | 132 | return response()->json('Image Deleted'); |
| 203 | } | 133 | } |
| 204 | 134 | ... | ... |
| ... | @@ -46,6 +46,7 @@ class PageController extends Controller | ... | @@ -46,6 +46,7 @@ class PageController extends Controller |
| 46 | $this->checkPermission('page-create'); | 46 | $this->checkPermission('page-create'); |
| 47 | $book = $this->bookRepo->getBySlug($bookSlug); | 47 | $book = $this->bookRepo->getBySlug($bookSlug); |
| 48 | $chapter = $chapterSlug ? $this->chapterRepo->getBySlug($chapterSlug, $book->id) : false; | 48 | $chapter = $chapterSlug ? $this->chapterRepo->getBySlug($chapterSlug, $book->id) : false; |
| 49 | + $this->setPageTitle('Create New Page'); | ||
| 49 | return view('pages/create', ['book' => $book, 'chapter' => $chapter]); | 50 | return view('pages/create', ['book' => $book, 'chapter' => $chapter]); |
| 50 | } | 51 | } |
| 51 | 52 | ||
| ... | @@ -89,6 +90,7 @@ class PageController extends Controller | ... | @@ -89,6 +90,7 @@ class PageController extends Controller |
| 89 | $page = $this->pageRepo->getBySlug($pageSlug, $book->id); | 90 | $page = $this->pageRepo->getBySlug($pageSlug, $book->id); |
| 90 | $sidebarTree = $this->bookRepo->getChildren($book); | 91 | $sidebarTree = $this->bookRepo->getChildren($book); |
| 91 | Views::add($page); | 92 | Views::add($page); |
| 93 | + $this->setPageTitle($page->getShortName()); | ||
| 92 | return view('pages/show', ['page' => $page, 'book' => $book, 'current' => $page, 'sidebarTree' => $sidebarTree]); | 94 | return view('pages/show', ['page' => $page, 'book' => $book, 'current' => $page, 'sidebarTree' => $sidebarTree]); |
| 93 | } | 95 | } |
| 94 | 96 | ||
| ... | @@ -104,6 +106,7 @@ class PageController extends Controller | ... | @@ -104,6 +106,7 @@ class PageController extends Controller |
| 104 | $this->checkPermission('page-update'); | 106 | $this->checkPermission('page-update'); |
| 105 | $book = $this->bookRepo->getBySlug($bookSlug); | 107 | $book = $this->bookRepo->getBySlug($bookSlug); |
| 106 | $page = $this->pageRepo->getBySlug($pageSlug, $book->id); | 108 | $page = $this->pageRepo->getBySlug($pageSlug, $book->id); |
| 109 | + $this->setPageTitle('Editing Page ' . $page->getShortName()); | ||
| 107 | return view('pages/edit', ['page' => $page, 'book' => $book, 'current' => $page]); | 110 | return view('pages/edit', ['page' => $page, 'book' => $book, 'current' => $page]); |
| 108 | } | 111 | } |
| 109 | 112 | ||
| ... | @@ -148,6 +151,7 @@ class PageController extends Controller | ... | @@ -148,6 +151,7 @@ class PageController extends Controller |
| 148 | $this->checkPermission('page-delete'); | 151 | $this->checkPermission('page-delete'); |
| 149 | $book = $this->bookRepo->getBySlug($bookSlug); | 152 | $book = $this->bookRepo->getBySlug($bookSlug); |
| 150 | $page = $this->pageRepo->getBySlug($pageSlug, $book->id); | 153 | $page = $this->pageRepo->getBySlug($pageSlug, $book->id); |
| 154 | + $this->setPageTitle('Delete Page ' . $page->getShortName()); | ||
| 151 | return view('pages/delete', ['book' => $book, 'page' => $page, 'current' => $page]); | 155 | return view('pages/delete', ['book' => $book, 'page' => $page, 'current' => $page]); |
| 152 | } | 156 | } |
| 153 | 157 | ||
| ... | @@ -179,6 +183,7 @@ class PageController extends Controller | ... | @@ -179,6 +183,7 @@ class PageController extends Controller |
| 179 | { | 183 | { |
| 180 | $book = $this->bookRepo->getBySlug($bookSlug); | 184 | $book = $this->bookRepo->getBySlug($bookSlug); |
| 181 | $page = $this->pageRepo->getBySlug($pageSlug, $book->id); | 185 | $page = $this->pageRepo->getBySlug($pageSlug, $book->id); |
| 186 | + $this->setPageTitle('Revisions For ' . $page->getShortName()); | ||
| 182 | return view('pages/revisions', ['page' => $page, 'book' => $book, 'current' => $page]); | 187 | return view('pages/revisions', ['page' => $page, 'book' => $book, 'current' => $page]); |
| 183 | } | 188 | } |
| 184 | 189 | ||
| ... | @@ -195,6 +200,7 @@ class PageController extends Controller | ... | @@ -195,6 +200,7 @@ class PageController extends Controller |
| 195 | $page = $this->pageRepo->getBySlug($pageSlug, $book->id); | 200 | $page = $this->pageRepo->getBySlug($pageSlug, $book->id); |
| 196 | $revision = $this->pageRepo->getRevisionById($revisionId); | 201 | $revision = $this->pageRepo->getRevisionById($revisionId); |
| 197 | $page->fill($revision->toArray()); | 202 | $page->fill($revision->toArray()); |
| 203 | + $this->setPageTitle('Page Revision For ' . $page->getShortName()); | ||
| 198 | return view('pages/revision', ['page' => $page, 'book' => $book]); | 204 | return view('pages/revision', ['page' => $page, 'book' => $book]); |
| 199 | } | 205 | } |
| 200 | 206 | ... | ... |
| ... | @@ -45,6 +45,7 @@ class SearchController extends Controller | ... | @@ -45,6 +45,7 @@ class SearchController extends Controller |
| 45 | $pages = $this->pageRepo->getBySearch($searchTerm); | 45 | $pages = $this->pageRepo->getBySearch($searchTerm); |
| 46 | $books = $this->bookRepo->getBySearch($searchTerm); | 46 | $books = $this->bookRepo->getBySearch($searchTerm); |
| 47 | $chapters = $this->chapterRepo->getBySearch($searchTerm); | 47 | $chapters = $this->chapterRepo->getBySearch($searchTerm); |
| 48 | + $this->setPageTitle('Search For ' . $searchTerm); | ||
| 48 | return view('search/all', ['pages' => $pages, 'books' => $books, 'chapters' => $chapters, 'searchTerm' => $searchTerm]); | 49 | return view('search/all', ['pages' => $pages, 'books' => $books, 'chapters' => $chapters, 'searchTerm' => $searchTerm]); |
| 49 | } | 50 | } |
| 50 | 51 | ... | ... |
| ... | @@ -18,6 +18,7 @@ class SettingController extends Controller | ... | @@ -18,6 +18,7 @@ class SettingController extends Controller |
| 18 | public function index() | 18 | public function index() |
| 19 | { | 19 | { |
| 20 | $this->checkPermission('settings-update'); | 20 | $this->checkPermission('settings-update'); |
| 21 | + $this->setPageTitle('Settings'); | ||
| 21 | return view('settings/index'); | 22 | return view('settings/index'); |
| 22 | } | 23 | } |
| 23 | 24 | ... | ... |
| ... | @@ -4,7 +4,7 @@ namespace BookStack\Http\Controllers; | ... | @@ -4,7 +4,7 @@ namespace BookStack\Http\Controllers; |
| 4 | 4 | ||
| 5 | use Illuminate\Http\Request; | 5 | use Illuminate\Http\Request; |
| 6 | 6 | ||
| 7 | -use Illuminate\Support\Facades\Hash; | 7 | +use Illuminate\Http\Response; |
| 8 | use BookStack\Http\Requests; | 8 | use BookStack\Http\Requests; |
| 9 | use BookStack\Repos\UserRepo; | 9 | use BookStack\Repos\UserRepo; |
| 10 | use BookStack\Services\SocialAuthService; | 10 | use BookStack\Services\SocialAuthService; |
| ... | @@ -18,7 +18,8 @@ class UserController extends Controller | ... | @@ -18,7 +18,8 @@ class UserController extends Controller |
| 18 | 18 | ||
| 19 | /** | 19 | /** |
| 20 | * UserController constructor. | 20 | * UserController constructor. |
| 21 | - * @param $user | 21 | + * @param User $user |
| 22 | + * @param UserRepo $userRepo | ||
| 22 | */ | 23 | */ |
| 23 | public function __construct(User $user, UserRepo $userRepo) | 24 | public function __construct(User $user, UserRepo $userRepo) |
| 24 | { | 25 | { |
| ... | @@ -29,18 +30,17 @@ class UserController extends Controller | ... | @@ -29,18 +30,17 @@ class UserController extends Controller |
| 29 | 30 | ||
| 30 | /** | 31 | /** |
| 31 | * Display a listing of the users. | 32 | * Display a listing of the users. |
| 32 | - * | ||
| 33 | * @return Response | 33 | * @return Response |
| 34 | */ | 34 | */ |
| 35 | public function index() | 35 | public function index() |
| 36 | { | 36 | { |
| 37 | $users = $this->user->all(); | 37 | $users = $this->user->all(); |
| 38 | + $this->setPageTitle('Users'); | ||
| 38 | return view('users/index', ['users' => $users]); | 39 | return view('users/index', ['users' => $users]); |
| 39 | } | 40 | } |
| 40 | 41 | ||
| 41 | /** | 42 | /** |
| 42 | * Show the form for creating a new user. | 43 | * Show the form for creating a new user. |
| 43 | - * | ||
| 44 | * @return Response | 44 | * @return Response |
| 45 | */ | 45 | */ |
| 46 | public function create() | 46 | public function create() |
| ... | @@ -51,7 +51,6 @@ class UserController extends Controller | ... | @@ -51,7 +51,6 @@ class UserController extends Controller |
| 51 | 51 | ||
| 52 | /** | 52 | /** |
| 53 | * Store a newly created user in storage. | 53 | * Store a newly created user in storage. |
| 54 | - * | ||
| 55 | * @param Request $request | 54 | * @param Request $request |
| 56 | * @return Response | 55 | * @return Response |
| 57 | */ | 56 | */ |
| ... | @@ -60,7 +59,7 @@ class UserController extends Controller | ... | @@ -60,7 +59,7 @@ class UserController extends Controller |
| 60 | $this->checkPermission('user-create'); | 59 | $this->checkPermission('user-create'); |
| 61 | $this->validate($request, [ | 60 | $this->validate($request, [ |
| 62 | 'name' => 'required', | 61 | 'name' => 'required', |
| 63 | - 'email' => 'required|email', | 62 | + 'email' => 'required|email|unique:users,email', |
| 64 | 'password' => 'required|min:5', | 63 | 'password' => 'required|min:5', |
| 65 | 'password-confirm' => 'required|same:password', | 64 | 'password-confirm' => 'required|same:password', |
| 66 | 'role' => 'required|exists:roles,id' | 65 | 'role' => 'required|exists:roles,id' |
| ... | @@ -71,13 +70,20 @@ class UserController extends Controller | ... | @@ -71,13 +70,20 @@ class UserController extends Controller |
| 71 | $user->save(); | 70 | $user->save(); |
| 72 | 71 | ||
| 73 | $user->attachRoleId($request->get('role')); | 72 | $user->attachRoleId($request->get('role')); |
| 73 | + | ||
| 74 | + // Get avatar from gravatar and save | ||
| 75 | + if (!env('DISABLE_EXTERNAL_SERVICES', false)) { | ||
| 76 | + $avatar = \Images::saveUserGravatar($user); | ||
| 77 | + $user->avatar()->associate($avatar); | ||
| 78 | + $user->save(); | ||
| 79 | + } | ||
| 80 | + | ||
| 74 | return redirect('/users'); | 81 | return redirect('/users'); |
| 75 | } | 82 | } |
| 76 | 83 | ||
| 77 | 84 | ||
| 78 | /** | 85 | /** |
| 79 | * Show the form for editing the specified user. | 86 | * Show the form for editing the specified user. |
| 80 | - * | ||
| 81 | * @param int $id | 87 | * @param int $id |
| 82 | * @param SocialAuthService $socialAuthService | 88 | * @param SocialAuthService $socialAuthService |
| 83 | * @return Response | 89 | * @return Response |
| ... | @@ -90,12 +96,12 @@ class UserController extends Controller | ... | @@ -90,12 +96,12 @@ class UserController extends Controller |
| 90 | 96 | ||
| 91 | $user = $this->user->findOrFail($id); | 97 | $user = $this->user->findOrFail($id); |
| 92 | $activeSocialDrivers = $socialAuthService->getActiveDrivers(); | 98 | $activeSocialDrivers = $socialAuthService->getActiveDrivers(); |
| 99 | + $this->setPageTitle('User Profile'); | ||
| 93 | return view('users/edit', ['user' => $user, 'activeSocialDrivers' => $activeSocialDrivers]); | 100 | return view('users/edit', ['user' => $user, 'activeSocialDrivers' => $activeSocialDrivers]); |
| 94 | } | 101 | } |
| 95 | 102 | ||
| 96 | /** | 103 | /** |
| 97 | * Update the specified user in storage. | 104 | * Update the specified user in storage. |
| 98 | - * | ||
| 99 | * @param Request $request | 105 | * @param Request $request |
| 100 | * @param int $id | 106 | * @param int $id |
| 101 | * @return Response | 107 | * @return Response |
| ... | @@ -139,12 +145,12 @@ class UserController extends Controller | ... | @@ -139,12 +145,12 @@ class UserController extends Controller |
| 139 | return $this->currentUser->id == $id; | 145 | return $this->currentUser->id == $id; |
| 140 | }); | 146 | }); |
| 141 | $user = $this->user->findOrFail($id); | 147 | $user = $this->user->findOrFail($id); |
| 148 | + $this->setPageTitle('Delete User ' . $user->name); | ||
| 142 | return view('users/delete', ['user' => $user]); | 149 | return view('users/delete', ['user' => $user]); |
| 143 | } | 150 | } |
| 144 | 151 | ||
| 145 | /** | 152 | /** |
| 146 | * Remove the specified user from storage. | 153 | * Remove the specified user from storage. |
| 147 | - * | ||
| 148 | * @param int $id | 154 | * @param int $id |
| 149 | * @return Response | 155 | * @return Response |
| 150 | */ | 156 | */ |
| ... | @@ -153,14 +159,14 @@ class UserController extends Controller | ... | @@ -153,14 +159,14 @@ class UserController extends Controller |
| 153 | $this->checkPermissionOr('user-delete', function () use ($id) { | 159 | $this->checkPermissionOr('user-delete', function () use ($id) { |
| 154 | return $this->currentUser->id == $id; | 160 | return $this->currentUser->id == $id; |
| 155 | }); | 161 | }); |
| 162 | + | ||
| 156 | $user = $this->userRepo->getById($id); | 163 | $user = $this->userRepo->getById($id); |
| 157 | - // Delete social accounts | 164 | + if ($this->userRepo->isOnlyAdmin($user)) { |
| 158 | - if($this->userRepo->isOnlyAdmin($user)) { | ||
| 159 | session()->flash('error', 'You cannot delete the only admin'); | 165 | session()->flash('error', 'You cannot delete the only admin'); |
| 160 | return redirect($user->getEditUrl()); | 166 | return redirect($user->getEditUrl()); |
| 161 | } | 167 | } |
| 162 | - $user->socialAccounts()->delete(); | 168 | + $this->userRepo->destroy($user); |
| 163 | - $user->delete(); | 169 | + |
| 164 | return redirect('/users'); | 170 | return redirect('/users'); |
| 165 | } | 171 | } |
| 166 | } | 172 | } | ... | ... |
| ... | @@ -45,8 +45,6 @@ Route::group(['middleware' => 'auth'], function () { | ... | @@ -45,8 +45,6 @@ Route::group(['middleware' => 'auth'], function () { |
| 45 | 45 | ||
| 46 | }); | 46 | }); |
| 47 | 47 | ||
| 48 | - // Uploads | ||
| 49 | - Route::post('/upload/image', 'ImageController@upload'); | ||
| 50 | 48 | ||
| 51 | // Users | 49 | // Users |
| 52 | Route::get('/users', 'UserController@index'); | 50 | Route::get('/users', 'UserController@index'); |
| ... | @@ -58,10 +56,18 @@ Route::group(['middleware' => 'auth'], function () { | ... | @@ -58,10 +56,18 @@ Route::group(['middleware' => 'auth'], function () { |
| 58 | Route::delete('/users/{id}', 'UserController@destroy'); | 56 | Route::delete('/users/{id}', 'UserController@destroy'); |
| 59 | 57 | ||
| 60 | // Image routes | 58 | // Image routes |
| 61 | - Route::get('/images/all', 'ImageController@getAll'); | 59 | + Route::group(['prefix' => 'images'], function() { |
| 62 | - Route::put('/images/update/{imageId}', 'ImageController@update'); | 60 | + // Get for user images |
| 63 | - Route::delete('/images/{imageId}', 'ImageController@destroy'); | 61 | + Route::get('/user/all', 'ImageController@getAllForUserType'); |
| 64 | - Route::get('/images/all/{page}', 'ImageController@getAll'); | 62 | + Route::get('/user/all/{page}', 'ImageController@getAllForUserType'); |
| 63 | + // Standard get, update and deletion for all types | ||
| 64 | + Route::get('/thumb/{id}/{width}/{height}/{crop}', 'ImageController@getThumbnail'); | ||
| 65 | + Route::put('/update/{imageId}', 'ImageController@update'); | ||
| 66 | + Route::post('/{type}/upload', 'ImageController@uploadByType'); | ||
| 67 | + Route::get('/{type}/all', 'ImageController@getAllByType'); | ||
| 68 | + Route::get('/{type}/all/{page}', 'ImageController@getAllByType'); | ||
| 69 | + Route::delete('/{imageId}', 'ImageController@destroy'); | ||
| 70 | + }); | ||
| 65 | 71 | ||
| 66 | // Links | 72 | // Links |
| 67 | Route::get('/link/{id}', 'PageController@redirectFromLink'); | 73 | Route::get('/link/{id}', 'PageController@redirectFromLink'); | ... | ... |
| ... | @@ -3,22 +3,24 @@ | ... | @@ -3,22 +3,24 @@ |
| 3 | namespace BookStack; | 3 | namespace BookStack; |
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | -class Image extends Entity | 6 | +use Illuminate\Database\Eloquent\Model; |
| 7 | +use Images; | ||
| 8 | + | ||
| 9 | +class Image extends Model | ||
| 7 | { | 10 | { |
| 11 | + use Ownable; | ||
| 8 | 12 | ||
| 9 | protected $fillable = ['name']; | 13 | protected $fillable = ['name']; |
| 10 | 14 | ||
| 11 | - public function getFilePath() | ||
| 12 | - { | ||
| 13 | - return storage_path() . $this->url; | ||
| 14 | - } | ||
| 15 | - | ||
| 16 | /** | 15 | /** |
| 17 | - * Get the url for this item. | 16 | + * Get a thumbnail for this image. |
| 17 | + * @param int $width | ||
| 18 | + * @param int $height | ||
| 19 | + * @param bool|false $keepRatio | ||
| 18 | * @return string | 20 | * @return string |
| 19 | */ | 21 | */ |
| 20 | - public function getUrl() | 22 | + public function getThumb($width, $height, $keepRatio = false) |
| 21 | { | 23 | { |
| 22 | - return public_path() . $this->url; | 24 | + return Images::getThumbnail($this, $width, $height, $keepRatio); |
| 23 | } | 25 | } |
| 24 | } | 26 | } | ... | ... |
app/Ownable.php
0 → 100644
| 1 | +<?php namespace BookStack; | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +trait Ownable | ||
| 5 | +{ | ||
| 6 | + /** | ||
| 7 | + * Relation for the user that created this entity. | ||
| 8 | + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||
| 9 | + */ | ||
| 10 | + public function createdBy() | ||
| 11 | + { | ||
| 12 | + return $this->belongsTo('BookStack\User', 'created_by'); | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + /** | ||
| 16 | + * Relation for the user that updated this entity. | ||
| 17 | + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||
| 18 | + */ | ||
| 19 | + public function updatedBy() | ||
| 20 | + { | ||
| 21 | + return $this->belongsTo('BookStack\User', 'updated_by'); | ||
| 22 | + } | ||
| 23 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -32,7 +32,6 @@ class Page extends Entity | ... | @@ -32,7 +32,6 @@ class Page extends Entity |
| 32 | return $this->chapter()->count() > 0; | 32 | return $this->chapter()->count() > 0; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | - | ||
| 36 | public function revisions() | 35 | public function revisions() |
| 37 | { | 36 | { |
| 38 | return $this->hasMany('BookStack\PageRevision')->orderBy('created_at', 'desc'); | 37 | return $this->hasMany('BookStack\PageRevision')->orderBy('created_at', 'desc'); |
| ... | @@ -40,7 +39,6 @@ class Page extends Entity | ... | @@ -40,7 +39,6 @@ class Page extends Entity |
| 40 | 39 | ||
| 41 | public function getUrl() | 40 | public function getUrl() |
| 42 | { | 41 | { |
| 43 | - // TODO - Extract this and share with chapters | ||
| 44 | $bookSlug = $this->getAttribute('bookSlug') ? $this->getAttribute('bookSlug') : $this->book->slug; | 42 | $bookSlug = $this->getAttribute('bookSlug') ? $this->getAttribute('bookSlug') : $this->book->slug; |
| 45 | return '/books/' . $bookSlug . '/page/' . $this->slug; | 43 | return '/books/' . $bookSlug . '/page/' . $this->slug; |
| 46 | } | 44 | } | ... | ... |
| ... | @@ -2,6 +2,7 @@ | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | ||
| 3 | namespace BookStack\Providers; | 3 | namespace BookStack\Providers; |
| 4 | 4 | ||
| 5 | +use BookStack\Services\ImageService; | ||
| 5 | use BookStack\Services\ViewService; | 6 | use BookStack\Services\ViewService; |
| 6 | use Illuminate\Support\ServiceProvider; | 7 | use Illuminate\Support\ServiceProvider; |
| 7 | use BookStack\Services\ActivityService; | 8 | use BookStack\Services\ActivityService; |
| ... | @@ -40,5 +41,12 @@ class CustomFacadeProvider extends ServiceProvider | ... | @@ -40,5 +41,12 @@ class CustomFacadeProvider extends ServiceProvider |
| 40 | $this->app->make('Illuminate\Contracts\Cache\Repository') | 41 | $this->app->make('Illuminate\Contracts\Cache\Repository') |
| 41 | ); | 42 | ); |
| 42 | }); | 43 | }); |
| 44 | + $this->app->bind('images', function() { | ||
| 45 | + return new ImageService( | ||
| 46 | + $this->app->make('Intervention\Image\ImageManager'), | ||
| 47 | + $this->app->make('Illuminate\Contracts\Filesystem\Factory'), | ||
| 48 | + $this->app->make('Illuminate\Contracts\Cache\Repository') | ||
| 49 | + ); | ||
| 50 | + }); | ||
| 43 | } | 51 | } |
| 44 | } | 52 | } | ... | ... |
| ... | @@ -78,6 +78,17 @@ class BookRepo | ... | @@ -78,6 +78,17 @@ class BookRepo |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | /** | 80 | /** |
| 81 | + * Gets the most viewed books. | ||
| 82 | + * @param int $count | ||
| 83 | + * @param int $page | ||
| 84 | + * @return mixed | ||
| 85 | + */ | ||
| 86 | + public function getPopular($count = 10, $page = 0) | ||
| 87 | + { | ||
| 88 | + return Views::getPopular($count, $page, $this->book); | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + /** | ||
| 81 | * Get a book by slug | 92 | * Get a book by slug |
| 82 | * @param $slug | 93 | * @param $slug |
| 83 | * @return mixed | 94 | * @return mixed | ... | ... |
app/Repos/ImageRepo.php
0 → 100644
| 1 | +<?php namespace BookStack\Repos; | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +use BookStack\Image; | ||
| 5 | +use BookStack\Services\ImageService; | ||
| 6 | +use Setting; | ||
| 7 | +use Symfony\Component\HttpFoundation\File\UploadedFile; | ||
| 8 | + | ||
| 9 | +class ImageRepo | ||
| 10 | +{ | ||
| 11 | + | ||
| 12 | + protected $image; | ||
| 13 | + protected $imageService; | ||
| 14 | + | ||
| 15 | + /** | ||
| 16 | + * ImageRepo constructor. | ||
| 17 | + * @param Image $image | ||
| 18 | + * @param ImageService $imageService | ||
| 19 | + */ | ||
| 20 | + public function __construct(Image $image, ImageService $imageService) | ||
| 21 | + { | ||
| 22 | + $this->image = $image; | ||
| 23 | + $this->imageService = $imageService; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * Get an image with the given id. | ||
| 29 | + * @param $id | ||
| 30 | + * @return mixed | ||
| 31 | + */ | ||
| 32 | + public function getById($id) | ||
| 33 | + { | ||
| 34 | + return $this->image->findOrFail($id); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * Gets a load images paginated, filtered by image type. | ||
| 40 | + * @param string $type | ||
| 41 | + * @param int $page | ||
| 42 | + * @param int $pageSize | ||
| 43 | + * @param bool|int $userFilter | ||
| 44 | + * @return array | ||
| 45 | + */ | ||
| 46 | + public function getPaginatedByType($type, $page = 0, $pageSize = 24, $userFilter = false) | ||
| 47 | + { | ||
| 48 | + $images = $this->image->where('type', '=', strtolower($type)); | ||
| 49 | + | ||
| 50 | + if ($userFilter !== false) { | ||
| 51 | + $images = $images->where('created_by', '=', $userFilter); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + $images = $images->orderBy('created_at', 'desc')->skip($pageSize * $page)->take($pageSize + 1)->get(); | ||
| 55 | + $hasMore = count($images) > $pageSize; | ||
| 56 | + | ||
| 57 | + $returnImages = $images->take(24); | ||
| 58 | + $returnImages->each(function ($image) { | ||
| 59 | + $this->loadThumbs($image); | ||
| 60 | + }); | ||
| 61 | + | ||
| 62 | + return [ | ||
| 63 | + 'images' => $returnImages, | ||
| 64 | + 'hasMore' => $hasMore | ||
| 65 | + ]; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + /** | ||
| 69 | + * Save a new image into storage and return the new image. | ||
| 70 | + * @param UploadedFile $uploadFile | ||
| 71 | + * @param string $type | ||
| 72 | + * @return Image | ||
| 73 | + */ | ||
| 74 | + public function saveNew(UploadedFile $uploadFile, $type) | ||
| 75 | + { | ||
| 76 | + $image = $this->imageService->saveNewFromUpload($uploadFile, $type); | ||
| 77 | + $this->loadThumbs($image); | ||
| 78 | + return $image; | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + /** | ||
| 82 | + * Update the details of an image via an array of properties. | ||
| 83 | + * @param Image $image | ||
| 84 | + * @param array $updateDetails | ||
| 85 | + * @return Image | ||
| 86 | + */ | ||
| 87 | + public function updateImageDetails(Image $image, $updateDetails) | ||
| 88 | + { | ||
| 89 | + $image->fill($updateDetails); | ||
| 90 | + $image->save(); | ||
| 91 | + $this->loadThumbs($image); | ||
| 92 | + return $image; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + | ||
| 96 | + /** | ||
| 97 | + * Destroys an Image object along with its files and thumbnails. | ||
| 98 | + * @param Image $image | ||
| 99 | + * @return bool | ||
| 100 | + */ | ||
| 101 | + public function destroyImage(Image $image) | ||
| 102 | + { | ||
| 103 | + $this->imageService->destroyImage($image); | ||
| 104 | + return true; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + | ||
| 108 | + /** | ||
| 109 | + * Load thumbnails onto an image object. | ||
| 110 | + * @param Image $image | ||
| 111 | + */ | ||
| 112 | + private function loadThumbs(Image $image) | ||
| 113 | + { | ||
| 114 | + $image->thumbs = [ | ||
| 115 | + 'gallery' => $this->getThumbnail($image, 150, 150), | ||
| 116 | + 'display' => $this->getThumbnail($image, 840, 0, true) | ||
| 117 | + ]; | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + /** | ||
| 121 | + * Get the thumbnail for an image. | ||
| 122 | + * If $keepRatio is true only the width will be used. | ||
| 123 | + * Checks the cache then storage to avoid creating / accessing the filesystem on every check. | ||
| 124 | + * | ||
| 125 | + * @param Image $image | ||
| 126 | + * @param int $width | ||
| 127 | + * @param int $height | ||
| 128 | + * @param bool $keepRatio | ||
| 129 | + * @return string | ||
| 130 | + */ | ||
| 131 | + public function getThumbnail(Image $image, $width = 220, $height = 220, $keepRatio = false) | ||
| 132 | + { | ||
| 133 | + return $this->imageService->getThumbnail($image, $width, $height, $keepRatio); | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + | ||
| 137 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -269,7 +269,7 @@ class PageRepo | ... | @@ -269,7 +269,7 @@ class PageRepo |
| 269 | * @param Page $page | 269 | * @param Page $page |
| 270 | * @return $this | 270 | * @return $this |
| 271 | */ | 271 | */ |
| 272 | - private function saveRevision(Page $page) | 272 | + public function saveRevision(Page $page) |
| 273 | { | 273 | { |
| 274 | $revision = $this->pageRevision->fill($page->toArray()); | 274 | $revision = $this->pageRevision->fill($page->toArray()); |
| 275 | $revision->page_id = $page->id; | 275 | $revision->page_id = $page->id; | ... | ... |
| ... | @@ -46,14 +46,19 @@ class UserRepo | ... | @@ -46,14 +46,19 @@ class UserRepo |
| 46 | public function registerNew(array $data) | 46 | public function registerNew(array $data) |
| 47 | { | 47 | { |
| 48 | $user = $this->create($data); | 48 | $user = $this->create($data); |
| 49 | - $roleId = \Setting::get('registration-role'); | 49 | + $this->attachDefaultRole($user); |
| 50 | - | 50 | + return $user; |
| 51 | - if ($roleId === false) { | 51 | + } |
| 52 | - $roleId = $this->role->getDefault()->id; | ||
| 53 | - } | ||
| 54 | 52 | ||
| 53 | + /** | ||
| 54 | + * Give a user the default role. Used when creating a new user. | ||
| 55 | + * @param $user | ||
| 56 | + */ | ||
| 57 | + public function attachDefaultRole($user) | ||
| 58 | + { | ||
| 59 | + $roleId = \Setting::get('registration-role'); | ||
| 60 | + if ($roleId === false) $roleId = $this->role->getDefault()->id; | ||
| 55 | $user->attachRoleId($roleId); | 61 | $user->attachRoleId($roleId); |
| 56 | - return $user; | ||
| 57 | } | 62 | } |
| 58 | 63 | ||
| 59 | /** | 64 | /** |
| ... | @@ -88,4 +93,14 @@ class UserRepo | ... | @@ -88,4 +93,14 @@ class UserRepo |
| 88 | 'password' => bcrypt($data['password']) | 93 | 'password' => bcrypt($data['password']) |
| 89 | ]); | 94 | ]); |
| 90 | } | 95 | } |
| 96 | + | ||
| 97 | + /** | ||
| 98 | + * Remove the given user from storage, Delete all related content. | ||
| 99 | + * @param User $user | ||
| 100 | + */ | ||
| 101 | + public function destroy(User $user) | ||
| 102 | + { | ||
| 103 | + $user->socialAccounts()->delete(); | ||
| 104 | + $user->delete(); | ||
| 105 | + } | ||
| 91 | } | 106 | } |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
app/Services/Facades/Images.php
0 → 100644
| 1 | +<?php namespace BookStack\Services\Facades; | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +use Illuminate\Support\Facades\Facade; | ||
| 5 | + | ||
| 6 | +class Images extends Facade | ||
| 7 | +{ | ||
| 8 | + /** | ||
| 9 | + * Get the registered name of the component. | ||
| 10 | + * | ||
| 11 | + * @return string | ||
| 12 | + */ | ||
| 13 | + protected static function getFacadeAccessor() { return 'images'; } | ||
| 14 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
app/Services/ImageService.php
0 → 100644
| 1 | +<?php namespace BookStack\Services; | ||
| 2 | + | ||
| 3 | +use BookStack\Image; | ||
| 4 | +use BookStack\User; | ||
| 5 | +use Intervention\Image\ImageManager; | ||
| 6 | +use Illuminate\Contracts\Filesystem\Factory as FileSystem; | ||
| 7 | +use Illuminate\Contracts\Filesystem\Filesystem as FileSystemInstance; | ||
| 8 | +use Illuminate\Contracts\Cache\Repository as Cache; | ||
| 9 | +use Setting; | ||
| 10 | +use Symfony\Component\HttpFoundation\File\UploadedFile; | ||
| 11 | + | ||
| 12 | +class ImageService | ||
| 13 | +{ | ||
| 14 | + | ||
| 15 | + protected $imageTool; | ||
| 16 | + protected $fileSystem; | ||
| 17 | + protected $cache; | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * @var FileSystemInstance | ||
| 21 | + */ | ||
| 22 | + protected $storageInstance; | ||
| 23 | + protected $storageUrl; | ||
| 24 | + | ||
| 25 | + /** | ||
| 26 | + * ImageService constructor. | ||
| 27 | + * @param $imageTool | ||
| 28 | + * @param $fileSystem | ||
| 29 | + * @param $cache | ||
| 30 | + */ | ||
| 31 | + public function __construct(ImageManager $imageTool, FileSystem $fileSystem, Cache $cache) | ||
| 32 | + { | ||
| 33 | + $this->imageTool = $imageTool; | ||
| 34 | + $this->fileSystem = $fileSystem; | ||
| 35 | + $this->cache = $cache; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * Saves a new image from an upload. | ||
| 40 | + * @param UploadedFile $uploadedFile | ||
| 41 | + * @param string $type | ||
| 42 | + * @return mixed | ||
| 43 | + */ | ||
| 44 | + public function saveNewFromUpload(UploadedFile $uploadedFile, $type) | ||
| 45 | + { | ||
| 46 | + $imageName = $uploadedFile->getClientOriginalName(); | ||
| 47 | + $imageData = file_get_contents($uploadedFile->getRealPath()); | ||
| 48 | + return $this->saveNew($imageName, $imageData, $type); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * Gets an image from url and saves it to the database. | ||
| 54 | + * @param $url | ||
| 55 | + * @param string $type | ||
| 56 | + * @param bool|string $imageName | ||
| 57 | + * @return mixed | ||
| 58 | + * @throws \Exception | ||
| 59 | + */ | ||
| 60 | + private function saveNewFromUrl($url, $type, $imageName = false) | ||
| 61 | + { | ||
| 62 | + $imageName = $imageName ? $imageName : basename($url); | ||
| 63 | + $imageData = file_get_contents($url); | ||
| 64 | + if($imageData === false) throw new \Exception('Cannot get image from ' . $url); | ||
| 65 | + return $this->saveNew($imageName, $imageData, $type); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + /** | ||
| 69 | + * Saves a new image | ||
| 70 | + * @param string $imageName | ||
| 71 | + * @param string $imageData | ||
| 72 | + * @param string $type | ||
| 73 | + * @return Image | ||
| 74 | + */ | ||
| 75 | + private function saveNew($imageName, $imageData, $type) | ||
| 76 | + { | ||
| 77 | + $storage = $this->getStorage(); | ||
| 78 | + $secureUploads = Setting::get('app-secure-images'); | ||
| 79 | + $imageName = str_replace(' ', '-', $imageName); | ||
| 80 | + | ||
| 81 | + if ($secureUploads) $imageName = str_random(16) . '-' . $imageName; | ||
| 82 | + | ||
| 83 | + $imagePath = '/uploads/images/' . $type . '/' . Date('Y-m-M') . '/'; | ||
| 84 | + while ($storage->exists($imagePath . $imageName)) { | ||
| 85 | + $imageName = str_random(3) . $imageName; | ||
| 86 | + } | ||
| 87 | + $fullPath = $imagePath . $imageName; | ||
| 88 | + | ||
| 89 | + $storage->put($fullPath, $imageData); | ||
| 90 | + | ||
| 91 | + $userId = auth()->user()->id; | ||
| 92 | + $image = Image::forceCreate([ | ||
| 93 | + 'name' => $imageName, | ||
| 94 | + 'path' => $fullPath, | ||
| 95 | + 'url' => $this->getPublicUrl($fullPath), | ||
| 96 | + 'type' => $type, | ||
| 97 | + 'created_by' => $userId, | ||
| 98 | + 'updated_by' => $userId | ||
| 99 | + ]); | ||
| 100 | + | ||
| 101 | + return $image; | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + /** | ||
| 105 | + * Get the thumbnail for an image. | ||
| 106 | + * If $keepRatio is true only the width will be used. | ||
| 107 | + * Checks the cache then storage to avoid creating / accessing the filesystem on every check. | ||
| 108 | + * | ||
| 109 | + * @param Image $image | ||
| 110 | + * @param int $width | ||
| 111 | + * @param int $height | ||
| 112 | + * @param bool $keepRatio | ||
| 113 | + * @return string | ||
| 114 | + */ | ||
| 115 | + public function getThumbnail(Image $image, $width = 220, $height = 220, $keepRatio = false) | ||
| 116 | + { | ||
| 117 | + $thumbDirName = '/' . ($keepRatio ? 'scaled-' : 'thumbs-') . $width . '-' . $height . '/'; | ||
| 118 | + $thumbFilePath = dirname($image->path) . $thumbDirName . basename($image->path); | ||
| 119 | + | ||
| 120 | + if ($this->cache->has('images-' . $image->id . '-' . $thumbFilePath) && $this->cache->get('images-' . $thumbFilePath)) { | ||
| 121 | + return $this->getPublicUrl($thumbFilePath); | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + $storage = $this->getStorage(); | ||
| 125 | + | ||
| 126 | + if ($storage->exists($thumbFilePath)) { | ||
| 127 | + return $this->getPublicUrl($thumbFilePath); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + // Otherwise create the thumbnail | ||
| 131 | + $thumb = $this->imageTool->make($storage->get($image->path)); | ||
| 132 | + if ($keepRatio) { | ||
| 133 | + $thumb->resize($width, null, function ($constraint) { | ||
| 134 | + $constraint->aspectRatio(); | ||
| 135 | + $constraint->upsize(); | ||
| 136 | + }); | ||
| 137 | + } else { | ||
| 138 | + $thumb->fit($width, $height); | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + $thumbData = (string)$thumb->encode(); | ||
| 142 | + $storage->put($thumbFilePath, $thumbData); | ||
| 143 | + $this->cache->put('images-' . $image->id . '-' . $thumbFilePath, $thumbFilePath, 60 * 72); | ||
| 144 | + | ||
| 145 | + return $this->getPublicUrl($thumbFilePath); | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + /** | ||
| 149 | + * Destroys an Image object along with its files and thumbnails. | ||
| 150 | + * @param Image $image | ||
| 151 | + * @return bool | ||
| 152 | + */ | ||
| 153 | + public function destroyImage(Image $image) | ||
| 154 | + { | ||
| 155 | + $storage = $this->getStorage(); | ||
| 156 | + | ||
| 157 | + $imageFolder = dirname($image->path); | ||
| 158 | + $imageFileName = basename($image->path); | ||
| 159 | + $allImages = collect($storage->allFiles($imageFolder)); | ||
| 160 | + | ||
| 161 | + $imagesToDelete = $allImages->filter(function ($imagePath) use ($imageFileName) { | ||
| 162 | + $expectedIndex = strlen($imagePath) - strlen($imageFileName); | ||
| 163 | + return strpos($imagePath, $imageFileName) === $expectedIndex; | ||
| 164 | + }); | ||
| 165 | + | ||
| 166 | + $storage->delete($imagesToDelete->all()); | ||
| 167 | + | ||
| 168 | + // Cleanup of empty folders | ||
| 169 | + foreach ($storage->directories($imageFolder) as $directory) { | ||
| 170 | + if ($this->isFolderEmpty($directory)) $storage->deleteDirectory($directory); | ||
| 171 | + } | ||
| 172 | + if ($this->isFolderEmpty($imageFolder)) $storage->deleteDirectory($imageFolder); | ||
| 173 | + | ||
| 174 | + $image->delete(); | ||
| 175 | + return true; | ||
| 176 | + } | ||
| 177 | + | ||
| 178 | + /** | ||
| 179 | + * Save a gravatar image and set a the profile image for a user. | ||
| 180 | + * @param User $user | ||
| 181 | + * @param int $size | ||
| 182 | + * @return mixed | ||
| 183 | + */ | ||
| 184 | + public function saveUserGravatar(User $user, $size = 500) | ||
| 185 | + { | ||
| 186 | + $emailHash = md5(strtolower(trim($user->email))); | ||
| 187 | + $url = 'http://www.gravatar.com/avatar/' . $emailHash . '?s=' . $size . '&d=identicon'; | ||
| 188 | + $imageName = str_replace(' ', '-', $user->name . '-gravatar.png'); | ||
| 189 | + $image = $this->saveNewFromUrl($url, 'user', $imageName); | ||
| 190 | + $image->created_by = $user->id; | ||
| 191 | + $image->save(); | ||
| 192 | + return $image; | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + /** | ||
| 196 | + * Get the storage that will be used for storing images. | ||
| 197 | + * @return FileSystemInstance | ||
| 198 | + */ | ||
| 199 | + private function getStorage() | ||
| 200 | + { | ||
| 201 | + if ($this->storageInstance !== null) return $this->storageInstance; | ||
| 202 | + | ||
| 203 | + $storageType = env('STORAGE_TYPE'); | ||
| 204 | + $this->storageInstance = $this->fileSystem->disk($storageType); | ||
| 205 | + | ||
| 206 | + return $this->storageInstance; | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + /** | ||
| 210 | + * Check whether or not a folder is empty. | ||
| 211 | + * @param $path | ||
| 212 | + * @return int | ||
| 213 | + */ | ||
| 214 | + private function isFolderEmpty($path) | ||
| 215 | + { | ||
| 216 | + $files = $this->getStorage()->files($path); | ||
| 217 | + $folders = $this->getStorage()->directories($path); | ||
| 218 | + return count($files) === 0 && count($folders) === 0; | ||
| 219 | + } | ||
| 220 | + | ||
| 221 | + /** | ||
| 222 | + * Gets a public facing url for an image by checking relevant environment variables. | ||
| 223 | + * @param $filePath | ||
| 224 | + * @return string | ||
| 225 | + */ | ||
| 226 | + private function getPublicUrl($filePath) | ||
| 227 | + { | ||
| 228 | + if ($this->storageUrl === null) { | ||
| 229 | + $storageUrl = env('STORAGE_URL'); | ||
| 230 | + | ||
| 231 | + // Get the standard public s3 url if s3 is set as storage type | ||
| 232 | + if ($storageUrl == false && env('STORAGE_TYPE') === 's3') { | ||
| 233 | + $storageDetails = config('filesystems.disks.s3'); | ||
| 234 | + $storageUrl = 'https://s3-' . $storageDetails['region'] . '.amazonaws.com/' . $storageDetails['bucket']; | ||
| 235 | + } | ||
| 236 | + | ||
| 237 | + $this->storageUrl = $storageUrl; | ||
| 238 | + } | ||
| 239 | + | ||
| 240 | + return ($this->storageUrl == false ? '' : rtrim($this->storageUrl, '/')) . $filePath; | ||
| 241 | + } | ||
| 242 | + | ||
| 243 | + | ||
| 244 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -44,6 +44,29 @@ class ViewService | ... | @@ -44,6 +44,29 @@ class ViewService |
| 44 | return 1; | 44 | return 1; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | + | ||
| 48 | + /** | ||
| 49 | + * Get the entities with the most views. | ||
| 50 | + * @param int $count | ||
| 51 | + * @param int $page | ||
| 52 | + * @param bool|false $filterModel | ||
| 53 | + */ | ||
| 54 | + public function getPopular($count = 10, $page = 0, $filterModel = false) | ||
| 55 | + { | ||
| 56 | + $skipCount = $count * $page; | ||
| 57 | + $query = $this->view->select('id', 'viewable_id', 'viewable_type', \DB::raw('SUM(views) as view_count')) | ||
| 58 | + ->groupBy('viewable_id', 'viewable_type') | ||
| 59 | + ->orderBy('view_count', 'desc'); | ||
| 60 | + | ||
| 61 | + if($filterModel) $query->where('viewable_type', '=', get_class($filterModel)); | ||
| 62 | + | ||
| 63 | + $views = $query->with('viewable')->skip($skipCount)->take($count)->get(); | ||
| 64 | + $viewedEntities = $views->map(function ($item) { | ||
| 65 | + return $item->viewable()->getResults(); | ||
| 66 | + }); | ||
| 67 | + return $viewedEntities; | ||
| 68 | + } | ||
| 69 | + | ||
| 47 | /** | 70 | /** |
| 48 | * Get all recently viewed entities for the current user. | 71 | * Get all recently viewed entities for the current user. |
| 49 | * @param int $count | 72 | * @param int $count | ... | ... |
| ... | @@ -24,7 +24,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon | ... | @@ -24,7 +24,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon |
| 24 | * | 24 | * |
| 25 | * @var array | 25 | * @var array |
| 26 | */ | 26 | */ |
| 27 | - protected $fillable = ['name', 'email', 'password']; | 27 | + protected $fillable = ['name', 'email', 'password', 'image_id']; |
| 28 | 28 | ||
| 29 | /** | 29 | /** |
| 30 | * The attributes excluded from the model's JSON form. | 30 | * The attributes excluded from the model's JSON form. |
| ... | @@ -145,8 +145,17 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon | ... | @@ -145,8 +145,17 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon |
| 145 | */ | 145 | */ |
| 146 | public function getAvatar($size = 50) | 146 | public function getAvatar($size = 50) |
| 147 | { | 147 | { |
| 148 | - $emailHash = md5(strtolower(trim($this->email))); | 148 | + if ($this->image_id === 0 || $this->image_id === '0' || $this->image_id === null) return '/user_avatar.png'; |
| 149 | - return '//www.gravatar.com/avatar/' . $emailHash . '?s=' . $size . '&d=identicon'; | 149 | + return $this->avatar->getThumb($size, $size, false); |
| 150 | + } | ||
| 151 | + | ||
| 152 | + /** | ||
| 153 | + * Get the avatar for the user. | ||
| 154 | + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||
| 155 | + */ | ||
| 156 | + public function avatar() | ||
| 157 | + { | ||
| 158 | + return $this->belongsTo('BookStack\Image', 'image_id'); | ||
| 150 | } | 159 | } |
| 151 | 160 | ||
| 152 | /** | 161 | /** | ... | ... |
app/helpers.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +if (! function_exists('versioned_asset')) { | ||
| 4 | + /** | ||
| 5 | + * Get the path to a versioned file. | ||
| 6 | + * | ||
| 7 | + * @param string $file | ||
| 8 | + * @return string | ||
| 9 | + * | ||
| 10 | + * @throws \InvalidArgumentException | ||
| 11 | + */ | ||
| 12 | + function versioned_asset($file) | ||
| 13 | + { | ||
| 14 | + static $manifest = null; | ||
| 15 | + | ||
| 16 | + if (is_null($manifest)) { | ||
| 17 | + $manifest = json_decode(file_get_contents(public_path('build/manifest.json')), true); | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + if (isset($manifest[$file])) { | ||
| 21 | + return '/' . $manifest[$file]; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + if (file_exists(public_path($file))) { | ||
| 25 | + return '/' . $file; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + throw new InvalidArgumentException("File {$file} not defined in asset manifest."); | ||
| 29 | + } | ||
| 30 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -8,15 +8,16 @@ | ... | @@ -8,15 +8,16 @@ |
| 8 | "php": ">=5.5.9", | 8 | "php": ">=5.5.9", |
| 9 | "laravel/framework": "5.1.*", | 9 | "laravel/framework": "5.1.*", |
| 10 | "intervention/image": "^2.3", | 10 | "intervention/image": "^2.3", |
| 11 | - "laravel/socialite": "^2.0" | 11 | + "laravel/socialite": "^2.0", |
| 12 | + "barryvdh/laravel-ide-helper": "^2.1", | ||
| 13 | + "barryvdh/laravel-debugbar": "^2.0", | ||
| 14 | + "league/flysystem-aws-s3-v3": "^1.0" | ||
| 12 | }, | 15 | }, |
| 13 | "require-dev": { | 16 | "require-dev": { |
| 14 | "fzaninotto/faker": "~1.4", | 17 | "fzaninotto/faker": "~1.4", |
| 15 | "mockery/mockery": "0.9.*", | 18 | "mockery/mockery": "0.9.*", |
| 16 | "phpunit/phpunit": "~4.0", | 19 | "phpunit/phpunit": "~4.0", |
| 17 | - "phpspec/phpspec": "~2.1", | 20 | + "phpspec/phpspec": "~2.1" |
| 18 | - "barryvdh/laravel-ide-helper": "^2.1", | ||
| 19 | - "barryvdh/laravel-debugbar": "^2.0" | ||
| 20 | }, | 21 | }, |
| 21 | "autoload": { | 22 | "autoload": { |
| 22 | "classmap": [ | 23 | "classmap": [ |
| ... | @@ -24,7 +25,10 @@ | ... | @@ -24,7 +25,10 @@ |
| 24 | ], | 25 | ], |
| 25 | "psr-4": { | 26 | "psr-4": { |
| 26 | "BookStack\\": "app/" | 27 | "BookStack\\": "app/" |
| 27 | - } | 28 | + }, |
| 29 | + "files": [ | ||
| 30 | + "app/helpers.php" | ||
| 31 | + ] | ||
| 28 | }, | 32 | }, |
| 29 | "autoload-dev": { | 33 | "autoload-dev": { |
| 30 | "classmap": [ | 34 | "classmap": [ | ... | ... |
| ... | @@ -4,10 +4,88 @@ | ... | @@ -4,10 +4,88 @@ |
| 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", | 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", |
| 5 | "This file is @generated automatically" | 5 | "This file is @generated automatically" |
| 6 | ], | 6 | ], |
| 7 | - "hash": "c216d0bcb72b4f2008d7fa8067da2f77", | 7 | + "hash": "19725116631f01881caafa33052eecb9", |
| 8 | - "content-hash": "3c421ae5b8e5c11792249142cb96ff25", | 8 | + "content-hash": "f1dbd776f0ae13ec99e4e6d99510cd8e", |
| 9 | "packages": [ | 9 | "packages": [ |
| 10 | { | 10 | { |
| 11 | + "name": "aws/aws-sdk-php", | ||
| 12 | + "version": "3.11.4", | ||
| 13 | + "source": { | ||
| 14 | + "type": "git", | ||
| 15 | + "url": "https://github.com/aws/aws-sdk-php.git", | ||
| 16 | + "reference": "2524c78e0fa1ed049719b8b6b0696f0b6dfb1ca2" | ||
| 17 | + }, | ||
| 18 | + "dist": { | ||
| 19 | + "type": "zip", | ||
| 20 | + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2524c78e0fa1ed049719b8b6b0696f0b6dfb1ca2", | ||
| 21 | + "reference": "2524c78e0fa1ed049719b8b6b0696f0b6dfb1ca2", | ||
| 22 | + "shasum": "" | ||
| 23 | + }, | ||
| 24 | + "require": { | ||
| 25 | + "guzzlehttp/guzzle": "~5.3|~6.0.1|~6.1", | ||
| 26 | + "guzzlehttp/promises": "~1.0", | ||
| 27 | + "guzzlehttp/psr7": "~1.0", | ||
| 28 | + "mtdowling/jmespath.php": "~2.2", | ||
| 29 | + "php": ">=5.5" | ||
| 30 | + }, | ||
| 31 | + "require-dev": { | ||
| 32 | + "andrewsville/php-token-reflection": "^1.4", | ||
| 33 | + "aws/aws-php-sns-message-validator": "~1.0", | ||
| 34 | + "behat/behat": "~3.0", | ||
| 35 | + "doctrine/cache": "~1.4", | ||
| 36 | + "ext-dom": "*", | ||
| 37 | + "ext-json": "*", | ||
| 38 | + "ext-openssl": "*", | ||
| 39 | + "ext-pcre": "*", | ||
| 40 | + "ext-simplexml": "*", | ||
| 41 | + "ext-spl": "*", | ||
| 42 | + "nette/neon": "^2.3", | ||
| 43 | + "phpunit/phpunit": "~4.0" | ||
| 44 | + }, | ||
| 45 | + "suggest": { | ||
| 46 | + "doctrine/cache": "To use the DoctrineCacheAdapter", | ||
| 47 | + "ext-curl": "To send requests using cURL", | ||
| 48 | + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages" | ||
| 49 | + }, | ||
| 50 | + "type": "library", | ||
| 51 | + "extra": { | ||
| 52 | + "branch-alias": { | ||
| 53 | + "dev-master": "3.0-dev" | ||
| 54 | + } | ||
| 55 | + }, | ||
| 56 | + "autoload": { | ||
| 57 | + "psr-4": { | ||
| 58 | + "Aws\\": "src/" | ||
| 59 | + }, | ||
| 60 | + "files": [ | ||
| 61 | + "src/functions.php" | ||
| 62 | + ] | ||
| 63 | + }, | ||
| 64 | + "notification-url": "https://packagist.org/downloads/", | ||
| 65 | + "license": [ | ||
| 66 | + "Apache-2.0" | ||
| 67 | + ], | ||
| 68 | + "authors": [ | ||
| 69 | + { | ||
| 70 | + "name": "Amazon Web Services", | ||
| 71 | + "homepage": "http://aws.amazon.com" | ||
| 72 | + } | ||
| 73 | + ], | ||
| 74 | + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", | ||
| 75 | + "homepage": "http://aws.amazon.com/sdkforphp", | ||
| 76 | + "keywords": [ | ||
| 77 | + "amazon", | ||
| 78 | + "aws", | ||
| 79 | + "cloud", | ||
| 80 | + "dynamodb", | ||
| 81 | + "ec2", | ||
| 82 | + "glacier", | ||
| 83 | + "s3", | ||
| 84 | + "sdk" | ||
| 85 | + ], | ||
| 86 | + "time": "2015-12-04 01:19:53" | ||
| 87 | + }, | ||
| 88 | + { | ||
| 11 | "name": "barryvdh/laravel-debugbar", | 89 | "name": "barryvdh/laravel-debugbar", |
| 12 | "version": "v2.0.6", | 90 | "version": "v2.0.6", |
| 13 | "source": { | 91 | "source": { |
| ... | @@ -126,29 +204,29 @@ | ... | @@ -126,29 +204,29 @@ |
| 126 | }, | 204 | }, |
| 127 | { | 205 | { |
| 128 | "name": "classpreloader/classpreloader", | 206 | "name": "classpreloader/classpreloader", |
| 129 | - "version": "2.0.0", | 207 | + "version": "3.0.0", |
| 130 | "source": { | 208 | "source": { |
| 131 | "type": "git", | 209 | "type": "git", |
| 132 | "url": "https://github.com/ClassPreloader/ClassPreloader.git", | 210 | "url": "https://github.com/ClassPreloader/ClassPreloader.git", |
| 133 | - "reference": "8c3c14b10309e3b40bce833913a6c0c0b8c8f962" | 211 | + "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a" |
| 134 | }, | 212 | }, |
| 135 | "dist": { | 213 | "dist": { |
| 136 | "type": "zip", | 214 | "type": "zip", |
| 137 | - "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/8c3c14b10309e3b40bce833913a6c0c0b8c8f962", | 215 | + "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/9b10b913c2bdf90c3d2e0d726b454fb7f77c552a", |
| 138 | - "reference": "8c3c14b10309e3b40bce833913a6c0c0b8c8f962", | 216 | + "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a", |
| 139 | "shasum": "" | 217 | "shasum": "" |
| 140 | }, | 218 | }, |
| 141 | "require": { | 219 | "require": { |
| 142 | - "nikic/php-parser": "~1.3", | 220 | + "nikic/php-parser": "^1.0|^2.0", |
| 143 | "php": ">=5.5.9" | 221 | "php": ">=5.5.9" |
| 144 | }, | 222 | }, |
| 145 | "require-dev": { | 223 | "require-dev": { |
| 146 | - "phpunit/phpunit": "~4.0" | 224 | + "phpunit/phpunit": "^4.8|^5.0" |
| 147 | }, | 225 | }, |
| 148 | "type": "library", | 226 | "type": "library", |
| 149 | "extra": { | 227 | "extra": { |
| 150 | "branch-alias": { | 228 | "branch-alias": { |
| 151 | - "dev-master": "2.0-dev" | 229 | + "dev-master": "3.0-dev" |
| 152 | } | 230 | } |
| 153 | }, | 231 | }, |
| 154 | "autoload": { | 232 | "autoload": { |
| ... | @@ -176,7 +254,7 @@ | ... | @@ -176,7 +254,7 @@ |
| 176 | "class", | 254 | "class", |
| 177 | "preload" | 255 | "preload" |
| 178 | ], | 256 | ], |
| 179 | - "time": "2015-06-28 21:39:13" | 257 | + "time": "2015-11-09 22:51:51" |
| 180 | }, | 258 | }, |
| 181 | { | 259 | { |
| 182 | "name": "danielstjules/stringy", | 260 | "name": "danielstjules/stringy", |
| ... | @@ -269,16 +347,16 @@ | ... | @@ -269,16 +347,16 @@ |
| 269 | }, | 347 | }, |
| 270 | { | 348 | { |
| 271 | "name": "doctrine/inflector", | 349 | "name": "doctrine/inflector", |
| 272 | - "version": "v1.0.1", | 350 | + "version": "v1.1.0", |
| 273 | "source": { | 351 | "source": { |
| 274 | "type": "git", | 352 | "type": "git", |
| 275 | "url": "https://github.com/doctrine/inflector.git", | 353 | "url": "https://github.com/doctrine/inflector.git", |
| 276 | - "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604" | 354 | + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" |
| 277 | }, | 355 | }, |
| 278 | "dist": { | 356 | "dist": { |
| 279 | "type": "zip", | 357 | "type": "zip", |
| 280 | - "url": "https://api.github.com/repos/doctrine/inflector/zipball/0bcb2e79d8571787f18b7eb036ed3d004908e604", | 358 | + "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", |
| 281 | - "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604", | 359 | + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", |
| 282 | "shasum": "" | 360 | "shasum": "" |
| 283 | }, | 361 | }, |
| 284 | "require": { | 362 | "require": { |
| ... | @@ -290,7 +368,7 @@ | ... | @@ -290,7 +368,7 @@ |
| 290 | "type": "library", | 368 | "type": "library", |
| 291 | "extra": { | 369 | "extra": { |
| 292 | "branch-alias": { | 370 | "branch-alias": { |
| 293 | - "dev-master": "1.0.x-dev" | 371 | + "dev-master": "1.1.x-dev" |
| 294 | } | 372 | } |
| 295 | }, | 373 | }, |
| 296 | "autoload": { | 374 | "autoload": { |
| ... | @@ -332,7 +410,7 @@ | ... | @@ -332,7 +410,7 @@ |
| 332 | "singularize", | 410 | "singularize", |
| 333 | "string" | 411 | "string" |
| 334 | ], | 412 | ], |
| 335 | - "time": "2014-12-20 21:24:13" | 413 | + "time": "2015-11-06 14:35:42" |
| 336 | }, | 414 | }, |
| 337 | { | 415 | { |
| 338 | "name": "guzzle/guzzle", | 416 | "name": "guzzle/guzzle", |
| ... | @@ -431,16 +509,16 @@ | ... | @@ -431,16 +509,16 @@ |
| 431 | }, | 509 | }, |
| 432 | { | 510 | { |
| 433 | "name": "guzzlehttp/guzzle", | 511 | "name": "guzzlehttp/guzzle", |
| 434 | - "version": "6.0.2", | 512 | + "version": "6.1.1", |
| 435 | "source": { | 513 | "source": { |
| 436 | "type": "git", | 514 | "type": "git", |
| 437 | "url": "https://github.com/guzzle/guzzle.git", | 515 | "url": "https://github.com/guzzle/guzzle.git", |
| 438 | - "reference": "a8dfeff00eb84616a17fea7a4d72af35e750410f" | 516 | + "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c" |
| 439 | }, | 517 | }, |
| 440 | "dist": { | 518 | "dist": { |
| 441 | "type": "zip", | 519 | "type": "zip", |
| 442 | - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a8dfeff00eb84616a17fea7a4d72af35e750410f", | 520 | + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/c6851d6e48f63b69357cbfa55bca116448140e0c", |
| 443 | - "reference": "a8dfeff00eb84616a17fea7a4d72af35e750410f", | 521 | + "reference": "c6851d6e48f63b69357cbfa55bca116448140e0c", |
| 444 | "shasum": "" | 522 | "shasum": "" |
| 445 | }, | 523 | }, |
| 446 | "require": { | 524 | "require": { |
| ... | @@ -456,7 +534,7 @@ | ... | @@ -456,7 +534,7 @@ |
| 456 | "type": "library", | 534 | "type": "library", |
| 457 | "extra": { | 535 | "extra": { |
| 458 | "branch-alias": { | 536 | "branch-alias": { |
| 459 | - "dev-master": "6.0-dev" | 537 | + "dev-master": "6.1-dev" |
| 460 | } | 538 | } |
| 461 | }, | 539 | }, |
| 462 | "autoload": { | 540 | "autoload": { |
| ... | @@ -489,20 +567,20 @@ | ... | @@ -489,20 +567,20 @@ |
| 489 | "rest", | 567 | "rest", |
| 490 | "web service" | 568 | "web service" |
| 491 | ], | 569 | ], |
| 492 | - "time": "2015-07-04 20:09:24" | 570 | + "time": "2015-11-23 00:47:50" |
| 493 | }, | 571 | }, |
| 494 | { | 572 | { |
| 495 | "name": "guzzlehttp/promises", | 573 | "name": "guzzlehttp/promises", |
| 496 | - "version": "1.0.2", | 574 | + "version": "1.0.3", |
| 497 | "source": { | 575 | "source": { |
| 498 | "type": "git", | 576 | "type": "git", |
| 499 | "url": "https://github.com/guzzle/promises.git", | 577 | "url": "https://github.com/guzzle/promises.git", |
| 500 | - "reference": "97fe7210def29451ec74923b27e552238defd75a" | 578 | + "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea" |
| 501 | }, | 579 | }, |
| 502 | "dist": { | 580 | "dist": { |
| 503 | "type": "zip", | 581 | "type": "zip", |
| 504 | - "url": "https://api.github.com/repos/guzzle/promises/zipball/97fe7210def29451ec74923b27e552238defd75a", | 582 | + "url": "https://api.github.com/repos/guzzle/promises/zipball/b1e1c0d55f8083c71eda2c28c12a228d708294ea", |
| 505 | - "reference": "97fe7210def29451ec74923b27e552238defd75a", | 583 | + "reference": "b1e1c0d55f8083c71eda2c28c12a228d708294ea", |
| 506 | "shasum": "" | 584 | "shasum": "" |
| 507 | }, | 585 | }, |
| 508 | "require": { | 586 | "require": { |
| ... | @@ -540,20 +618,20 @@ | ... | @@ -540,20 +618,20 @@ |
| 540 | "keywords": [ | 618 | "keywords": [ |
| 541 | "promise" | 619 | "promise" |
| 542 | ], | 620 | ], |
| 543 | - "time": "2015-08-15 19:37:21" | 621 | + "time": "2015-10-15 22:28:00" |
| 544 | }, | 622 | }, |
| 545 | { | 623 | { |
| 546 | "name": "guzzlehttp/psr7", | 624 | "name": "guzzlehttp/psr7", |
| 547 | - "version": "1.2.0", | 625 | + "version": "1.2.1", |
| 548 | "source": { | 626 | "source": { |
| 549 | "type": "git", | 627 | "type": "git", |
| 550 | "url": "https://github.com/guzzle/psr7.git", | 628 | "url": "https://github.com/guzzle/psr7.git", |
| 551 | - "reference": "4ef919b0cf3b1989523138b60163bbcb7ba1ff7e" | 629 | + "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982" |
| 552 | }, | 630 | }, |
| 553 | "dist": { | 631 | "dist": { |
| 554 | "type": "zip", | 632 | "type": "zip", |
| 555 | - "url": "https://api.github.com/repos/guzzle/psr7/zipball/4ef919b0cf3b1989523138b60163bbcb7ba1ff7e", | 633 | + "url": "https://api.github.com/repos/guzzle/psr7/zipball/4d0bdbe1206df7440219ce14c972aa57cc5e4982", |
| 556 | - "reference": "4ef919b0cf3b1989523138b60163bbcb7ba1ff7e", | 634 | + "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982", |
| 557 | "shasum": "" | 635 | "shasum": "" |
| 558 | }, | 636 | }, |
| 559 | "require": { | 637 | "require": { |
| ... | @@ -598,20 +676,20 @@ | ... | @@ -598,20 +676,20 @@ |
| 598 | "stream", | 676 | "stream", |
| 599 | "uri" | 677 | "uri" |
| 600 | ], | 678 | ], |
| 601 | - "time": "2015-08-15 19:32:36" | 679 | + "time": "2015-11-03 01:34:55" |
| 602 | }, | 680 | }, |
| 603 | { | 681 | { |
| 604 | "name": "intervention/image", | 682 | "name": "intervention/image", |
| 605 | - "version": "2.3.1", | 683 | + "version": "2.3.4", |
| 606 | "source": { | 684 | "source": { |
| 607 | "type": "git", | 685 | "type": "git", |
| 608 | "url": "https://github.com/Intervention/image.git", | 686 | "url": "https://github.com/Intervention/image.git", |
| 609 | - "reference": "156f9d6f8a186c68b92f0c50084718f02dae1b5f" | 687 | + "reference": "a67ee32df0c6820cc6e861ad4144ee0ef9c74aa3" |
| 610 | }, | 688 | }, |
| 611 | "dist": { | 689 | "dist": { |
| 612 | "type": "zip", | 690 | "type": "zip", |
| 613 | - "url": "https://api.github.com/repos/Intervention/image/zipball/156f9d6f8a186c68b92f0c50084718f02dae1b5f", | 691 | + "url": "https://api.github.com/repos/Intervention/image/zipball/a67ee32df0c6820cc6e861ad4144ee0ef9c74aa3", |
| 614 | - "reference": "156f9d6f8a186c68b92f0c50084718f02dae1b5f", | 692 | + "reference": "a67ee32df0c6820cc6e861ad4144ee0ef9c74aa3", |
| 615 | "shasum": "" | 693 | "shasum": "" |
| 616 | }, | 694 | }, |
| 617 | "require": { | 695 | "require": { |
| ... | @@ -660,7 +738,7 @@ | ... | @@ -660,7 +738,7 @@ |
| 660 | "thumbnail", | 738 | "thumbnail", |
| 661 | "watermark" | 739 | "watermark" |
| 662 | ], | 740 | ], |
| 663 | - "time": "2015-07-10 15:03:58" | 741 | + "time": "2015-11-30 17:03:21" |
| 664 | }, | 742 | }, |
| 665 | { | 743 | { |
| 666 | "name": "jakub-onderka/php-console-color", | 744 | "name": "jakub-onderka/php-console-color", |
| ... | @@ -809,20 +887,20 @@ | ... | @@ -809,20 +887,20 @@ |
| 809 | }, | 887 | }, |
| 810 | { | 888 | { |
| 811 | "name": "laravel/framework", | 889 | "name": "laravel/framework", |
| 812 | - "version": "v5.1.10", | 890 | + "version": "v5.1.25", |
| 813 | "source": { | 891 | "source": { |
| 814 | "type": "git", | 892 | "type": "git", |
| 815 | "url": "https://github.com/laravel/framework.git", | 893 | "url": "https://github.com/laravel/framework.git", |
| 816 | - "reference": "d47ccc8de10ccb6f328cc90f901ca5e47e077c93" | 894 | + "reference": "53979acc664debc401bfcb61086c4fc4f196b22d" |
| 817 | }, | 895 | }, |
| 818 | "dist": { | 896 | "dist": { |
| 819 | "type": "zip", | 897 | "type": "zip", |
| 820 | - "url": "https://api.github.com/repos/laravel/framework/zipball/d47ccc8de10ccb6f328cc90f901ca5e47e077c93", | 898 | + "url": "https://api.github.com/repos/laravel/framework/zipball/53979acc664debc401bfcb61086c4fc4f196b22d", |
| 821 | - "reference": "d47ccc8de10ccb6f328cc90f901ca5e47e077c93", | 899 | + "reference": "53979acc664debc401bfcb61086c4fc4f196b22d", |
| 822 | "shasum": "" | 900 | "shasum": "" |
| 823 | }, | 901 | }, |
| 824 | "require": { | 902 | "require": { |
| 825 | - "classpreloader/classpreloader": "~2.0", | 903 | + "classpreloader/classpreloader": "~2.0|~3.0", |
| 826 | "danielstjules/stringy": "~1.8", | 904 | "danielstjules/stringy": "~1.8", |
| 827 | "doctrine/inflector": "~1.0", | 905 | "doctrine/inflector": "~1.0", |
| 828 | "ext-mbstring": "*", | 906 | "ext-mbstring": "*", |
| ... | @@ -832,8 +910,9 @@ | ... | @@ -832,8 +910,9 @@ |
| 832 | "monolog/monolog": "~1.11", | 910 | "monolog/monolog": "~1.11", |
| 833 | "mtdowling/cron-expression": "~1.0", | 911 | "mtdowling/cron-expression": "~1.0", |
| 834 | "nesbot/carbon": "~1.19", | 912 | "nesbot/carbon": "~1.19", |
| 913 | + "paragonie/random_compat": "~1.1", | ||
| 835 | "php": ">=5.5.9", | 914 | "php": ">=5.5.9", |
| 836 | - "psy/psysh": "~0.5.1", | 915 | + "psy/psysh": "0.6.*", |
| 837 | "swiftmailer/swiftmailer": "~5.1", | 916 | "swiftmailer/swiftmailer": "~5.1", |
| 838 | "symfony/console": "2.7.*", | 917 | "symfony/console": "2.7.*", |
| 839 | "symfony/css-selector": "2.7.*", | 918 | "symfony/css-selector": "2.7.*", |
| ... | @@ -882,7 +961,7 @@ | ... | @@ -882,7 +961,7 @@ |
| 882 | "require-dev": { | 961 | "require-dev": { |
| 883 | "aws/aws-sdk-php": "~3.0", | 962 | "aws/aws-sdk-php": "~3.0", |
| 884 | "iron-io/iron_mq": "~2.0", | 963 | "iron-io/iron_mq": "~2.0", |
| 885 | - "mockery/mockery": "~0.9.1", | 964 | + "mockery/mockery": "~0.9.2", |
| 886 | "pda/pheanstalk": "~3.0", | 965 | "pda/pheanstalk": "~3.0", |
| 887 | "phpunit/phpunit": "~4.0", | 966 | "phpunit/phpunit": "~4.0", |
| 888 | "predis/predis": "~1.0" | 967 | "predis/predis": "~1.0" |
| ... | @@ -933,20 +1012,20 @@ | ... | @@ -933,20 +1012,20 @@ |
| 933 | "framework", | 1012 | "framework", |
| 934 | "laravel" | 1013 | "laravel" |
| 935 | ], | 1014 | ], |
| 936 | - "time": "2015-08-12 18:16:08" | 1015 | + "time": "2015-11-30 19:24:36" |
| 937 | }, | 1016 | }, |
| 938 | { | 1017 | { |
| 939 | "name": "laravel/socialite", | 1018 | "name": "laravel/socialite", |
| 940 | - "version": "v2.0.12", | 1019 | + "version": "v2.0.14", |
| 941 | "source": { | 1020 | "source": { |
| 942 | "type": "git", | 1021 | "type": "git", |
| 943 | "url": "https://github.com/laravel/socialite.git", | 1022 | "url": "https://github.com/laravel/socialite.git", |
| 944 | - "reference": "0bb08c8666f4c01e55e3b3b0e42f2b5075be6a6e" | 1023 | + "reference": "b15f4be0ac739405120d74b837af423aa71502d9" |
| 945 | }, | 1024 | }, |
| 946 | "dist": { | 1025 | "dist": { |
| 947 | "type": "zip", | 1026 | "type": "zip", |
| 948 | - "url": "https://api.github.com/repos/laravel/socialite/zipball/0bb08c8666f4c01e55e3b3b0e42f2b5075be6a6e", | 1027 | + "url": "https://api.github.com/repos/laravel/socialite/zipball/b15f4be0ac739405120d74b837af423aa71502d9", |
| 949 | - "reference": "0bb08c8666f4c01e55e3b3b0e42f2b5075be6a6e", | 1028 | + "reference": "b15f4be0ac739405120d74b837af423aa71502d9", |
| 950 | "shasum": "" | 1029 | "shasum": "" |
| 951 | }, | 1030 | }, |
| 952 | "require": { | 1031 | "require": { |
| ... | @@ -987,25 +1066,28 @@ | ... | @@ -987,25 +1066,28 @@ |
| 987 | "laravel", | 1066 | "laravel", |
| 988 | "oauth" | 1067 | "oauth" |
| 989 | ], | 1068 | ], |
| 990 | - "time": "2015-08-30 01:12:56" | 1069 | + "time": "2015-10-16 15:39:46" |
| 991 | }, | 1070 | }, |
| 992 | { | 1071 | { |
| 993 | "name": "league/flysystem", | 1072 | "name": "league/flysystem", |
| 994 | - "version": "1.0.11", | 1073 | + "version": "1.0.15", |
| 995 | "source": { | 1074 | "source": { |
| 996 | "type": "git", | 1075 | "type": "git", |
| 997 | "url": "https://github.com/thephpleague/flysystem.git", | 1076 | "url": "https://github.com/thephpleague/flysystem.git", |
| 998 | - "reference": "c16222fdc02467eaa12cb6d6d0e65527741f6040" | 1077 | + "reference": "31525caf9e8772683672fefd8a1ca0c0736020f4" |
| 999 | }, | 1078 | }, |
| 1000 | "dist": { | 1079 | "dist": { |
| 1001 | "type": "zip", | 1080 | "type": "zip", |
| 1002 | - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/c16222fdc02467eaa12cb6d6d0e65527741f6040", | 1081 | + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/31525caf9e8772683672fefd8a1ca0c0736020f4", |
| 1003 | - "reference": "c16222fdc02467eaa12cb6d6d0e65527741f6040", | 1082 | + "reference": "31525caf9e8772683672fefd8a1ca0c0736020f4", |
| 1004 | "shasum": "" | 1083 | "shasum": "" |
| 1005 | }, | 1084 | }, |
| 1006 | "require": { | 1085 | "require": { |
| 1007 | "php": ">=5.4.0" | 1086 | "php": ">=5.4.0" |
| 1008 | }, | 1087 | }, |
| 1088 | + "conflict": { | ||
| 1089 | + "league/flysystem-sftp": "<1.0.6" | ||
| 1090 | + }, | ||
| 1009 | "require-dev": { | 1091 | "require-dev": { |
| 1010 | "ext-fileinfo": "*", | 1092 | "ext-fileinfo": "*", |
| 1011 | "mockery/mockery": "~0.9", | 1093 | "mockery/mockery": "~0.9", |
| ... | @@ -1068,20 +1150,67 @@ | ... | @@ -1068,20 +1150,67 @@ |
| 1068 | "sftp", | 1150 | "sftp", |
| 1069 | "storage" | 1151 | "storage" |
| 1070 | ], | 1152 | ], |
| 1071 | - "time": "2015-07-28 20:41:58" | 1153 | + "time": "2015-09-30 22:26:59" |
| 1154 | + }, | ||
| 1155 | + { | ||
| 1156 | + "name": "league/flysystem-aws-s3-v3", | ||
| 1157 | + "version": "1.0.9", | ||
| 1158 | + "source": { | ||
| 1159 | + "type": "git", | ||
| 1160 | + "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git", | ||
| 1161 | + "reference": "595e24678bf78f8107ebc9355d8376ae0eb712c6" | ||
| 1162 | + }, | ||
| 1163 | + "dist": { | ||
| 1164 | + "type": "zip", | ||
| 1165 | + "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/595e24678bf78f8107ebc9355d8376ae0eb712c6", | ||
| 1166 | + "reference": "595e24678bf78f8107ebc9355d8376ae0eb712c6", | ||
| 1167 | + "shasum": "" | ||
| 1168 | + }, | ||
| 1169 | + "require": { | ||
| 1170 | + "aws/aws-sdk-php": "^3.0.0", | ||
| 1171 | + "league/flysystem": "~1.0", | ||
| 1172 | + "php": ">=5.5.0" | ||
| 1173 | + }, | ||
| 1174 | + "require-dev": { | ||
| 1175 | + "henrikbjorn/phpspec-code-coverage": "~1.0.1", | ||
| 1176 | + "phpspec/phpspec": "^2.0.0" | ||
| 1177 | + }, | ||
| 1178 | + "type": "library", | ||
| 1179 | + "extra": { | ||
| 1180 | + "branch-alias": { | ||
| 1181 | + "dev-master": "1.0-dev" | ||
| 1182 | + } | ||
| 1183 | + }, | ||
| 1184 | + "autoload": { | ||
| 1185 | + "psr-4": { | ||
| 1186 | + "League\\Flysystem\\AwsS3v3\\": "src/" | ||
| 1187 | + } | ||
| 1188 | + }, | ||
| 1189 | + "notification-url": "https://packagist.org/downloads/", | ||
| 1190 | + "license": [ | ||
| 1191 | + "MIT" | ||
| 1192 | + ], | ||
| 1193 | + "authors": [ | ||
| 1194 | + { | ||
| 1195 | + "name": "Frank de Jonge", | ||
| 1196 | + "email": "info@frenky.net" | ||
| 1197 | + } | ||
| 1198 | + ], | ||
| 1199 | + "description": "Flysystem adapter for the AWS S3 SDK v3.x", | ||
| 1200 | + "time": "2015-11-19 08:44:16" | ||
| 1072 | }, | 1201 | }, |
| 1073 | { | 1202 | { |
| 1074 | "name": "league/oauth1-client", | 1203 | "name": "league/oauth1-client", |
| 1075 | - "version": "1.6.0", | 1204 | + "version": "1.6.1", |
| 1076 | "source": { | 1205 | "source": { |
| 1077 | "type": "git", | 1206 | "type": "git", |
| 1078 | "url": "https://github.com/thephpleague/oauth1-client.git", | 1207 | "url": "https://github.com/thephpleague/oauth1-client.git", |
| 1079 | - "reference": "4d4edd9b6014f882e319231a9b3351e3a1dfdc81" | 1208 | + "reference": "cef3ceda13c78f89c323e4d5e6301c0eb7cea422" |
| 1080 | }, | 1209 | }, |
| 1081 | "dist": { | 1210 | "dist": { |
| 1082 | "type": "zip", | 1211 | "type": "zip", |
| 1083 | - "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/4d4edd9b6014f882e319231a9b3351e3a1dfdc81", | 1212 | + "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/cef3ceda13c78f89c323e4d5e6301c0eb7cea422", |
| 1084 | - "reference": "4d4edd9b6014f882e319231a9b3351e3a1dfdc81", | 1213 | + "reference": "cef3ceda13c78f89c323e4d5e6301c0eb7cea422", |
| 1085 | "shasum": "" | 1214 | "shasum": "" |
| 1086 | }, | 1215 | }, |
| 1087 | "require": { | 1216 | "require": { |
| ... | @@ -1131,7 +1260,7 @@ | ... | @@ -1131,7 +1260,7 @@ |
| 1131 | "tumblr", | 1260 | "tumblr", |
| 1132 | "twitter" | 1261 | "twitter" |
| 1133 | ], | 1262 | ], |
| 1134 | - "time": "2015-08-22 09:49:14" | 1263 | + "time": "2015-10-23 04:02:07" |
| 1135 | }, | 1264 | }, |
| 1136 | { | 1265 | { |
| 1137 | "name": "maximebf/debugbar", | 1266 | "name": "maximebf/debugbar", |
| ... | @@ -1191,16 +1320,16 @@ | ... | @@ -1191,16 +1320,16 @@ |
| 1191 | }, | 1320 | }, |
| 1192 | { | 1321 | { |
| 1193 | "name": "monolog/monolog", | 1322 | "name": "monolog/monolog", |
| 1194 | - "version": "1.16.0", | 1323 | + "version": "1.17.2", |
| 1195 | "source": { | 1324 | "source": { |
| 1196 | "type": "git", | 1325 | "type": "git", |
| 1197 | "url": "https://github.com/Seldaek/monolog.git", | 1326 | "url": "https://github.com/Seldaek/monolog.git", |
| 1198 | - "reference": "c0c0b4bee3aabce7182876b0d912ef2595563db7" | 1327 | + "reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24" |
| 1199 | }, | 1328 | }, |
| 1200 | "dist": { | 1329 | "dist": { |
| 1201 | "type": "zip", | 1330 | "type": "zip", |
| 1202 | - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c0c0b4bee3aabce7182876b0d912ef2595563db7", | 1331 | + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bee7f0dc9c3e0b69a6039697533dca1e845c8c24", |
| 1203 | - "reference": "c0c0b4bee3aabce7182876b0d912ef2595563db7", | 1332 | + "reference": "bee7f0dc9c3e0b69a6039697533dca1e845c8c24", |
| 1204 | "shasum": "" | 1333 | "shasum": "" |
| 1205 | }, | 1334 | }, |
| 1206 | "require": { | 1335 | "require": { |
| ... | @@ -1214,10 +1343,11 @@ | ... | @@ -1214,10 +1343,11 @@ |
| 1214 | "aws/aws-sdk-php": "^2.4.9", | 1343 | "aws/aws-sdk-php": "^2.4.9", |
| 1215 | "doctrine/couchdb": "~1.0@dev", | 1344 | "doctrine/couchdb": "~1.0@dev", |
| 1216 | "graylog2/gelf-php": "~1.0", | 1345 | "graylog2/gelf-php": "~1.0", |
| 1346 | + "jakub-onderka/php-parallel-lint": "0.9", | ||
| 1217 | "php-console/php-console": "^3.1.3", | 1347 | "php-console/php-console": "^3.1.3", |
| 1218 | "phpunit/phpunit": "~4.5", | 1348 | "phpunit/phpunit": "~4.5", |
| 1219 | "phpunit/phpunit-mock-objects": "2.3.0", | 1349 | "phpunit/phpunit-mock-objects": "2.3.0", |
| 1220 | - "raven/raven": "~0.8", | 1350 | + "raven/raven": "^0.13", |
| 1221 | "ruflin/elastica": ">=0.90 <3.0", | 1351 | "ruflin/elastica": ">=0.90 <3.0", |
| 1222 | "swiftmailer/swiftmailer": "~5.3", | 1352 | "swiftmailer/swiftmailer": "~5.3", |
| 1223 | "videlalvaro/php-amqplib": "~2.4" | 1353 | "videlalvaro/php-amqplib": "~2.4" |
| ... | @@ -1263,7 +1393,7 @@ | ... | @@ -1263,7 +1393,7 @@ |
| 1263 | "logging", | 1393 | "logging", |
| 1264 | "psr-3" | 1394 | "psr-3" |
| 1265 | ], | 1395 | ], |
| 1266 | - "time": "2015-08-09 17:44:44" | 1396 | + "time": "2015-10-14 12:51:02" |
| 1267 | }, | 1397 | }, |
| 1268 | { | 1398 | { |
| 1269 | "name": "mtdowling/cron-expression", | 1399 | "name": "mtdowling/cron-expression", |
| ... | @@ -1310,17 +1440,72 @@ | ... | @@ -1310,17 +1440,72 @@ |
| 1310 | "time": "2015-01-11 23:07:46" | 1440 | "time": "2015-01-11 23:07:46" |
| 1311 | }, | 1441 | }, |
| 1312 | { | 1442 | { |
| 1443 | + "name": "mtdowling/jmespath.php", | ||
| 1444 | + "version": "2.2.0", | ||
| 1445 | + "source": { | ||
| 1446 | + "type": "git", | ||
| 1447 | + "url": "https://github.com/jmespath/jmespath.php.git", | ||
| 1448 | + "reference": "a7d99d0c836e69d27b7bfca1d33ca2759fba3289" | ||
| 1449 | + }, | ||
| 1450 | + "dist": { | ||
| 1451 | + "type": "zip", | ||
| 1452 | + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/a7d99d0c836e69d27b7bfca1d33ca2759fba3289", | ||
| 1453 | + "reference": "a7d99d0c836e69d27b7bfca1d33ca2759fba3289", | ||
| 1454 | + "shasum": "" | ||
| 1455 | + }, | ||
| 1456 | + "require": { | ||
| 1457 | + "php": ">=5.4.0" | ||
| 1458 | + }, | ||
| 1459 | + "require-dev": { | ||
| 1460 | + "phpunit/phpunit": "~4.0" | ||
| 1461 | + }, | ||
| 1462 | + "bin": [ | ||
| 1463 | + "bin/jp.php" | ||
| 1464 | + ], | ||
| 1465 | + "type": "library", | ||
| 1466 | + "extra": { | ||
| 1467 | + "branch-alias": { | ||
| 1468 | + "dev-master": "2.0-dev" | ||
| 1469 | + } | ||
| 1470 | + }, | ||
| 1471 | + "autoload": { | ||
| 1472 | + "psr-4": { | ||
| 1473 | + "JmesPath\\": "src/" | ||
| 1474 | + }, | ||
| 1475 | + "files": [ | ||
| 1476 | + "src/JmesPath.php" | ||
| 1477 | + ] | ||
| 1478 | + }, | ||
| 1479 | + "notification-url": "https://packagist.org/downloads/", | ||
| 1480 | + "license": [ | ||
| 1481 | + "MIT" | ||
| 1482 | + ], | ||
| 1483 | + "authors": [ | ||
| 1484 | + { | ||
| 1485 | + "name": "Michael Dowling", | ||
| 1486 | + "email": "mtdowling@gmail.com", | ||
| 1487 | + "homepage": "https://github.com/mtdowling" | ||
| 1488 | + } | ||
| 1489 | + ], | ||
| 1490 | + "description": "Declaratively specify how to extract elements from a JSON document", | ||
| 1491 | + "keywords": [ | ||
| 1492 | + "json", | ||
| 1493 | + "jsonpath" | ||
| 1494 | + ], | ||
| 1495 | + "time": "2015-05-27 17:21:31" | ||
| 1496 | + }, | ||
| 1497 | + { | ||
| 1313 | "name": "nesbot/carbon", | 1498 | "name": "nesbot/carbon", |
| 1314 | - "version": "1.20.0", | 1499 | + "version": "1.21.0", |
| 1315 | "source": { | 1500 | "source": { |
| 1316 | "type": "git", | 1501 | "type": "git", |
| 1317 | "url": "https://github.com/briannesbitt/Carbon.git", | 1502 | "url": "https://github.com/briannesbitt/Carbon.git", |
| 1318 | - "reference": "bfd3eaba109c9a2405c92174c8e17f20c2b9caf3" | 1503 | + "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7" |
| 1319 | }, | 1504 | }, |
| 1320 | "dist": { | 1505 | "dist": { |
| 1321 | "type": "zip", | 1506 | "type": "zip", |
| 1322 | - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/bfd3eaba109c9a2405c92174c8e17f20c2b9caf3", | 1507 | + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7b08ec6f75791e130012f206e3f7b0e76e18e3d7", |
| 1323 | - "reference": "bfd3eaba109c9a2405c92174c8e17f20c2b9caf3", | 1508 | + "reference": "7b08ec6f75791e130012f206e3f7b0e76e18e3d7", |
| 1324 | "shasum": "" | 1509 | "shasum": "" |
| 1325 | }, | 1510 | }, |
| 1326 | "require": { | 1511 | "require": { |
| ... | @@ -1328,12 +1513,12 @@ | ... | @@ -1328,12 +1513,12 @@ |
| 1328 | "symfony/translation": "~2.6|~3.0" | 1513 | "symfony/translation": "~2.6|~3.0" |
| 1329 | }, | 1514 | }, |
| 1330 | "require-dev": { | 1515 | "require-dev": { |
| 1331 | - "phpunit/phpunit": "~4.0" | 1516 | + "phpunit/phpunit": "~4.0|~5.0" |
| 1332 | }, | 1517 | }, |
| 1333 | "type": "library", | 1518 | "type": "library", |
| 1334 | "autoload": { | 1519 | "autoload": { |
| 1335 | - "psr-0": { | 1520 | + "psr-4": { |
| 1336 | - "Carbon": "src" | 1521 | + "Carbon\\": "src/Carbon/" |
| 1337 | } | 1522 | } |
| 1338 | }, | 1523 | }, |
| 1339 | "notification-url": "https://packagist.org/downloads/", | 1524 | "notification-url": "https://packagist.org/downloads/", |
| ... | @@ -1354,20 +1539,20 @@ | ... | @@ -1354,20 +1539,20 @@ |
| 1354 | "datetime", | 1539 | "datetime", |
| 1355 | "time" | 1540 | "time" |
| 1356 | ], | 1541 | ], |
| 1357 | - "time": "2015-06-25 04:19:39" | 1542 | + "time": "2015-11-04 20:07:17" |
| 1358 | }, | 1543 | }, |
| 1359 | { | 1544 | { |
| 1360 | "name": "nikic/php-parser", | 1545 | "name": "nikic/php-parser", |
| 1361 | - "version": "v1.4.0", | 1546 | + "version": "v1.4.1", |
| 1362 | "source": { | 1547 | "source": { |
| 1363 | "type": "git", | 1548 | "type": "git", |
| 1364 | "url": "https://github.com/nikic/PHP-Parser.git", | 1549 | "url": "https://github.com/nikic/PHP-Parser.git", |
| 1365 | - "reference": "196f177cfefa0f1f7166c0a05d8255889be12418" | 1550 | + "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51" |
| 1366 | }, | 1551 | }, |
| 1367 | "dist": { | 1552 | "dist": { |
| 1368 | "type": "zip", | 1553 | "type": "zip", |
| 1369 | - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/196f177cfefa0f1f7166c0a05d8255889be12418", | 1554 | + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", |
| 1370 | - "reference": "196f177cfefa0f1f7166c0a05d8255889be12418", | 1555 | + "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", |
| 1371 | "shasum": "" | 1556 | "shasum": "" |
| 1372 | }, | 1557 | }, |
| 1373 | "require": { | 1558 | "require": { |
| ... | @@ -1399,7 +1584,55 @@ | ... | @@ -1399,7 +1584,55 @@ |
| 1399 | "parser", | 1584 | "parser", |
| 1400 | "php" | 1585 | "php" |
| 1401 | ], | 1586 | ], |
| 1402 | - "time": "2015-07-14 17:31:05" | 1587 | + "time": "2015-09-19 14:15:08" |
| 1588 | + }, | ||
| 1589 | + { | ||
| 1590 | + "name": "paragonie/random_compat", | ||
| 1591 | + "version": "1.1.1", | ||
| 1592 | + "source": { | ||
| 1593 | + "type": "git", | ||
| 1594 | + "url": "https://github.com/paragonie/random_compat.git", | ||
| 1595 | + "reference": "a208865a5aeffc2dbbef2a5b3409887272d93f32" | ||
| 1596 | + }, | ||
| 1597 | + "dist": { | ||
| 1598 | + "type": "zip", | ||
| 1599 | + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/a208865a5aeffc2dbbef2a5b3409887272d93f32", | ||
| 1600 | + "reference": "a208865a5aeffc2dbbef2a5b3409887272d93f32", | ||
| 1601 | + "shasum": "" | ||
| 1602 | + }, | ||
| 1603 | + "require": { | ||
| 1604 | + "php": ">=5.2.0" | ||
| 1605 | + }, | ||
| 1606 | + "require-dev": { | ||
| 1607 | + "phpunit/phpunit": "4.*|5.*" | ||
| 1608 | + }, | ||
| 1609 | + "suggest": { | ||
| 1610 | + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." | ||
| 1611 | + }, | ||
| 1612 | + "type": "library", | ||
| 1613 | + "autoload": { | ||
| 1614 | + "files": [ | ||
| 1615 | + "lib/random.php" | ||
| 1616 | + ] | ||
| 1617 | + }, | ||
| 1618 | + "notification-url": "https://packagist.org/downloads/", | ||
| 1619 | + "license": [ | ||
| 1620 | + "MIT" | ||
| 1621 | + ], | ||
| 1622 | + "authors": [ | ||
| 1623 | + { | ||
| 1624 | + "name": "Paragon Initiative Enterprises", | ||
| 1625 | + "email": "security@paragonie.com", | ||
| 1626 | + "homepage": "https://paragonie.com" | ||
| 1627 | + } | ||
| 1628 | + ], | ||
| 1629 | + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", | ||
| 1630 | + "keywords": [ | ||
| 1631 | + "csprng", | ||
| 1632 | + "pseudorandom", | ||
| 1633 | + "random" | ||
| 1634 | + ], | ||
| 1635 | + "time": "2015-12-01 02:52:15" | ||
| 1403 | }, | 1636 | }, |
| 1404 | { | 1637 | { |
| 1405 | "name": "phpdocumentor/reflection-docblock", | 1638 | "name": "phpdocumentor/reflection-docblock", |
| ... | @@ -1539,29 +1772,29 @@ | ... | @@ -1539,29 +1772,29 @@ |
| 1539 | }, | 1772 | }, |
| 1540 | { | 1773 | { |
| 1541 | "name": "psy/psysh", | 1774 | "name": "psy/psysh", |
| 1542 | - "version": "v0.5.2", | 1775 | + "version": "v0.6.1", |
| 1543 | "source": { | 1776 | "source": { |
| 1544 | "type": "git", | 1777 | "type": "git", |
| 1545 | "url": "https://github.com/bobthecow/psysh.git", | 1778 | "url": "https://github.com/bobthecow/psysh.git", |
| 1546 | - "reference": "aaf8772ade08b5f0f6830774a5d5c2f800415975" | 1779 | + "reference": "0f04df0b23663799a8941fae13cd8e6299bde3ed" |
| 1547 | }, | 1780 | }, |
| 1548 | "dist": { | 1781 | "dist": { |
| 1549 | "type": "zip", | 1782 | "type": "zip", |
| 1550 | - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/aaf8772ade08b5f0f6830774a5d5c2f800415975", | 1783 | + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/0f04df0b23663799a8941fae13cd8e6299bde3ed", |
| 1551 | - "reference": "aaf8772ade08b5f0f6830774a5d5c2f800415975", | 1784 | + "reference": "0f04df0b23663799a8941fae13cd8e6299bde3ed", |
| 1552 | "shasum": "" | 1785 | "shasum": "" |
| 1553 | }, | 1786 | }, |
| 1554 | "require": { | 1787 | "require": { |
| 1555 | "dnoegel/php-xdg-base-dir": "0.1", | 1788 | "dnoegel/php-xdg-base-dir": "0.1", |
| 1556 | "jakub-onderka/php-console-highlighter": "0.3.*", | 1789 | "jakub-onderka/php-console-highlighter": "0.3.*", |
| 1557 | - "nikic/php-parser": "^1.2.1", | 1790 | + "nikic/php-parser": "^1.2.1|~2.0", |
| 1558 | "php": ">=5.3.9", | 1791 | "php": ">=5.3.9", |
| 1559 | "symfony/console": "~2.3.10|^2.4.2|~3.0", | 1792 | "symfony/console": "~2.3.10|^2.4.2|~3.0", |
| 1560 | "symfony/var-dumper": "~2.7|~3.0" | 1793 | "symfony/var-dumper": "~2.7|~3.0" |
| 1561 | }, | 1794 | }, |
| 1562 | "require-dev": { | 1795 | "require-dev": { |
| 1563 | "fabpot/php-cs-fixer": "~1.5", | 1796 | "fabpot/php-cs-fixer": "~1.5", |
| 1564 | - "phpunit/phpunit": "~3.7|~4.0", | 1797 | + "phpunit/phpunit": "~3.7|~4.0|~5.0", |
| 1565 | "squizlabs/php_codesniffer": "~2.0", | 1798 | "squizlabs/php_codesniffer": "~2.0", |
| 1566 | "symfony/finder": "~2.1|~3.0" | 1799 | "symfony/finder": "~2.1|~3.0" |
| 1567 | }, | 1800 | }, |
| ... | @@ -1577,15 +1810,15 @@ | ... | @@ -1577,15 +1810,15 @@ |
| 1577 | "type": "library", | 1810 | "type": "library", |
| 1578 | "extra": { | 1811 | "extra": { |
| 1579 | "branch-alias": { | 1812 | "branch-alias": { |
| 1580 | - "dev-develop": "0.6.x-dev" | 1813 | + "dev-develop": "0.7.x-dev" |
| 1581 | } | 1814 | } |
| 1582 | }, | 1815 | }, |
| 1583 | "autoload": { | 1816 | "autoload": { |
| 1584 | "files": [ | 1817 | "files": [ |
| 1585 | "src/Psy/functions.php" | 1818 | "src/Psy/functions.php" |
| 1586 | ], | 1819 | ], |
| 1587 | - "psr-0": { | 1820 | + "psr-4": { |
| 1588 | - "Psy\\": "src/" | 1821 | + "Psy\\": "src/Psy/" |
| 1589 | } | 1822 | } |
| 1590 | }, | 1823 | }, |
| 1591 | "notification-url": "https://packagist.org/downloads/", | 1824 | "notification-url": "https://packagist.org/downloads/", |
| ... | @@ -1607,7 +1840,7 @@ | ... | @@ -1607,7 +1840,7 @@ |
| 1607 | "interactive", | 1840 | "interactive", |
| 1608 | "shell" | 1841 | "shell" |
| 1609 | ], | 1842 | ], |
| 1610 | - "time": "2015-07-16 15:26:57" | 1843 | + "time": "2015-11-12 16:18:56" |
| 1611 | }, | 1844 | }, |
| 1612 | { | 1845 | { |
| 1613 | "name": "swiftmailer/swiftmailer", | 1846 | "name": "swiftmailer/swiftmailer", |
| ... | @@ -1664,35 +1897,37 @@ | ... | @@ -1664,35 +1897,37 @@ |
| 1664 | }, | 1897 | }, |
| 1665 | { | 1898 | { |
| 1666 | "name": "symfony/class-loader", | 1899 | "name": "symfony/class-loader", |
| 1667 | - "version": "v2.7.3", | 1900 | + "version": "v2.8.0", |
| 1668 | "source": { | 1901 | "source": { |
| 1669 | "type": "git", | 1902 | "type": "git", |
| 1670 | "url": "https://github.com/symfony/class-loader.git", | 1903 | "url": "https://github.com/symfony/class-loader.git", |
| 1671 | - "reference": "2fccbc544997340808801a7410cdcb96dd12edc4" | 1904 | + "reference": "51f83451bf0ddfc696e47e4642d6cd10fcfce160" |
| 1672 | }, | 1905 | }, |
| 1673 | "dist": { | 1906 | "dist": { |
| 1674 | "type": "zip", | 1907 | "type": "zip", |
| 1675 | - "url": "https://api.github.com/repos/symfony/class-loader/zipball/2fccbc544997340808801a7410cdcb96dd12edc4", | 1908 | + "url": "https://api.github.com/repos/symfony/class-loader/zipball/51f83451bf0ddfc696e47e4642d6cd10fcfce160", |
| 1676 | - "reference": "2fccbc544997340808801a7410cdcb96dd12edc4", | 1909 | + "reference": "51f83451bf0ddfc696e47e4642d6cd10fcfce160", |
| 1677 | "shasum": "" | 1910 | "shasum": "" |
| 1678 | }, | 1911 | }, |
| 1679 | "require": { | 1912 | "require": { |
| 1680 | "php": ">=5.3.9" | 1913 | "php": ">=5.3.9" |
| 1681 | }, | 1914 | }, |
| 1682 | "require-dev": { | 1915 | "require-dev": { |
| 1683 | - "symfony/finder": "~2.0,>=2.0.5", | 1916 | + "symfony/finder": "~2.0,>=2.0.5|~3.0.0" |
| 1684 | - "symfony/phpunit-bridge": "~2.7" | ||
| 1685 | }, | 1917 | }, |
| 1686 | "type": "library", | 1918 | "type": "library", |
| 1687 | "extra": { | 1919 | "extra": { |
| 1688 | "branch-alias": { | 1920 | "branch-alias": { |
| 1689 | - "dev-master": "2.7-dev" | 1921 | + "dev-master": "2.8-dev" |
| 1690 | } | 1922 | } |
| 1691 | }, | 1923 | }, |
| 1692 | "autoload": { | 1924 | "autoload": { |
| 1693 | "psr-4": { | 1925 | "psr-4": { |
| 1694 | "Symfony\\Component\\ClassLoader\\": "" | 1926 | "Symfony\\Component\\ClassLoader\\": "" |
| 1695 | - } | 1927 | + }, |
| 1928 | + "exclude-from-classmap": [ | ||
| 1929 | + "/Tests/" | ||
| 1930 | + ] | ||
| 1696 | }, | 1931 | }, |
| 1697 | "notification-url": "https://packagist.org/downloads/", | 1932 | "notification-url": "https://packagist.org/downloads/", |
| 1698 | "license": [ | 1933 | "license": [ |
| ... | @@ -1710,20 +1945,20 @@ | ... | @@ -1710,20 +1945,20 @@ |
| 1710 | ], | 1945 | ], |
| 1711 | "description": "Symfony ClassLoader Component", | 1946 | "description": "Symfony ClassLoader Component", |
| 1712 | "homepage": "https://symfony.com", | 1947 | "homepage": "https://symfony.com", |
| 1713 | - "time": "2015-06-25 12:52:11" | 1948 | + "time": "2015-11-26 07:00:59" |
| 1714 | }, | 1949 | }, |
| 1715 | { | 1950 | { |
| 1716 | "name": "symfony/console", | 1951 | "name": "symfony/console", |
| 1717 | - "version": "v2.7.3", | 1952 | + "version": "v2.7.7", |
| 1718 | "source": { | 1953 | "source": { |
| 1719 | "type": "git", | 1954 | "type": "git", |
| 1720 | "url": "https://github.com/symfony/console.git", | 1955 | "url": "https://github.com/symfony/console.git", |
| 1721 | - "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e" | 1956 | + "reference": "16bb1cb86df43c90931df65f529e7ebd79636750" |
| 1722 | }, | 1957 | }, |
| 1723 | "dist": { | 1958 | "dist": { |
| 1724 | "type": "zip", | 1959 | "type": "zip", |
| 1725 | - "url": "https://api.github.com/repos/symfony/console/zipball/d6cf02fe73634c96677e428f840704bfbcaec29e", | 1960 | + "url": "https://api.github.com/repos/symfony/console/zipball/16bb1cb86df43c90931df65f529e7ebd79636750", |
| 1726 | - "reference": "d6cf02fe73634c96677e428f840704bfbcaec29e", | 1961 | + "reference": "16bb1cb86df43c90931df65f529e7ebd79636750", |
| 1727 | "shasum": "" | 1962 | "shasum": "" |
| 1728 | }, | 1963 | }, |
| 1729 | "require": { | 1964 | "require": { |
| ... | @@ -1732,7 +1967,6 @@ | ... | @@ -1732,7 +1967,6 @@ |
| 1732 | "require-dev": { | 1967 | "require-dev": { |
| 1733 | "psr/log": "~1.0", | 1968 | "psr/log": "~1.0", |
| 1734 | "symfony/event-dispatcher": "~2.1", | 1969 | "symfony/event-dispatcher": "~2.1", |
| 1735 | - "symfony/phpunit-bridge": "~2.7", | ||
| 1736 | "symfony/process": "~2.1" | 1970 | "symfony/process": "~2.1" |
| 1737 | }, | 1971 | }, |
| 1738 | "suggest": { | 1972 | "suggest": { |
| ... | @@ -1749,7 +1983,10 @@ | ... | @@ -1749,7 +1983,10 @@ |
| 1749 | "autoload": { | 1983 | "autoload": { |
| 1750 | "psr-4": { | 1984 | "psr-4": { |
| 1751 | "Symfony\\Component\\Console\\": "" | 1985 | "Symfony\\Component\\Console\\": "" |
| 1752 | - } | 1986 | + }, |
| 1987 | + "exclude-from-classmap": [ | ||
| 1988 | + "/Tests/" | ||
| 1989 | + ] | ||
| 1753 | }, | 1990 | }, |
| 1754 | "notification-url": "https://packagist.org/downloads/", | 1991 | "notification-url": "https://packagist.org/downloads/", |
| 1755 | "license": [ | 1992 | "license": [ |
| ... | @@ -1767,28 +2004,25 @@ | ... | @@ -1767,28 +2004,25 @@ |
| 1767 | ], | 2004 | ], |
| 1768 | "description": "Symfony Console Component", | 2005 | "description": "Symfony Console Component", |
| 1769 | "homepage": "https://symfony.com", | 2006 | "homepage": "https://symfony.com", |
| 1770 | - "time": "2015-07-28 15:18:12" | 2007 | + "time": "2015-11-18 09:54:26" |
| 1771 | }, | 2008 | }, |
| 1772 | { | 2009 | { |
| 1773 | "name": "symfony/css-selector", | 2010 | "name": "symfony/css-selector", |
| 1774 | - "version": "v2.7.3", | 2011 | + "version": "v2.7.7", |
| 1775 | "source": { | 2012 | "source": { |
| 1776 | "type": "git", | 2013 | "type": "git", |
| 1777 | "url": "https://github.com/symfony/css-selector.git", | 2014 | "url": "https://github.com/symfony/css-selector.git", |
| 1778 | - "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092" | 2015 | + "reference": "abb47717fb88aebd9437da2fc8bb01a50a36679f" |
| 1779 | }, | 2016 | }, |
| 1780 | "dist": { | 2017 | "dist": { |
| 1781 | "type": "zip", | 2018 | "type": "zip", |
| 1782 | - "url": "https://api.github.com/repos/symfony/css-selector/zipball/0b5c07b516226b7dd32afbbc82fe547a469c5092", | 2019 | + "url": "https://api.github.com/repos/symfony/css-selector/zipball/abb47717fb88aebd9437da2fc8bb01a50a36679f", |
| 1783 | - "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092", | 2020 | + "reference": "abb47717fb88aebd9437da2fc8bb01a50a36679f", |
| 1784 | "shasum": "" | 2021 | "shasum": "" |
| 1785 | }, | 2022 | }, |
| 1786 | "require": { | 2023 | "require": { |
| 1787 | "php": ">=5.3.9" | 2024 | "php": ">=5.3.9" |
| 1788 | }, | 2025 | }, |
| 1789 | - "require-dev": { | ||
| 1790 | - "symfony/phpunit-bridge": "~2.7" | ||
| 1791 | - }, | ||
| 1792 | "type": "library", | 2026 | "type": "library", |
| 1793 | "extra": { | 2027 | "extra": { |
| 1794 | "branch-alias": { | 2028 | "branch-alias": { |
| ... | @@ -1798,7 +2032,10 @@ | ... | @@ -1798,7 +2032,10 @@ |
| 1798 | "autoload": { | 2032 | "autoload": { |
| 1799 | "psr-4": { | 2033 | "psr-4": { |
| 1800 | "Symfony\\Component\\CssSelector\\": "" | 2034 | "Symfony\\Component\\CssSelector\\": "" |
| 1801 | - } | 2035 | + }, |
| 2036 | + "exclude-from-classmap": [ | ||
| 2037 | + "/Tests/" | ||
| 2038 | + ] | ||
| 1802 | }, | 2039 | }, |
| 1803 | "notification-url": "https://packagist.org/downloads/", | 2040 | "notification-url": "https://packagist.org/downloads/", |
| 1804 | "license": [ | 2041 | "license": [ |
| ... | @@ -1820,20 +2057,20 @@ | ... | @@ -1820,20 +2057,20 @@ |
| 1820 | ], | 2057 | ], |
| 1821 | "description": "Symfony CssSelector Component", | 2058 | "description": "Symfony CssSelector Component", |
| 1822 | "homepage": "https://symfony.com", | 2059 | "homepage": "https://symfony.com", |
| 1823 | - "time": "2015-05-15 13:33:16" | 2060 | + "time": "2015-10-30 20:10:21" |
| 1824 | }, | 2061 | }, |
| 1825 | { | 2062 | { |
| 1826 | "name": "symfony/debug", | 2063 | "name": "symfony/debug", |
| 1827 | - "version": "v2.7.3", | 2064 | + "version": "v2.7.7", |
| 1828 | "source": { | 2065 | "source": { |
| 1829 | "type": "git", | 2066 | "type": "git", |
| 1830 | "url": "https://github.com/symfony/debug.git", | 2067 | "url": "https://github.com/symfony/debug.git", |
| 1831 | - "reference": "9daa1bf9f7e615fa2fba30357e479a90141222e3" | 2068 | + "reference": "0dbc119596f4afc82d9b2eb2a7e6a4af1ee763fa" |
| 1832 | }, | 2069 | }, |
| 1833 | "dist": { | 2070 | "dist": { |
| 1834 | "type": "zip", | 2071 | "type": "zip", |
| 1835 | - "url": "https://api.github.com/repos/symfony/debug/zipball/9daa1bf9f7e615fa2fba30357e479a90141222e3", | 2072 | + "url": "https://api.github.com/repos/symfony/debug/zipball/0dbc119596f4afc82d9b2eb2a7e6a4af1ee763fa", |
| 1836 | - "reference": "9daa1bf9f7e615fa2fba30357e479a90141222e3", | 2073 | + "reference": "0dbc119596f4afc82d9b2eb2a7e6a4af1ee763fa", |
| 1837 | "shasum": "" | 2074 | "shasum": "" |
| 1838 | }, | 2075 | }, |
| 1839 | "require": { | 2076 | "require": { |
| ... | @@ -1845,13 +2082,7 @@ | ... | @@ -1845,13 +2082,7 @@ |
| 1845 | }, | 2082 | }, |
| 1846 | "require-dev": { | 2083 | "require-dev": { |
| 1847 | "symfony/class-loader": "~2.2", | 2084 | "symfony/class-loader": "~2.2", |
| 1848 | - "symfony/http-foundation": "~2.1", | 2085 | + "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2" |
| 1849 | - "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2", | ||
| 1850 | - "symfony/phpunit-bridge": "~2.7" | ||
| 1851 | - }, | ||
| 1852 | - "suggest": { | ||
| 1853 | - "symfony/http-foundation": "", | ||
| 1854 | - "symfony/http-kernel": "" | ||
| 1855 | }, | 2086 | }, |
| 1856 | "type": "library", | 2087 | "type": "library", |
| 1857 | "extra": { | 2088 | "extra": { |
| ... | @@ -1862,7 +2093,10 @@ | ... | @@ -1862,7 +2093,10 @@ |
| 1862 | "autoload": { | 2093 | "autoload": { |
| 1863 | "psr-4": { | 2094 | "psr-4": { |
| 1864 | "Symfony\\Component\\Debug\\": "" | 2095 | "Symfony\\Component\\Debug\\": "" |
| 1865 | - } | 2096 | + }, |
| 2097 | + "exclude-from-classmap": [ | ||
| 2098 | + "/Tests/" | ||
| 2099 | + ] | ||
| 1866 | }, | 2100 | }, |
| 1867 | "notification-url": "https://packagist.org/downloads/", | 2101 | "notification-url": "https://packagist.org/downloads/", |
| 1868 | "license": [ | 2102 | "license": [ |
| ... | @@ -1880,28 +2114,27 @@ | ... | @@ -1880,28 +2114,27 @@ |
| 1880 | ], | 2114 | ], |
| 1881 | "description": "Symfony Debug Component", | 2115 | "description": "Symfony Debug Component", |
| 1882 | "homepage": "https://symfony.com", | 2116 | "homepage": "https://symfony.com", |
| 1883 | - "time": "2015-07-09 16:07:40" | 2117 | + "time": "2015-10-30 20:10:21" |
| 1884 | }, | 2118 | }, |
| 1885 | { | 2119 | { |
| 1886 | "name": "symfony/dom-crawler", | 2120 | "name": "symfony/dom-crawler", |
| 1887 | - "version": "v2.7.3", | 2121 | + "version": "v2.7.7", |
| 1888 | "source": { | 2122 | "source": { |
| 1889 | "type": "git", | 2123 | "type": "git", |
| 1890 | "url": "https://github.com/symfony/dom-crawler.git", | 2124 | "url": "https://github.com/symfony/dom-crawler.git", |
| 1891 | - "reference": "9dabece63182e95c42b06967a0d929a5df78bc35" | 2125 | + "reference": "b33593cbfe1d81b50d48353f338aca76a08658d8" |
| 1892 | }, | 2126 | }, |
| 1893 | "dist": { | 2127 | "dist": { |
| 1894 | "type": "zip", | 2128 | "type": "zip", |
| 1895 | - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/9dabece63182e95c42b06967a0d929a5df78bc35", | 2129 | + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b33593cbfe1d81b50d48353f338aca76a08658d8", |
| 1896 | - "reference": "9dabece63182e95c42b06967a0d929a5df78bc35", | 2130 | + "reference": "b33593cbfe1d81b50d48353f338aca76a08658d8", |
| 1897 | "shasum": "" | 2131 | "shasum": "" |
| 1898 | }, | 2132 | }, |
| 1899 | "require": { | 2133 | "require": { |
| 1900 | "php": ">=5.3.9" | 2134 | "php": ">=5.3.9" |
| 1901 | }, | 2135 | }, |
| 1902 | "require-dev": { | 2136 | "require-dev": { |
| 1903 | - "symfony/css-selector": "~2.3", | 2137 | + "symfony/css-selector": "~2.3" |
| 1904 | - "symfony/phpunit-bridge": "~2.7" | ||
| 1905 | }, | 2138 | }, |
| 1906 | "suggest": { | 2139 | "suggest": { |
| 1907 | "symfony/css-selector": "" | 2140 | "symfony/css-selector": "" |
| ... | @@ -1915,7 +2148,10 @@ | ... | @@ -1915,7 +2148,10 @@ |
| 1915 | "autoload": { | 2148 | "autoload": { |
| 1916 | "psr-4": { | 2149 | "psr-4": { |
| 1917 | "Symfony\\Component\\DomCrawler\\": "" | 2150 | "Symfony\\Component\\DomCrawler\\": "" |
| 1918 | - } | 2151 | + }, |
| 2152 | + "exclude-from-classmap": [ | ||
| 2153 | + "/Tests/" | ||
| 2154 | + ] | ||
| 1919 | }, | 2155 | }, |
| 1920 | "notification-url": "https://packagist.org/downloads/", | 2156 | "notification-url": "https://packagist.org/downloads/", |
| 1921 | "license": [ | 2157 | "license": [ |
| ... | @@ -1933,20 +2169,20 @@ | ... | @@ -1933,20 +2169,20 @@ |
| 1933 | ], | 2169 | ], |
| 1934 | "description": "Symfony DomCrawler Component", | 2170 | "description": "Symfony DomCrawler Component", |
| 1935 | "homepage": "https://symfony.com", | 2171 | "homepage": "https://symfony.com", |
| 1936 | - "time": "2015-07-09 16:07:40" | 2172 | + "time": "2015-11-02 20:20:53" |
| 1937 | }, | 2173 | }, |
| 1938 | { | 2174 | { |
| 1939 | "name": "symfony/event-dispatcher", | 2175 | "name": "symfony/event-dispatcher", |
| 1940 | - "version": "v2.7.3", | 2176 | + "version": "v2.8.0", |
| 1941 | "source": { | 2177 | "source": { |
| 1942 | "type": "git", | 2178 | "type": "git", |
| 1943 | "url": "https://github.com/symfony/event-dispatcher.git", | 2179 | "url": "https://github.com/symfony/event-dispatcher.git", |
| 1944 | - "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3" | 2180 | + "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc" |
| 1945 | }, | 2181 | }, |
| 1946 | "dist": { | 2182 | "dist": { |
| 1947 | "type": "zip", | 2183 | "type": "zip", |
| 1948 | - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9310b5f9a87ec2ea75d20fec0b0017c77c66dac3", | 2184 | + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5eb815363c0388e83247e7e9853e5dbc14999cc", |
| 1949 | - "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3", | 2185 | + "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc", |
| 1950 | "shasum": "" | 2186 | "shasum": "" |
| 1951 | }, | 2187 | }, |
| 1952 | "require": { | 2188 | "require": { |
| ... | @@ -1954,11 +2190,10 @@ | ... | @@ -1954,11 +2190,10 @@ |
| 1954 | }, | 2190 | }, |
| 1955 | "require-dev": { | 2191 | "require-dev": { |
| 1956 | "psr/log": "~1.0", | 2192 | "psr/log": "~1.0", |
| 1957 | - "symfony/config": "~2.0,>=2.0.5", | 2193 | + "symfony/config": "~2.0,>=2.0.5|~3.0.0", |
| 1958 | - "symfony/dependency-injection": "~2.6", | 2194 | + "symfony/dependency-injection": "~2.6|~3.0.0", |
| 1959 | - "symfony/expression-language": "~2.6", | 2195 | + "symfony/expression-language": "~2.6|~3.0.0", |
| 1960 | - "symfony/phpunit-bridge": "~2.7", | 2196 | + "symfony/stopwatch": "~2.3|~3.0.0" |
| 1961 | - "symfony/stopwatch": "~2.3" | ||
| 1962 | }, | 2197 | }, |
| 1963 | "suggest": { | 2198 | "suggest": { |
| 1964 | "symfony/dependency-injection": "", | 2199 | "symfony/dependency-injection": "", |
| ... | @@ -1967,13 +2202,16 @@ | ... | @@ -1967,13 +2202,16 @@ |
| 1967 | "type": "library", | 2202 | "type": "library", |
| 1968 | "extra": { | 2203 | "extra": { |
| 1969 | "branch-alias": { | 2204 | "branch-alias": { |
| 1970 | - "dev-master": "2.7-dev" | 2205 | + "dev-master": "2.8-dev" |
| 1971 | } | 2206 | } |
| 1972 | }, | 2207 | }, |
| 1973 | "autoload": { | 2208 | "autoload": { |
| 1974 | "psr-4": { | 2209 | "psr-4": { |
| 1975 | "Symfony\\Component\\EventDispatcher\\": "" | 2210 | "Symfony\\Component\\EventDispatcher\\": "" |
| 1976 | - } | 2211 | + }, |
| 2212 | + "exclude-from-classmap": [ | ||
| 2213 | + "/Tests/" | ||
| 2214 | + ] | ||
| 1977 | }, | 2215 | }, |
| 1978 | "notification-url": "https://packagist.org/downloads/", | 2216 | "notification-url": "https://packagist.org/downloads/", |
| 1979 | "license": [ | 2217 | "license": [ |
| ... | @@ -1991,28 +2229,25 @@ | ... | @@ -1991,28 +2229,25 @@ |
| 1991 | ], | 2229 | ], |
| 1992 | "description": "Symfony EventDispatcher Component", | 2230 | "description": "Symfony EventDispatcher Component", |
| 1993 | "homepage": "https://symfony.com", | 2231 | "homepage": "https://symfony.com", |
| 1994 | - "time": "2015-06-18 19:21:56" | 2232 | + "time": "2015-10-30 20:15:42" |
| 1995 | }, | 2233 | }, |
| 1996 | { | 2234 | { |
| 1997 | "name": "symfony/finder", | 2235 | "name": "symfony/finder", |
| 1998 | - "version": "v2.7.3", | 2236 | + "version": "v2.7.7", |
| 1999 | "source": { | 2237 | "source": { |
| 2000 | "type": "git", | 2238 | "type": "git", |
| 2001 | - "url": "https://github.com/symfony/Finder.git", | 2239 | + "url": "https://github.com/symfony/finder.git", |
| 2002 | - "reference": "ae0f363277485094edc04c9f3cbe595b183b78e4" | 2240 | + "reference": "a06a0c0ff7db3736a50d530c908cca547bf13da9" |
| 2003 | }, | 2241 | }, |
| 2004 | "dist": { | 2242 | "dist": { |
| 2005 | "type": "zip", | 2243 | "type": "zip", |
| 2006 | - "url": "https://api.github.com/repos/symfony/Finder/zipball/ae0f363277485094edc04c9f3cbe595b183b78e4", | 2244 | + "url": "https://api.github.com/repos/symfony/finder/zipball/a06a0c0ff7db3736a50d530c908cca547bf13da9", |
| 2007 | - "reference": "ae0f363277485094edc04c9f3cbe595b183b78e4", | 2245 | + "reference": "a06a0c0ff7db3736a50d530c908cca547bf13da9", |
| 2008 | "shasum": "" | 2246 | "shasum": "" |
| 2009 | }, | 2247 | }, |
| 2010 | "require": { | 2248 | "require": { |
| 2011 | "php": ">=5.3.9" | 2249 | "php": ">=5.3.9" |
| 2012 | }, | 2250 | }, |
| 2013 | - "require-dev": { | ||
| 2014 | - "symfony/phpunit-bridge": "~2.7" | ||
| 2015 | - }, | ||
| 2016 | "type": "library", | 2251 | "type": "library", |
| 2017 | "extra": { | 2252 | "extra": { |
| 2018 | "branch-alias": { | 2253 | "branch-alias": { |
| ... | @@ -2022,7 +2257,10 @@ | ... | @@ -2022,7 +2257,10 @@ |
| 2022 | "autoload": { | 2257 | "autoload": { |
| 2023 | "psr-4": { | 2258 | "psr-4": { |
| 2024 | "Symfony\\Component\\Finder\\": "" | 2259 | "Symfony\\Component\\Finder\\": "" |
| 2025 | - } | 2260 | + }, |
| 2261 | + "exclude-from-classmap": [ | ||
| 2262 | + "/Tests/" | ||
| 2263 | + ] | ||
| 2026 | }, | 2264 | }, |
| 2027 | "notification-url": "https://packagist.org/downloads/", | 2265 | "notification-url": "https://packagist.org/downloads/", |
| 2028 | "license": [ | 2266 | "license": [ |
| ... | @@ -2040,28 +2278,27 @@ | ... | @@ -2040,28 +2278,27 @@ |
| 2040 | ], | 2278 | ], |
| 2041 | "description": "Symfony Finder Component", | 2279 | "description": "Symfony Finder Component", |
| 2042 | "homepage": "https://symfony.com", | 2280 | "homepage": "https://symfony.com", |
| 2043 | - "time": "2015-07-09 16:07:40" | 2281 | + "time": "2015-10-30 20:10:21" |
| 2044 | }, | 2282 | }, |
| 2045 | { | 2283 | { |
| 2046 | "name": "symfony/http-foundation", | 2284 | "name": "symfony/http-foundation", |
| 2047 | - "version": "v2.7.3", | 2285 | + "version": "v2.7.7", |
| 2048 | "source": { | 2286 | "source": { |
| 2049 | "type": "git", | 2287 | "type": "git", |
| 2050 | "url": "https://github.com/symfony/http-foundation.git", | 2288 | "url": "https://github.com/symfony/http-foundation.git", |
| 2051 | - "reference": "863af6898081b34c65d42100c370b9f3c51b70ca" | 2289 | + "reference": "e83a3d105ddaf5a113e803c904fdec552d1f1c35" |
| 2052 | }, | 2290 | }, |
| 2053 | "dist": { | 2291 | "dist": { |
| 2054 | "type": "zip", | 2292 | "type": "zip", |
| 2055 | - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/863af6898081b34c65d42100c370b9f3c51b70ca", | 2293 | + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e83a3d105ddaf5a113e803c904fdec552d1f1c35", |
| 2056 | - "reference": "863af6898081b34c65d42100c370b9f3c51b70ca", | 2294 | + "reference": "e83a3d105ddaf5a113e803c904fdec552d1f1c35", |
| 2057 | "shasum": "" | 2295 | "shasum": "" |
| 2058 | }, | 2296 | }, |
| 2059 | "require": { | 2297 | "require": { |
| 2060 | "php": ">=5.3.9" | 2298 | "php": ">=5.3.9" |
| 2061 | }, | 2299 | }, |
| 2062 | "require-dev": { | 2300 | "require-dev": { |
| 2063 | - "symfony/expression-language": "~2.4", | 2301 | + "symfony/expression-language": "~2.4" |
| 2064 | - "symfony/phpunit-bridge": "~2.7" | ||
| 2065 | }, | 2302 | }, |
| 2066 | "type": "library", | 2303 | "type": "library", |
| 2067 | "extra": { | 2304 | "extra": { |
| ... | @@ -2075,6 +2312,9 @@ | ... | @@ -2075,6 +2312,9 @@ |
| 2075 | }, | 2312 | }, |
| 2076 | "classmap": [ | 2313 | "classmap": [ |
| 2077 | "Resources/stubs" | 2314 | "Resources/stubs" |
| 2315 | + ], | ||
| 2316 | + "exclude-from-classmap": [ | ||
| 2317 | + "/Tests/" | ||
| 2078 | ] | 2318 | ] |
| 2079 | }, | 2319 | }, |
| 2080 | "notification-url": "https://packagist.org/downloads/", | 2320 | "notification-url": "https://packagist.org/downloads/", |
| ... | @@ -2093,20 +2333,20 @@ | ... | @@ -2093,20 +2333,20 @@ |
| 2093 | ], | 2333 | ], |
| 2094 | "description": "Symfony HttpFoundation Component", | 2334 | "description": "Symfony HttpFoundation Component", |
| 2095 | "homepage": "https://symfony.com", | 2335 | "homepage": "https://symfony.com", |
| 2096 | - "time": "2015-07-22 10:11:00" | 2336 | + "time": "2015-11-20 17:41:18" |
| 2097 | }, | 2337 | }, |
| 2098 | { | 2338 | { |
| 2099 | "name": "symfony/http-kernel", | 2339 | "name": "symfony/http-kernel", |
| 2100 | - "version": "v2.7.3", | 2340 | + "version": "v2.7.7", |
| 2101 | "source": { | 2341 | "source": { |
| 2102 | "type": "git", | 2342 | "type": "git", |
| 2103 | "url": "https://github.com/symfony/http-kernel.git", | 2343 | "url": "https://github.com/symfony/http-kernel.git", |
| 2104 | - "reference": "405d3e7a59ff7a28ec469441326a0ac79065ea98" | 2344 | + "reference": "5570de31e8fbc03777a8c61eb24f9b626e5e5941" |
| 2105 | }, | 2345 | }, |
| 2106 | "dist": { | 2346 | "dist": { |
| 2107 | "type": "zip", | 2347 | "type": "zip", |
| 2108 | - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/405d3e7a59ff7a28ec469441326a0ac79065ea98", | 2348 | + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/5570de31e8fbc03777a8c61eb24f9b626e5e5941", |
| 2109 | - "reference": "405d3e7a59ff7a28ec469441326a0ac79065ea98", | 2349 | + "reference": "5570de31e8fbc03777a8c61eb24f9b626e5e5941", |
| 2110 | "shasum": "" | 2350 | "shasum": "" |
| 2111 | }, | 2351 | }, |
| 2112 | "require": { | 2352 | "require": { |
| ... | @@ -2129,7 +2369,6 @@ | ... | @@ -2129,7 +2369,6 @@ |
| 2129 | "symfony/dom-crawler": "~2.0,>=2.0.5", | 2369 | "symfony/dom-crawler": "~2.0,>=2.0.5", |
| 2130 | "symfony/expression-language": "~2.4", | 2370 | "symfony/expression-language": "~2.4", |
| 2131 | "symfony/finder": "~2.0,>=2.0.5", | 2371 | "symfony/finder": "~2.0,>=2.0.5", |
| 2132 | - "symfony/phpunit-bridge": "~2.7", | ||
| 2133 | "symfony/process": "~2.0,>=2.0.5", | 2372 | "symfony/process": "~2.0,>=2.0.5", |
| 2134 | "symfony/routing": "~2.2", | 2373 | "symfony/routing": "~2.2", |
| 2135 | "symfony/stopwatch": "~2.3", | 2374 | "symfony/stopwatch": "~2.3", |
| ... | @@ -2155,7 +2394,10 @@ | ... | @@ -2155,7 +2394,10 @@ |
| 2155 | "autoload": { | 2394 | "autoload": { |
| 2156 | "psr-4": { | 2395 | "psr-4": { |
| 2157 | "Symfony\\Component\\HttpKernel\\": "" | 2396 | "Symfony\\Component\\HttpKernel\\": "" |
| 2158 | - } | 2397 | + }, |
| 2398 | + "exclude-from-classmap": [ | ||
| 2399 | + "/Tests/" | ||
| 2400 | + ] | ||
| 2159 | }, | 2401 | }, |
| 2160 | "notification-url": "https://packagist.org/downloads/", | 2402 | "notification-url": "https://packagist.org/downloads/", |
| 2161 | "license": [ | 2403 | "license": [ |
| ... | @@ -2173,28 +2415,25 @@ | ... | @@ -2173,28 +2415,25 @@ |
| 2173 | ], | 2415 | ], |
| 2174 | "description": "Symfony HttpKernel Component", | 2416 | "description": "Symfony HttpKernel Component", |
| 2175 | "homepage": "https://symfony.com", | 2417 | "homepage": "https://symfony.com", |
| 2176 | - "time": "2015-07-31 13:24:45" | 2418 | + "time": "2015-11-23 11:57:49" |
| 2177 | }, | 2419 | }, |
| 2178 | { | 2420 | { |
| 2179 | "name": "symfony/process", | 2421 | "name": "symfony/process", |
| 2180 | - "version": "v2.7.3", | 2422 | + "version": "v2.7.7", |
| 2181 | "source": { | 2423 | "source": { |
| 2182 | "type": "git", | 2424 | "type": "git", |
| 2183 | - "url": "https://github.com/symfony/Process.git", | 2425 | + "url": "https://github.com/symfony/process.git", |
| 2184 | - "reference": "48aeb0e48600321c272955132d7606ab0a49adb3" | 2426 | + "reference": "f6290983c8725d0afa29bdc3e5295879de3e58f5" |
| 2185 | }, | 2427 | }, |
| 2186 | "dist": { | 2428 | "dist": { |
| 2187 | "type": "zip", | 2429 | "type": "zip", |
| 2188 | - "url": "https://api.github.com/repos/symfony/Process/zipball/48aeb0e48600321c272955132d7606ab0a49adb3", | 2430 | + "url": "https://api.github.com/repos/symfony/process/zipball/f6290983c8725d0afa29bdc3e5295879de3e58f5", |
| 2189 | - "reference": "48aeb0e48600321c272955132d7606ab0a49adb3", | 2431 | + "reference": "f6290983c8725d0afa29bdc3e5295879de3e58f5", |
| 2190 | "shasum": "" | 2432 | "shasum": "" |
| 2191 | }, | 2433 | }, |
| 2192 | "require": { | 2434 | "require": { |
| 2193 | "php": ">=5.3.9" | 2435 | "php": ">=5.3.9" |
| 2194 | }, | 2436 | }, |
| 2195 | - "require-dev": { | ||
| 2196 | - "symfony/phpunit-bridge": "~2.7" | ||
| 2197 | - }, | ||
| 2198 | "type": "library", | 2437 | "type": "library", |
| 2199 | "extra": { | 2438 | "extra": { |
| 2200 | "branch-alias": { | 2439 | "branch-alias": { |
| ... | @@ -2204,7 +2443,10 @@ | ... | @@ -2204,7 +2443,10 @@ |
| 2204 | "autoload": { | 2443 | "autoload": { |
| 2205 | "psr-4": { | 2444 | "psr-4": { |
| 2206 | "Symfony\\Component\\Process\\": "" | 2445 | "Symfony\\Component\\Process\\": "" |
| 2207 | - } | 2446 | + }, |
| 2447 | + "exclude-from-classmap": [ | ||
| 2448 | + "/Tests/" | ||
| 2449 | + ] | ||
| 2208 | }, | 2450 | }, |
| 2209 | "notification-url": "https://packagist.org/downloads/", | 2451 | "notification-url": "https://packagist.org/downloads/", |
| 2210 | "license": [ | 2452 | "license": [ |
| ... | @@ -2222,20 +2464,20 @@ | ... | @@ -2222,20 +2464,20 @@ |
| 2222 | ], | 2464 | ], |
| 2223 | "description": "Symfony Process Component", | 2465 | "description": "Symfony Process Component", |
| 2224 | "homepage": "https://symfony.com", | 2466 | "homepage": "https://symfony.com", |
| 2225 | - "time": "2015-07-01 11:25:50" | 2467 | + "time": "2015-11-19 16:11:24" |
| 2226 | }, | 2468 | }, |
| 2227 | { | 2469 | { |
| 2228 | "name": "symfony/routing", | 2470 | "name": "symfony/routing", |
| 2229 | - "version": "v2.7.3", | 2471 | + "version": "v2.7.7", |
| 2230 | "source": { | 2472 | "source": { |
| 2231 | "type": "git", | 2473 | "type": "git", |
| 2232 | - "url": "https://github.com/symfony/Routing.git", | 2474 | + "url": "https://github.com/symfony/routing.git", |
| 2233 | - "reference": "ea9134f277162b02e5f80ac058b75a77637b0d26" | 2475 | + "reference": "7450f6196711b124fb8b04a12286d01a0401ddfe" |
| 2234 | }, | 2476 | }, |
| 2235 | "dist": { | 2477 | "dist": { |
| 2236 | "type": "zip", | 2478 | "type": "zip", |
| 2237 | - "url": "https://api.github.com/repos/symfony/Routing/zipball/ea9134f277162b02e5f80ac058b75a77637b0d26", | 2479 | + "url": "https://api.github.com/repos/symfony/routing/zipball/7450f6196711b124fb8b04a12286d01a0401ddfe", |
| 2238 | - "reference": "ea9134f277162b02e5f80ac058b75a77637b0d26", | 2480 | + "reference": "7450f6196711b124fb8b04a12286d01a0401ddfe", |
| 2239 | "shasum": "" | 2481 | "shasum": "" |
| 2240 | }, | 2482 | }, |
| 2241 | "require": { | 2483 | "require": { |
| ... | @@ -2251,7 +2493,6 @@ | ... | @@ -2251,7 +2493,6 @@ |
| 2251 | "symfony/config": "~2.7", | 2493 | "symfony/config": "~2.7", |
| 2252 | "symfony/expression-language": "~2.4", | 2494 | "symfony/expression-language": "~2.4", |
| 2253 | "symfony/http-foundation": "~2.3", | 2495 | "symfony/http-foundation": "~2.3", |
| 2254 | - "symfony/phpunit-bridge": "~2.7", | ||
| 2255 | "symfony/yaml": "~2.0,>=2.0.5" | 2496 | "symfony/yaml": "~2.0,>=2.0.5" |
| 2256 | }, | 2497 | }, |
| 2257 | "suggest": { | 2498 | "suggest": { |
| ... | @@ -2269,7 +2510,10 @@ | ... | @@ -2269,7 +2510,10 @@ |
| 2269 | "autoload": { | 2510 | "autoload": { |
| 2270 | "psr-4": { | 2511 | "psr-4": { |
| 2271 | "Symfony\\Component\\Routing\\": "" | 2512 | "Symfony\\Component\\Routing\\": "" |
| 2272 | - } | 2513 | + }, |
| 2514 | + "exclude-from-classmap": [ | ||
| 2515 | + "/Tests/" | ||
| 2516 | + ] | ||
| 2273 | }, | 2517 | }, |
| 2274 | "notification-url": "https://packagist.org/downloads/", | 2518 | "notification-url": "https://packagist.org/downloads/", |
| 2275 | "license": [ | 2519 | "license": [ |
| ... | @@ -2293,20 +2537,20 @@ | ... | @@ -2293,20 +2537,20 @@ |
| 2293 | "uri", | 2537 | "uri", |
| 2294 | "url" | 2538 | "url" |
| 2295 | ], | 2539 | ], |
| 2296 | - "time": "2015-07-09 16:07:40" | 2540 | + "time": "2015-11-18 13:41:01" |
| 2297 | }, | 2541 | }, |
| 2298 | { | 2542 | { |
| 2299 | "name": "symfony/translation", | 2543 | "name": "symfony/translation", |
| 2300 | - "version": "v2.7.3", | 2544 | + "version": "v2.7.7", |
| 2301 | "source": { | 2545 | "source": { |
| 2302 | "type": "git", | 2546 | "type": "git", |
| 2303 | - "url": "https://github.com/symfony/Translation.git", | 2547 | + "url": "https://github.com/symfony/translation.git", |
| 2304 | - "reference": "c8dc34cc936152c609cdd722af317e4239d10dd6" | 2548 | + "reference": "e4ecb9c3ba1304eaf24de15c2d7a428101c1982f" |
| 2305 | }, | 2549 | }, |
| 2306 | "dist": { | 2550 | "dist": { |
| 2307 | "type": "zip", | 2551 | "type": "zip", |
| 2308 | - "url": "https://api.github.com/repos/symfony/Translation/zipball/c8dc34cc936152c609cdd722af317e4239d10dd6", | 2552 | + "url": "https://api.github.com/repos/symfony/translation/zipball/e4ecb9c3ba1304eaf24de15c2d7a428101c1982f", |
| 2309 | - "reference": "c8dc34cc936152c609cdd722af317e4239d10dd6", | 2553 | + "reference": "e4ecb9c3ba1304eaf24de15c2d7a428101c1982f", |
| 2310 | "shasum": "" | 2554 | "shasum": "" |
| 2311 | }, | 2555 | }, |
| 2312 | "require": { | 2556 | "require": { |
| ... | @@ -2318,8 +2562,7 @@ | ... | @@ -2318,8 +2562,7 @@ |
| 2318 | "require-dev": { | 2562 | "require-dev": { |
| 2319 | "psr/log": "~1.0", | 2563 | "psr/log": "~1.0", |
| 2320 | "symfony/config": "~2.7", | 2564 | "symfony/config": "~2.7", |
| 2321 | - "symfony/intl": "~2.3", | 2565 | + "symfony/intl": "~2.4", |
| 2322 | - "symfony/phpunit-bridge": "~2.7", | ||
| 2323 | "symfony/yaml": "~2.2" | 2566 | "symfony/yaml": "~2.2" |
| 2324 | }, | 2567 | }, |
| 2325 | "suggest": { | 2568 | "suggest": { |
| ... | @@ -2336,7 +2579,10 @@ | ... | @@ -2336,7 +2579,10 @@ |
| 2336 | "autoload": { | 2579 | "autoload": { |
| 2337 | "psr-4": { | 2580 | "psr-4": { |
| 2338 | "Symfony\\Component\\Translation\\": "" | 2581 | "Symfony\\Component\\Translation\\": "" |
| 2339 | - } | 2582 | + }, |
| 2583 | + "exclude-from-classmap": [ | ||
| 2584 | + "/Tests/" | ||
| 2585 | + ] | ||
| 2340 | }, | 2586 | }, |
| 2341 | "notification-url": "https://packagist.org/downloads/", | 2587 | "notification-url": "https://packagist.org/downloads/", |
| 2342 | "license": [ | 2588 | "license": [ |
| ... | @@ -2354,28 +2600,25 @@ | ... | @@ -2354,28 +2600,25 @@ |
| 2354 | ], | 2600 | ], |
| 2355 | "description": "Symfony Translation Component", | 2601 | "description": "Symfony Translation Component", |
| 2356 | "homepage": "https://symfony.com", | 2602 | "homepage": "https://symfony.com", |
| 2357 | - "time": "2015-07-09 16:07:40" | 2603 | + "time": "2015-11-18 13:41:01" |
| 2358 | }, | 2604 | }, |
| 2359 | { | 2605 | { |
| 2360 | "name": "symfony/var-dumper", | 2606 | "name": "symfony/var-dumper", |
| 2361 | - "version": "v2.7.3", | 2607 | + "version": "v2.7.7", |
| 2362 | "source": { | 2608 | "source": { |
| 2363 | "type": "git", | 2609 | "type": "git", |
| 2364 | "url": "https://github.com/symfony/var-dumper.git", | 2610 | "url": "https://github.com/symfony/var-dumper.git", |
| 2365 | - "reference": "e8903ebba5eb019f5886ffce739ea9e3b7519579" | 2611 | + "reference": "72bcb27411780eaee9469729aace73c0d46fb2b8" |
| 2366 | }, | 2612 | }, |
| 2367 | "dist": { | 2613 | "dist": { |
| 2368 | "type": "zip", | 2614 | "type": "zip", |
| 2369 | - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e8903ebba5eb019f5886ffce739ea9e3b7519579", | 2615 | + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/72bcb27411780eaee9469729aace73c0d46fb2b8", |
| 2370 | - "reference": "e8903ebba5eb019f5886ffce739ea9e3b7519579", | 2616 | + "reference": "72bcb27411780eaee9469729aace73c0d46fb2b8", |
| 2371 | "shasum": "" | 2617 | "shasum": "" |
| 2372 | }, | 2618 | }, |
| 2373 | "require": { | 2619 | "require": { |
| 2374 | "php": ">=5.3.9" | 2620 | "php": ">=5.3.9" |
| 2375 | }, | 2621 | }, |
| 2376 | - "require-dev": { | ||
| 2377 | - "symfony/phpunit-bridge": "~2.7" | ||
| 2378 | - }, | ||
| 2379 | "suggest": { | 2622 | "suggest": { |
| 2380 | "ext-symfony_debug": "" | 2623 | "ext-symfony_debug": "" |
| 2381 | }, | 2624 | }, |
| ... | @@ -2391,7 +2634,10 @@ | ... | @@ -2391,7 +2634,10 @@ |
| 2391 | ], | 2634 | ], |
| 2392 | "psr-4": { | 2635 | "psr-4": { |
| 2393 | "Symfony\\Component\\VarDumper\\": "" | 2636 | "Symfony\\Component\\VarDumper\\": "" |
| 2394 | - } | 2637 | + }, |
| 2638 | + "exclude-from-classmap": [ | ||
| 2639 | + "/Tests/" | ||
| 2640 | + ] | ||
| 2395 | }, | 2641 | }, |
| 2396 | "notification-url": "https://packagist.org/downloads/", | 2642 | "notification-url": "https://packagist.org/downloads/", |
| 2397 | "license": [ | 2643 | "license": [ |
| ... | @@ -2413,7 +2659,7 @@ | ... | @@ -2413,7 +2659,7 @@ |
| 2413 | "debug", | 2659 | "debug", |
| 2414 | "dump" | 2660 | "dump" |
| 2415 | ], | 2661 | ], |
| 2416 | - "time": "2015-07-28 15:18:12" | 2662 | + "time": "2015-11-18 13:41:01" |
| 2417 | }, | 2663 | }, |
| 2418 | { | 2664 | { |
| 2419 | "name": "vlucas/phpdotenv", | 2665 | "name": "vlucas/phpdotenv", |
| ... | @@ -2715,36 +2961,36 @@ | ... | @@ -2715,36 +2961,36 @@ |
| 2715 | }, | 2961 | }, |
| 2716 | { | 2962 | { |
| 2717 | "name": "phpspec/phpspec", | 2963 | "name": "phpspec/phpspec", |
| 2718 | - "version": "2.2.1", | 2964 | + "version": "2.4.0", |
| 2719 | "source": { | 2965 | "source": { |
| 2720 | "type": "git", | 2966 | "type": "git", |
| 2721 | "url": "https://github.com/phpspec/phpspec.git", | 2967 | "url": "https://github.com/phpspec/phpspec.git", |
| 2722 | - "reference": "e9a40577323e67f1de2e214abf32976a0352d8f8" | 2968 | + "reference": "1d3938e6d9ffb1bd4805ea8ddac62ea48767f358" |
| 2723 | }, | 2969 | }, |
| 2724 | "dist": { | 2970 | "dist": { |
| 2725 | "type": "zip", | 2971 | "type": "zip", |
| 2726 | - "url": "https://api.github.com/repos/phpspec/phpspec/zipball/e9a40577323e67f1de2e214abf32976a0352d8f8", | 2972 | + "url": "https://api.github.com/repos/phpspec/phpspec/zipball/1d3938e6d9ffb1bd4805ea8ddac62ea48767f358", |
| 2727 | - "reference": "e9a40577323e67f1de2e214abf32976a0352d8f8", | 2973 | + "reference": "1d3938e6d9ffb1bd4805ea8ddac62ea48767f358", |
| 2728 | "shasum": "" | 2974 | "shasum": "" |
| 2729 | }, | 2975 | }, |
| 2730 | "require": { | 2976 | "require": { |
| 2731 | "doctrine/instantiator": "^1.0.1", | 2977 | "doctrine/instantiator": "^1.0.1", |
| 2978 | + "ext-tokenizer": "*", | ||
| 2732 | "php": ">=5.3.3", | 2979 | "php": ">=5.3.3", |
| 2733 | "phpspec/php-diff": "~1.0.0", | 2980 | "phpspec/php-diff": "~1.0.0", |
| 2734 | "phpspec/prophecy": "~1.4", | 2981 | "phpspec/prophecy": "~1.4", |
| 2735 | "sebastian/exporter": "~1.0", | 2982 | "sebastian/exporter": "~1.0", |
| 2736 | - "symfony/console": "~2.3", | 2983 | + "symfony/console": "~2.3|~3.0", |
| 2737 | - "symfony/event-dispatcher": "~2.1", | 2984 | + "symfony/event-dispatcher": "~2.1|~3.0", |
| 2738 | - "symfony/finder": "~2.1", | 2985 | + "symfony/finder": "~2.1|~3.0", |
| 2739 | - "symfony/process": "~2.1", | 2986 | + "symfony/process": "^2.6|~3.0", |
| 2740 | - "symfony/yaml": "~2.1" | 2987 | + "symfony/yaml": "~2.1|~3.0" |
| 2741 | }, | 2988 | }, |
| 2742 | "require-dev": { | 2989 | "require-dev": { |
| 2743 | "behat/behat": "^3.0.11", | 2990 | "behat/behat": "^3.0.11", |
| 2744 | "bossa/phpspec2-expect": "~1.0", | 2991 | "bossa/phpspec2-expect": "~1.0", |
| 2745 | "phpunit/phpunit": "~4.4", | 2992 | "phpunit/phpunit": "~4.4", |
| 2746 | - "symfony/filesystem": "~2.1", | 2993 | + "symfony/filesystem": "~2.1|~3.0" |
| 2747 | - "symfony/process": "~2.1" | ||
| 2748 | }, | 2994 | }, |
| 2749 | "suggest": { | 2995 | "suggest": { |
| 2750 | "phpspec/nyan-formatters": "~1.0 – Adds Nyan formatters" | 2996 | "phpspec/nyan-formatters": "~1.0 – Adds Nyan formatters" |
| ... | @@ -2789,7 +3035,7 @@ | ... | @@ -2789,7 +3035,7 @@ |
| 2789 | "testing", | 3035 | "testing", |
| 2790 | "tests" | 3036 | "tests" |
| 2791 | ], | 3037 | ], |
| 2792 | - "time": "2015-05-30 15:21:40" | 3038 | + "time": "2015-11-29 02:03:49" |
| 2793 | }, | 3039 | }, |
| 2794 | { | 3040 | { |
| 2795 | "name": "phpspec/prophecy", | 3041 | "name": "phpspec/prophecy", |
| ... | @@ -2853,16 +3099,16 @@ | ... | @@ -2853,16 +3099,16 @@ |
| 2853 | }, | 3099 | }, |
| 2854 | { | 3100 | { |
| 2855 | "name": "phpunit/php-code-coverage", | 3101 | "name": "phpunit/php-code-coverage", |
| 2856 | - "version": "2.2.2", | 3102 | + "version": "2.2.4", |
| 2857 | "source": { | 3103 | "source": { |
| 2858 | "type": "git", | 3104 | "type": "git", |
| 2859 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", | 3105 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", |
| 2860 | - "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c" | 3106 | + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" |
| 2861 | }, | 3107 | }, |
| 2862 | "dist": { | 3108 | "dist": { |
| 2863 | "type": "zip", | 3109 | "type": "zip", |
| 2864 | - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2d7c03c0e4e080901b8f33b2897b0577be18a13c", | 3110 | + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", |
| 2865 | - "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c", | 3111 | + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", |
| 2866 | "shasum": "" | 3112 | "shasum": "" |
| 2867 | }, | 3113 | }, |
| 2868 | "require": { | 3114 | "require": { |
| ... | @@ -2911,7 +3157,7 @@ | ... | @@ -2911,7 +3157,7 @@ |
| 2911 | "testing", | 3157 | "testing", |
| 2912 | "xunit" | 3158 | "xunit" |
| 2913 | ], | 3159 | ], |
| 2914 | - "time": "2015-08-04 03:42:39" | 3160 | + "time": "2015-10-06 15:47:00" |
| 2915 | }, | 3161 | }, |
| 2916 | { | 3162 | { |
| 2917 | "name": "phpunit/php-file-iterator", | 3163 | "name": "phpunit/php-file-iterator", |
| ... | @@ -3044,16 +3290,16 @@ | ... | @@ -3044,16 +3290,16 @@ |
| 3044 | }, | 3290 | }, |
| 3045 | { | 3291 | { |
| 3046 | "name": "phpunit/php-token-stream", | 3292 | "name": "phpunit/php-token-stream", |
| 3047 | - "version": "1.4.6", | 3293 | + "version": "1.4.8", |
| 3048 | "source": { | 3294 | "source": { |
| 3049 | "type": "git", | 3295 | "type": "git", |
| 3050 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", | 3296 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", |
| 3051 | - "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b" | 3297 | + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" |
| 3052 | }, | 3298 | }, |
| 3053 | "dist": { | 3299 | "dist": { |
| 3054 | "type": "zip", | 3300 | "type": "zip", |
| 3055 | - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3ab72c62e550370a6cd5dc873e1a04ab57562f5b", | 3301 | + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", |
| 3056 | - "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b", | 3302 | + "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", |
| 3057 | "shasum": "" | 3303 | "shasum": "" |
| 3058 | }, | 3304 | }, |
| 3059 | "require": { | 3305 | "require": { |
| ... | @@ -3089,20 +3335,20 @@ | ... | @@ -3089,20 +3335,20 @@ |
| 3089 | "keywords": [ | 3335 | "keywords": [ |
| 3090 | "tokenizer" | 3336 | "tokenizer" |
| 3091 | ], | 3337 | ], |
| 3092 | - "time": "2015-08-16 08:51:00" | 3338 | + "time": "2015-09-15 10:49:45" |
| 3093 | }, | 3339 | }, |
| 3094 | { | 3340 | { |
| 3095 | "name": "phpunit/phpunit", | 3341 | "name": "phpunit/phpunit", |
| 3096 | - "version": "4.8.4", | 3342 | + "version": "4.8.19", |
| 3097 | "source": { | 3343 | "source": { |
| 3098 | "type": "git", | 3344 | "type": "git", |
| 3099 | "url": "https://github.com/sebastianbergmann/phpunit.git", | 3345 | "url": "https://github.com/sebastianbergmann/phpunit.git", |
| 3100 | - "reference": "55bf1d6092b0e13a1f26bd5eaffeef3d8ad85ea7" | 3346 | + "reference": "b2caaf8947aba5e002d42126723e9d69795f32b4" |
| 3101 | }, | 3347 | }, |
| 3102 | "dist": { | 3348 | "dist": { |
| 3103 | "type": "zip", | 3349 | "type": "zip", |
| 3104 | - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/55bf1d6092b0e13a1f26bd5eaffeef3d8ad85ea7", | 3350 | + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b2caaf8947aba5e002d42126723e9d69795f32b4", |
| 3105 | - "reference": "55bf1d6092b0e13a1f26bd5eaffeef3d8ad85ea7", | 3351 | + "reference": "b2caaf8947aba5e002d42126723e9d69795f32b4", |
| 3106 | "shasum": "" | 3352 | "shasum": "" |
| 3107 | }, | 3353 | }, |
| 3108 | "require": { | 3354 | "require": { |
| ... | @@ -3161,24 +3407,24 @@ | ... | @@ -3161,24 +3407,24 @@ |
| 3161 | "testing", | 3407 | "testing", |
| 3162 | "xunit" | 3408 | "xunit" |
| 3163 | ], | 3409 | ], |
| 3164 | - "time": "2015-08-15 04:21:23" | 3410 | + "time": "2015-11-30 08:18:59" |
| 3165 | }, | 3411 | }, |
| 3166 | { | 3412 | { |
| 3167 | "name": "phpunit/phpunit-mock-objects", | 3413 | "name": "phpunit/phpunit-mock-objects", |
| 3168 | - "version": "2.3.6", | 3414 | + "version": "2.3.8", |
| 3169 | "source": { | 3415 | "source": { |
| 3170 | "type": "git", | 3416 | "type": "git", |
| 3171 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", | 3417 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", |
| 3172 | - "reference": "18dfbcb81d05e2296c0bcddd4db96cade75e6f42" | 3418 | + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" |
| 3173 | }, | 3419 | }, |
| 3174 | "dist": { | 3420 | "dist": { |
| 3175 | "type": "zip", | 3421 | "type": "zip", |
| 3176 | - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/18dfbcb81d05e2296c0bcddd4db96cade75e6f42", | 3422 | + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", |
| 3177 | - "reference": "18dfbcb81d05e2296c0bcddd4db96cade75e6f42", | 3423 | + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", |
| 3178 | "shasum": "" | 3424 | "shasum": "" |
| 3179 | }, | 3425 | }, |
| 3180 | "require": { | 3426 | "require": { |
| 3181 | - "doctrine/instantiator": "~1.0,>=1.0.2", | 3427 | + "doctrine/instantiator": "^1.0.2", |
| 3182 | "php": ">=5.3.3", | 3428 | "php": ">=5.3.3", |
| 3183 | "phpunit/php-text-template": "~1.2", | 3429 | "phpunit/php-text-template": "~1.2", |
| 3184 | "sebastian/exporter": "~1.2" | 3430 | "sebastian/exporter": "~1.2" |
| ... | @@ -3217,7 +3463,7 @@ | ... | @@ -3217,7 +3463,7 @@ |
| 3217 | "mock", | 3463 | "mock", |
| 3218 | "xunit" | 3464 | "xunit" |
| 3219 | ], | 3465 | ], |
| 3220 | - "time": "2015-07-10 06:54:24" | 3466 | + "time": "2015-10-02 06:51:40" |
| 3221 | }, | 3467 | }, |
| 3222 | { | 3468 | { |
| 3223 | "name": "sebastian/comparator", | 3469 | "name": "sebastian/comparator", |
| ... | @@ -3337,16 +3583,16 @@ | ... | @@ -3337,16 +3583,16 @@ |
| 3337 | }, | 3583 | }, |
| 3338 | { | 3584 | { |
| 3339 | "name": "sebastian/environment", | 3585 | "name": "sebastian/environment", |
| 3340 | - "version": "1.3.2", | 3586 | + "version": "1.3.3", |
| 3341 | "source": { | 3587 | "source": { |
| 3342 | "type": "git", | 3588 | "type": "git", |
| 3343 | "url": "https://github.com/sebastianbergmann/environment.git", | 3589 | "url": "https://github.com/sebastianbergmann/environment.git", |
| 3344 | - "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44" | 3590 | + "reference": "6e7133793a8e5a5714a551a8324337374be209df" |
| 3345 | }, | 3591 | }, |
| 3346 | "dist": { | 3592 | "dist": { |
| 3347 | "type": "zip", | 3593 | "type": "zip", |
| 3348 | - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44", | 3594 | + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e7133793a8e5a5714a551a8324337374be209df", |
| 3349 | - "reference": "6324c907ce7a52478eeeaede764f48733ef5ae44", | 3595 | + "reference": "6e7133793a8e5a5714a551a8324337374be209df", |
| 3350 | "shasum": "" | 3596 | "shasum": "" |
| 3351 | }, | 3597 | }, |
| 3352 | "require": { | 3598 | "require": { |
| ... | @@ -3383,7 +3629,7 @@ | ... | @@ -3383,7 +3629,7 @@ |
| 3383 | "environment", | 3629 | "environment", |
| 3384 | "hhvm" | 3630 | "hhvm" |
| 3385 | ], | 3631 | ], |
| 3386 | - "time": "2015-08-03 06:14:51" | 3632 | + "time": "2015-12-02 08:37:27" |
| 3387 | }, | 3633 | }, |
| 3388 | { | 3634 | { |
| 3389 | "name": "sebastian/exporter", | 3635 | "name": "sebastian/exporter", |
| ... | @@ -3453,16 +3699,16 @@ | ... | @@ -3453,16 +3699,16 @@ |
| 3453 | }, | 3699 | }, |
| 3454 | { | 3700 | { |
| 3455 | "name": "sebastian/global-state", | 3701 | "name": "sebastian/global-state", |
| 3456 | - "version": "1.0.0", | 3702 | + "version": "1.1.1", |
| 3457 | "source": { | 3703 | "source": { |
| 3458 | "type": "git", | 3704 | "type": "git", |
| 3459 | "url": "https://github.com/sebastianbergmann/global-state.git", | 3705 | "url": "https://github.com/sebastianbergmann/global-state.git", |
| 3460 | - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" | 3706 | + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" |
| 3461 | }, | 3707 | }, |
| 3462 | "dist": { | 3708 | "dist": { |
| 3463 | "type": "zip", | 3709 | "type": "zip", |
| 3464 | - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", | 3710 | + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", |
| 3465 | - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", | 3711 | + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", |
| 3466 | "shasum": "" | 3712 | "shasum": "" |
| 3467 | }, | 3713 | }, |
| 3468 | "require": { | 3714 | "require": { |
| ... | @@ -3500,7 +3746,7 @@ | ... | @@ -3500,7 +3746,7 @@ |
| 3500 | "keywords": [ | 3746 | "keywords": [ |
| 3501 | "global state" | 3747 | "global state" |
| 3502 | ], | 3748 | ], |
| 3503 | - "time": "2014-10-06 09:23:50" | 3749 | + "time": "2015-10-12 03:26:01" |
| 3504 | }, | 3750 | }, |
| 3505 | { | 3751 | { |
| 3506 | "name": "sebastian/recursion-context", | 3752 | "name": "sebastian/recursion-context", |
| ... | @@ -3592,34 +3838,34 @@ | ... | @@ -3592,34 +3838,34 @@ |
| 3592 | }, | 3838 | }, |
| 3593 | { | 3839 | { |
| 3594 | "name": "symfony/yaml", | 3840 | "name": "symfony/yaml", |
| 3595 | - "version": "v2.7.3", | 3841 | + "version": "v3.0.0", |
| 3596 | "source": { | 3842 | "source": { |
| 3597 | "type": "git", | 3843 | "type": "git", |
| 3598 | - "url": "https://github.com/symfony/Yaml.git", | 3844 | + "url": "https://github.com/symfony/yaml.git", |
| 3599 | - "reference": "71340e996171474a53f3d29111d046be4ad8a0ff" | 3845 | + "reference": "177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002" |
| 3600 | }, | 3846 | }, |
| 3601 | "dist": { | 3847 | "dist": { |
| 3602 | "type": "zip", | 3848 | "type": "zip", |
| 3603 | - "url": "https://api.github.com/repos/symfony/Yaml/zipball/71340e996171474a53f3d29111d046be4ad8a0ff", | 3849 | + "url": "https://api.github.com/repos/symfony/yaml/zipball/177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002", |
| 3604 | - "reference": "71340e996171474a53f3d29111d046be4ad8a0ff", | 3850 | + "reference": "177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002", |
| 3605 | "shasum": "" | 3851 | "shasum": "" |
| 3606 | }, | 3852 | }, |
| 3607 | "require": { | 3853 | "require": { |
| 3608 | - "php": ">=5.3.9" | 3854 | + "php": ">=5.5.9" |
| 3609 | - }, | ||
| 3610 | - "require-dev": { | ||
| 3611 | - "symfony/phpunit-bridge": "~2.7" | ||
| 3612 | }, | 3855 | }, |
| 3613 | "type": "library", | 3856 | "type": "library", |
| 3614 | "extra": { | 3857 | "extra": { |
| 3615 | "branch-alias": { | 3858 | "branch-alias": { |
| 3616 | - "dev-master": "2.7-dev" | 3859 | + "dev-master": "3.0-dev" |
| 3617 | } | 3860 | } |
| 3618 | }, | 3861 | }, |
| 3619 | "autoload": { | 3862 | "autoload": { |
| 3620 | "psr-4": { | 3863 | "psr-4": { |
| 3621 | "Symfony\\Component\\Yaml\\": "" | 3864 | "Symfony\\Component\\Yaml\\": "" |
| 3622 | - } | 3865 | + }, |
| 3866 | + "exclude-from-classmap": [ | ||
| 3867 | + "/Tests/" | ||
| 3868 | + ] | ||
| 3623 | }, | 3869 | }, |
| 3624 | "notification-url": "https://packagist.org/downloads/", | 3870 | "notification-url": "https://packagist.org/downloads/", |
| 3625 | "license": [ | 3871 | "license": [ |
| ... | @@ -3637,7 +3883,7 @@ | ... | @@ -3637,7 +3883,7 @@ |
| 3637 | ], | 3883 | ], |
| 3638 | "description": "Symfony Yaml Component", | 3884 | "description": "Symfony Yaml Component", |
| 3639 | "homepage": "https://symfony.com", | 3885 | "homepage": "https://symfony.com", |
| 3640 | - "time": "2015-07-28 14:07:07" | 3886 | + "time": "2015-11-30 12:36:17" |
| 3641 | } | 3887 | } |
| 3642 | ], | 3888 | ], |
| 3643 | "aliases": [], | 3889 | "aliases": [], | ... | ... |
| ... | @@ -13,7 +13,7 @@ return [ | ... | @@ -13,7 +13,7 @@ return [ |
| 13 | | | 13 | | |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | - 'debug' => env('APP_DEBUG', false), | 16 | + 'debug' => env('APP_DEBUG', false), |
| 17 | 17 | ||
| 18 | /* | 18 | /* |
| 19 | |-------------------------------------------------------------------------- | 19 | |-------------------------------------------------------------------------- |
| ... | @@ -26,7 +26,7 @@ return [ | ... | @@ -26,7 +26,7 @@ return [ |
| 26 | | | 26 | | |
| 27 | */ | 27 | */ |
| 28 | 28 | ||
| 29 | - 'url' => env('APP_URL', 'http://localhost'), | 29 | + 'url' => env('APP_URL', 'http://localhost'), |
| 30 | 30 | ||
| 31 | /* | 31 | /* |
| 32 | |-------------------------------------------------------------------------- | 32 | |-------------------------------------------------------------------------- |
| ... | @@ -39,7 +39,7 @@ return [ | ... | @@ -39,7 +39,7 @@ return [ |
| 39 | | | 39 | | |
| 40 | */ | 40 | */ |
| 41 | 41 | ||
| 42 | - 'timezone' => 'UTC', | 42 | + 'timezone' => 'UTC', |
| 43 | 43 | ||
| 44 | /* | 44 | /* |
| 45 | |-------------------------------------------------------------------------- | 45 | |-------------------------------------------------------------------------- |
| ... | @@ -52,7 +52,7 @@ return [ | ... | @@ -52,7 +52,7 @@ return [ |
| 52 | | | 52 | | |
| 53 | */ | 53 | */ |
| 54 | 54 | ||
| 55 | - 'locale' => 'en', | 55 | + 'locale' => 'en', |
| 56 | 56 | ||
| 57 | /* | 57 | /* |
| 58 | |-------------------------------------------------------------------------- | 58 | |-------------------------------------------------------------------------- |
| ... | @@ -78,9 +78,9 @@ return [ | ... | @@ -78,9 +78,9 @@ return [ |
| 78 | | | 78 | | |
| 79 | */ | 79 | */ |
| 80 | 80 | ||
| 81 | - 'key' => env('APP_KEY', 'AbAZchsay4uBTU33RubBzLKw203yqSqr'), | 81 | + 'key' => env('APP_KEY', 'AbAZchsay4uBTU33RubBzLKw203yqSqr'), |
| 82 | 82 | ||
| 83 | - 'cipher' => 'AES-256-CBC', | 83 | + 'cipher' => 'AES-256-CBC', |
| 84 | 84 | ||
| 85 | /* | 85 | /* |
| 86 | |-------------------------------------------------------------------------- | 86 | |-------------------------------------------------------------------------- |
| ... | @@ -95,7 +95,7 @@ return [ | ... | @@ -95,7 +95,7 @@ return [ |
| 95 | | | 95 | | |
| 96 | */ | 96 | */ |
| 97 | 97 | ||
| 98 | - 'log' => 'single', | 98 | + 'log' => 'single', |
| 99 | 99 | ||
| 100 | /* | 100 | /* |
| 101 | |-------------------------------------------------------------------------- | 101 | |-------------------------------------------------------------------------- |
| ... | @@ -108,7 +108,7 @@ return [ | ... | @@ -108,7 +108,7 @@ return [ |
| 108 | | | 108 | | |
| 109 | */ | 109 | */ |
| 110 | 110 | ||
| 111 | - 'providers' => [ | 111 | + 'providers' => [ |
| 112 | 112 | ||
| 113 | /* | 113 | /* |
| 114 | * Laravel Framework Service Providers... | 114 | * Laravel Framework Service Providers... |
| ... | @@ -167,7 +167,7 @@ return [ | ... | @@ -167,7 +167,7 @@ return [ |
| 167 | | | 167 | | |
| 168 | */ | 168 | */ |
| 169 | 169 | ||
| 170 | - 'aliases' => [ | 170 | + 'aliases' => [ |
| 171 | 171 | ||
| 172 | 'App' => Illuminate\Support\Facades\App::class, | 172 | 'App' => Illuminate\Support\Facades\App::class, |
| 173 | 'Artisan' => Illuminate\Support\Facades\Artisan::class, | 173 | 'Artisan' => Illuminate\Support\Facades\Artisan::class, |
| ... | @@ -208,15 +208,16 @@ return [ | ... | @@ -208,15 +208,16 @@ return [ |
| 208 | */ | 208 | */ |
| 209 | 209 | ||
| 210 | 'ImageTool' => Intervention\Image\Facades\Image::class, | 210 | 'ImageTool' => Intervention\Image\Facades\Image::class, |
| 211 | - 'Debugbar' => Barryvdh\Debugbar\Facade::class, | 211 | + 'Debugbar' => Barryvdh\Debugbar\Facade::class, |
| 212 | 212 | ||
| 213 | /** | 213 | /** |
| 214 | * Custom | 214 | * Custom |
| 215 | */ | 215 | */ |
| 216 | 216 | ||
| 217 | - 'Activity' => BookStack\Services\Facades\Activity::class, | 217 | + 'Activity' => BookStack\Services\Facades\Activity::class, |
| 218 | - 'Setting' => BookStack\Services\Facades\Setting::class, | 218 | + 'Setting' => BookStack\Services\Facades\Setting::class, |
| 219 | - 'Views' => BookStack\Services\Facades\Views::class, | 219 | + 'Views' => BookStack\Services\Facades\Views::class, |
| 220 | + 'Images' => \BookStack\Services\Facades\Images::class, | ||
| 220 | 221 | ||
| 221 | ], | 222 | ], |
| 222 | 223 | ... | ... |
| ... | @@ -45,7 +45,7 @@ return [ | ... | @@ -45,7 +45,7 @@ return [ |
| 45 | 45 | ||
| 46 | 'local' => [ | 46 | 'local' => [ |
| 47 | 'driver' => 'local', | 47 | 'driver' => 'local', |
| 48 | - 'root' => storage_path('app'), | 48 | + 'root' => public_path(), |
| 49 | ], | 49 | ], |
| 50 | 50 | ||
| 51 | 'ftp' => [ | 51 | 'ftp' => [ |
| ... | @@ -64,10 +64,10 @@ return [ | ... | @@ -64,10 +64,10 @@ return [ |
| 64 | 64 | ||
| 65 | 's3' => [ | 65 | 's3' => [ |
| 66 | 'driver' => 's3', | 66 | 'driver' => 's3', |
| 67 | - 'key' => 'your-key', | 67 | + 'key' => env('STORAGE_S3_KEY', 'your-key'), |
| 68 | - 'secret' => 'your-secret', | 68 | + 'secret' => env('STORAGE_S3_SECRET', 'your-secret'), |
| 69 | - 'region' => 'your-region', | 69 | + 'region' => env('STORAGE_S3_REGION', 'your-region'), |
| 70 | - 'bucket' => 'your-bucket', | 70 | + 'bucket' => env('STORAGE_S3_BUCKET', 'your-bucket'), |
| 71 | ], | 71 | ], |
| 72 | 72 | ||
| 73 | 'rackspace' => [ | 73 | 'rackspace' => [ | ... | ... |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use Illuminate\Database\Schema\Blueprint; | ||
| 4 | +use Illuminate\Database\Migrations\Migration; | ||
| 5 | + | ||
| 6 | +class FulltextWeighting extends Migration | ||
| 7 | +{ | ||
| 8 | + /** | ||
| 9 | + * Run the migrations. | ||
| 10 | + * | ||
| 11 | + * @return void | ||
| 12 | + */ | ||
| 13 | + public function up() | ||
| 14 | + { | ||
| 15 | + DB::statement('ALTER TABLE pages ADD FULLTEXT name_search(name)'); | ||
| 16 | + DB::statement('ALTER TABLE books ADD FULLTEXT name_search(name)'); | ||
| 17 | + DB::statement('ALTER TABLE chapters ADD FULLTEXT name_search(name)'); | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + /** | ||
| 21 | + * Reverse the migrations. | ||
| 22 | + * | ||
| 23 | + * @return void | ||
| 24 | + */ | ||
| 25 | + public function down() | ||
| 26 | + { | ||
| 27 | + Schema::table('pages', function(Blueprint $table) { | ||
| 28 | + $table->dropIndex('name_search'); | ||
| 29 | + }); | ||
| 30 | + Schema::table('books', function(Blueprint $table) { | ||
| 31 | + $table->dropIndex('name_search'); | ||
| 32 | + }); | ||
| 33 | + Schema::table('chapters', function(Blueprint $table) { | ||
| 34 | + $table->dropIndex('name_search'); | ||
| 35 | + }); | ||
| 36 | + } | ||
| 37 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use BookStack\Image; | ||
| 4 | +use Illuminate\Database\Schema\Blueprint; | ||
| 5 | +use Illuminate\Database\Migrations\Migration; | ||
| 6 | + | ||
| 7 | +class AddImageUploadTypes extends Migration | ||
| 8 | +{ | ||
| 9 | + /** | ||
| 10 | + * Run the migrations. | ||
| 11 | + * | ||
| 12 | + * @return void | ||
| 13 | + */ | ||
| 14 | + public function up() | ||
| 15 | + { | ||
| 16 | + Schema::table('images', function (Blueprint $table) { | ||
| 17 | + $table->string('path', 400); | ||
| 18 | + $table->string('type')->index(); | ||
| 19 | + }); | ||
| 20 | + | ||
| 21 | + Image::all()->each(function($image) { | ||
| 22 | + $image->path = $image->url; | ||
| 23 | + $image->type = 'gallery'; | ||
| 24 | + $image->save(); | ||
| 25 | + }); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * Reverse the migrations. | ||
| 30 | + * | ||
| 31 | + * @return void | ||
| 32 | + */ | ||
| 33 | + public function down() | ||
| 34 | + { | ||
| 35 | + Schema::table('images', function (Blueprint $table) { | ||
| 36 | + $table->dropColumn('type'); | ||
| 37 | + $table->dropColumn('path'); | ||
| 38 | + }); | ||
| 39 | + | ||
| 40 | + } | ||
| 41 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use Illuminate\Database\Schema\Blueprint; | ||
| 4 | +use Illuminate\Database\Migrations\Migration; | ||
| 5 | + | ||
| 6 | +class AddUserAvatars extends Migration | ||
| 7 | +{ | ||
| 8 | + /** | ||
| 9 | + * Run the migrations. | ||
| 10 | + * | ||
| 11 | + * @return void | ||
| 12 | + */ | ||
| 13 | + public function up() | ||
| 14 | + { | ||
| 15 | + Schema::table('users', function (Blueprint $table) { | ||
| 16 | + $table->integer('image_id')->default(0); | ||
| 17 | + }); | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + /** | ||
| 21 | + * Reverse the migrations. | ||
| 22 | + * | ||
| 23 | + * @return void | ||
| 24 | + */ | ||
| 25 | + public function down() | ||
| 26 | + { | ||
| 27 | + Schema::table('users', function (Blueprint $table) { | ||
| 28 | + $table->dropColumn('image_id'); | ||
| 29 | + }); | ||
| 30 | + } | ||
| 31 | +} |
| ... | @@ -23,7 +23,9 @@ class DummyContentSeeder extends Seeder | ... | @@ -23,7 +23,9 @@ class DummyContentSeeder extends Seeder |
| 23 | $pages = factory(\BookStack\Page::class, 10)->make(['created_by' => $user->id, 'updated_by' => $user->id, 'book_id' => $book->id]); | 23 | $pages = factory(\BookStack\Page::class, 10)->make(['created_by' => $user->id, 'updated_by' => $user->id, 'book_id' => $book->id]); |
| 24 | $chapter->pages()->saveMany($pages); | 24 | $chapter->pages()->saveMany($pages); |
| 25 | }); | 25 | }); |
| 26 | + $pages = factory(\BookStack\Page::class, 3)->make(['created_by' => $user->id, 'updated_by' => $user->id]); | ||
| 26 | $book->chapters()->saveMany($chapters); | 27 | $book->chapters()->saveMany($chapters); |
| 28 | + $book->pages()->saveMany($pages); | ||
| 27 | }); | 29 | }); |
| 28 | } | 30 | } |
| 29 | } | 31 | } | ... | ... |
| 1 | var elixir = require('laravel-elixir'); | 1 | var elixir = require('laravel-elixir'); |
| 2 | 2 | ||
| 3 | +// Custom extensions | ||
| 4 | +var gulp = require('gulp'); | ||
| 5 | +var Task = elixir.Task; | ||
| 6 | +var fs = require('fs'); | ||
| 7 | + | ||
| 8 | +elixir.extend('queryVersion', function(inputFiles) { | ||
| 9 | + new Task('queryVersion', function() { | ||
| 10 | + var manifestObject = {}; | ||
| 11 | + var uidString = Date.now().toString(16).slice(4); | ||
| 12 | + for (var i = 0; i < inputFiles.length; i++) { | ||
| 13 | + var file = inputFiles[i]; | ||
| 14 | + manifestObject[file] = file + '?version=' + uidString; | ||
| 15 | + } | ||
| 16 | + var fileContents = JSON.stringify(manifestObject, null, 1); | ||
| 17 | + fs.writeFileSync('public/build/manifest.json', fileContents); | ||
| 18 | + }).watch(['./public/css/*.css', './public/js/*.js']); | ||
| 19 | +}); | ||
| 20 | + | ||
| 3 | elixir(function(mix) { | 21 | elixir(function(mix) { |
| 4 | mix.sass('styles.scss') | 22 | mix.sass('styles.scss') |
| 5 | .sass('print-styles.scss') | 23 | .sass('print-styles.scss') |
| 6 | .browserify(['jquery-extensions.js', 'global.js'], 'public/js/common.js') | 24 | .browserify(['jquery-extensions.js', 'global.js'], 'public/js/common.js') |
| 7 | - .version(['css/styles.css', 'css/print-styles.css', 'js/common.js']); | 25 | + .queryVersion(['css/styles.css', 'css/print-styles.css', 'js/common.js']); |
| 8 | }); | 26 | }); | ... | ... |
| ... | @@ -26,5 +26,6 @@ | ... | @@ -26,5 +26,6 @@ |
| 26 | <env name="QUEUE_DRIVER" value="sync"/> | 26 | <env name="QUEUE_DRIVER" value="sync"/> |
| 27 | <env name="DB_CONNECTION" value="mysql_testing"/> | 27 | <env name="DB_CONNECTION" value="mysql_testing"/> |
| 28 | <env name="MAIL_PRETEND" value="true"/> | 28 | <env name="MAIL_PRETEND" value="true"/> |
| 29 | + <env name="DISABLE_EXTERNAL_SERVICES" value="true"/> | ||
| 29 | </php> | 30 | </php> |
| 30 | </phpunit> | 31 | </phpunit> | ... | ... |
public/user_avatar.png
0 → 100644
7.23 KB
| ... | @@ -5,7 +5,7 @@ A platform to create documentation/wiki content. General information about BookS | ... | @@ -5,7 +5,7 @@ A platform to create documentation/wiki content. General information about BookS |
| 5 | 5 | ||
| 6 | ## Requirements | 6 | ## Requirements |
| 7 | 7 | ||
| 8 | -BookStack has the similar requirements to Laravel. On top of those are some front-end build tools which are only required when developing. | 8 | +BookStack has similar requirements to Laravel. On top of those are some front-end build tools which are only required when developing. |
| 9 | 9 | ||
| 10 | * PHP >= 5.5.9 | 10 | * PHP >= 5.5.9 |
| 11 | * OpenSSL PHP Extension | 11 | * OpenSSL PHP Extension |
| ... | @@ -25,11 +25,11 @@ Ensure the requirements are met before installing. | ... | @@ -25,11 +25,11 @@ Ensure the requirements are met before installing. |
| 25 | 25 | ||
| 26 | This project currently uses the `release` branch of this repository as a stable channel for providing updates. | 26 | This project currently uses the `release` branch of this repository as a stable channel for providing updates. |
| 27 | 27 | ||
| 28 | -The installation is currently somewhat complicated. Some PHP/Laravel experience will benefit. | 28 | +The installation is currently somewhat complicated and will be made simpler in future releases. Some PHP/Laravel experience will currently benefit. |
| 29 | 29 | ||
| 30 | 1. Clone the release branch of this repository into a folder. | 30 | 1. Clone the release branch of this repository into a folder. |
| 31 | 31 | ||
| 32 | -``` | 32 | +``` |
| 33 | git clone https://github.com/ssddanbrown/BookStack.git --branch release --single-branch | 33 | git clone https://github.com/ssddanbrown/BookStack.git --branch release --single-branch |
| 34 | ``` | 34 | ``` |
| 35 | 35 | ||
| ... | @@ -37,7 +37,7 @@ git clone https://github.com/ssddanbrown/BookStack.git --branch release --single | ... | @@ -37,7 +37,7 @@ git clone https://github.com/ssddanbrown/BookStack.git --branch release --single |
| 37 | 3. Copy the `.env.example` file to `.env` and fill with your own database and mail details. | 37 | 3. Copy the `.env.example` file to `.env` and fill with your own database and mail details. |
| 38 | 4. Ensure the `storage` & `bootstrap/cache` folders are writable by the web server. | 38 | 4. Ensure the `storage` & `bootstrap/cache` folders are writable by the web server. |
| 39 | 5. In the application root, Run `php artisan key:generate` to generate a unique application key. | 39 | 5. In the application root, Run `php artisan key:generate` to generate a unique application key. |
| 40 | -6. If not using apache or `.htaccess` files are disable you will have to create some URL rewrite rules as shown below. | 40 | +6. If not using apache or if `.htaccess` files are disabled you will have to create some URL rewrite rules as shown below. |
| 41 | 7. Run `php migrate` to update the database. | 41 | 7. Run `php migrate` to update the database. |
| 42 | 8. Done! You can now login using the default admin details `admin@admin.com` with a password of `password`. It is recommended to change these details directly after first logging in. | 42 | 8. Done! You can now login using the default admin details `admin@admin.com` with a password of `password`. It is recommended to change these details directly after first logging in. |
| 43 | 43 | ||
| ... | @@ -76,3 +76,17 @@ Once done you can run `phpunit` in the application root directory to run all tes | ... | @@ -76,3 +76,17 @@ Once done you can run `phpunit` in the application root directory to run all tes |
| 76 | ## License | 76 | ## License |
| 77 | 77 | ||
| 78 | BookStack is provided under the MIT License. | 78 | BookStack is provided under the MIT License. |
| 79 | + | ||
| 80 | +## Attribution | ||
| 81 | + | ||
| 82 | +These are the great projects used to help build BookStack: | ||
| 83 | + | ||
| 84 | +* [Laravel](http://laravel.com/) | ||
| 85 | +* [VueJS](http://vuejs.org/) | ||
| 86 | +* [jQuery](https://jquery.com/) | ||
| 87 | +* [TinyMCE](https://www.tinymce.com/) | ||
| 88 | +* [highlight.js](https://highlightjs.org/) | ||
| 89 | +* [jQuery Sortable](https://johnny.github.io/jquery-sortable/) | ||
| 90 | +* [Material Design Iconic Font](http://zavoloklom.github.io/material-design-iconic-font/icons.html) | ||
| 91 | +* [Dropzone.js](http://www.dropzonejs.com/) | ||
| 92 | +* [ZeroClipboard](http://zeroclipboard.org/) | ... | ... |
| ... | @@ -7,7 +7,7 @@ | ... | @@ -7,7 +7,7 @@ |
| 7 | <div v-for="image in images"> | 7 | <div v-for="image in images"> |
| 8 | <img class="anim fadeIn" | 8 | <img class="anim fadeIn" |
| 9 | :class="{selected: (image==selectedImage)}" | 9 | :class="{selected: (image==selectedImage)}" |
| 10 | - :src="image.thumbnail" :alt="image.title" :title="image.name" | 10 | + :src="image.thumbs.gallery" :alt="image.title" :title="image.name" |
| 11 | @click="imageClick(image)" | 11 | @click="imageClick(image)" |
| 12 | :style="{animationDelay: ($index > 26) ? '160ms' : ($index * 25) + 'ms'}"> | 12 | :style="{animationDelay: ($index > 26) ? '160ms' : ($index * 25) + 'ms'}"> |
| 13 | </div> | 13 | </div> |
| ... | @@ -76,6 +76,13 @@ | ... | @@ -76,6 +76,13 @@ |
| 76 | } | 76 | } |
| 77 | }, | 77 | }, |
| 78 | 78 | ||
| 79 | + props: { | ||
| 80 | + imageType: { | ||
| 81 | + type: String, | ||
| 82 | + required: true | ||
| 83 | + } | ||
| 84 | + }, | ||
| 85 | + | ||
| 79 | created: function () { | 86 | created: function () { |
| 80 | window.ImageManager = this; | 87 | window.ImageManager = this; |
| 81 | }, | 88 | }, |
| ... | @@ -88,7 +95,7 @@ | ... | @@ -88,7 +95,7 @@ |
| 88 | methods: { | 95 | methods: { |
| 89 | fetchData: function () { | 96 | fetchData: function () { |
| 90 | var _this = this; | 97 | var _this = this; |
| 91 | - this.$http.get('/images/all/' + _this.page, function (data) { | 98 | + this.$http.get('/images/' + _this.imageType + '/all/' + _this.page, function (data) { |
| 92 | _this.images = _this.images.concat(data.images); | 99 | _this.images = _this.images.concat(data.images); |
| 93 | _this.hasMore = data.hasMore; | 100 | _this.hasMore = data.hasMore; |
| 94 | _this.page++; | 101 | _this.page++; |
| ... | @@ -98,7 +105,7 @@ | ... | @@ -98,7 +105,7 @@ |
| 98 | setupDropZone: function () { | 105 | setupDropZone: function () { |
| 99 | var _this = this; | 106 | var _this = this; |
| 100 | var dropZone = new Dropzone(_this.$els.dropZone, { | 107 | var dropZone = new Dropzone(_this.$els.dropZone, { |
| 101 | - url: '/upload/image', | 108 | + url: '/images/' + _this.imageType + '/upload', |
| 102 | init: function () { | 109 | init: function () { |
| 103 | var dz = this; | 110 | var dz = this; |
| 104 | this.on("sending", function (file, xhr, data) { | 111 | this.on("sending", function (file, xhr, data) { |
| ... | @@ -110,8 +117,8 @@ | ... | @@ -110,8 +117,8 @@ |
| 110 | dz.removeFile(file); | 117 | dz.removeFile(file); |
| 111 | }); | 118 | }); |
| 112 | }); | 119 | }); |
| 113 | - this.on('error', function(file, errorMessage, xhr) { | 120 | + this.on('error', function (file, errorMessage, xhr) { |
| 114 | - if(errorMessage.file) { | 121 | + if (errorMessage.file) { |
| 115 | $(file.previewElement).find('[data-dz-errormessage]').text(errorMessage.file[0]); | 122 | $(file.previewElement).find('[data-dz-errormessage]').text(errorMessage.file[0]); |
| 116 | } | 123 | } |
| 117 | console.log(errorMessage); | 124 | console.log(errorMessage); |
| ... | @@ -120,6 +127,10 @@ | ... | @@ -120,6 +127,10 @@ |
| 120 | }); | 127 | }); |
| 121 | }, | 128 | }, |
| 122 | 129 | ||
| 130 | + returnCallback: function (image) { | ||
| 131 | + this.callback(image); | ||
| 132 | + }, | ||
| 133 | + | ||
| 123 | imageClick: function (image) { | 134 | imageClick: function (image) { |
| 124 | var dblClickTime = 380; | 135 | var dblClickTime = 380; |
| 125 | var cTime = (new Date()).getTime(); | 136 | var cTime = (new Date()).getTime(); |
| ... | @@ -127,7 +138,7 @@ | ... | @@ -127,7 +138,7 @@ |
| 127 | if (this.cClickTime !== 0 && timeDiff < dblClickTime && this.selectedImage === image) { | 138 | if (this.cClickTime !== 0 && timeDiff < dblClickTime && this.selectedImage === image) { |
| 128 | // DoubleClick | 139 | // DoubleClick |
| 129 | if (this.callback) { | 140 | if (this.callback) { |
| 130 | - this.callback(image); | 141 | + this.returnCallback(image); |
| 131 | } | 142 | } |
| 132 | this.hide(); | 143 | this.hide(); |
| 133 | } else { | 144 | } else { |
| ... | @@ -139,7 +150,7 @@ | ... | @@ -139,7 +150,7 @@ |
| 139 | 150 | ||
| 140 | selectButtonClick: function () { | 151 | selectButtonClick: function () { |
| 141 | if (this.callback) { | 152 | if (this.callback) { |
| 142 | - this.callback(this.selectedImage); | 153 | + this.returnCallback(this.selectedImage); |
| 143 | } | 154 | } |
| 144 | this.hide(); | 155 | this.hide(); |
| 145 | }, | 156 | }, | ... | ... |
| ... | @@ -7,31 +7,89 @@ | ... | @@ -7,31 +7,89 @@ |
| 7 | </div> | 7 | </div> |
| 8 | <button class="button" type="button" @click="showImageManager">Select Image</button> | 8 | <button class="button" type="button" @click="showImageManager">Select Image</button> |
| 9 | <br> | 9 | <br> |
| 10 | - <button class="text-button" @click="reset" type="button">Reset</button> <span class="sep">|</span> <button class="text-button neg" v-on:click="remove" type="button">Remove</button> | 10 | + <button class="text-button" @click="reset" type="button">Reset</button> <span v-show="showRemove" class="sep">|</span> <button v-show="showRemove" class="text-button neg" @click="remove" type="button">Remove</button> |
| 11 | - <input type="hidden" :name="name" :id="name" v-model="image"> | 11 | + <input type="hidden" :name="name" :id="name" v-model="value"> |
| 12 | </div> | 12 | </div> |
| 13 | </template> | 13 | </template> |
| 14 | 14 | ||
| 15 | <script> | 15 | <script> |
| 16 | module.exports = { | 16 | module.exports = { |
| 17 | - props: ['currentImage', 'name', 'imageClass', 'defaultImage'], | 17 | + props: { |
| 18 | + currentImage: { | ||
| 19 | + required: true, | ||
| 20 | + type: String | ||
| 21 | + }, | ||
| 22 | + currentId: { | ||
| 23 | + required: false, | ||
| 24 | + default: 'false', | ||
| 25 | + type: String | ||
| 26 | + }, | ||
| 27 | + name: { | ||
| 28 | + required: true, | ||
| 29 | + type: String | ||
| 30 | + }, | ||
| 31 | + defaultImage: { | ||
| 32 | + required: true, | ||
| 33 | + type: String | ||
| 34 | + }, | ||
| 35 | + imageClass: { | ||
| 36 | + required: true, | ||
| 37 | + type: String | ||
| 38 | + }, | ||
| 39 | + resizeWidth: { | ||
| 40 | + type: String | ||
| 41 | + }, | ||
| 42 | + resizeHeight: { | ||
| 43 | + type: String | ||
| 44 | + }, | ||
| 45 | + resizeCrop: { | ||
| 46 | + type: Boolean | ||
| 47 | + }, | ||
| 48 | + showRemove: { | ||
| 49 | + type: Boolean, | ||
| 50 | + default: 'true' | ||
| 51 | + } | ||
| 52 | + }, | ||
| 18 | data: function() { | 53 | data: function() { |
| 19 | return { | 54 | return { |
| 20 | - image: this.currentImage | 55 | + image: this.currentImage, |
| 56 | + value: false | ||
| 21 | } | 57 | } |
| 22 | }, | 58 | }, |
| 59 | + compiled: function() { | ||
| 60 | + this.value = this.currentId === 'false' ? this.currentImage : this.currentId; | ||
| 61 | + }, | ||
| 23 | methods: { | 62 | methods: { |
| 63 | + setCurrentValue: function(imageModel, imageUrl) { | ||
| 64 | + this.image = imageUrl; | ||
| 65 | + this.value = this.currentId === 'false' ? imageUrl : imageModel.id; | ||
| 66 | + }, | ||
| 24 | showImageManager: function(e) { | 67 | showImageManager: function(e) { |
| 25 | var _this = this; | 68 | var _this = this; |
| 26 | ImageManager.show(function(image) { | 69 | ImageManager.show(function(image) { |
| 27 | - _this.image = image.url; | 70 | + _this.updateImageFromModel(image); |
| 28 | }); | 71 | }); |
| 29 | }, | 72 | }, |
| 30 | reset: function() { | 73 | reset: function() { |
| 31 | - this.image = ''; | 74 | + this.setCurrentValue({id: 0}, this.defaultImage); |
| 32 | }, | 75 | }, |
| 33 | remove: function() { | 76 | remove: function() { |
| 34 | this.image = 'none'; | 77 | this.image = 'none'; |
| 78 | + }, | ||
| 79 | + updateImageFromModel: function(model) { | ||
| 80 | + var _this = this; | ||
| 81 | + var isResized = _this.resizeWidth && _this.resizeHeight; | ||
| 82 | + | ||
| 83 | + if (!isResized) { | ||
| 84 | + _this.setCurrentValue(model, model.url); | ||
| 85 | + return; | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + var cropped = _this.resizeCrop ? 'true' : 'false'; | ||
| 89 | + var requestString = '/images/thumb/' + model.id + '/' + _this.resizeWidth + '/' + _this.resizeHeight + '/' + cropped; | ||
| 90 | + _this.$http.get(requestString, function(data) { | ||
| 91 | + _this.setCurrentValue(model, data.url); | ||
| 92 | + }); | ||
| 35 | } | 93 | } |
| 36 | } | 94 | } |
| 37 | }; | 95 | }; | ... | ... |
| ... | @@ -100,7 +100,7 @@ module.exports = { | ... | @@ -100,7 +100,7 @@ module.exports = { |
| 100 | onclick: function() { | 100 | onclick: function() { |
| 101 | ImageManager.show(function(image) { | 101 | ImageManager.show(function(image) { |
| 102 | var html = '<a href="'+image.url+'" target="_blank">'; | 102 | var html = '<a href="'+image.url+'" target="_blank">'; |
| 103 | - html += '<img src="'+image.display+'" alt="'+image.name+'">'; | 103 | + html += '<img src="'+image.thumbs.display+'" alt="'+image.name+'">'; |
| 104 | html += '</a>'; | 104 | html += '</a>'; |
| 105 | editor.execCommand('mceInsertContent', false, html); | 105 | editor.execCommand('mceInsertContent', false, html); |
| 106 | }); | 106 | }); | ... | ... |
| ... | @@ -118,6 +118,9 @@ | ... | @@ -118,6 +118,9 @@ |
| 118 | text-decoration: none; | 118 | text-decoration: none; |
| 119 | } | 119 | } |
| 120 | } | 120 | } |
| 121 | + li a i { | ||
| 122 | + padding-right: $-xs + 2px; | ||
| 123 | + } | ||
| 121 | li, a { | 124 | li, a { |
| 122 | display: block; | 125 | display: block; |
| 123 | } | 126 | } |
| ... | @@ -150,11 +153,11 @@ | ... | @@ -150,11 +153,11 @@ |
| 150 | } | 153 | } |
| 151 | .list-item-page { | 154 | .list-item-page { |
| 152 | border-bottom: none; | 155 | border-bottom: none; |
| 156 | + border-left: 5px solid $color-page; | ||
| 157 | + margin: 10px 10px; | ||
| 153 | } | 158 | } |
| 154 | .page { | 159 | .page { |
| 155 | color: $color-page !important; | 160 | color: $color-page !important; |
| 156 | - border-left: 5px solid $color-page; | ||
| 157 | - margin: 10px 10px; | ||
| 158 | border-bottom: none; | 161 | border-bottom: none; |
| 159 | &.selected { | 162 | &.selected { |
| 160 | background-color: rgba($color-page, 0.1); | 163 | background-color: rgba($color-page, 0.1); | ... | ... |
| ... | @@ -32,10 +32,16 @@ body.dragging, body.dragging * { | ... | @@ -32,10 +32,16 @@ body.dragging, body.dragging * { |
| 32 | .avatar { | 32 | .avatar { |
| 33 | border-radius: 100%; | 33 | border-radius: 100%; |
| 34 | background-color: #EEE; | 34 | background-color: #EEE; |
| 35 | + width: 30px; | ||
| 36 | + height: 30px; | ||
| 35 | &.med { | 37 | &.med { |
| 36 | width: 40px; | 38 | width: 40px; |
| 37 | height: 40px; | 39 | height: 40px; |
| 38 | } | 40 | } |
| 41 | + &.large { | ||
| 42 | + width: 80px; | ||
| 43 | + height: 80px; | ||
| 44 | + } | ||
| 39 | } | 45 | } |
| 40 | 46 | ||
| 41 | // System wide notifications | 47 | // System wide notifications | ... | ... |
| 1 | <!DOCTYPE html> | 1 | <!DOCTYPE html> |
| 2 | <html> | 2 | <html> |
| 3 | <head> | 3 | <head> |
| 4 | - <title>BookStack</title> | 4 | + <title>{{ isset($pageTitle) ? $pageTitle . ' | ' : '' }}{{ Setting::get('app-name', 'BookStack') }}</title> |
| 5 | 5 | ||
| 6 | <!-- Meta --> | 6 | <!-- Meta --> |
| 7 | <meta name="viewport" content="width=device-width"> | 7 | <meta name="viewport" content="width=device-width"> |
| ... | @@ -9,8 +9,8 @@ | ... | @@ -9,8 +9,8 @@ |
| 9 | <meta charset="utf-8"> | 9 | <meta charset="utf-8"> |
| 10 | 10 | ||
| 11 | <!-- Styles and Fonts --> | 11 | <!-- Styles and Fonts --> |
| 12 | - <link rel="stylesheet" href="{{ elixir('css/styles.css') }}"> | 12 | + <link rel="stylesheet" href="{{ versioned_asset('css/styles.css') }}"> |
| 13 | - <link rel="stylesheet" media="print" href="{{ elixir('css/print-styles.css') }}"> | 13 | + <link rel="stylesheet" media="print" href="{{ versioned_asset('css/print-styles.css') }}"> |
| 14 | <link href='//fonts.googleapis.com/css?family=Roboto:400,400italic,500,500italic,700,700italic,300italic,100,300' rel='stylesheet' type='text/css'> | 14 | <link href='//fonts.googleapis.com/css?family=Roboto:400,400italic,500,500italic,700,700italic,300italic,100,300' rel='stylesheet' type='text/css'> |
| 15 | <link rel="stylesheet" href="/libs/material-design-iconic-font/css/material-design-iconic-font.min.css"> | 15 | <link rel="stylesheet" href="/libs/material-design-iconic-font/css/material-design-iconic-font.min.css"> |
| 16 | 16 | ||
| ... | @@ -79,6 +79,6 @@ | ... | @@ -79,6 +79,6 @@ |
| 79 | </section> | 79 | </section> |
| 80 | 80 | ||
| 81 | @yield('bottom') | 81 | @yield('bottom') |
| 82 | -<script src="{{ elixir('js/common.js') }}"></script> | 82 | +<script src="{{ versioned_asset('js/common.js') }}"></script> |
| 83 | </body> | 83 | </body> |
| 84 | </html> | 84 | </html> | ... | ... |
| ... | @@ -34,11 +34,22 @@ | ... | @@ -34,11 +34,22 @@ |
| 34 | @endif | 34 | @endif |
| 35 | </div> | 35 | </div> |
| 36 | <div class="col-sm-4 col-sm-offset-1"> | 36 | <div class="col-sm-4 col-sm-offset-1"> |
| 37 | + <div id="recents"> | ||
| 38 | + @if($recents) | ||
| 39 | + <div class="margin-top large"> </div> | ||
| 40 | + <h3>Recently Viewed</h3> | ||
| 41 | + @include('partials/entity-list', ['entities' => $recents]) | ||
| 42 | + @endif | ||
| 43 | + </div> | ||
| 37 | <div class="margin-top large"> </div> | 44 | <div class="margin-top large"> </div> |
| 38 | - @if($recents) | 45 | + <div id="popular"> |
| 39 | - <h3>Recently Viewed</h3> | 46 | + <h3>Popular Books</h3> |
| 40 | - @include('partials/entity-list', ['entities' => $recents]) | 47 | + @if(count($popular) > 0) |
| 41 | - @endif | 48 | + @include('partials/entity-list', ['entities' => $popular]) |
| 49 | + @else | ||
| 50 | + <p class="text-muted">The most popular books will appear here.</p> | ||
| 51 | + @endif | ||
| 52 | + </div> | ||
| 42 | </div> | 53 | </div> |
| 43 | </div> | 54 | </div> |
| 44 | </div> | 55 | </div> | ... | ... |
| ... | @@ -58,7 +58,7 @@ | ... | @@ -58,7 +58,7 @@ |
| 58 | <p class="text-muted small"> | 58 | <p class="text-muted small"> |
| 59 | Created {{$book->created_at->diffForHumans()}} @if($book->createdBy) by {{$book->createdBy->name}} @endif | 59 | Created {{$book->created_at->diffForHumans()}} @if($book->createdBy) by {{$book->createdBy->name}} @endif |
| 60 | <br> | 60 | <br> |
| 61 | - Last Updated {{$book->updated_at->diffForHumans()}} @if($book->createdBy) by {{$book->updatedBy->name}} @endif | 61 | + Last Updated {{$book->updated_at->diffForHumans()}} @if($book->updatedBy) by {{$book->updatedBy->name}} @endif |
| 62 | </p> | 62 | </p> |
| 63 | </div> | 63 | </div> |
| 64 | </div> | 64 | </div> | ... | ... |
| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | <h3 class="text-book"><i class="zmdi zmdi-book"></i>{{ $book->name }}</h3> | 2 | <h3 class="text-book"><i class="zmdi zmdi-book"></i>{{ $book->name }}</h3> |
| 3 | <ul class="sortable-page-list sort-list"> | 3 | <ul class="sortable-page-list sort-list"> |
| 4 | @foreach($bookChildren as $bookChild) | 4 | @foreach($bookChildren as $bookChild) |
| 5 | - <li data-id="{{$bookChild->id}}" data-type="{{ $bookChild->getName() }}" class="text-{{ $bookChild->getName() }}"> | 5 | + <li data-id="{{$bookChild->id}}" data-type="{{ $bookChild->getClassName() }}" class="text-{{ $bookChild->getClassName() }}"> |
| 6 | <i class="zmdi {{ $bookChild->isA('chapter') ? 'zmdi-collection-bookmark':'zmdi-file-text'}}"></i>{{ $bookChild->name }} | 6 | <i class="zmdi {{ $bookChild->isA('chapter') ? 'zmdi-collection-bookmark':'zmdi-file-text'}}"></i>{{ $bookChild->name }} |
| 7 | @if($bookChild->isA('chapter')) | 7 | @if($bookChild->isA('chapter')) |
| 8 | <ul> | 8 | <ul> | ... | ... |
| ... | @@ -56,7 +56,7 @@ | ... | @@ -56,7 +56,7 @@ |
| 56 | <p class="text-muted small"> | 56 | <p class="text-muted small"> |
| 57 | Created {{$chapter->created_at->diffForHumans()}} @if($chapter->createdBy) by {{$chapter->createdBy->name}} @endif | 57 | Created {{$chapter->created_at->diffForHumans()}} @if($chapter->createdBy) by {{$chapter->createdBy->name}} @endif |
| 58 | <br> | 58 | <br> |
| 59 | - Last Updated {{$chapter->updated_at->diffForHumans()}} @if($chapter->createdBy) by {{$chapter->updatedBy->name}} @endif | 59 | + Last Updated {{$chapter->updated_at->diffForHumans()}} @if($chapter->updatedBy) by {{$chapter->updatedBy->name}} @endif |
| 60 | </p> | 60 | </p> |
| 61 | </div> | 61 | </div> |
| 62 | <div class="col-md-3 col-md-offset-1"> | 62 | <div class="col-md-3 col-md-offset-1"> | ... | ... |
| ... | @@ -14,6 +14,6 @@ | ... | @@ -14,6 +14,6 @@ |
| 14 | @include('pages/form', ['model' => $page]) | 14 | @include('pages/form', ['model' => $page]) |
| 15 | </form> | 15 | </form> |
| 16 | </div> | 16 | </div> |
| 17 | - <image-manager></image-manager> | 17 | + <image-manager image-type="gallery"></image-manager> |
| 18 | 18 | ||
| 19 | @stop | 19 | @stop |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -32,8 +32,12 @@ | ... | @@ -32,8 +32,12 @@ |
| 32 | @foreach($page->revisions as $revision) | 32 | @foreach($page->revisions as $revision) |
| 33 | <tr> | 33 | <tr> |
| 34 | <td>{{$revision->name}}</td> | 34 | <td>{{$revision->name}}</td> |
| 35 | - <td style="line-height: 0;"><img class="avatar" src="{{ $revision->createdBy->getAvatar(30) }}" alt="{{$revision->createdBy->name}}"></td> | 35 | + <td style="line-height: 0;"> |
| 36 | - <td> {{$revision->createdBy->name}}</td> | 36 | + @if($revision->createdBy) |
| 37 | + <img class="avatar" src="{{ $revision->createdBy->getAvatar(30) }}" alt="{{$revision->createdBy->name}}"> | ||
| 38 | + @endif | ||
| 39 | + </td> | ||
| 40 | + <td> @if($revision->createdBy) {{$revision->createdBy->name}} @else Deleted User @endif</td> | ||
| 37 | <td><small>{{$revision->created_at->format('jS F, Y H:i:s')}} ({{$revision->created_at->diffForHumans()}})</small></td> | 41 | <td><small>{{$revision->created_at->format('jS F, Y H:i:s')}} ({{$revision->created_at->diffForHumans()}})</small></td> |
| 38 | <td> | 42 | <td> |
| 39 | <a href="{{$revision->getUrl()}}" target="_blank">Preview</a> | 43 | <a href="{{$revision->getUrl()}}" target="_blank">Preview</a> | ... | ... |
| ... | @@ -7,12 +7,12 @@ | ... | @@ -7,12 +7,12 @@ |
| 7 | <div class="row"> | 7 | <div class="row"> |
| 8 | <div class="col-sm-6 faded"> | 8 | <div class="col-sm-6 faded"> |
| 9 | <div class="breadcrumbs"> | 9 | <div class="breadcrumbs"> |
| 10 | - <a href="{{$book->getUrl()}}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $book->name }}</a> | 10 | + <a href="{{$book->getUrl()}}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $book->getShortName() }}</a> |
| 11 | @if($page->hasChapter()) | 11 | @if($page->hasChapter()) |
| 12 | <span class="sep">»</span> | 12 | <span class="sep">»</span> |
| 13 | <a href="{{ $page->chapter->getUrl() }}" class="text-chapter text-button"> | 13 | <a href="{{ $page->chapter->getUrl() }}" class="text-chapter text-button"> |
| 14 | <i class="zmdi zmdi-collection-bookmark"></i> | 14 | <i class="zmdi zmdi-collection-bookmark"></i> |
| 15 | - {{$page->chapter->name}} | 15 | + {{$page->chapter->getShortName()}} |
| 16 | </a> | 16 | </a> |
| 17 | @endif | 17 | @endif |
| 18 | </div> | 18 | </div> |
| ... | @@ -53,7 +53,7 @@ | ... | @@ -53,7 +53,7 @@ |
| 53 | <p class="text-muted small"> | 53 | <p class="text-muted small"> |
| 54 | Created {{$page->created_at->diffForHumans()}} @if($page->createdBy) by {{$page->createdBy->name}} @endif | 54 | Created {{$page->created_at->diffForHumans()}} @if($page->createdBy) by {{$page->createdBy->name}} @endif |
| 55 | <br> | 55 | <br> |
| 56 | - Last Updated {{$page->updated_at->diffForHumans()}} @if($page->createdBy) by {{$page->updatedBy->name}} @endif | 56 | + Last Updated {{$page->updated_at->diffForHumans()}} @if($page->updatedBy) by {{$page->updatedBy->name}} @endif |
| 57 | </p> | 57 | </p> |
| 58 | 58 | ||
| 59 | </div> | 59 | </div> | ... | ... |
| ... | @@ -6,8 +6,8 @@ | ... | @@ -6,8 +6,8 @@ |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | @foreach($sidebarTree as $bookChild) | 8 | @foreach($sidebarTree as $bookChild) |
| 9 | - <li class="list-item-{{ $bookChild->getName() }} {{ $bookChild->getName() }}"> | 9 | + <li class="list-item-{{ $bookChild->getClassName() }} {{ $bookChild->getClassName() }}"> |
| 10 | - <a href="{{$bookChild->getUrl()}}" class="{{ $bookChild->getName() }} {{ $current->matches($bookChild)? 'selected' : '' }}"> | 10 | + <a href="{{$bookChild->getUrl()}}" class="{{ $bookChild->getClassName() }} {{ $current->matches($bookChild)? 'selected' : '' }}"> |
| 11 | @if($bookChild->isA('chapter'))<i class="zmdi zmdi-collection-bookmark"></i>@else <i class="zmdi zmdi-file-text"></i>@endif{{ $bookChild->name }} | 11 | @if($bookChild->isA('chapter'))<i class="zmdi zmdi-collection-bookmark"></i>@else <i class="zmdi zmdi-file-text"></i>@endif{{ $bookChild->name }} |
| 12 | </a> | 12 | </a> |
| 13 | 13 | ... | ... |
| ... | @@ -10,6 +10,8 @@ | ... | @@ -10,6 +10,8 @@ |
| 10 | <div class="right"> | 10 | <div class="right"> |
| 11 | @if($activity->user) | 11 | @if($activity->user) |
| 12 | {{$activity->user->name}} | 12 | {{$activity->user->name}} |
| 13 | + @else | ||
| 14 | + A deleted user | ||
| 13 | @endif | 15 | @endif |
| 14 | 16 | ||
| 15 | {{ $activity->getText() }} | 17 | {{ $activity->getText() }} | ... | ... |
| 1 | 1 | ||
| 2 | @if(count($entities) > 0) | 2 | @if(count($entities) > 0) |
| 3 | - @foreach($entities as $entity) | 3 | + @foreach($entities as $index => $entity) |
| 4 | @if($entity->isA('page')) | 4 | @if($entity->isA('page')) |
| 5 | @include('pages/list-item', ['page' => $entity]) | 5 | @include('pages/list-item', ['page' => $entity]) |
| 6 | @elseif($entity->isA('book')) | 6 | @elseif($entity->isA('book')) |
| ... | @@ -8,7 +8,11 @@ | ... | @@ -8,7 +8,11 @@ |
| 8 | @elseif($entity->isA('chapter')) | 8 | @elseif($entity->isA('chapter')) |
| 9 | @include('chapters/list-item', ['chapter' => $entity, 'hidePages' => true]) | 9 | @include('chapters/list-item', ['chapter' => $entity, 'hidePages' => true]) |
| 10 | @endif | 10 | @endif |
| 11 | - <hr> | 11 | + |
| 12 | + @if($index !== count($entities) - 1) | ||
| 13 | + <hr> | ||
| 14 | + @endif | ||
| 15 | + | ||
| 12 | @endforeach | 16 | @endforeach |
| 13 | @else | 17 | @else |
| 14 | <p class="text-muted"> | 18 | <p class="text-muted"> | ... | ... |
| ... | @@ -23,12 +23,17 @@ | ... | @@ -23,12 +23,17 @@ |
| 23 | <label>Allow public viewing?</label> | 23 | <label>Allow public viewing?</label> |
| 24 | <toggle-switch name="setting-app-public" value="{{ Setting::get('app-public') }}"></toggle-switch> | 24 | <toggle-switch name="setting-app-public" value="{{ Setting::get('app-public') }}"></toggle-switch> |
| 25 | </div> | 25 | </div> |
| 26 | + <div class="form-group"> | ||
| 27 | + <label>Enable higher security image uploads?</label> | ||
| 28 | + <p class="small">For performance reasons, all images are public by default, This option adds a random, hard-to-guess characters in front of image names. Ensure directory indexes are not enabled to prevent easy access.</p> | ||
| 29 | + <toggle-switch name="setting-app-secure-images" value="{{ Setting::get('app-secure-images') }}"></toggle-switch> | ||
| 30 | + </div> | ||
| 26 | </div> | 31 | </div> |
| 27 | <div class="col-md-6"> | 32 | <div class="col-md-6"> |
| 28 | <div class="form-group" id="logo-control"> | 33 | <div class="form-group" id="logo-control"> |
| 29 | <label for="setting-app-logo">Application Logo</label> | 34 | <label for="setting-app-logo">Application Logo</label> |
| 30 | - <p class="small">This image should be 43px in height. </p> | 35 | + <p class="small">This image should be 43px in height. <br>Large images will be scaled down.</p> |
| 31 | - <image-picker current-image="{{ Setting::get('app-logo', '') }}" default-image="/logo.png" name="setting-app-logo" image-class="logo-image"></image-picker> | 36 | + <image-picker resize-height="43" resize-width="200" current-image="{{ Setting::get('app-logo', '') }}" default-image="/logo.png" name="setting-app-logo" image-class="logo-image"></image-picker> |
| 32 | </div> | 37 | </div> |
| 33 | </div> | 38 | </div> |
| 34 | </div> | 39 | </div> |
| ... | @@ -57,7 +62,7 @@ | ... | @@ -57,7 +62,7 @@ |
| 57 | </select> | 62 | </select> |
| 58 | </div> | 63 | </div> |
| 59 | <div class="form-group"> | 64 | <div class="form-group"> |
| 60 | - <label for="setting-registration-confirmation">Require Email Confirmation?</label> | 65 | + <label for="setting-registration-confirmation">Require email confirmation?</label> |
| 61 | <p class="small">If domain restriction is used then email confirmation will be required and the below value will be ignored.</p> | 66 | <p class="small">If domain restriction is used then email confirmation will be required and the below value will be ignored.</p> |
| 62 | <toggle-switch name="setting-registration-confirmation" value="{{ Setting::get('registration-confirmation') }}"></toggle-switch> | 67 | <toggle-switch name="setting-registration-confirmation" value="{{ Setting::get('registration-confirmation') }}"></toggle-switch> |
| 63 | </div> | 68 | </div> |
| ... | @@ -81,6 +86,6 @@ | ... | @@ -81,6 +86,6 @@ |
| 81 | 86 | ||
| 82 | </div> | 87 | </div> |
| 83 | 88 | ||
| 84 | -<image-manager></image-manager> | 89 | +<image-manager image-type="system"></image-manager> |
| 85 | 90 | ||
| 86 | @stop | 91 | @stop | ... | ... |
| ... | @@ -19,26 +19,25 @@ | ... | @@ -19,26 +19,25 @@ |
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | <div class="container small"> | 21 | <div class="container small"> |
| 22 | - | 22 | + <form action="/users/{{$user->id}}" method="post"> |
| 23 | <div class="row"> | 23 | <div class="row"> |
| 24 | <div class="col-md-6"> | 24 | <div class="col-md-6"> |
| 25 | <h1>Edit {{ $user->id === $currentUser->id ? 'Profile' : 'User' }}</h1> | 25 | <h1>Edit {{ $user->id === $currentUser->id ? 'Profile' : 'User' }}</h1> |
| 26 | - <form action="/users/{{$user->id}}" method="post"> | 26 | + {!! csrf_field() !!} |
| 27 | - {!! csrf_field() !!} | 27 | + <input type="hidden" name="_method" value="put"> |
| 28 | - <input type="hidden" name="_method" value="put"> | 28 | + @include('users/form', ['model' => $user]) |
| 29 | - @include('users/form', ['model' => $user]) | 29 | + |
| 30 | - </form> | ||
| 31 | </div> | 30 | </div> |
| 32 | <div class="col-md-6"> | 31 | <div class="col-md-6"> |
| 33 | <h1> </h1> | 32 | <h1> </h1> |
| 34 | - <div class="shaded padded margin-top"> | 33 | + <div class="form-group" id="logo-control"> |
| 35 | - <p> | 34 | + <label for="user-avatar">User Avatar</label> |
| 36 | - <img class="avatar" src="{{ $user->getAvatar(80) }}" alt="{{ $user->name }}"> | 35 | + <p class="small">This image should be approx 256px square.</p> |
| 37 | - </p> | 36 | + <image-picker resize-height="512" resize-width="512" current-image="{{ $user->getAvatar(80) }}" current-id="{{ $user->image_id }}" default-image="/user_avatar.png" name="image_id" show-remove="false" image-class="avatar large"></image-picker> |
| 38 | - <p class="text-muted">You can change your profile picture at <a href="http://en.gravatar.com/">Gravatar</a>.</p> | ||
| 39 | </div> | 37 | </div> |
| 40 | </div> | 38 | </div> |
| 41 | </div> | 39 | </div> |
| 40 | + </form> | ||
| 42 | 41 | ||
| 43 | <hr class="margin-top large"> | 42 | <hr class="margin-top large"> |
| 44 | 43 | ||
| ... | @@ -80,5 +79,5 @@ | ... | @@ -80,5 +79,5 @@ |
| 80 | </div> | 79 | </div> |
| 81 | 80 | ||
| 82 | <p class="margin-top large"><br></p> | 81 | <p class="margin-top large"><br></p> |
| 83 | - | 82 | + <image-manager image-type="user"></image-manager> |
| 84 | @stop | 83 | @stop | ... | ... |
| ... | @@ -36,4 +36,5 @@ | ... | @@ -36,4 +36,5 @@ |
| 36 | <div class="form-group"> | 36 | <div class="form-group"> |
| 37 | <a href="/users" class="button muted">Cancel</a> | 37 | <a href="/users" class="button muted">Cancel</a> |
| 38 | <button class="button pos" type="submit">Save</button> | 38 | <button class="button pos" type="submit">Save</button> |
| 39 | -</div> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 39 | +</div> | ||
| 40 | + | ... | ... |
tests/ActivityTrackingTest.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use Illuminate\Foundation\Testing\WithoutMiddleware; | ||
| 4 | +use Illuminate\Foundation\Testing\DatabaseMigrations; | ||
| 5 | +use Illuminate\Foundation\Testing\DatabaseTransactions; | ||
| 6 | + | ||
| 7 | +class ActivityTrackingTest extends TestCase | ||
| 8 | +{ | ||
| 9 | + | ||
| 10 | + public function testRecentlyViewedBooks() | ||
| 11 | + { | ||
| 12 | + $books = \BookStack\Book::all()->take(10); | ||
| 13 | + | ||
| 14 | + $this->asAdmin()->visit('/books') | ||
| 15 | + ->dontSeeInElement('#recents', $books[0]->name) | ||
| 16 | + ->dontSeeInElement('#recents', $books[1]->name) | ||
| 17 | + ->visit($books[0]->getUrl()) | ||
| 18 | + ->visit($books[1]->getUrl()) | ||
| 19 | + ->visit('/books') | ||
| 20 | + ->seeInElement('#recents', $books[0]->name) | ||
| 21 | + ->seeInElement('#recents', $books[1]->name); | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + public function testPopularBooks() | ||
| 25 | + { | ||
| 26 | + $books = \BookStack\Book::all()->take(10); | ||
| 27 | + | ||
| 28 | + $this->asAdmin()->visit('/books') | ||
| 29 | + ->dontSeeInElement('#popular', $books[0]->name) | ||
| 30 | + ->dontSeeInElement('#popular', $books[1]->name) | ||
| 31 | + ->visit($books[0]->getUrl()) | ||
| 32 | + ->visit($books[1]->getUrl()) | ||
| 33 | + ->visit($books[0]->getUrl()) | ||
| 34 | + ->visit('/books') | ||
| 35 | + ->seeInNthElement('#popular .book', 0, $books[0]->name) | ||
| 36 | + ->seeInNthElement('#popular .book', 1, $books[1]->name); | ||
| 37 | + } | ||
| 38 | +} |
| ... | @@ -171,4 +171,43 @@ class EntityTest extends TestCase | ... | @@ -171,4 +171,43 @@ class EntityTest extends TestCase |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | 173 | ||
| 174 | + public function testEntitiesViewableAfterCreatorDeletion() | ||
| 175 | + { | ||
| 176 | + // Create required assets and revisions | ||
| 177 | + $creator = $this->getNewUser(); | ||
| 178 | + $updater = $this->getNewUser(); | ||
| 179 | + $entities = $this->createEntityChainBelongingToUser($creator, $updater); | ||
| 180 | + $this->actingAs($creator); | ||
| 181 | + app('BookStack\Repos\UserRepo')->destroy($creator); | ||
| 182 | + app('BookStack\Repos\PageRepo')->saveRevision($entities['page']); | ||
| 183 | + | ||
| 184 | + $this->checkEntitiesViewable($entities); | ||
| 185 | + } | ||
| 186 | + | ||
| 187 | + public function testEntitiesViewableAfterUpdaterDeletion() | ||
| 188 | + { | ||
| 189 | + // Create required assets and revisions | ||
| 190 | + $creator = $this->getNewUser(); | ||
| 191 | + $updater = $this->getNewUser(); | ||
| 192 | + $entities = $this->createEntityChainBelongingToUser($creator, $updater); | ||
| 193 | + $this->actingAs($updater); | ||
| 194 | + app('BookStack\Repos\UserRepo')->destroy($updater); | ||
| 195 | + app('BookStack\Repos\PageRepo')->saveRevision($entities['page']); | ||
| 196 | + | ||
| 197 | + $this->checkEntitiesViewable($entities); | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + private function checkEntitiesViewable($entities) | ||
| 201 | + { | ||
| 202 | + // Check pages and books are visible. | ||
| 203 | + $this->asAdmin(); | ||
| 204 | + $this->visit($entities['book']->getUrl())->seeStatusCode(200) | ||
| 205 | + ->visit($entities['chapter']->getUrl())->seeStatusCode(200) | ||
| 206 | + ->visit($entities['page']->getUrl())->seeStatusCode(200); | ||
| 207 | + // Check revision listing shows no errors. | ||
| 208 | + $this->visit($entities['page']->getUrl()) | ||
| 209 | + ->click('Revisions')->seeStatusCode(200); | ||
| 210 | + } | ||
| 211 | + | ||
| 212 | + | ||
| 174 | } | 213 | } | ... | ... |
| ... | @@ -48,4 +48,65 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase | ... | @@ -48,4 +48,65 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase |
| 48 | $settings->put($key, $value); | 48 | $settings->put($key, $value); |
| 49 | } | 49 | } |
| 50 | } | 50 | } |
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * Create a group of entities that belong to a specific user. | ||
| 54 | + * @param $creatorUser | ||
| 55 | + * @param $updaterUser | ||
| 56 | + * @return array | ||
| 57 | + */ | ||
| 58 | + protected function createEntityChainBelongingToUser($creatorUser, $updaterUser = false) | ||
| 59 | + { | ||
| 60 | + if ($updaterUser === false) $updaterUser = $creatorUser; | ||
| 61 | + $book = factory(BookStack\Book::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id]); | ||
| 62 | + $chapter = factory(BookStack\Chapter::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id]); | ||
| 63 | + $page = factory(BookStack\Page::class)->create(['created_by' => $creatorUser->id, 'updated_by' => $updaterUser->id, 'book_id' => $book->id]); | ||
| 64 | + $book->chapters()->saveMany([$chapter]); | ||
| 65 | + $chapter->pages()->saveMany([$page]); | ||
| 66 | + return [ | ||
| 67 | + 'book' => $book, | ||
| 68 | + 'chapter' => $chapter, | ||
| 69 | + 'page' => $page | ||
| 70 | + ]; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + /** | ||
| 74 | + * Quick way to create a new user | ||
| 75 | + * @param array $attributes | ||
| 76 | + * @return mixed | ||
| 77 | + */ | ||
| 78 | + protected function getNewUser($attributes = []) | ||
| 79 | + { | ||
| 80 | + $user = factory(\BookStack\User::class)->create($attributes); | ||
| 81 | + $userRepo = app('BookStack\Repos\UserRepo'); | ||
| 82 | + $userRepo->attachDefaultRole($user); | ||
| 83 | + return $user; | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + /** | ||
| 87 | + * Assert that a given string is seen inside an element. | ||
| 88 | + * | ||
| 89 | + * @param bool|string|null $element | ||
| 90 | + * @param integer $position | ||
| 91 | + * @param string $text | ||
| 92 | + * @param bool $negate | ||
| 93 | + * @return $this | ||
| 94 | + */ | ||
| 95 | + protected function seeInNthElement($element, $position, $text, $negate = false) | ||
| 96 | + { | ||
| 97 | + $method = $negate ? 'assertNotRegExp' : 'assertRegExp'; | ||
| 98 | + | ||
| 99 | + $rawPattern = preg_quote($text, '/'); | ||
| 100 | + | ||
| 101 | + $escapedPattern = preg_quote(e($text), '/'); | ||
| 102 | + | ||
| 103 | + $content = $this->crawler->filter($element)->eq($position)->html(); | ||
| 104 | + | ||
| 105 | + $pattern = $rawPattern == $escapedPattern | ||
| 106 | + ? $rawPattern : "({$rawPattern}|{$escapedPattern})"; | ||
| 107 | + | ||
| 108 | + $this->$method("/$pattern/i", $content); | ||
| 109 | + | ||
| 110 | + return $this; | ||
| 111 | + } | ||
| 51 | } | 112 | } | ... | ... |
-
Please register or sign in to post a comment