FEATURE #1423: add uploading of title photo for content pages
This commit is contained in:
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin;
|
|||||||
use App\Enumerations\ActiveContentStatuses;
|
use App\Enumerations\ActiveContentStatuses;
|
||||||
use App\Http\Requests\CreateNewContentRequest;
|
use App\Http\Requests\CreateNewContentRequest;
|
||||||
use App\Models\Content;
|
use App\Models\Content;
|
||||||
|
use App\Models\File;
|
||||||
use App\Models\Module;
|
use App\Models\Module;
|
||||||
use App\Models\Template;
|
use App\Models\Template;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
@@ -11,6 +12,22 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|||||||
|
|
||||||
class CreateNewContent extends Controller
|
class CreateNewContent extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var File
|
||||||
|
*/
|
||||||
|
private $file;
|
||||||
|
/**
|
||||||
|
* @var Content
|
||||||
|
*/
|
||||||
|
private $content;
|
||||||
|
|
||||||
|
public function __construct(File $file, Content $content)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->file = $file;
|
||||||
|
$this->content = $content;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display form for new content page
|
* Display form for new content page
|
||||||
*
|
*
|
||||||
@@ -29,16 +46,15 @@ class CreateNewContent extends Controller
|
|||||||
->get();
|
->get();
|
||||||
|
|
||||||
// create default content object
|
// create default content object
|
||||||
$page = new Content();
|
$this->content->status = Content::STATUS_DRAFT;
|
||||||
$page->status = Content::STATUS_DRAFT;
|
|
||||||
|
|
||||||
// render view
|
// render view
|
||||||
return view('admin.content.new', [
|
return view('admin.content.new', [
|
||||||
'contentStatuses' => $statuses,
|
'contentStatuses' => $statuses,
|
||||||
'templates' => $templates,
|
'templates' => $templates,
|
||||||
'moduleId' => $moduleId,
|
'moduleId' => $moduleId,
|
||||||
'page' => $page,
|
'page' => $this->content,
|
||||||
'rootPages' => $page->rootPages(),
|
'rootPages' => $this->content->rootPages(),
|
||||||
'moduleName' => trans($module->name),
|
'moduleName' => trans($module->name),
|
||||||
'formSectionNames' => call_user_func([$module->handler, 'getExtendedFormSections']),
|
'formSectionNames' => call_user_func([$module->handler, 'getExtendedFormSections']),
|
||||||
'formSections' => call_user_func([$module->handler, 'getExtendedFormInputsCreate']),
|
'formSections' => call_user_func([$module->handler, 'getExtendedFormInputsCreate']),
|
||||||
@@ -82,6 +98,13 @@ class CreateNewContent extends Controller
|
|||||||
$page->parent_id = $request->parentPage;
|
$page->parent_id = $request->parentPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// upload file - if provided
|
||||||
|
if ($request->hasFile('titlePhoto')) {
|
||||||
|
$file = $this->file->upload($request->file('titlePhoto'), $request);
|
||||||
|
|
||||||
|
$page->title_photo = $file['filename'];
|
||||||
|
}
|
||||||
|
|
||||||
// save module-specific stuff
|
// save module-specific stuff
|
||||||
call_user_func_array([$module->handler, 'createNew'], [&$page, $request]);
|
call_user_func_array([$module->handler, 'createNew'], [&$page, $request]);
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ use App\Enumerations\ModulesHandlerToId;
|
|||||||
use App\Http\Requests\EditContentRequest;
|
use App\Http\Requests\EditContentRequest;
|
||||||
use App\Models\Content;
|
use App\Models\Content;
|
||||||
use App\Models\ContentHistory;
|
use App\Models\ContentHistory;
|
||||||
|
use App\Models\File;
|
||||||
use App\Models\Template;
|
use App\Models\Template;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Modules\StaticPages\Http\Requests\EditStaticPageRequest;
|
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
class EditContent extends Controller
|
class EditContent extends Controller
|
||||||
@@ -17,10 +17,15 @@ class EditContent extends Controller
|
|||||||
* @var ContentHistory
|
* @var ContentHistory
|
||||||
*/
|
*/
|
||||||
private $history;
|
private $history;
|
||||||
|
/**
|
||||||
|
* @var File
|
||||||
|
*/
|
||||||
|
private $file;
|
||||||
|
|
||||||
public function __construct(ContentHistory $history)
|
public function __construct(ContentHistory $history, File $file)
|
||||||
{
|
{
|
||||||
$this->history = $history;
|
$this->history = $history;
|
||||||
|
$this->file = $file;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,6 +86,14 @@ class EditContent extends Controller
|
|||||||
|
|
||||||
$request->url = Str::slug($request->url);
|
$request->url = Str::slug($request->url);
|
||||||
$request->parentPage = $request->parentPage ? $request->parentPage : null;
|
$request->parentPage = $request->parentPage ? $request->parentPage : null;
|
||||||
|
$request->titlePhotoFilename = $page->title_photo;
|
||||||
|
|
||||||
|
// upload file - if provided
|
||||||
|
if ($request->hasFile('titlePhoto')) {
|
||||||
|
$file = $this->file->upload($request->file('titlePhoto'), $request);
|
||||||
|
|
||||||
|
$request->titlePhotoFilename = $file['filename'];
|
||||||
|
}
|
||||||
|
|
||||||
// array of fields in database and fields from request
|
// array of fields in database and fields from request
|
||||||
$fields = [
|
$fields = [
|
||||||
@@ -93,7 +106,8 @@ class EditContent extends Controller
|
|||||||
'meta_description' => 'metaDescription',
|
'meta_description' => 'metaDescription',
|
||||||
'content' => 'pageContent',
|
'content' => 'pageContent',
|
||||||
'parent_id' => 'parentPage',
|
'parent_id' => 'parentPage',
|
||||||
'status' => 'status'
|
'status' => 'status',
|
||||||
|
'title_photo' => 'titlePhotoFilename'
|
||||||
];
|
];
|
||||||
|
|
||||||
// save new values with history
|
// save new values with history
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ class CreateNewContentRequest extends Request
|
|||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'title' => 'required',
|
'titlePhoto' => 'image',
|
||||||
'url' => 'required|unique:contents,url',
|
'title' => 'required',
|
||||||
'template' => 'required|exists:templates,template_name',
|
'url' => 'required|unique:contents,url',
|
||||||
'published_from' => 'date',
|
'template' => 'required|exists:templates,template_name',
|
||||||
'published_to' => 'date',
|
'status' => 'required|in:draft,protected,public',
|
||||||
'title_photo' => 'exists:files,id',
|
'title_photo' => 'exists:files,id',
|
||||||
'module_settings' => 'json',
|
'parentPage' => 'exists:contents,id',
|
||||||
'status' => 'required|in:draft,protected,public',
|
'published_from' => 'date',
|
||||||
'parentPage' => 'exists:contents,id'
|
'published_to' => 'date',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-11
@@ -3,7 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Events\UploadFile;
|
use App\Events\UploadFile;
|
||||||
use App\Http\Requests\UploadRequest;
|
use App\Http\Requests\Request;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
@@ -49,13 +49,13 @@ class File extends Model
|
|||||||
/**
|
/**
|
||||||
* Saves file into FS and creates new record in database
|
* Saves file into FS and creates new record in database
|
||||||
*
|
*
|
||||||
* @param UploadedFile $file
|
* @param UploadedFile $file
|
||||||
* @param UploadRequest $request
|
* @param Request $request
|
||||||
*
|
*
|
||||||
* @return array associative array - key 'file' is type of SymphonyFile and contains info about real file, key 'id'
|
* @return array associative array - key 'file' is type of SymphonyFile and contains info about real file, key 'id'
|
||||||
* is ID of row in files table
|
* is ID of row in files table
|
||||||
*/
|
*/
|
||||||
public function upload(UploadedFile $file, UploadRequest $request)
|
public function upload(UploadedFile $file, Request $request)
|
||||||
{
|
{
|
||||||
$destination = config('app.upload_path');
|
$destination = config('app.upload_path');
|
||||||
$filename = $this->getFilename($file);
|
$filename = $this->getFilename($file);
|
||||||
@@ -70,8 +70,9 @@ class File extends Model
|
|||||||
Event::fire(new UploadFile($uploadedFile, $id));
|
Event::fire(new UploadFile($uploadedFile, $id));
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'file' => $file,
|
'filename' => $filename,
|
||||||
'id' => $id
|
'file' => $file,
|
||||||
|
'id' => $id
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,12 +82,12 @@ class File extends Model
|
|||||||
* This file saves new record into database. It also calculates hash of given file, obtains MIME type etc.
|
* This file saves new record into database. It also calculates hash of given file, obtains MIME type etc.
|
||||||
*
|
*
|
||||||
* @param SymphonyFile $file
|
* @param SymphonyFile $file
|
||||||
* @param UploadRequest $request
|
* @param Request $request
|
||||||
* @param $originalFilename
|
* @param $originalFilename
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
protected function saveIntoDatabase(SymphonyFile $file, UploadRequest $request, $originalFilename)
|
protected function saveIntoDatabase(SymphonyFile $file, Request $request, $originalFilename)
|
||||||
{
|
{
|
||||||
// get path and hash of uploaded file
|
// get path and hash of uploaded file
|
||||||
$path = config('app.upload_path') . DIRECTORY_SEPARATOR . $file->getFilename();
|
$path = config('app.upload_path') . DIRECTORY_SEPARATOR . $file->getFilename();
|
||||||
@@ -101,13 +102,14 @@ class File extends Model
|
|||||||
$newFile->hash_algorithm = self::HASH_ALGORITHM;
|
$newFile->hash_algorithm = self::HASH_ALGORITHM;
|
||||||
$newFile->mime_type = $file->getMimeType();
|
$newFile->mime_type = $file->getMimeType();
|
||||||
$newFile->file_size = $file->getSize();
|
$newFile->file_size = $file->getSize();
|
||||||
$newFile->directory_id = $request->directoryId;
|
|
||||||
|
|
||||||
// save optional fields
|
// save optional fields
|
||||||
$optionalFields = ['description', 'keywords'];
|
$optionalFields = ['description', 'keywords', 'directoryId'];
|
||||||
foreach ($optionalFields as $field) {
|
foreach ($optionalFields as $field) {
|
||||||
if ($request->has($field)) {
|
if ($request->has($field)) {
|
||||||
$newFile->$field = $request->$field;
|
|
||||||
|
$snakeField = snake_case($field);
|
||||||
|
$newFile->$snakeField = $request->$field;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class ChangeContentTitleImageIdForFilename extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
|
||||||
|
try {
|
||||||
|
Schema::table('contents', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('fk_content_file1');
|
||||||
|
});
|
||||||
|
} catch (\Illuminate\Database\QueryException $e) {
|
||||||
|
// probably foreign does not exist, try to remove one from migration
|
||||||
|
|
||||||
|
try {
|
||||||
|
Schema::table('contents', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('contents_title_photo_foreign');
|
||||||
|
});
|
||||||
|
} catch (\Illuminate\Database\QueryException $ex) {
|
||||||
|
// ignore this error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// force Doctrine to consider enum type as string
|
||||||
|
$platform = Schema::getConnection()
|
||||||
|
->getDoctrineSchemaManager()
|
||||||
|
->getDatabasePlatform();
|
||||||
|
$platform->registerDoctrineTypeMapping('enum', 'string');
|
||||||
|
|
||||||
|
Schema::table('contents', function (Blueprint $table) {
|
||||||
|
$table->string('title_photo', 128)
|
||||||
|
->nullable()
|
||||||
|
->default(null)
|
||||||
|
->comment('This photo is supposed to be displayed e.g. on list of all pages.')
|
||||||
|
->change();
|
||||||
|
|
||||||
|
$table->foreign('title_photo')
|
||||||
|
->references('filename')
|
||||||
|
->on('files')
|
||||||
|
->onUpdate('cascade')
|
||||||
|
->onDelete('set null');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
// force Doctrine to consider enum type as string
|
||||||
|
$platform = Schema::getConnection()
|
||||||
|
->getDoctrineSchemaManager()
|
||||||
|
->getDatabasePlatform();
|
||||||
|
$platform->registerDoctrineTypeMapping('enum', 'string');
|
||||||
|
|
||||||
|
// delete all title photos
|
||||||
|
DB::statement('UPDATE contents SET title_photo = NULL');
|
||||||
|
|
||||||
|
Schema::table('contents', function (Blueprint $table) {
|
||||||
|
$table->dropForeign('contents_title_photo_foreign');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('contents', function (Blueprint $table) {
|
||||||
|
$table->integer('title_photo', false)
|
||||||
|
->change();
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('contents', function (Blueprint $table) {
|
||||||
|
$table->foreign('title_photo')
|
||||||
|
->references('id')
|
||||||
|
->on('files');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+4
@@ -127,6 +127,10 @@ code {
|
|||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#appearance .title-photo img {
|
||||||
|
max-height: 10em;
|
||||||
|
}
|
||||||
|
|
||||||
.red {
|
.red {
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,5 +36,6 @@ return [
|
|||||||
'overview' => 'List of all content pages',
|
'overview' => 'List of all content pages',
|
||||||
'homepageSetup' => 'Homepage successfully set up.',
|
'homepageSetup' => 'Homepage successfully set up.',
|
||||||
'setHomepage' => 'Set page as homepage',
|
'setHomepage' => 'Set page as homepage',
|
||||||
'noParentPage' => ' -- No parent page -- '
|
'noParentPage' => ' -- No parent page -- ',
|
||||||
|
'uploadTitleImage' => 'Upload title image'
|
||||||
];
|
];
|
||||||
@@ -1,22 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
return [
|
return [
|
||||||
'pageName' => 'History of :name',
|
'pageName' => 'History of :name',
|
||||||
'columnPageContent' => 'Page content',
|
'columnPageContent' => 'Page content',
|
||||||
'columnUrl' => 'URL',
|
'columnUrl' => 'URL',
|
||||||
'columnTitle' => 'Title',
|
'columnTitle' => 'Title',
|
||||||
'columnMetaKeywords' => 'Meta keywords',
|
'columnMetaKeywords' => 'Meta keywords',
|
||||||
'columnMetaDescription' => 'Description',
|
'columnMetaDescription' => 'Description',
|
||||||
'columnStatus' => 'Page visibility',
|
'columnStatus' => 'Page visibility',
|
||||||
'columnTemplate' => 'Template',
|
'columnTemplate' => 'Template',
|
||||||
'columnIs_homepage' => 'Homepage',
|
'columnIs_homepage' => 'Homepage',
|
||||||
'columnParentPage' => 'Parent page',
|
'columnParentPage' => 'Parent page',
|
||||||
'emptyValue' => '<em>none</em>',
|
'columnTitlePhotoFilename' => 'Title photo',
|
||||||
'changedFromTo' => 'Changed from <del>:from</del> to <ins>:to</ins>',
|
'emptyValue' => '<em>none</em>',
|
||||||
'numOfChanges' => 'One change|:count changes',
|
'changedFromTo' => 'Changed from <del>:from</del> to <ins>:to</ins>',
|
||||||
'diff' => 'Difference',
|
'numOfChanges' => 'One change|:count changes',
|
||||||
'diffPageName' => 'Difference of :column',
|
'diff' => 'Difference',
|
||||||
'backToOverview' => 'Back to history overview',
|
'diffPageName' => 'Difference of :column',
|
||||||
'backToEdit' => 'Back to editation form',
|
'backToOverview' => 'Back to history overview',
|
||||||
'setupAsHomepage' => 'Setup as homepage'
|
'backToEdit' => 'Back to editation form',
|
||||||
|
'setupAsHomepage' => 'Setup as homepage'
|
||||||
|
|
||||||
];
|
];
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<form method="POST" action="{{route('content.editPost', ['pageId' => $page->id])}}">
|
<form method="POST" enctype="multipart/form-data" action="{{route('content.editPost', ['pageId' => $page->id])}}">
|
||||||
{!! csrf_field() !!}
|
{!! csrf_field() !!}
|
||||||
|
|
||||||
@include('admin.content.formInputs')
|
@include('admin.content.formInputs')
|
||||||
|
|||||||
@@ -1,3 +1,26 @@
|
|||||||
|
@if($page->title_photo)
|
||||||
|
<div class="row">
|
||||||
|
<div class="column large-12 title-photo text-center">
|
||||||
|
<img src="{{config('app.upload_url')}}/{{$page->title_photo}}" alt="" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="column large-12">
|
||||||
|
<label>
|
||||||
|
@lang('admin/contents.uploadTitleImage')
|
||||||
|
<input type="file" id="titlePhoto" name="titlePhoto" />
|
||||||
|
</label>
|
||||||
|
@if (isset($errors) && $errors->has('titlePhoto'))
|
||||||
|
<div class="callout alert">
|
||||||
|
{{ $errors->first('titlePhoto') }}
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="columns large-12">
|
<div class="columns large-12">
|
||||||
<label>
|
<label>
|
||||||
|
|||||||
@@ -55,13 +55,12 @@
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@if (isset($errors) && $errors->has('status'))
|
@if (isset($errors) && $errors->has('parentPage'))
|
||||||
<div class="callout alert">
|
<div class="callout alert">
|
||||||
{{ $errors->first('status') }}
|
{{ $errors->first('parentPage') }}
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<form method="POST" action="{{route('content.newPost', ['moduleId' => $moduleId])}}">
|
<form method="POST" enctype="multipart/form-data" action="{{route('content.newPost', ['moduleId' => $moduleId])}}">
|
||||||
{!! csrf_field() !!}
|
{!! csrf_field() !!}
|
||||||
|
|
||||||
@include('admin.content.formInputs')
|
@include('admin.content.formInputs')
|
||||||
|
|||||||
Reference in New Issue
Block a user