Merge branch 'development' into release
This commit is contained in:
commit
e9c9792cb9
|
@ -56,6 +56,7 @@ Name :: Languages
|
||||||
@arcoai :: Spanish
|
@arcoai :: Spanish
|
||||||
@Jokuna :: Korean
|
@Jokuna :: Korean
|
||||||
@smartshogu :: German; German Informal
|
@smartshogu :: German; German Informal
|
||||||
|
@samadha56 :: Persian
|
||||||
cipi1965 :: Italian
|
cipi1965 :: Italian
|
||||||
Mykola Ronik (Mantikor) :: Ukrainian
|
Mykola Ronik (Mantikor) :: Ukrainian
|
||||||
furkanoyk :: Turkish
|
furkanoyk :: Turkish
|
||||||
|
@ -268,3 +269,4 @@ mcgong (GongMingCai) :: Chinese Simplified; Chinese Traditional
|
||||||
Nanang Setia Budi (sefidananang) :: Indonesian
|
Nanang Setia Budi (sefidananang) :: Indonesian
|
||||||
Андрей Павлов (andrei.pavlov) :: Russian
|
Андрей Павлов (andrei.pavlov) :: Russian
|
||||||
Alex Navarro (alex.n.navarro) :: Portuguese, Brazilian
|
Alex Navarro (alex.n.navarro) :: Portuguese, Brazilian
|
||||||
|
Ji-Hyeon Gim (PotatoGim) :: Korean
|
||||||
|
|
|
@ -34,7 +34,13 @@ class PermissionApplicator
|
||||||
$ownRolePermission = $user->can($fullPermission . '-own');
|
$ownRolePermission = $user->can($fullPermission . '-own');
|
||||||
$nonJointPermissions = ['restrictions', 'image', 'attachment', 'comment'];
|
$nonJointPermissions = ['restrictions', 'image', 'attachment', 'comment'];
|
||||||
$ownerField = ($ownable instanceof Entity) ? 'owned_by' : 'created_by';
|
$ownerField = ($ownable instanceof Entity) ? 'owned_by' : 'created_by';
|
||||||
$isOwner = $user->id === $ownable->getAttribute($ownerField);
|
$ownableFieldVal = $ownable->getAttribute($ownerField);
|
||||||
|
|
||||||
|
if (is_null($ownableFieldVal)) {
|
||||||
|
throw new InvalidArgumentException("{$ownerField} field used but has not been loaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
$isOwner = $user->id === $ownableFieldVal;
|
||||||
$hasRolePermission = $allRolePermission || ($isOwner && $ownRolePermission);
|
$hasRolePermission = $allRolePermission || ($isOwner && $ownRolePermission);
|
||||||
|
|
||||||
// Handle non entity specific jointPermissions
|
// Handle non entity specific jointPermissions
|
||||||
|
@ -68,6 +74,11 @@ class PermissionApplicator
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($chain as $currentEntity) {
|
foreach ($chain as $currentEntity) {
|
||||||
|
|
||||||
|
if (is_null($currentEntity->restricted)) {
|
||||||
|
throw new InvalidArgumentException("Entity restricted field used but has not been loaded");
|
||||||
|
}
|
||||||
|
|
||||||
if ($currentEntity->restricted) {
|
if ($currentEntity->restricted) {
|
||||||
return $currentEntity->permissions()
|
return $currentEntity->permissions()
|
||||||
->whereIn('role_id', $userRoleIds)
|
->whereIn('role_id', $userRoleIds)
|
||||||
|
|
|
@ -80,6 +80,11 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
||||||
*/
|
*/
|
||||||
protected ?Collection $permissions;
|
protected ?Collection $permissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This holds the user's avatar URL when loaded to prevent re-calculating within the same request.
|
||||||
|
*/
|
||||||
|
protected string $avatarUrl = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This holds the default user when loaded.
|
* This holds the default user when loaded.
|
||||||
*
|
*
|
||||||
|
@ -233,12 +238,17 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
||||||
return $default;
|
return $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!empty($this->avatarUrl)) {
|
||||||
|
return $this->avatarUrl;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$avatar = $this->avatar ? url($this->avatar->getThumb($size, $size, false)) : $default;
|
$avatar = $this->avatar ? url($this->avatar->getThumb($size, $size, false)) : $default;
|
||||||
} catch (Exception $err) {
|
} catch (Exception $err) {
|
||||||
$avatar = $default;
|
$avatar = $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->avatarUrl = $avatar;
|
||||||
return $avatar;
|
return $avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ class BaseRepo
|
||||||
$this->tagRepo->saveTagsToEntity($entity, $input['tags']);
|
$this->tagRepo->saveTagsToEntity($entity, $input['tags']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$entity->refresh();
|
||||||
$entity->rebuildPermissions();
|
$entity->rebuildPermissions();
|
||||||
$entity->indexForSearch();
|
$entity->indexForSearch();
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ class BookshelfRepo
|
||||||
public function copyDownPermissions(Bookshelf $shelf, $checkUserPermissions = true): int
|
public function copyDownPermissions(Bookshelf $shelf, $checkUserPermissions = true): int
|
||||||
{
|
{
|
||||||
$shelfPermissions = $shelf->permissions()->get(['role_id', 'action'])->toArray();
|
$shelfPermissions = $shelf->permissions()->get(['role_id', 'action'])->toArray();
|
||||||
$shelfBooks = $shelf->books()->get(['id', 'restricted']);
|
$shelfBooks = $shelf->books()->get(['id', 'restricted', 'owned_by']);
|
||||||
$updatedBookCount = 0;
|
$updatedBookCount = 0;
|
||||||
|
|
||||||
/** @var Book $book */
|
/** @var Book $book */
|
||||||
|
|
|
@ -163,7 +163,7 @@ class SearchRunner
|
||||||
$entityQuery = $entityModelInstance->newQuery()->scopes('visible');
|
$entityQuery = $entityModelInstance->newQuery()->scopes('visible');
|
||||||
|
|
||||||
if ($entityModelInstance instanceof Page) {
|
if ($entityModelInstance instanceof Page) {
|
||||||
$entityQuery->select($entityModelInstance::$listAttributes);
|
$entityQuery->select(array_merge($entityModelInstance::$listAttributes, ['restricted', 'owned_by']));
|
||||||
} else {
|
} else {
|
||||||
$entityQuery->select(['*']);
|
$entityQuery->select(['*']);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,9 @@ class PageApiController extends ApiController
|
||||||
*
|
*
|
||||||
* Pages will always have HTML content. They may have markdown content
|
* Pages will always have HTML content. They may have markdown content
|
||||||
* if the markdown editor was used to last update the page.
|
* if the markdown editor was used to last update the page.
|
||||||
|
*
|
||||||
|
* See the "Content Security" section of these docs for security considerations when using
|
||||||
|
* the page content returned from this endpoint.
|
||||||
*/
|
*/
|
||||||
public function read(string $id)
|
public function read(string $id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,7 +87,7 @@ class FavouriteController extends Controller
|
||||||
|
|
||||||
$modelInstance = $model->newQuery()
|
$modelInstance = $model->newQuery()
|
||||||
->where('id', '=', $modelInfo['id'])
|
->where('id', '=', $modelInfo['id'])
|
||||||
->first(['id', 'name']);
|
->first(['id', 'name', 'restricted', 'owned_by']);
|
||||||
|
|
||||||
$inaccessibleEntity = ($modelInstance instanceof Entity && !userCan('view', $modelInstance));
|
$inaccessibleEntity = ($modelInstance instanceof Entity && !userCan('view', $modelInstance));
|
||||||
if (is_null($modelInstance) || $inaccessibleEntity) {
|
if (is_null($modelInstance) || $inaccessibleEntity) {
|
||||||
|
|
|
@ -11,11 +11,8 @@ use Ssddanbrown\HtmlDiff\Diff;
|
||||||
|
|
||||||
class PageRevisionController extends Controller
|
class PageRevisionController extends Controller
|
||||||
{
|
{
|
||||||
protected $pageRepo;
|
protected PageRepo $pageRepo;
|
||||||
|
|
||||||
/**
|
|
||||||
* PageRevisionController constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(PageRepo $pageRepo)
|
public function __construct(PageRepo $pageRepo)
|
||||||
{
|
{
|
||||||
$this->pageRepo = $pageRepo;
|
$this->pageRepo = $pageRepo;
|
||||||
|
@ -29,11 +26,19 @@ class PageRevisionController extends Controller
|
||||||
public function index(string $bookSlug, string $pageSlug)
|
public function index(string $bookSlug, string $pageSlug)
|
||||||
{
|
{
|
||||||
$page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
|
$page = $this->pageRepo->getBySlug($bookSlug, $pageSlug);
|
||||||
$this->setPageTitle(trans('entities.pages_revisions_named', ['pageName'=>$page->getShortName()]));
|
$revisions = $page->revisions()->select([
|
||||||
|
'id', 'page_id', 'name', 'created_at', 'created_by', 'updated_at',
|
||||||
|
'type', 'revision_number', 'summary',
|
||||||
|
])
|
||||||
|
->selectRaw("IF(markdown = '', false, true) as is_markdown")
|
||||||
|
->with(['page.book', 'createdBy'])
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$this->setPageTitle(trans('entities.pages_revisions_named', ['pageName' => $page->getShortName()]));
|
||||||
|
|
||||||
return view('pages.revisions', [
|
return view('pages.revisions', [
|
||||||
|
'revisions' => $revisions,
|
||||||
'page' => $page,
|
'page' => $page,
|
||||||
'current' => $page,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,11 @@ class HtmlContentFilter
|
||||||
$badIframes = $xPath->query('//*[' . static::xpathContains('@src', 'data:') . '] | //*[' . static::xpathContains('@src', 'javascript:') . '] | //*[@srcdoc]');
|
$badIframes = $xPath->query('//*[' . static::xpathContains('@src', 'data:') . '] | //*[' . static::xpathContains('@src', 'javascript:') . '] | //*[@srcdoc]');
|
||||||
static::removeNodes($badIframes);
|
static::removeNodes($badIframes);
|
||||||
|
|
||||||
|
// Remove tags hiding JavaScript or data uris in values attribute.
|
||||||
|
// For example, SVG animate tag can exploit javascript in values.
|
||||||
|
$badValuesTags = $xPath->query('//*[' . static::xpathContains('@values', 'data:') . '] | //*[' . static::xpathContains('@values', 'javascript:') . ']');
|
||||||
|
static::removeNodes($badValuesTags);
|
||||||
|
|
||||||
// Remove elements with a xlink:href attribute
|
// Remove elements with a xlink:href attribute
|
||||||
// Used in SVG but deprecated anyway, so we'll be a bit more heavy-handed here.
|
// Used in SVG but deprecated anyway, so we'll be a bit more heavy-handed here.
|
||||||
$xlinkHrefAttributes = $xPath->query('//@*[contains(name(), \'xlink:href\')]');
|
$xlinkHrefAttributes = $xPath->query('//@*[contains(name(), \'xlink:href\')]');
|
||||||
|
|
|
@ -111,10 +111,8 @@ function defineCodeBlockCustomElement(editor) {
|
||||||
const container = this.shadowRoot.querySelector('.CodeMirrorContainer');
|
const container = this.shadowRoot.querySelector('.CodeMirrorContainer');
|
||||||
const renderCodeMirror = (Code) => {
|
const renderCodeMirror = (Code) => {
|
||||||
this.cm = Code.wysiwygView(container, content, this.getLanguage());
|
this.cm = Code.wysiwygView(container, content, this.getLanguage());
|
||||||
Code.updateLayout(this.cm);
|
setTimeout(() => Code.updateLayout(this.cm), 10);
|
||||||
setTimeout(() => {
|
setTimeout(() => this.style.height = null, 12);
|
||||||
this.style.height = null;
|
|
||||||
}, 1);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
window.importVersioned('code').then((Code) => {
|
window.importVersioned('code').then((Code) => {
|
||||||
|
|
|
@ -28,8 +28,8 @@ return [
|
||||||
// Books
|
// Books
|
||||||
'book_create' => 'ایجاد کتاب',
|
'book_create' => 'ایجاد کتاب',
|
||||||
'book_create_notification' => 'کتاب با موفقیت ایجاد شد',
|
'book_create_notification' => 'کتاب با موفقیت ایجاد شد',
|
||||||
'book_create_from_chapter' => 'converted chapter to book',
|
'book_create_from_chapter' => 'تبدیل فصل به کتاب',
|
||||||
'book_create_from_chapter_notification' => 'Chapter successfully converted to a book',
|
'book_create_from_chapter_notification' => 'فصل با موفقیت به یک کتاب تبدیل شد',
|
||||||
'book_update' => 'به روزرسانی کتاب',
|
'book_update' => 'به روزرسانی کتاب',
|
||||||
'book_update_notification' => 'کتاب با موفقیت به روزرسانی شد',
|
'book_update_notification' => 'کتاب با موفقیت به روزرسانی شد',
|
||||||
'book_delete' => 'حذف کتاب',
|
'book_delete' => 'حذف کتاب',
|
||||||
|
@ -38,10 +38,10 @@ return [
|
||||||
'book_sort_notification' => 'کتاب با موفقیت مرتب سازی شد',
|
'book_sort_notification' => 'کتاب با موفقیت مرتب سازی شد',
|
||||||
|
|
||||||
// Bookshelves
|
// Bookshelves
|
||||||
'bookshelf_create' => 'ایجاد قفسه کتاب',
|
'bookshelf_create' => 'ایجاد قفسه کتاب',
|
||||||
'bookshelf_create_notification' => 'قفسه کتاب با موفقیت ایجاد شد',
|
'bookshelf_create_notification' => 'قفسه کتاب با موفقیت ایجاد شد',
|
||||||
'bookshelf_create_from_book' => 'converted book to bookshelf',
|
'bookshelf_create_from_book' => 'تبدیل کتاب به قفسه',
|
||||||
'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf',
|
'bookshelf_create_from_book_notification' => 'کتاب با موفقیت به یک قفسه تبدیل شد',
|
||||||
'bookshelf_update' => 'به روزرسانی قفسه کتاب',
|
'bookshelf_update' => 'به روزرسانی قفسه کتاب',
|
||||||
'bookshelf_update_notification' => 'قفسه کتاب با موفقیت به روزرسانی شد',
|
'bookshelf_update_notification' => 'قفسه کتاب با موفقیت به روزرسانی شد',
|
||||||
'bookshelf_delete' => 'حذف قفسه کتاب',
|
'bookshelf_delete' => 'حذف قفسه کتاب',
|
||||||
|
|
|
@ -42,13 +42,13 @@ return [
|
||||||
'configure' => 'پیکربندی کنید',
|
'configure' => 'پیکربندی کنید',
|
||||||
'fullscreen' => 'تمام صفحه',
|
'fullscreen' => 'تمام صفحه',
|
||||||
'favourite' => 'علاقهمندی',
|
'favourite' => 'علاقهمندی',
|
||||||
'unfavourite' => 'Unfavourite',
|
'unfavourite' => 'حذف از علاقهمندی',
|
||||||
'next' => 'بعدی',
|
'next' => 'بعدی',
|
||||||
'previous' => 'قبلى',
|
'previous' => 'قبلى',
|
||||||
'filter_active' => 'فیلتر فعال:',
|
'filter_active' => 'فیلتر فعال:',
|
||||||
'filter_clear' => 'پاک کردن فیلتر',
|
'filter_clear' => 'پاک کردن فیلتر',
|
||||||
'download' => 'Download',
|
'download' => 'دانلود',
|
||||||
'open_in_tab' => 'Open in Tab',
|
'open_in_tab' => 'باز کردن در تب جدید',
|
||||||
|
|
||||||
// Sort Options
|
// Sort Options
|
||||||
'sort_options' => 'گزینههای مرتب سازی',
|
'sort_options' => 'گزینههای مرتب سازی',
|
||||||
|
@ -56,7 +56,7 @@ return [
|
||||||
'sort_ascending' => 'مرتبسازی صعودی',
|
'sort_ascending' => 'مرتبسازی صعودی',
|
||||||
'sort_descending' => 'مرتبسازی نزولی',
|
'sort_descending' => 'مرتبسازی نزولی',
|
||||||
'sort_name' => 'نام',
|
'sort_name' => 'نام',
|
||||||
'sort_default' => 'پیشفرض',
|
'sort_default' => 'پیشفرض',
|
||||||
'sort_created_at' => 'تاریخ ایجاد',
|
'sort_created_at' => 'تاریخ ایجاد',
|
||||||
'sort_updated_at' => 'تاریخ بروزرسانی',
|
'sort_updated_at' => 'تاریخ بروزرسانی',
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ return [
|
||||||
'details' => 'جزییات',
|
'details' => 'جزییات',
|
||||||
'grid_view' => 'نمایش شبکهای',
|
'grid_view' => 'نمایش شبکهای',
|
||||||
'list_view' => 'نمای لیست',
|
'list_view' => 'نمای لیست',
|
||||||
'default' => 'پیشفرض',
|
'default' => 'پیشفرض',
|
||||||
'breadcrumb' => 'مسیر جاری',
|
'breadcrumb' => 'مسیر جاری',
|
||||||
'status' => 'وضعیت',
|
'status' => 'وضعیت',
|
||||||
'status_active' => 'فعال',
|
'status_active' => 'فعال',
|
||||||
|
|
|
@ -24,7 +24,7 @@ return [
|
||||||
'width' => 'عرض',
|
'width' => 'عرض',
|
||||||
'height' => 'ارتفاع',
|
'height' => 'ارتفاع',
|
||||||
'More' => 'بیشتر',
|
'More' => 'بیشتر',
|
||||||
'select' => 'Select...',
|
'select' => 'انتخاب...',
|
||||||
|
|
||||||
// Toolbar
|
// Toolbar
|
||||||
'formats' => 'الگو',
|
'formats' => 'الگو',
|
||||||
|
@ -35,7 +35,7 @@ return [
|
||||||
'paragraph' => 'پاراگراف',
|
'paragraph' => 'پاراگراف',
|
||||||
'blockquote' => 'نقل قول',
|
'blockquote' => 'نقل قول',
|
||||||
'inline_code' => 'کد درون خطی',
|
'inline_code' => 'کد درون خطی',
|
||||||
'callouts' => 'تعليق تفسيري',
|
'callouts' => 'قالب پیام و هشدار',
|
||||||
'callout_information' => 'اطلاعات',
|
'callout_information' => 'اطلاعات',
|
||||||
'callout_success' => 'موفق',
|
'callout_success' => 'موفق',
|
||||||
'callout_warning' => 'هشدار',
|
'callout_warning' => 'هشدار',
|
||||||
|
@ -44,128 +44,128 @@ return [
|
||||||
'italic' => 'حروف کج(ایتالیک)',
|
'italic' => 'حروف کج(ایتالیک)',
|
||||||
'underline' => 'زیرخط',
|
'underline' => 'زیرخط',
|
||||||
'strikethrough' => 'خط خورده',
|
'strikethrough' => 'خط خورده',
|
||||||
'superscript' => 'Superscript',
|
'superscript' => 'بالانویسی',
|
||||||
'subscript' => 'Subscript',
|
'subscript' => 'پایین نویسی',
|
||||||
'text_color' => 'Text color',
|
'text_color' => 'رنگ متن',
|
||||||
'custom_color' => 'Custom color',
|
'custom_color' => 'رنگ دلخواه',
|
||||||
'remove_color' => 'Remove color',
|
'remove_color' => 'حذف رنگ',
|
||||||
'background_color' => 'Background color',
|
'background_color' => 'رنگ زمینه',
|
||||||
'align_left' => 'Align left',
|
'align_left' => 'چپ چین',
|
||||||
'align_center' => 'Align center',
|
'align_center' => 'وسط چین',
|
||||||
'align_right' => 'Align right',
|
'align_right' => 'راست چین',
|
||||||
'align_justify' => 'Justify',
|
'align_justify' => 'همتراز',
|
||||||
'list_bullet' => 'Bullet list',
|
'list_bullet' => 'لیست نشانه دار',
|
||||||
'list_numbered' => 'Numbered list',
|
'list_numbered' => 'لیست عددی',
|
||||||
'list_task' => 'Task list',
|
'list_task' => 'لیست کار',
|
||||||
'indent_increase' => 'Increase indent',
|
'indent_increase' => 'افزایش تورفتگی',
|
||||||
'indent_decrease' => 'Decrease indent',
|
'indent_decrease' => 'کاهش تورفتگی',
|
||||||
'table' => 'Table',
|
'table' => 'جدول',
|
||||||
'insert_image' => 'Insert image',
|
'insert_image' => 'افزودن تصویر',
|
||||||
'insert_image_title' => 'Insert/Edit Image',
|
'insert_image_title' => 'افزودن/ویرایش تصویر',
|
||||||
'insert_link' => 'Insert/edit link',
|
'insert_link' => 'افزودن/ویرایش پیوند',
|
||||||
'insert_link_title' => 'Insert/Edit Link',
|
'insert_link_title' => 'افزودن/ویرایش پیوند',
|
||||||
'insert_horizontal_line' => 'Insert horizontal line',
|
'insert_horizontal_line' => 'افزودن خط افقی',
|
||||||
'insert_code_block' => 'Insert code block',
|
'insert_code_block' => 'افزودن بلوک کد',
|
||||||
'insert_drawing' => 'Insert/edit drawing',
|
'insert_drawing' => 'افزودن/ویرایش طرح',
|
||||||
'drawing_manager' => 'Drawing manager',
|
'drawing_manager' => 'مدیریت طراحی',
|
||||||
'insert_media' => 'Insert/edit media',
|
'insert_media' => 'افزودن/ویرایش رسانه',
|
||||||
'insert_media_title' => 'Insert/Edit Media',
|
'insert_media_title' => 'افزودن/ویرایش رسانه',
|
||||||
'clear_formatting' => 'Clear formatting',
|
'clear_formatting' => 'حذف قالب بندی',
|
||||||
'source_code' => 'Source code',
|
'source_code' => 'کد منبع',
|
||||||
'source_code_title' => 'Source Code',
|
'source_code_title' => 'کد منبع',
|
||||||
'fullscreen' => 'Fullscreen',
|
'fullscreen' => 'تمام صفحه',
|
||||||
'image_options' => 'Image options',
|
'image_options' => 'تنظیمات تصویر',
|
||||||
|
|
||||||
// Tables
|
// Tables
|
||||||
'table_properties' => 'Table properties',
|
'table_properties' => 'تنظیمات جدول',
|
||||||
'table_properties_title' => 'Table Properties',
|
'table_properties_title' => 'تنظیمات جدول',
|
||||||
'delete_table' => 'Delete table',
|
'delete_table' => 'حذف جدول',
|
||||||
'insert_row_before' => 'Insert row before',
|
'insert_row_before' => 'افزودن سطر به قبل',
|
||||||
'insert_row_after' => 'Insert row after',
|
'insert_row_after' => 'افزودن سطر به بعد',
|
||||||
'delete_row' => 'Delete row',
|
'delete_row' => 'حذف سطر',
|
||||||
'insert_column_before' => 'Insert column before',
|
'insert_column_before' => 'افزودن ستون به قبل',
|
||||||
'insert_column_after' => 'Insert column after',
|
'insert_column_after' => 'افزودن ستون به بعد',
|
||||||
'delete_column' => 'Delete column',
|
'delete_column' => 'حذف ستون',
|
||||||
'table_cell' => 'Cell',
|
'table_cell' => 'سلول',
|
||||||
'table_row' => 'Row',
|
'table_row' => 'سطر',
|
||||||
'table_column' => 'Column',
|
'table_column' => 'ستون',
|
||||||
'cell_properties' => 'Cell properties',
|
'cell_properties' => 'تنظیمات سلول',
|
||||||
'cell_properties_title' => 'Cell Properties',
|
'cell_properties_title' => 'تنظیمات سلول',
|
||||||
'cell_type' => 'Cell type',
|
'cell_type' => 'نوع سلول',
|
||||||
'cell_type_cell' => 'Cell',
|
'cell_type_cell' => 'سلول',
|
||||||
'cell_scope' => 'Scope',
|
'cell_scope' => 'محدوده',
|
||||||
'cell_type_header' => 'Header cell',
|
'cell_type_header' => 'بالای سلول',
|
||||||
'merge_cells' => 'Merge cells',
|
'merge_cells' => 'ادغام سلول ها',
|
||||||
'split_cell' => 'Split cell',
|
'split_cell' => 'جداسازی سلول ها',
|
||||||
'table_row_group' => 'Row Group',
|
'table_row_group' => 'گروه بندی سطر',
|
||||||
'table_column_group' => 'Column Group',
|
'table_column_group' => 'گروه بندی ستون',
|
||||||
'horizontal_align' => 'Horizontal align',
|
'horizontal_align' => 'تراز افقی',
|
||||||
'vertical_align' => 'Vertical align',
|
'vertical_align' => 'تراز عمودی',
|
||||||
'border_width' => 'Border width',
|
'border_width' => 'پهنای حاشیه',
|
||||||
'border_style' => 'Border style',
|
'border_style' => 'سبک حاشیه',
|
||||||
'border_color' => 'Border color',
|
'border_color' => 'رنگ حاشیه',
|
||||||
'row_properties' => 'Row properties',
|
'row_properties' => 'تنظیمات سطر',
|
||||||
'row_properties_title' => 'Row Properties',
|
'row_properties_title' => 'تنظیمات سطر',
|
||||||
'cut_row' => 'Cut row',
|
'cut_row' => 'برش سطر',
|
||||||
'copy_row' => 'Copy row',
|
'copy_row' => 'کپی سطر',
|
||||||
'paste_row_before' => 'Paste row before',
|
'paste_row_before' => 'چسباندن سطر به قبل',
|
||||||
'paste_row_after' => 'Paste row after',
|
'paste_row_after' => 'چسباندن سطر به بعد',
|
||||||
'row_type' => 'Row type',
|
'row_type' => 'نوع سطر',
|
||||||
'row_type_header' => 'Header',
|
'row_type_header' => 'سربرگ',
|
||||||
'row_type_body' => 'Body',
|
'row_type_body' => 'بدنه',
|
||||||
'row_type_footer' => 'Footer',
|
'row_type_footer' => 'پانوشت',
|
||||||
'alignment' => 'Alignment',
|
'alignment' => 'ترازبندی',
|
||||||
'cut_column' => 'Cut column',
|
'cut_column' => 'برش ستون',
|
||||||
'copy_column' => 'Copy column',
|
'copy_column' => 'کپی ستون',
|
||||||
'paste_column_before' => 'Paste column before',
|
'paste_column_before' => 'چسباندن ستون به قبل',
|
||||||
'paste_column_after' => 'Paste column after',
|
'paste_column_after' => 'چسباندن ستون به بعد',
|
||||||
'cell_padding' => 'Cell padding',
|
'cell_padding' => 'حاشیه سلول',
|
||||||
'cell_spacing' => 'Cell spacing',
|
'cell_spacing' => 'فاصله سلول',
|
||||||
'caption' => 'Caption',
|
'caption' => 'عنوان',
|
||||||
'show_caption' => 'Show caption',
|
'show_caption' => 'مشاهده عنوان',
|
||||||
'constrain' => 'Constrain proportions',
|
'constrain' => 'محدودسازی نسبت ها',
|
||||||
'cell_border_solid' => 'Solid',
|
'cell_border_solid' => 'یکپارچه',
|
||||||
'cell_border_dotted' => 'Dotted',
|
'cell_border_dotted' => 'نقطه چین',
|
||||||
'cell_border_dashed' => 'Dashed',
|
'cell_border_dashed' => 'خط چین',
|
||||||
'cell_border_double' => 'Double',
|
'cell_border_double' => 'دوتایی',
|
||||||
'cell_border_groove' => 'Groove',
|
'cell_border_groove' => 'شیار',
|
||||||
'cell_border_ridge' => 'Ridge',
|
'cell_border_ridge' => 'لبه',
|
||||||
'cell_border_inset' => 'Inset',
|
'cell_border_inset' => 'داخل',
|
||||||
'cell_border_outset' => 'Outset',
|
'cell_border_outset' => 'خارج',
|
||||||
'cell_border_none' => 'None',
|
'cell_border_none' => 'هیچ کدام',
|
||||||
'cell_border_hidden' => 'Hidden',
|
'cell_border_hidden' => 'مخفی',
|
||||||
|
|
||||||
// Images, links, details/summary & embed
|
// Images, links, details/summary & embed
|
||||||
'source' => 'Source',
|
'source' => 'منبع',
|
||||||
'alt_desc' => 'Alternative description',
|
'alt_desc' => 'توضیحات جایگزین',
|
||||||
'embed' => 'Embed',
|
'embed' => 'درج',
|
||||||
'paste_embed' => 'Paste your embed code below:',
|
'paste_embed' => 'کد درج را در زیر وارد نمایید:',
|
||||||
'url' => 'URL',
|
'url' => 'آدرس',
|
||||||
'text_to_display' => 'Text to display',
|
'text_to_display' => 'متن جهت نمایش',
|
||||||
'title' => 'Title',
|
'title' => 'عنوان',
|
||||||
'open_link' => 'Open link in...',
|
'open_link' => 'باز کردن لینک در ...',
|
||||||
'open_link_current' => 'Current window',
|
'open_link_current' => 'پنجره کنونی',
|
||||||
'open_link_new' => 'New window',
|
'open_link_new' => 'پنجره جدید',
|
||||||
'insert_collapsible' => 'Insert collapsible block',
|
'insert_collapsible' => 'درج بلوک جمع شونده',
|
||||||
'collapsible_unwrap' => 'Unwrap',
|
'collapsible_unwrap' => 'باز کردن',
|
||||||
'edit_label' => 'Edit label',
|
'edit_label' => 'ویرایش برچسب',
|
||||||
'toggle_open_closed' => 'Toggle open/closed',
|
'toggle_open_closed' => 'بستن/بازکردن',
|
||||||
'collapsible_edit' => 'Edit collapsible block',
|
'collapsible_edit' => 'ویرایش بلوک جمع شونده',
|
||||||
'toggle_label' => 'Toggle label',
|
'toggle_label' => 'تغییر برچسب',
|
||||||
|
|
||||||
// About view
|
// About view
|
||||||
'about' => 'About the editor',
|
'about' => 'درباره ویرایشگر',
|
||||||
'about_title' => 'About the WYSIWYG Editor',
|
'about_title' => 'درباره ویرایشگر WYSIWYG',
|
||||||
'editor_license' => 'Editor License & Copyright',
|
'editor_license' => 'مجوز و حق کپی رایت ویرایشگر',
|
||||||
'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under the MIT license.',
|
'editor_tiny_license' => 'این ویرایشگر توسط :tinyLink و تحت مجوز MIT ساخته شده است.',
|
||||||
'editor_tiny_license_link' => 'The copyright and license details of TinyMCE can be found here.',
|
'editor_tiny_license_link' => 'جزئیات کپی رایت و مجوز TinyMCE را می توانید در اینجا پیدا کنید.',
|
||||||
'save_continue' => 'Save Page & Continue',
|
'save_continue' => 'ذخیره صفحه و ادامه',
|
||||||
'callouts_cycle' => '(Keep pressing to toggle through types)',
|
'callouts_cycle' => '(جهت تغییر نوع ها چندین بار فشار دهید)',
|
||||||
'link_selector' => 'Link to content',
|
'link_selector' => 'پیوند به محتوا',
|
||||||
'shortcuts' => 'Shortcuts',
|
'shortcuts' => 'میانبرها',
|
||||||
'shortcut' => 'Shortcut',
|
'shortcut' => 'میانبر',
|
||||||
'shortcuts_intro' => 'The following shortcuts are available in the editor:',
|
'shortcuts_intro' => 'میانبرهای قابل استفاده در این ویرایشگر:',
|
||||||
'windows_linux' => '(Windows/Linux)',
|
'windows_linux' => '(ویندوز/لینوکس)',
|
||||||
'mac' => '(Mac)',
|
'mac' => '(مک)',
|
||||||
'description' => 'Description',
|
'description' => 'توضیحات',
|
||||||
];
|
];
|
||||||
|
|
|
@ -48,7 +48,7 @@ return [
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
'search_results' => 'نتایج جستجو',
|
'search_results' => 'نتایج جستجو',
|
||||||
'search_total_results_found' => ':count result found|:count total results found',
|
'search_total_results_found' => 'نتیجه یافت شد :count | نتایج یافت شده :count',
|
||||||
'search_clear' => 'پاک کردن جستجو',
|
'search_clear' => 'پاک کردن جستجو',
|
||||||
'search_no_pages' => 'هیچ صفحه ای با این جستجو مطابقت ندارد',
|
'search_no_pages' => 'هیچ صفحه ای با این جستجو مطابقت ندارد',
|
||||||
'search_for_term' => 'جستجو برای :term',
|
'search_for_term' => 'جستجو برای :term',
|
||||||
|
@ -79,7 +79,7 @@ return [
|
||||||
'x_shelves' => ':count تاقچه|:count تاقچه',
|
'x_shelves' => ':count تاقچه|:count تاقچه',
|
||||||
'shelves_long' => 'قفسه کتاب',
|
'shelves_long' => 'قفسه کتاب',
|
||||||
'shelves_empty' => 'هیچ قفسه ای ایجاد نشده است',
|
'shelves_empty' => 'هیچ قفسه ای ایجاد نشده است',
|
||||||
'shelves_create' => 'Create New Shelf',
|
'shelves_create' => 'ایجاد قفسه جدید',
|
||||||
'shelves_popular' => 'قفسه های محبوب',
|
'shelves_popular' => 'قفسه های محبوب',
|
||||||
'shelves_new' => 'قفسه های جدید',
|
'shelves_new' => 'قفسه های جدید',
|
||||||
'shelves_new_action' => 'قفسه جدید',
|
'shelves_new_action' => 'قفسه جدید',
|
||||||
|
@ -104,7 +104,7 @@ return [
|
||||||
'shelves_copy_permissions_to_books' => 'کپی مجوزها در کتابها',
|
'shelves_copy_permissions_to_books' => 'کپی مجوزها در کتابها',
|
||||||
'shelves_copy_permissions' => 'مجوزهای کپی',
|
'shelves_copy_permissions' => 'مجوزهای کپی',
|
||||||
'shelves_copy_permissions_explain' => 'با این کار تنظیمات مجوز فعلی این قفسه کتاب برای همه کتابهای موجود در آن اعمال میشود. قبل از فعال کردن، مطمئن شوید که هر گونه تغییر در مجوزهای این قفسه کتاب ذخیره شده است.',
|
'shelves_copy_permissions_explain' => 'با این کار تنظیمات مجوز فعلی این قفسه کتاب برای همه کتابهای موجود در آن اعمال میشود. قبل از فعال کردن، مطمئن شوید که هر گونه تغییر در مجوزهای این قفسه کتاب ذخیره شده است.',
|
||||||
'shelves_copy_permission_success' => 'مجوزهای قفسه کتاب در :count books کپی شد',
|
'shelves_copy_permission_success' => 'مجوزهای قفسه کتاب در :count کتاب کپی شد',
|
||||||
|
|
||||||
// Books
|
// Books
|
||||||
'book' => 'کتاب',
|
'book' => 'کتاب',
|
||||||
|
@ -359,14 +359,14 @@ return [
|
||||||
'copy_consider_access' => 'تغییر مکان، مالک یا مجوزها ممکن است منجر به دسترسی به این محتوا برای افرادی شود که قبلاً به آنها دسترسی نداشتند.',
|
'copy_consider_access' => 'تغییر مکان، مالک یا مجوزها ممکن است منجر به دسترسی به این محتوا برای افرادی شود که قبلاً به آنها دسترسی نداشتند.',
|
||||||
|
|
||||||
// Conversions
|
// Conversions
|
||||||
'convert_to_shelf' => 'Convert to Shelf',
|
'convert_to_shelf' => 'تبدیل به قفسه',
|
||||||
'convert_to_shelf_contents_desc' => 'You can convert this book to a new shelf with the same contents. Chapters contained within this book will be converted to new books. If this book contains any pages, that are not in a chapter, this book will be renamed and contain such pages, and this book will become part of the new shelf.',
|
'convert_to_shelf_contents_desc' => 'شما می توانید این کتاب را به یک قفسه جدید با همان مطالب تبدیل کنید. فصل های موجود در این کتاب به کتاب های جدید تبدیل می شوند. اگر این کتاب حاوی صفحاتی باشد که در یک فصل نیستند، این کتاب تغییر نام داده و حاوی چنین صفحاتی است و این کتاب بخشی از قفسه جدید خواهد شد.',
|
||||||
'convert_to_shelf_permissions_desc' => 'Any permissions set on this book will be copied to the new shelf and to all new child books that don\'t have their own permissions enforced. Note that permissions on shelves do not auto-cascade to content within, as they do for books.',
|
'convert_to_shelf_permissions_desc' => 'هر گونه مجوز تنظیم شده در این کتاب در قفسه جدید و همه کتابهای فرزند جدید که مجوزهای خود را ندارند کپی میشود. توجه داشته باشید که مجوزهای موجود در قفسهها مانند کتابها به طور خودکار به محتوای درون آن ها شامل نمی شود.',
|
||||||
'convert_book' => 'Convert Book',
|
'convert_book' => 'تبدیل کتاب',
|
||||||
'convert_book_confirm' => 'Are you sure you want to convert this book?',
|
'convert_book_confirm' => 'آیا از تبدیل این کتاب مطمئن هستید؟',
|
||||||
'convert_undo_warning' => 'This cannot be as easily undone.',
|
'convert_undo_warning' => 'برگشت دادن این فرایند به آسانی نخواهد بود.',
|
||||||
'convert_to_book' => 'Convert to Book',
|
'convert_to_book' => 'تبدیل به کتاب',
|
||||||
'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.',
|
'convert_to_book_desc' => 'می توانید این فصل را به یک کتاب جدید با همین مطالب تبدیل کنید. هر مجوزی که در این فصل تنظیم شده است در کتاب جدید کپی می شود، اما هر گونه مجوز ارثی، از کتاب والد، کپی نمی شود که می تواند منجر به تغییر کنترل دسترسی شود.',
|
||||||
'convert_chapter' => 'Convert Chapter',
|
'convert_chapter' => 'تبدیل فصل',
|
||||||
'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?',
|
'convert_chapter_confirm' => 'آیا از تبدیل این فصل مطمئن هستید؟',
|
||||||
];
|
];
|
||||||
|
|
|
@ -28,7 +28,7 @@ return [
|
||||||
'app_secure_images_toggle' => 'آپلود تصویر با امنیت بالاتر',
|
'app_secure_images_toggle' => 'آپلود تصویر با امنیت بالاتر',
|
||||||
'app_secure_images_desc' => 'به دلایل عملکرد، همه تصاویر عمومی هستند. این گزینه یک رشته تصادفی و غیرقابل حدس زدن را در مقابل آدرس های تصویر اضافه می کند. برای جلوگیری از دسترسی آسان، اطمینان حاصل کنید که فهرست های دایرکتوری فعال نیستند.',
|
'app_secure_images_desc' => 'به دلایل عملکرد، همه تصاویر عمومی هستند. این گزینه یک رشته تصادفی و غیرقابل حدس زدن را در مقابل آدرس های تصویر اضافه می کند. برای جلوگیری از دسترسی آسان، اطمینان حاصل کنید که فهرست های دایرکتوری فعال نیستند.',
|
||||||
'app_default_editor' => 'ویرایشگر پیش فرض صفحه',
|
'app_default_editor' => 'ویرایشگر پیش فرض صفحه',
|
||||||
'app_default_editor_desc' => 'Select which editor will be used by default when editing new pages. This can be overridden at a page level where permissions allow.',
|
'app_default_editor_desc' => 'ویرایشگر پیش فرض در زمان ویرایش صفحات را انتخاب نمایید. این انتخاب می تواند جایگزین یک سطح صفحه که مجوز داده شده است، شود.',
|
||||||
'app_custom_html' => 'محتوای اصلی HTML سفارشی',
|
'app_custom_html' => 'محتوای اصلی HTML سفارشی',
|
||||||
'app_custom_html_desc' => 'هر محتوای اضافه شده در اینجا در پایین بخش <head> هر صفحه درج می شود. این برای تغییر سبک ها یا اضافه کردن کد تجزیه و تحلیل مفید است.',
|
'app_custom_html_desc' => 'هر محتوای اضافه شده در اینجا در پایین بخش <head> هر صفحه درج می شود. این برای تغییر سبک ها یا اضافه کردن کد تجزیه و تحلیل مفید است.',
|
||||||
'app_custom_html_disabled_notice' => 'محتوای سر HTML سفارشی در این صفحه تنظیمات غیرفعال است تا اطمینان حاصل شود که هر گونه تغییر شکسته می تواند برگردانده شود.',
|
'app_custom_html_disabled_notice' => 'محتوای سر HTML سفارشی در این صفحه تنظیمات غیرفعال است تا اطمینان حاصل شود که هر گونه تغییر شکسته می تواند برگردانده شود.',
|
||||||
|
@ -42,7 +42,7 @@ return [
|
||||||
'app_footer_links' => 'پیوندهای پاورقی',
|
'app_footer_links' => 'پیوندهای پاورقی',
|
||||||
'app_footer_links_desc' => 'پیوندهایی را برای نمایش در پاورقی سایت اضافه کنید. اینها در پایین اکثر صفحات نمایش داده می شوند، از جمله صفحاتی که نیازی به ورود به سیستم ندارند. می توانید از برچسب "trans::<key>" برای استفاده از ترجمه های تعریف شده توسط سیستم استفاده کنید. به عنوان مثال: با استفاده از "trans::common.privacy_policy" متن ترجمه شده "خط مشی رازداری" و "trans::common.terms_of_service" متن ترجمه شده "شرایط خدمات" را ارائه می دهد.',
|
'app_footer_links_desc' => 'پیوندهایی را برای نمایش در پاورقی سایت اضافه کنید. اینها در پایین اکثر صفحات نمایش داده می شوند، از جمله صفحاتی که نیازی به ورود به سیستم ندارند. می توانید از برچسب "trans::<key>" برای استفاده از ترجمه های تعریف شده توسط سیستم استفاده کنید. به عنوان مثال: با استفاده از "trans::common.privacy_policy" متن ترجمه شده "خط مشی رازداری" و "trans::common.terms_of_service" متن ترجمه شده "شرایط خدمات" را ارائه می دهد.',
|
||||||
'app_footer_links_label' => 'برچسب پیوند',
|
'app_footer_links_label' => 'برچسب پیوند',
|
||||||
'app_footer_links_url' => 'لینک URL',
|
'app_footer_links_url' => 'آدرس پیوند',
|
||||||
'app_footer_links_add' => 'پیوند پاورقی را اضافه کنید',
|
'app_footer_links_add' => 'پیوند پاورقی را اضافه کنید',
|
||||||
'app_disable_comments' => 'غیرفعال کردن نظرات',
|
'app_disable_comments' => 'غیرفعال کردن نظرات',
|
||||||
'app_disable_comments_toggle' => 'نظرات را غیرفعال کنید',
|
'app_disable_comments_toggle' => 'نظرات را غیرفعال کنید',
|
||||||
|
@ -152,7 +152,7 @@ return [
|
||||||
'role_access_api' => 'دسترسی به API سیستم',
|
'role_access_api' => 'دسترسی به API سیستم',
|
||||||
'role_manage_settings' => 'تنظیمات برنامه را مدیریت کنید',
|
'role_manage_settings' => 'تنظیمات برنامه را مدیریت کنید',
|
||||||
'role_export_content' => 'صادرات محتوا',
|
'role_export_content' => 'صادرات محتوا',
|
||||||
'role_editor_change' => 'Change page editor',
|
'role_editor_change' => 'تغییر ویرایشگر صفحه',
|
||||||
'role_asset' => 'مجوزهای دارایی',
|
'role_asset' => 'مجوزهای دارایی',
|
||||||
'roles_system_warning' => 'توجه داشته باشید که دسترسی به هر یک از سه مجوز فوق میتواند به کاربر اجازه دهد تا امتیازات خود یا امتیازات دیگران را در سیستم تغییر دهد. فقط نقش هایی را با این مجوزها به کاربران مورد اعتماد اختصاص دهید.',
|
'roles_system_warning' => 'توجه داشته باشید که دسترسی به هر یک از سه مجوز فوق میتواند به کاربر اجازه دهد تا امتیازات خود یا امتیازات دیگران را در سیستم تغییر دهد. فقط نقش هایی را با این مجوزها به کاربران مورد اعتماد اختصاص دهید.',
|
||||||
'role_asset_desc' => 'این مجوزها دسترسی پیشفرض به داراییهای درون سیستم را کنترل میکنند. مجوزهای مربوط به کتابها، فصلها و صفحات این مجوزها را لغو میکنند.',
|
'role_asset_desc' => 'این مجوزها دسترسی پیشفرض به داراییهای درون سیستم را کنترل میکنند. مجوزهای مربوط به کتابها، فصلها و صفحات این مجوزها را لغو میکنند.',
|
||||||
|
|
|
@ -23,7 +23,7 @@ return [
|
||||||
'string' => ':attribute باید بین :min و :max کاراکتر باشد.',
|
'string' => ':attribute باید بین :min و :max کاراکتر باشد.',
|
||||||
'array' => ':attribute باید بین :min و :max آیتم باشد.',
|
'array' => ':attribute باید بین :min و :max آیتم باشد.',
|
||||||
],
|
],
|
||||||
'boolean' => 'فیلد :attribute فقط میتواند true و یا false باشد.',
|
'boolean' => ':attribute فقط میتواند true و یا false باشد.',
|
||||||
'confirmed' => ':attribute با فیلد تکرار مطابقت ندارد.',
|
'confirmed' => ':attribute با فیلد تکرار مطابقت ندارد.',
|
||||||
'date' => ':attribute یک تاریخ معتبر نیست.',
|
'date' => ':attribute یک تاریخ معتبر نیست.',
|
||||||
'date_format' => ':attribute با الگوی :format مطابقت ندارد.',
|
'date_format' => ':attribute با الگوی :format مطابقت ندارد.',
|
||||||
|
@ -31,9 +31,9 @@ return [
|
||||||
'digits' => ':attribute باید :digits رقم باشد.',
|
'digits' => ':attribute باید :digits رقم باشد.',
|
||||||
'digits_between' => ':attribute باید بین :min و :max رقم باشد.',
|
'digits_between' => ':attribute باید بین :min و :max رقم باشد.',
|
||||||
'email' => ':attribute باید یک ایمیل معتبر باشد.',
|
'email' => ':attribute باید یک ایمیل معتبر باشد.',
|
||||||
'ends_with' => 'فیلد :attribute باید با یکی از مقادیر زیر خاتمه یابد: :values',
|
'ends_with' => ':attribute باید با یکی از مقادیر زیر خاتمه یابد: :values',
|
||||||
'file' => 'The :attribute must be provided as a valid file.',
|
'file' => ':attribute باید به عنوان یک فایل معتبر شناخته شود.',
|
||||||
'filled' => 'فیلد :attribute باید مقدار داشته باشد.',
|
'filled' => ':attribute باید مقدار داشته باشد.',
|
||||||
'gt' => [
|
'gt' => [
|
||||||
'numeric' => ':attribute باید بزرگتر از :value باشد.',
|
'numeric' => ':attribute باید بزرگتر از :value باشد.',
|
||||||
'file' => ':attribute باید بزرگتر از :value کیلوبایت باشد.',
|
'file' => ':attribute باید بزرگتر از :value کیلوبایت باشد.',
|
||||||
|
@ -54,7 +54,7 @@ return [
|
||||||
'ip' => ':attribute باید آدرس IP معتبر باشد.',
|
'ip' => ':attribute باید آدرس IP معتبر باشد.',
|
||||||
'ipv4' => ':attribute باید یک آدرس معتبر از نوع IPv4 باشد.',
|
'ipv4' => ':attribute باید یک آدرس معتبر از نوع IPv4 باشد.',
|
||||||
'ipv6' => ':attribute باید یک آدرس معتبر از نوع IPv6 باشد.',
|
'ipv6' => ':attribute باید یک آدرس معتبر از نوع IPv6 باشد.',
|
||||||
'json' => 'فیلد :attribute باید یک رشته از نوع JSON باشد.',
|
'json' => ':attribute باید یک رشته از نوع JSON باشد.',
|
||||||
'lt' => [
|
'lt' => [
|
||||||
'numeric' => ':attribute باید کوچکتر از :value باشد.',
|
'numeric' => ':attribute باید کوچکتر از :value باشد.',
|
||||||
'file' => ':attribute باید کوچکتر از :value کیلوبایت باشد.',
|
'file' => ':attribute باید کوچکتر از :value کیلوبایت باشد.',
|
||||||
|
@ -84,7 +84,7 @@ return [
|
||||||
'not_regex' => 'فرمت :attribute معتبر نیست.',
|
'not_regex' => 'فرمت :attribute معتبر نیست.',
|
||||||
'numeric' => ':attribute باید عدد یا رشتهای از اعداد باشد.',
|
'numeric' => ':attribute باید عدد یا رشتهای از اعداد باشد.',
|
||||||
'regex' => 'فرمت :attribute معتبر نیست.',
|
'regex' => 'فرمت :attribute معتبر نیست.',
|
||||||
'required' => 'فیلد :attribute الزامی است.',
|
'required' => ':attribute الزامی است.',
|
||||||
'required_if' => 'هنگامی که :other برابر با :value است، فیلد :attribute الزامی است.',
|
'required_if' => 'هنگامی که :other برابر با :value است، فیلد :attribute الزامی است.',
|
||||||
'required_with' => 'در صورت وجود فیلد :values، فیلد :attribute نیز الزامی است.',
|
'required_with' => 'در صورت وجود فیلد :values، فیلد :attribute نیز الزامی است.',
|
||||||
'required_with_all' => 'در صورت وجود فیلدهای :values، فیلد :attribute نیز الزامی است.',
|
'required_with_all' => 'در صورت وجود فیلدهای :values، فیلد :attribute نیز الزامی است.',
|
||||||
|
|
|
@ -157,7 +157,7 @@ return [
|
||||||
'about' => 'エディタについて',
|
'about' => 'エディタについて',
|
||||||
'about_title' => 'WYSIWYGエディタについて',
|
'about_title' => 'WYSIWYGエディタについて',
|
||||||
'editor_license' => 'エディタのライセンスと著作権',
|
'editor_license' => 'エディタのライセンスと著作権',
|
||||||
'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under the MIT license.',
|
'editor_tiny_license' => 'このエディタはMITライセンスの下で提供される:tinyLinkを利用して構築されています。',
|
||||||
'editor_tiny_license_link' => 'TinyMCEの著作権およびライセンスの詳細は、こちらをご覧ください。',
|
'editor_tiny_license_link' => 'TinyMCEの著作権およびライセンスの詳細は、こちらをご覧ください。',
|
||||||
'save_continue' => 'ページを保存して続行',
|
'save_continue' => 'ページを保存して続行',
|
||||||
'callouts_cycle' => '(押し続けて種類を切り替え)',
|
'callouts_cycle' => '(押し続けて種類を切り替え)',
|
||||||
|
|
|
@ -28,8 +28,8 @@ return [
|
||||||
// Books
|
// Books
|
||||||
'book_create' => '책자 만들기',
|
'book_create' => '책자 만들기',
|
||||||
'book_create_notification' => '책 생성함',
|
'book_create_notification' => '책 생성함',
|
||||||
'book_create_from_chapter' => 'converted chapter to book',
|
'book_create_from_chapter' => '챕터를 책으로 변환',
|
||||||
'book_create_from_chapter_notification' => 'Chapter successfully converted to a book',
|
'book_create_from_chapter_notification' => '챕터를 책으로 변환했습니다.',
|
||||||
'book_update' => '책 수정',
|
'book_update' => '책 수정',
|
||||||
'book_update_notification' => '책 수정함',
|
'book_update_notification' => '책 수정함',
|
||||||
'book_delete' => '책 지우기',
|
'book_delete' => '책 지우기',
|
||||||
|
@ -40,8 +40,8 @@ return [
|
||||||
// Bookshelves
|
// Bookshelves
|
||||||
'bookshelf_create' => '책꽂이 만들기',
|
'bookshelf_create' => '책꽂이 만들기',
|
||||||
'bookshelf_create_notification' => '책꽂이 생성함',
|
'bookshelf_create_notification' => '책꽂이 생성함',
|
||||||
'bookshelf_create_from_book' => 'converted book to bookshelf',
|
'bookshelf_create_from_book' => '책을 책꽂이로 변환',
|
||||||
'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf',
|
'bookshelf_create_from_book_notification' => '책을 책꽂이로 변환했습니다.',
|
||||||
'bookshelf_update' => '책꽂이 수정',
|
'bookshelf_update' => '책꽂이 수정',
|
||||||
'bookshelf_update_notification' => '책꽂이 수정함',
|
'bookshelf_update_notification' => '책꽂이 수정함',
|
||||||
'bookshelf_delete' => '책꽂이 지우기',
|
'bookshelf_delete' => '책꽂이 지우기',
|
||||||
|
@ -64,8 +64,8 @@ return [
|
||||||
'webhook_delete_notification' => '웹 훅 삭제함',
|
'webhook_delete_notification' => '웹 훅 삭제함',
|
||||||
|
|
||||||
// Users
|
// Users
|
||||||
'user_update_notification' => 'User successfully updated',
|
'user_update_notification' => '사용자가 업데이트되었습니다',
|
||||||
'user_delete_notification' => 'User successfully removed',
|
'user_delete_notification' => '사용자가 삭제되었습니다',
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
'commented_on' => '댓글 쓰기',
|
'commented_on' => '댓글 쓰기',
|
||||||
|
|
|
@ -39,9 +39,9 @@ return [
|
||||||
'register_success' => '가입했습니다! 이제 로그인할 수 있습니다.',
|
'register_success' => '가입했습니다! 이제 로그인할 수 있습니다.',
|
||||||
|
|
||||||
// Login auto-initiation
|
// Login auto-initiation
|
||||||
'auto_init_starting' => 'Attempting Login',
|
'auto_init_starting' => '로그인 시도 중',
|
||||||
'auto_init_starting_desc' => 'We\'re contacting your authentication system to start the login process. If there\'s no progress after 5 seconds you can try clicking the link below.',
|
'auto_init_starting_desc' => '로그인을 시작하기 위해 인증 시스템에 접근 중입니다. 5초 후에도 아무런 반응이 없다면 아래 링크를 클릭하세요.',
|
||||||
'auto_init_start_link' => 'Proceed with authentication',
|
'auto_init_start_link' => '인증 진행',
|
||||||
|
|
||||||
// Password Reset
|
// Password Reset
|
||||||
'reset_password' => '패스워드 바꾸기',
|
'reset_password' => '패스워드 바꾸기',
|
||||||
|
|
|
@ -19,7 +19,7 @@ return [
|
||||||
'description' => '설명',
|
'description' => '설명',
|
||||||
'role' => '권한',
|
'role' => '권한',
|
||||||
'cover_image' => '대표 이미지',
|
'cover_image' => '대표 이미지',
|
||||||
'cover_image_description' => '이미지 규격은 440x250px 내외입니다.',
|
'cover_image_description' => '이미지 크기는 440x250px 내외입니다.',
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
'actions' => '활동',
|
'actions' => '활동',
|
||||||
|
@ -47,8 +47,8 @@ return [
|
||||||
'previous' => '이전',
|
'previous' => '이전',
|
||||||
'filter_active' => '적용 중:',
|
'filter_active' => '적용 중:',
|
||||||
'filter_clear' => '모든 필터 해제',
|
'filter_clear' => '모든 필터 해제',
|
||||||
'download' => 'Download',
|
'download' => '내려받기',
|
||||||
'open_in_tab' => 'Open in Tab',
|
'open_in_tab' => '탭에서 열기',
|
||||||
|
|
||||||
// Sort Options
|
// Sort Options
|
||||||
'sort_options' => '정렬 기준',
|
'sort_options' => '정렬 기준',
|
||||||
|
|
|
@ -7,58 +7,58 @@
|
||||||
*/
|
*/
|
||||||
return [
|
return [
|
||||||
// General editor terms
|
// General editor terms
|
||||||
'general' => 'General',
|
'general' => '일반',
|
||||||
'advanced' => 'Advanced',
|
'advanced' => '고급',
|
||||||
'none' => 'None',
|
'none' => '없음',
|
||||||
'cancel' => 'Cancel',
|
'cancel' => '취소',
|
||||||
'save' => 'Save',
|
'save' => '저장',
|
||||||
'close' => 'Close',
|
'close' => '닫기',
|
||||||
'undo' => 'Undo',
|
'undo' => '되돌리기',
|
||||||
'redo' => 'Redo',
|
'redo' => '다시 실행',
|
||||||
'left' => 'Left',
|
'left' => '왼쪽',
|
||||||
'center' => 'Center',
|
'center' => '가운데',
|
||||||
'right' => 'Right',
|
'right' => '오른쪽',
|
||||||
'top' => 'Top',
|
'top' => '위',
|
||||||
'middle' => 'Middle',
|
'middle' => '가운데',
|
||||||
'bottom' => 'Bottom',
|
'bottom' => '아래',
|
||||||
'width' => 'Width',
|
'width' => '너비',
|
||||||
'height' => 'Height',
|
'height' => '높이',
|
||||||
'More' => 'More',
|
'More' => '더 보기',
|
||||||
'select' => 'Select...',
|
'select' => '선택...',
|
||||||
|
|
||||||
// Toolbar
|
// Toolbar
|
||||||
'formats' => 'Formats',
|
'formats' => '형식',
|
||||||
'header_large' => 'Large Header',
|
'header_large' => '큰 제목',
|
||||||
'header_medium' => 'Medium Header',
|
'header_medium' => '중간 제목',
|
||||||
'header_small' => 'Small Header',
|
'header_small' => '작은 제목',
|
||||||
'header_tiny' => 'Tiny Header',
|
'header_tiny' => '가장 작은 제목',
|
||||||
'paragraph' => 'Paragraph',
|
'paragraph' => '단락',
|
||||||
'blockquote' => 'Blockquote',
|
'blockquote' => '인용',
|
||||||
'inline_code' => 'Inline code',
|
'inline_code' => '인라인 코드',
|
||||||
'callouts' => 'Callouts',
|
'callouts' => '범례',
|
||||||
'callout_information' => 'Information',
|
'callout_information' => '정보',
|
||||||
'callout_success' => 'Success',
|
'callout_success' => '성공',
|
||||||
'callout_warning' => 'Warning',
|
'callout_warning' => '경고',
|
||||||
'callout_danger' => 'Danger',
|
'callout_danger' => '위험',
|
||||||
'bold' => 'Bold',
|
'bold' => '굵게',
|
||||||
'italic' => 'Italic',
|
'italic' => '기울임',
|
||||||
'underline' => 'Underline',
|
'underline' => '밑줄',
|
||||||
'strikethrough' => 'Strikethrough',
|
'strikethrough' => '취소선',
|
||||||
'superscript' => 'Superscript',
|
'superscript' => '윗첨자',
|
||||||
'subscript' => 'Subscript',
|
'subscript' => '아랫첨자',
|
||||||
'text_color' => 'Text color',
|
'text_color' => '글자 색상',
|
||||||
'custom_color' => 'Custom color',
|
'custom_color' => '사용자 지정 색상',
|
||||||
'remove_color' => 'Remove color',
|
'remove_color' => '색상 제거',
|
||||||
'background_color' => 'Background color',
|
'background_color' => '배경 색상',
|
||||||
'align_left' => 'Align left',
|
'align_left' => '왼쪽 정렬',
|
||||||
'align_center' => 'Align center',
|
'align_center' => '가운데 정렬',
|
||||||
'align_right' => 'Align right',
|
'align_right' => '오른쪽 정렬',
|
||||||
'align_justify' => 'Justify',
|
'align_justify' => '양쪽 맞춤',
|
||||||
'list_bullet' => 'Bullet list',
|
'list_bullet' => '글머리 기호 목록',
|
||||||
'list_numbered' => 'Numbered list',
|
'list_numbered' => '번호 매기기 목록',
|
||||||
'list_task' => 'Task list',
|
'list_task' => '작업 목록',
|
||||||
'indent_increase' => 'Increase indent',
|
'indent_increase' => '들여쓰기 증가',
|
||||||
'indent_decrease' => 'Decrease indent',
|
'indent_decrease' => '들여쓰기 감소',
|
||||||
'table' => 'Table',
|
'table' => 'Table',
|
||||||
'insert_image' => 'Insert image',
|
'insert_image' => 'Insert image',
|
||||||
'insert_image_title' => 'Insert/Edit Image',
|
'insert_image_title' => 'Insert/Edit Image',
|
||||||
|
@ -111,59 +111,59 @@ return [
|
||||||
'paste_row_before' => 'Paste row before',
|
'paste_row_before' => 'Paste row before',
|
||||||
'paste_row_after' => 'Paste row after',
|
'paste_row_after' => 'Paste row after',
|
||||||
'row_type' => 'Row type',
|
'row_type' => 'Row type',
|
||||||
'row_type_header' => 'Header',
|
'row_type_header' => '머리글',
|
||||||
'row_type_body' => 'Body',
|
'row_type_body' => '본문',
|
||||||
'row_type_footer' => 'Footer',
|
'row_type_footer' => '바닥글',
|
||||||
'alignment' => 'Alignment',
|
'alignment' => '정렬',
|
||||||
'cut_column' => 'Cut column',
|
'cut_column' => '열 잘라내기',
|
||||||
'copy_column' => 'Copy column',
|
'copy_column' => '열 복사',
|
||||||
'paste_column_before' => 'Paste column before',
|
'paste_column_before' => '열 앞에 붙여넣기',
|
||||||
'paste_column_after' => 'Paste column after',
|
'paste_column_after' => '열 뒤에 붙여넣기',
|
||||||
'cell_padding' => 'Cell padding',
|
'cell_padding' => '셀 패딩',
|
||||||
'cell_spacing' => 'Cell spacing',
|
'cell_spacing' => '셀 간격',
|
||||||
'caption' => 'Caption',
|
'caption' => '캡션',
|
||||||
'show_caption' => 'Show caption',
|
'show_caption' => '캡션 보기',
|
||||||
'constrain' => 'Constrain proportions',
|
'constrain' => '비율 유지',
|
||||||
'cell_border_solid' => 'Solid',
|
'cell_border_solid' => '단색',
|
||||||
'cell_border_dotted' => 'Dotted',
|
'cell_border_dotted' => '점선',
|
||||||
'cell_border_dashed' => 'Dashed',
|
'cell_border_dashed' => '파선',
|
||||||
'cell_border_double' => 'Double',
|
'cell_border_double' => '겹선',
|
||||||
'cell_border_groove' => 'Groove',
|
'cell_border_groove' => 'Groove',
|
||||||
'cell_border_ridge' => 'Ridge',
|
'cell_border_ridge' => 'Ridge',
|
||||||
'cell_border_inset' => 'Inset',
|
'cell_border_inset' => 'Inset',
|
||||||
'cell_border_outset' => 'Outset',
|
'cell_border_outset' => 'Outset',
|
||||||
'cell_border_none' => 'None',
|
'cell_border_none' => '없음',
|
||||||
'cell_border_hidden' => 'Hidden',
|
'cell_border_hidden' => '숨김',
|
||||||
|
|
||||||
// Images, links, details/summary & embed
|
// Images, links, details/summary & embed
|
||||||
'source' => 'Source',
|
'source' => '원본',
|
||||||
'alt_desc' => 'Alternative description',
|
'alt_desc' => '대체 설명',
|
||||||
'embed' => 'Embed',
|
'embed' => 'Embed',
|
||||||
'paste_embed' => 'Paste your embed code below:',
|
'paste_embed' => 'Paste your embed code below:',
|
||||||
'url' => 'URL',
|
'url' => 'URL',
|
||||||
'text_to_display' => 'Text to display',
|
'text_to_display' => '표시할 텍스트',
|
||||||
'title' => 'Title',
|
'title' => '제목',
|
||||||
'open_link' => 'Open link in...',
|
'open_link' => '링크 열기...',
|
||||||
'open_link_current' => 'Current window',
|
'open_link_current' => '현재 창',
|
||||||
'open_link_new' => 'New window',
|
'open_link_new' => '새 창',
|
||||||
'insert_collapsible' => 'Insert collapsible block',
|
'insert_collapsible' => 'Insert collapsible block',
|
||||||
'collapsible_unwrap' => 'Unwrap',
|
'collapsible_unwrap' => 'Unwrap',
|
||||||
'edit_label' => 'Edit label',
|
'edit_label' => '레이블 수정',
|
||||||
'toggle_open_closed' => 'Toggle open/closed',
|
'toggle_open_closed' => '열림/닫힘 전환',
|
||||||
'collapsible_edit' => 'Edit collapsible block',
|
'collapsible_edit' => 'Edit collapsible block',
|
||||||
'toggle_label' => 'Toggle label',
|
'toggle_label' => '레이블 보이기/숨기기',
|
||||||
|
|
||||||
// About view
|
// About view
|
||||||
'about' => 'About the editor',
|
'about' => 'About the editor',
|
||||||
'about_title' => 'About the WYSIWYG Editor',
|
'about_title' => 'WYSIWYG 편집기에 대하여',
|
||||||
'editor_license' => 'Editor License & Copyright',
|
'editor_license' => '편집기 라이선스 & 저작권',
|
||||||
'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under the MIT license.',
|
'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under the MIT license.',
|
||||||
'editor_tiny_license_link' => 'The copyright and license details of TinyMCE can be found here.',
|
'editor_tiny_license_link' => 'The copyright and license details of TinyMCE can be found here.',
|
||||||
'save_continue' => 'Save Page & Continue',
|
'save_continue' => '저장하고 계속하기',
|
||||||
'callouts_cycle' => '(Keep pressing to toggle through types)',
|
'callouts_cycle' => '(Keep pressing to toggle through types)',
|
||||||
'link_selector' => 'Link to content',
|
'link_selector' => 'Link to content',
|
||||||
'shortcuts' => 'Shortcuts',
|
'shortcuts' => '단축키',
|
||||||
'shortcut' => 'Shortcut',
|
'shortcut' => '단축키',
|
||||||
'shortcuts_intro' => 'The following shortcuts are available in the editor:',
|
'shortcuts_intro' => 'The following shortcuts are available in the editor:',
|
||||||
'windows_linux' => '(Windows/Linux)',
|
'windows_linux' => '(Windows/Linux)',
|
||||||
'mac' => '(Mac)',
|
'mac' => '(Mac)',
|
||||||
|
|
|
@ -24,7 +24,7 @@ return [
|
||||||
'meta_updated_name' => '수정함 :timeLength, :user',
|
'meta_updated_name' => '수정함 :timeLength, :user',
|
||||||
'meta_owned_name' => '소유함 :user',
|
'meta_owned_name' => '소유함 :user',
|
||||||
'entity_select' => '항목 선택',
|
'entity_select' => '항목 선택',
|
||||||
'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item',
|
'entity_select_lack_permission' => '이 항목을 선택하기 위해 필요한 권한이 없습니다',
|
||||||
'images' => '이미지',
|
'images' => '이미지',
|
||||||
'my_recent_drafts' => '내 최근의 초안 문서',
|
'my_recent_drafts' => '내 최근의 초안 문서',
|
||||||
'my_recently_viewed' => '내가 읽은 문서',
|
'my_recently_viewed' => '내가 읽은 문서',
|
||||||
|
@ -88,7 +88,7 @@ return [
|
||||||
'shelves_save' => '저장',
|
'shelves_save' => '저장',
|
||||||
'shelves_books' => '이 책꽂이에 있는 책들',
|
'shelves_books' => '이 책꽂이에 있는 책들',
|
||||||
'shelves_add_books' => '이 책꽂이에 책 추가',
|
'shelves_add_books' => '이 책꽂이에 책 추가',
|
||||||
'shelves_drag_books' => 'Drag books below to add them to this shelf',
|
'shelves_drag_books' => '책을 이 책장에 추가하려면 아래로 드래그하세요',
|
||||||
'shelves_empty_contents' => '이 책꽂이에 책이 없습니다.',
|
'shelves_empty_contents' => '이 책꽂이에 책이 없습니다.',
|
||||||
'shelves_edit_and_assign' => '책꽂이 바꾸기로 책을 추가하세요.',
|
'shelves_edit_and_assign' => '책꽂이 바꾸기로 책을 추가하세요.',
|
||||||
'shelves_edit_named' => ':name 바꾸기',
|
'shelves_edit_named' => ':name 바꾸기',
|
||||||
|
@ -171,7 +171,7 @@ return [
|
||||||
'chapters_permissions_active' => '문서 권한 허용함',
|
'chapters_permissions_active' => '문서 권한 허용함',
|
||||||
'chapters_permissions_success' => '권한 저장함',
|
'chapters_permissions_success' => '권한 저장함',
|
||||||
'chapters_search_this' => '이 챕터에서 검색',
|
'chapters_search_this' => '이 챕터에서 검색',
|
||||||
'chapter_sort_book' => 'Sort Book',
|
'chapter_sort_book' => '책 정렬하기',
|
||||||
|
|
||||||
// Pages
|
// Pages
|
||||||
'page' => '문서',
|
'page' => '문서',
|
||||||
|
@ -198,16 +198,16 @@ return [
|
||||||
'pages_edit_draft_save_at' => '보관함: ',
|
'pages_edit_draft_save_at' => '보관함: ',
|
||||||
'pages_edit_delete_draft' => '초안 삭제',
|
'pages_edit_delete_draft' => '초안 삭제',
|
||||||
'pages_edit_discard_draft' => '폐기',
|
'pages_edit_discard_draft' => '폐기',
|
||||||
'pages_edit_switch_to_markdown' => 'Switch to Markdown Editor',
|
'pages_edit_switch_to_markdown' => '마크다운 편집기로 전환',
|
||||||
'pages_edit_switch_to_markdown_clean' => '(Clean Content)',
|
'pages_edit_switch_to_markdown_clean' => '(Clean Content)',
|
||||||
'pages_edit_switch_to_markdown_stable' => '(Stable Content)',
|
'pages_edit_switch_to_markdown_stable' => '(Stable Content)',
|
||||||
'pages_edit_switch_to_wysiwyg' => 'Switch to WYSIWYG Editor',
|
'pages_edit_switch_to_wysiwyg' => 'WYSIWYG 편집기로 전환',
|
||||||
'pages_edit_set_changelog' => '수정본 설명',
|
'pages_edit_set_changelog' => '수정본 설명',
|
||||||
'pages_edit_enter_changelog_desc' => '수정본 설명',
|
'pages_edit_enter_changelog_desc' => '수정본 설명',
|
||||||
'pages_edit_enter_changelog' => '설명',
|
'pages_edit_enter_changelog' => '설명',
|
||||||
'pages_editor_switch_title' => 'Switch Editor',
|
'pages_editor_switch_title' => '편집기 전환',
|
||||||
'pages_editor_switch_are_you_sure' => 'Are you sure you want to change the editor for this page?',
|
'pages_editor_switch_are_you_sure' => '이 페이지의 편집기를 변경하시겠어요?',
|
||||||
'pages_editor_switch_consider_following' => 'Consider the following when changing editors:',
|
'pages_editor_switch_consider_following' => '편집기를 전환할 때에 다음 사항들을 고려하세요:',
|
||||||
'pages_editor_switch_consideration_a' => 'Once saved, the new editor option will be used by any future editors, including those that may not be able to change editor type themselves.',
|
'pages_editor_switch_consideration_a' => 'Once saved, the new editor option will be used by any future editors, including those that may not be able to change editor type themselves.',
|
||||||
'pages_editor_switch_consideration_b' => 'This can potentially lead to a loss of detail and syntax in certain circumstances.',
|
'pages_editor_switch_consideration_b' => 'This can potentially lead to a loss of detail and syntax in certain circumstances.',
|
||||||
'pages_editor_switch_consideration_c' => 'Tag or changelog changes, made since last save, won\'t persist across this change.',
|
'pages_editor_switch_consideration_c' => 'Tag or changelog changes, made since last save, won\'t persist across this change.',
|
||||||
|
@ -237,7 +237,7 @@ return [
|
||||||
'pages_revisions_number' => 'No.',
|
'pages_revisions_number' => 'No.',
|
||||||
'pages_revisions_numbered' => '수정본 :id',
|
'pages_revisions_numbered' => '수정본 :id',
|
||||||
'pages_revisions_numbered_changes' => '수정본 :id에서 바꾼 부분',
|
'pages_revisions_numbered_changes' => '수정본 :id에서 바꾼 부분',
|
||||||
'pages_revisions_editor' => 'Editor Type',
|
'pages_revisions_editor' => '편집기 유형',
|
||||||
'pages_revisions_changelog' => '설명',
|
'pages_revisions_changelog' => '설명',
|
||||||
'pages_revisions_changes' => '바꾼 부분',
|
'pages_revisions_changes' => '바꾼 부분',
|
||||||
'pages_revisions_current' => '현재 판본',
|
'pages_revisions_current' => '현재 판본',
|
||||||
|
@ -359,14 +359,14 @@ return [
|
||||||
'copy_consider_access' => '경로, 소유자, 권한이 바뀌면 이 문서를 본 적 없는 사용자가 볼 수도 있습니다.',
|
'copy_consider_access' => '경로, 소유자, 권한이 바뀌면 이 문서를 본 적 없는 사용자가 볼 수도 있습니다.',
|
||||||
|
|
||||||
// Conversions
|
// Conversions
|
||||||
'convert_to_shelf' => 'Convert to Shelf',
|
'convert_to_shelf' => '책장으로 변환',
|
||||||
'convert_to_shelf_contents_desc' => 'You can convert this book to a new shelf with the same contents. Chapters contained within this book will be converted to new books. If this book contains any pages, that are not in a chapter, this book will be renamed and contain such pages, and this book will become part of the new shelf.',
|
'convert_to_shelf_contents_desc' => 'You can convert this book to a new shelf with the same contents. Chapters contained within this book will be converted to new books. If this book contains any pages, that are not in a chapter, this book will be renamed and contain such pages, and this book will become part of the new shelf.',
|
||||||
'convert_to_shelf_permissions_desc' => 'Any permissions set on this book will be copied to the new shelf and to all new child books that don\'t have their own permissions enforced. Note that permissions on shelves do not auto-cascade to content within, as they do for books.',
|
'convert_to_shelf_permissions_desc' => 'Any permissions set on this book will be copied to the new shelf and to all new child books that don\'t have their own permissions enforced. Note that permissions on shelves do not auto-cascade to content within, as they do for books.',
|
||||||
'convert_book' => 'Convert Book',
|
'convert_book' => '책 변환',
|
||||||
'convert_book_confirm' => 'Are you sure you want to convert this book?',
|
'convert_book_confirm' => '이 책을 변환하시겠어요?',
|
||||||
'convert_undo_warning' => 'This cannot be as easily undone.',
|
'convert_undo_warning' => '이 작업은 되돌리기 어렵습니다.',
|
||||||
'convert_to_book' => 'Convert to Book',
|
'convert_to_book' => '책으로 변환',
|
||||||
'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.',
|
'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.',
|
||||||
'convert_chapter' => 'Convert Chapter',
|
'convert_chapter' => '챕터 변환',
|
||||||
'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?',
|
'convert_chapter_confirm' => '이 챕터를 변환하시겠어요?',
|
||||||
];
|
];
|
||||||
|
|
|
@ -87,7 +87,7 @@ return [
|
||||||
'404_page_not_found' => '404 Not Found',
|
'404_page_not_found' => '404 Not Found',
|
||||||
'sorry_page_not_found' => '문서를 못 찾았습니다.',
|
'sorry_page_not_found' => '문서를 못 찾았습니다.',
|
||||||
'sorry_page_not_found_permission_warning' => '문서를 볼 권한이 없습니다.',
|
'sorry_page_not_found_permission_warning' => '문서를 볼 권한이 없습니다.',
|
||||||
'image_not_found' => 'Image Not Found',
|
'image_not_found' => '이미지를 찾을 수 없습니다',
|
||||||
'image_not_found_subtitle' => '이미지를 못 찾았습니다.',
|
'image_not_found_subtitle' => '이미지를 못 찾았습니다.',
|
||||||
'image_not_found_details' => '이미지가 지워졌을 수 있습니다.',
|
'image_not_found_details' => '이미지가 지워졌을 수 있습니다.',
|
||||||
'return_home' => '처음으로 돌아가기',
|
'return_home' => '처음으로 돌아가기',
|
||||||
|
|
|
@ -10,8 +10,8 @@ return [
|
||||||
'settings' => '설정',
|
'settings' => '설정',
|
||||||
'settings_save' => '적용',
|
'settings_save' => '적용',
|
||||||
'settings_save_success' => '설정 적용함',
|
'settings_save_success' => '설정 적용함',
|
||||||
'system_version' => 'System Version',
|
'system_version' => '시스템 버전',
|
||||||
'categories' => 'Categories',
|
'categories' => '카테고리',
|
||||||
|
|
||||||
// App Settings
|
// App Settings
|
||||||
'app_customization' => '맞춤',
|
'app_customization' => '맞춤',
|
||||||
|
@ -27,8 +27,8 @@ return [
|
||||||
'app_secure_images' => '이미지 주소 보호',
|
'app_secure_images' => '이미지 주소 보호',
|
||||||
'app_secure_images_toggle' => '이미지 주소 보호',
|
'app_secure_images_toggle' => '이미지 주소 보호',
|
||||||
'app_secure_images_desc' => '성능상의 문제로 이미지에 누구나 접근할 수 있기 때문에 이미지 주소를 무작위한 문자로 구성합니다. 폴더 색인을 끄세요.',
|
'app_secure_images_desc' => '성능상의 문제로 이미지에 누구나 접근할 수 있기 때문에 이미지 주소를 무작위한 문자로 구성합니다. 폴더 색인을 끄세요.',
|
||||||
'app_default_editor' => 'Default Page Editor',
|
'app_default_editor' => '기본 페이지 편집기',
|
||||||
'app_default_editor_desc' => 'Select which editor will be used by default when editing new pages. This can be overridden at a page level where permissions allow.',
|
'app_default_editor_desc' => '새 페이지를 편집할 때 기본으로 사용될 편집기를 선택합니다. 권한을 갖고 있다면 페이지마다 다르게 적용될 수 있습니다.',
|
||||||
'app_custom_html' => '헤드 작성',
|
'app_custom_html' => '헤드 작성',
|
||||||
'app_custom_html_desc' => '설정 페이지를 제외한 모든 페이지 head 태그 끝머리에 추가합니다.',
|
'app_custom_html_desc' => '설정 페이지를 제외한 모든 페이지 head 태그 끝머리에 추가합니다.',
|
||||||
'app_custom_html_disabled_notice' => '문제가 생겨도 설정 페이지에서 되돌릴 수 있어요.',
|
'app_custom_html_disabled_notice' => '문제가 생겨도 설정 페이지에서 되돌릴 수 있어요.',
|
||||||
|
@ -152,7 +152,7 @@ return [
|
||||||
'role_access_api' => '시스템 접근 API',
|
'role_access_api' => '시스템 접근 API',
|
||||||
'role_manage_settings' => '사이트 설정 관리',
|
'role_manage_settings' => '사이트 설정 관리',
|
||||||
'role_export_content' => '항목 내보내기',
|
'role_export_content' => '항목 내보내기',
|
||||||
'role_editor_change' => 'Change page editor',
|
'role_editor_change' => '페이지 편집기 변경',
|
||||||
'role_asset' => '권한 항목',
|
'role_asset' => '권한 항목',
|
||||||
'roles_system_warning' => '위 세 권한은 자신의 권한이나 다른 유저의 권한을 바꿀 수 있습니다.',
|
'roles_system_warning' => '위 세 권한은 자신의 권한이나 다른 유저의 권한을 바꿀 수 있습니다.',
|
||||||
'role_asset_desc' => '책, 챕터, 문서별 권한은 이 설정에 우선합니다.',
|
'role_asset_desc' => '책, 챕터, 문서별 권한은 이 설정에 우선합니다.',
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
<div class="mb-xs"><a href="#listing-endpoints">Listing Endpoints</a></div>
|
<div class="mb-xs"><a href="#listing-endpoints">Listing Endpoints</a></div>
|
||||||
<div class="mb-xs"><a href="#error-handling">Error Handling</a></div>
|
<div class="mb-xs"><a href="#error-handling">Error Handling</a></div>
|
||||||
<div class="mb-xs"><a href="#rate-limits">Rate Limits</a></div>
|
<div class="mb-xs"><a href="#rate-limits">Rate Limits</a></div>
|
||||||
|
<div class="mb-xs"><a href="#content-security">Content Security</a></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@foreach($docs as $model => $endpoints)
|
@foreach($docs as $model => $endpoints)
|
||||||
|
|
|
@ -179,4 +179,20 @@ API_REQUESTS_PER_MIN=180</code></pre>
|
||||||
It's generally good practice to limit requests made from your API client, where possible, to avoid
|
It's generally good practice to limit requests made from your API client, where possible, to avoid
|
||||||
affecting normal use of the system caused by over-consuming system resources.
|
affecting normal use of the system caused by over-consuming system resources.
|
||||||
Keep in mind there may be other rate-limiting factors such as web-server & firewall controls.
|
Keep in mind there may be other rate-limiting factors such as web-server & firewall controls.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h5 id="content-security" class="text-mono mb-m">Content Security</h5>
|
||||||
|
<p>
|
||||||
|
Many of the available endpoints will return content that has been provided by user input.
|
||||||
|
Some of this content may be provided in a certain data-format (Such as HTML or Markdown for page content).
|
||||||
|
Such content is not guaranteed to be safe so keep security in mind when dealing with such user-input.
|
||||||
|
In some cases, the system will apply some filtering to content in an attempt to prevent certain vulnerabilities, but
|
||||||
|
this is not assured to be a bullet-proof defence.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Within its own interfaces, unless disabled, the system makes use of Content Security Policy (CSP) rules to heavily negate
|
||||||
|
cross-site scripting vulnerabilities from user content. If displaying user content externally, it's advised you
|
||||||
|
also use defences such as CSP or the disabling of JavaScript completely.
|
||||||
</p>
|
</p>
|
|
@ -0,0 +1,69 @@
|
||||||
|
<tr>
|
||||||
|
<td>{{ $revision->revision_number == 0 ? '' : $revision->revision_number }}</td>
|
||||||
|
<td>
|
||||||
|
{{ $revision->name }}
|
||||||
|
<br>
|
||||||
|
<small class="text-muted">({{ $revision->is_markdown ? 'Markdown' : 'WYSIWYG' }})</small>
|
||||||
|
</td>
|
||||||
|
<td style="line-height: 0;" width="30">
|
||||||
|
@if($revision->createdBy)
|
||||||
|
<img class="avatar" src="{{ $revision->createdBy->getAvatar(30) }}" alt="{{ $revision->createdBy->name }}">
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td width="260">
|
||||||
|
@if($revision->createdBy) {{ $revision->createdBy->name }} @else {{ trans('common.deleted_user') }} @endif
|
||||||
|
<br>
|
||||||
|
<div class="text-muted">
|
||||||
|
<small>{{ $revision->created_at->formatLocalized('%e %B %Y %H:%M:%S') }}</small>
|
||||||
|
<small>({{ $revision->created_at->diffForHumans() }})</small>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ $revision->summary }}
|
||||||
|
</td>
|
||||||
|
<td class="actions text-small text-right">
|
||||||
|
<a href="{{ $revision->getUrl('changes') }}" target="_blank" rel="noopener">{{ trans('entities.pages_revisions_changes') }}</a>
|
||||||
|
<span class="text-muted"> | </span>
|
||||||
|
|
||||||
|
|
||||||
|
@if ($index === 0)
|
||||||
|
<a target="_blank" rel="noopener" href="{{ $revision->page->getUrl() }}"><i>{{ trans('entities.pages_revisions_current') }}</i></a>
|
||||||
|
@else
|
||||||
|
<a href="{{ $revision->getUrl() }}" target="_blank" rel="noopener">{{ trans('entities.pages_revisions_preview') }}</a>
|
||||||
|
<span class="text-muted"> | </span>
|
||||||
|
<div component="dropdown" class="dropdown-container">
|
||||||
|
<a refs="dropdown@toggle" href="#" aria-haspopup="true" aria-expanded="false">{{ trans('entities.pages_revisions_restore') }}</a>
|
||||||
|
<ul refs="dropdown@menu" class="dropdown-menu" role="menu">
|
||||||
|
<li class="px-m py-s"><small class="text-muted">{{trans('entities.revision_restore_confirm')}}</small></li>
|
||||||
|
<li>
|
||||||
|
<form action="{{ $revision->getUrl('/restore') }}" method="POST">
|
||||||
|
{!! csrf_field() !!}
|
||||||
|
<input type="hidden" name="_method" value="PUT">
|
||||||
|
<button type="submit" class="text-primary icon-item">
|
||||||
|
@icon('history')
|
||||||
|
<div>{{ trans('entities.pages_revisions_restore') }}</div>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<span class="text-muted"> | </span>
|
||||||
|
<div component="dropdown" class="dropdown-container">
|
||||||
|
<a refs="dropdown@toggle" href="#" aria-haspopup="true" aria-expanded="false">{{ trans('common.delete') }}</a>
|
||||||
|
<ul refs="dropdown@menu" class="dropdown-menu" role="menu">
|
||||||
|
<li class="px-m py-s"><small class="text-muted">{{trans('entities.revision_delete_confirm')}}</small></li>
|
||||||
|
<li>
|
||||||
|
<form action="{{ $revision->getUrl('/delete/') }}" method="POST">
|
||||||
|
{!! csrf_field() !!}
|
||||||
|
<input type="hidden" name="_method" value="DELETE">
|
||||||
|
<button type="submit" class="text-neg icon-item">
|
||||||
|
@icon('delete')
|
||||||
|
<div>{{ trans('common.delete') }}</div>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
</tr>
|
|
@ -17,11 +17,11 @@
|
||||||
|
|
||||||
<main class="card content-wrap">
|
<main class="card content-wrap">
|
||||||
<h1 class="list-heading">{{ trans('entities.pages_revisions') }}</h1>
|
<h1 class="list-heading">{{ trans('entities.pages_revisions') }}</h1>
|
||||||
@if(count($page->revisions) > 0)
|
@if(count($revisions) > 0)
|
||||||
|
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<tr>
|
<tr>
|
||||||
<th width="40">{{ trans('entities.pages_revisions_number') }}</th>
|
<th width="56">{{ trans('entities.pages_revisions_number') }}</th>
|
||||||
<th>
|
<th>
|
||||||
{{ trans('entities.pages_name') }} / {{ trans('entities.pages_revisions_editor') }}
|
{{ trans('entities.pages_name') }} / {{ trans('entities.pages_revisions_editor') }}
|
||||||
</th>
|
</th>
|
||||||
|
@ -29,76 +29,8 @@
|
||||||
<th>{{ trans('entities.pages_revisions_changelog') }}</th>
|
<th>{{ trans('entities.pages_revisions_changelog') }}</th>
|
||||||
<th class="text-right">{{ trans('common.actions') }}</th>
|
<th class="text-right">{{ trans('common.actions') }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
@foreach($page->revisions as $index => $revision)
|
@foreach($revisions as $index => $revision)
|
||||||
<tr>
|
@include('pages.parts.revision-table-row', ['revision' => $revision])
|
||||||
<td>{{ $revision->revision_number == 0 ? '' : $revision->revision_number }}</td>
|
|
||||||
<td>
|
|
||||||
{{ $revision->name }}
|
|
||||||
<br>
|
|
||||||
<small class="text-muted">({{ $revision->markdown ? 'Markdown' : 'WYSIWYG' }})</small>
|
|
||||||
</td>
|
|
||||||
<td style="line-height: 0;" width="30">
|
|
||||||
@if($revision->createdBy)
|
|
||||||
<img class="avatar" src="{{ $revision->createdBy->getAvatar(30) }}" alt="{{ $revision->createdBy->name }}">
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
<td width="260">
|
|
||||||
@if($revision->createdBy) {{ $revision->createdBy->name }} @else {{ trans('common.deleted_user') }} @endif
|
|
||||||
<br>
|
|
||||||
<div class="text-muted">
|
|
||||||
<small>{{ $revision->created_at->formatLocalized('%e %B %Y %H:%M:%S') }}</small>
|
|
||||||
<small>({{ $revision->created_at->diffForHumans() }})</small>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ $revision->summary }}
|
|
||||||
</td>
|
|
||||||
<td class="actions text-small text-right">
|
|
||||||
<a href="{{ $revision->getUrl('changes') }}" target="_blank" rel="noopener">{{ trans('entities.pages_revisions_changes') }}</a>
|
|
||||||
<span class="text-muted"> | </span>
|
|
||||||
|
|
||||||
|
|
||||||
@if ($index === 0)
|
|
||||||
<a target="_blank" rel="noopener" href="{{ $page->getUrl() }}"><i>{{ trans('entities.pages_revisions_current') }}</i></a>
|
|
||||||
@else
|
|
||||||
<a href="{{ $revision->getUrl() }}" target="_blank" rel="noopener">{{ trans('entities.pages_revisions_preview') }}</a>
|
|
||||||
<span class="text-muted"> | </span>
|
|
||||||
<div component="dropdown" class="dropdown-container">
|
|
||||||
<a refs="dropdown@toggle" href="#" aria-haspopup="true" aria-expanded="false">{{ trans('entities.pages_revisions_restore') }}</a>
|
|
||||||
<ul refs="dropdown@menu" class="dropdown-menu" role="menu">
|
|
||||||
<li class="px-m py-s"><small class="text-muted">{{trans('entities.revision_restore_confirm')}}</small></li>
|
|
||||||
<li>
|
|
||||||
<form action="{{ $revision->getUrl('/restore') }}" method="POST">
|
|
||||||
{!! csrf_field() !!}
|
|
||||||
<input type="hidden" name="_method" value="PUT">
|
|
||||||
<button type="submit" class="text-primary icon-item">
|
|
||||||
@icon('history')
|
|
||||||
<div>{{ trans('entities.pages_revisions_restore') }}</div>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<span class="text-muted"> | </span>
|
|
||||||
<div component="dropdown" class="dropdown-container">
|
|
||||||
<a refs="dropdown@toggle" href="#" aria-haspopup="true" aria-expanded="false">{{ trans('common.delete') }}</a>
|
|
||||||
<ul refs="dropdown@menu" class="dropdown-menu" role="menu">
|
|
||||||
<li class="px-m py-s"><small class="text-muted">{{trans('entities.revision_delete_confirm')}}</small></li>
|
|
||||||
<li>
|
|
||||||
<form action="{{ $revision->getUrl('/delete/') }}" method="POST">
|
|
||||||
{!! csrf_field() !!}
|
|
||||||
<input type="hidden" name="_method" value="DELETE">
|
|
||||||
<button type="submit" class="text-neg icon-item">
|
|
||||||
@icon('delete')
|
|
||||||
<div>{{ trans('common.delete') }}</div>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
@endforeach
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
|
@ -325,11 +325,14 @@ class PageContentTest extends TestCase
|
||||||
$pageView->assertDontSee('abc123abc123');
|
$pageView->assertDontSee('abc123abc123');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_svg_xlink_hrefs_are_removed()
|
public function test_svg_script_usage_is_removed()
|
||||||
{
|
{
|
||||||
$checks = [
|
$checks = [
|
||||||
'<svg id="test" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100"><a xlink:href="javascript:alert(document.domain)"><rect x="0" y="0" width="100" height="100" /></a></svg>',
|
'<svg id="test" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100"><a xlink:href="javascript:alert(document.domain)"><rect x="0" y="0" width="100" height="100" /></a></svg>',
|
||||||
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><use xlink:href="data:application/xml;base64 ,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KPGRlZnM+CjxjaXJjbGUgaWQ9InRlc3QiIHI9IjAiIGN4PSIwIiBjeT0iMCIgc3R5bGU9ImZpbGw6ICNGMDAiPgo8c2V0IGF0dHJpYnV0ZU5hbWU9ImZpbGwiIGF0dHJpYnV0ZVR5cGU9IkNTUyIgb25iZWdpbj0nYWxlcnQoZG9jdW1lbnQuZG9tYWluKScKb25lbmQ9J2FsZXJ0KCJvbmVuZCIpJyB0bz0iIzAwRiIgYmVnaW49IjBzIiBkdXI9Ijk5OXMiIC8+CjwvY2lyY2xlPgo8L2RlZnM+Cjx1c2UgeGxpbms6aHJlZj0iI3Rlc3QiLz4KPC9zdmc+#test"/></svg>',
|
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><use xlink:href="data:application/xml;base64 ,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KPGRlZnM+CjxjaXJjbGUgaWQ9InRlc3QiIHI9IjAiIGN4PSIwIiBjeT0iMCIgc3R5bGU9ImZpbGw6ICNGMDAiPgo8c2V0IGF0dHJpYnV0ZU5hbWU9ImZpbGwiIGF0dHJpYnV0ZVR5cGU9IkNTUyIgb25iZWdpbj0nYWxlcnQoZG9jdW1lbnQuZG9tYWluKScKb25lbmQ9J2FsZXJ0KCJvbmVuZCIpJyB0bz0iIzAwRiIgYmVnaW49IjBzIiBkdXI9Ijk5OXMiIC8+CjwvY2lyY2xlPgo8L2RlZnM+Cjx1c2UgeGxpbms6aHJlZj0iI3Rlc3QiLz4KPC9zdmc+#test"/></svg>',
|
||||||
|
'<svg><animate href=#xss attributeName=href values=javascript:alert(1) /></svg>',
|
||||||
|
'<svg><animate href="#xss" attributeName="href" values="a;javascript:alert(1)" /></svg>',
|
||||||
|
'<svg><animate href="#xss" attributeName="href" values="a;data:alert(1)" /></svg>',
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->asEditor();
|
$this->asEditor();
|
||||||
|
@ -341,9 +344,11 @@ class PageContentTest extends TestCase
|
||||||
|
|
||||||
$pageView = $this->get($page->getUrl());
|
$pageView = $this->get($page->getUrl());
|
||||||
$pageView->assertStatus(200);
|
$pageView->assertStatus(200);
|
||||||
$this->withHtml($pageView)->assertElementNotContains('.page-content', 'alert');
|
$html = $this->withHtml($pageView);
|
||||||
$this->withHtml($pageView)->assertElementNotContains('.page-content', 'xlink:href');
|
$html->assertElementNotContains('.page-content', 'alert');
|
||||||
$this->withHtml($pageView)->assertElementNotContains('.page-content', 'application/xml');
|
$html->assertElementNotContains('.page-content', 'xlink:href');
|
||||||
|
$html->assertElementNotContains('.page-content', 'application/xml');
|
||||||
|
$html->assertElementNotContains('.page-content', 'javascript');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<?php
|
<?php namespace Tests;
|
||||||
|
|
||||||
use BookStack\Actions\Favourite;
|
use BookStack\Actions\Favourite;
|
||||||
|
use BookStack\Auth\User;
|
||||||
use BookStack\Entities\Models\Book;
|
use BookStack\Entities\Models\Book;
|
||||||
use BookStack\Entities\Models\Bookshelf;
|
use BookStack\Entities\Models\Bookshelf;
|
||||||
use BookStack\Entities\Models\Chapter;
|
use BookStack\Entities\Models\Chapter;
|
||||||
use BookStack\Entities\Models\Page;
|
use BookStack\Entities\Models\Page;
|
||||||
use Tests\TestCase;
|
|
||||||
|
|
||||||
class FavouriteTest extends TestCase
|
class FavouriteTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -58,6 +58,30 @@ class FavouriteTest extends TestCase
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_favourite_flow_with_own_permissions()
|
||||||
|
{
|
||||||
|
/** @var Book $book */
|
||||||
|
$book = Book::query()->first();
|
||||||
|
$user = User::factory()->create();
|
||||||
|
$book->owned_by = $user->id;
|
||||||
|
$book->save();
|
||||||
|
|
||||||
|
$this->giveUserPermissions($user, ['book-view-own']);
|
||||||
|
|
||||||
|
$this->actingAs($user)->get($book->getUrl());
|
||||||
|
$resp = $this->post('/favourites/add', [
|
||||||
|
'type' => get_class($book),
|
||||||
|
'id' => $book->id,
|
||||||
|
]);
|
||||||
|
$resp->assertRedirect($book->getUrl());
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('favourites', [
|
||||||
|
'user_id' => $user->id,
|
||||||
|
'favouritable_type' => $book->getMorphClass(),
|
||||||
|
'favouritable_id' => $book->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_book_chapter_shelf_pages_contain_favourite_button()
|
public function test_book_chapter_shelf_pages_contain_favourite_button()
|
||||||
{
|
{
|
||||||
$entities = [
|
$entities = [
|
||||||
|
|
Loading…
Reference in New Issue