/**
* ImageController constructor.
- * @param Image $image
- * @param File $file
+ * @param Image $image
+ * @param File $file
* @param ImageRepo $imageRepo
*/
public function __construct(Image $image, File $file, ImageRepo $imageRepo)
/**
* Get all images for a specific type, Paginated
+ * @param string $type
* @param int $page
* @return \Illuminate\Http\JsonResponse
*/
/**
* Handles image uploads for use on pages.
- * @param string $type
+ * @param string $type
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
{
$this->checkPermission('image-create-all');
$this->validate($request, [
- 'file' => 'image|mimes:jpeg,gif,png'
+ 'file' => 'image|mimes:jpeg,gif,png',
+ 'uploaded_to' => 'integer|exists:pages,id'
]);
$imageUpload = $request->file('file');
try {
- $image = $this->imageRepo->saveNew($imageUpload, $type);
+ $uploadedTo = $request->has('uploaded_to') ? $request->get('uploaded_to') : 0;
+ $image = $this->imageRepo->saveNew($imageUpload, $type, $uploadedTo);
} catch (ImageUploadException $e) {
return response($e->getMessage(), 500);
}
/**
* Update image details
- * @param $imageId
+ * @param integer $imageId
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
/**
* Deletes an image and all thumbnail/image files
* @param PageRepo $pageRepo
- * @param Request $request
- * @param int $id
+ * @param Request $request
+ * @param int $id
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(PageRepo $pageRepo, Request $request, $id)
use BookStack\Image;
use BookStack\Services\ImageService;
+use BookStack\Services\RestrictionService;
use Setting;
use Symfony\Component\HttpFoundation\File\UploadedFile;
protected $image;
protected $imageService;
+ protected $restictionService;
/**
* ImageRepo constructor.
- * @param Image $image
+ * @param Image $image
* @param ImageService $imageService
+ * @param RestrictionService $restrictionService
*/
- public function __construct(Image $image, ImageService $imageService)
+ public function __construct(Image $image, ImageService $imageService, RestrictionService $restrictionService)
{
$this->image = $image;
$this->imageService = $imageService;
+ $this->restictionService = $restrictionService;
}
return $this->image->findOrFail($id);
}
-
/**
* Gets a load images paginated, filtered by image type.
* @param string $type
- * @param int $page
- * @param int $pageSize
- * @param bool|int $userFilter
+ * @param int $page
+ * @param int $pageSize
+ * @param bool|int $userFilter
* @return array
*/
public function getPaginatedByType($type, $page = 0, $pageSize = 24, $userFilter = false)
$images = $images->where('created_by', '=', $userFilter);
}
+ $images = $this->restictionService->filterRelatedPages($images, 'images', 'uploaded_to');
$images = $images->orderBy('created_at', 'desc')->skip($pageSize * $page)->take($pageSize + 1)->get();
$hasMore = count($images) > $pageSize;
/**
* Save a new image into storage and return the new image.
* @param UploadedFile $uploadFile
- * @param string $type
+ * @param string $type
+ * @param int $uploadedTo
* @return Image
*/
- public function saveNew(UploadedFile $uploadFile, $type)
+ public function saveNew(UploadedFile $uploadFile, $type, $uploadedTo = 0)
{
- $image = $this->imageService->saveNewFromUpload($uploadFile, $type);
+ $image = $this->imageService->saveNewFromUpload($uploadFile, $type, $uploadedTo);
$this->loadThumbs($image);
return $image;
}
* Checks the cache then storage to avoid creating / accessing the filesystem on every check.
*
* @param Image $image
- * @param int $width
- * @param int $height
- * @param bool $keepRatio
+ * @param int $width
+ * @param int $height
+ * @param bool $keepRatio
* @return string
*/
public function getThumbnail(Image $image, $width = 220, $height = 220, $keepRatio = false)
/**
* Saves a new image from an upload.
* @param UploadedFile $uploadedFile
- * @param string $type
+ * @param string $type
+ * @param int $uploadedTo
* @return mixed
+ * @throws ImageUploadException
*/
- public function saveNewFromUpload(UploadedFile $uploadedFile, $type)
+ public function saveNewFromUpload(UploadedFile $uploadedFile, $type, $uploadedTo = 0)
{
$imageName = $uploadedFile->getClientOriginalName();
$imageData = file_get_contents($uploadedFile->getRealPath());
- return $this->saveNew($imageName, $imageData, $type);
+ return $this->saveNew($imageName, $imageData, $type, $uploadedTo);
}
* @param string $imageName
* @param string $imageData
* @param string $type
+ * @param int $uploadedTo
* @return Image
* @throws ImageUploadException
*/
- private function saveNew($imageName, $imageData, $type)
+ private function saveNew($imageName, $imageData, $type, $uploadedTo = 0)
{
$storage = $this->getStorage();
$secureUploads = setting('app-secure-images');
'name' => $imageName,
'path' => $fullPath,
'url' => $this->getPublicUrl($fullPath),
- 'type' => $type
+ 'type' => $type,
+ 'uploaded_to' => $uploadedTo
];
if (auth()->user() && auth()->user()->id !== 0) {
public function enforcePageRestrictions($query, $action = 'view')
{
// Prevent drafts being visible to others.
- $query = $query->where(function($query) {
+ $query = $query->where(function ($query) {
$query->where('draft', '=', false);
if ($this->currentUser) {
- $query->orWhere(function($query) {
+ $query->orWhere(function ($query) {
$query->where('draft', '=', true)->where('created_by', '=', $this->currentUser->id);
});
}
});
}
+ /**
+ * Filters pages that are a direct relation to another item.
+ * @param $query
+ * @param $tableName
+ * @param $entityIdColumn
+ * @return mixed
+ */
+ public function filterRelatedPages($query, $tableName, $entityIdColumn)
+ {
+ if ($this->isAdmin) return $query;
+ $this->currentAction = 'view';
+ $tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn];
+ return $query->where(function ($query) use (&$tableDetails) {
+ $query->where(function ($query) use (&$tableDetails) {
+ $query->whereExists(function ($query) use (&$tableDetails) {
+ $query->select('*')->from('pages')->whereRaw('pages.id=' . $tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'])
+ ->where(function ($query) {
+ $this->pageRestrictionQuery($query);
+ });
+ })->orWhere($tableDetails['entityIdColumn'], '=', 0);
+ });
+ });
+ }
+
/**
* The query to check the restrictions on an entity.
* @param $query
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
-class ImageEntitiesAndPageDrafts extends Migration
+class AddPageDrafts extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
- Schema::table('images', function (Blueprint $table) {
- $table->string('entity_type', 100);
- $table->integer('entity_id');
- $table->index(['entity_type', 'entity_id']);
- });
-
Schema::table('pages', function(Blueprint $table) {
$table->boolean('draft')->default(false);
$table->index('draft');
*/
public function down()
{
- Schema::table('images', function (Blueprint $table) {
- $table->dropIndex(['entity_type', 'entity_id']);
- $table->dropColumn('entity_type');
- $table->dropColumn('entity_id');
- });
-
Schema::table('pages', function (Blueprint $table) {
$table->dropColumn('draft');
});
$scope.hasMore = false;
$scope.imageUpdateSuccess = false;
$scope.imageDeleteSuccess = false;
+ $scope.uploadedTo = $attrs.uploadedTo;
var page = 0;
var previousClickTime = 0;
scope: {
uploadUrl: '@',
eventSuccess: '=',
- eventError: '='
+ eventError: '=',
+ uploadedTo: '@'
},
link: function (scope, element, attrs) {
var dropZone = new DropZone(element[0].querySelector('.dropzone-container'), {
dz.on('sending', function (file, xhr, data) {
var token = window.document.querySelector('meta[name=token]').getAttribute('content');
data.append('_token', token);
+ var uploadedTo = typeof scope.uploadedTo === 'undefined' ? 0 : scope.uploadedTo;
+ data.append('uploaded_to', uploadedTo);
});
if (typeof scope.eventSuccess !== 'undefined') dz.on('success', scope.eventSuccess);
dz.on('success', function (file, data) {
@include('pages/form', ['model' => $draft])
</form>
</div>
- @include('partials/image-manager', ['imageType' => 'gallery'])
+ @include('partials/image-manager', ['imageType' => 'gallery', 'uploaded_to' => $draft->id])
@stop
\ No newline at end of file
@include('pages/form', ['model' => $page])
</form>
</div>
- @include('partials/image-manager', ['imageType' => 'gallery'])
+ @include('partials/image-manager', ['imageType' => 'gallery', 'uploaded_to' => $page->id])
@stop
\ No newline at end of file
-<div id="image-manager" image-type="{{ $imageType }}" ng-controller="ImageManagerController">
+<div id="image-manager" image-type="{{ $imageType }}" ng-controller="ImageManagerController" uploaded-to="{{ $uploaded_to or 0 }}">
<div class="overlay anim-slide" ng-show="showing" ng-cloak ng-click="hide()">
<div class="image-manager-body" ng-click="$event.stopPropagation()">
<div class="image-manager-sidebar">
<h2>Images</h2>
- <drop-zone upload-url="@{{getUploadUrl()}}" event-success="uploadSuccess"></drop-zone>
+ <drop-zone upload-url="@{{getUploadUrl()}}" uploaded-to="@{{uploadedTo}}" event-success="uploadSuccess"></drop-zone>
<div class="image-manager-details anim fadeIn" ng-show="selectedImage">
<hr class="even">