1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-16 11:44:42 +02:00

Fix issue processwire/processwire-issues#183 allow for front-end editing of fields in repeater items, individually per-field by non-superusers with edit access to the page the owns the repeater field.

This commit is contained in:
Ryan Cramer
2019-03-01 11:36:52 -05:00
parent 731cc3e92e
commit 8952afbddb
2 changed files with 55 additions and 18 deletions

View File

@@ -119,29 +119,54 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
$template->set('pageClass', $class);
$template->save();
}
/** @var Page $page */
$page = $this->wire('page');
$process = $this->wire('page')->process;
/** @var Process|null $process */
$process = $page->process;
/** @var User $user */
$user = $this->wire('user');
if($process == 'ProcessPageEdit' || $process == 'ProcessProfile') {
/** @var Config $config */
$config = $this->wire('config');
/** @var WireInput $input */
$input = $this->wire('input');
$inEditor = $process == 'ProcessPageEdit' || $process == 'ProcessProfile';
$isSuperuser = $user->isSuperuser();
if($inEditor) {
// ProcessPageEdit or ProcessProfile
$this->addHookBefore('ProcessPageEdit::ajaxSave', $this, 'hookProcessPageEditAjaxSave');
if($this->wire('config')->ajax) {
// handle scenario of repeater within repeater field
$fieldName = $this->wire('input')->get('field');
$pageID = (int) $this->wire('input')->get('id');
if($pageID && strpos($fieldName, '_repeater') && preg_match('/^(.+)_repeater\d+$/', $fieldName, $matches)) {
$editPage = $this->wire('pages')->get($pageID);
if($editPage->id && strpos($editPage->template->name, self::templateNamePrefix) === 0) {
// update field name to exclude the _repeater1234 part at the end, so that PageEdit recognizes it
$this->wire('input')->get->field = $matches[1];
}
}
if($inEditor && $config->ajax) {
// handle scenario of repeater within repeater field
$fieldName = $input->get('field');
$pageID = (int) $input->get('id');
if($pageID && strpos($fieldName, '_repeater') && preg_match('/^(.+)_repeater\d+$/', $fieldName, $matches)) {
$editPage = $this->wire('pages')->get($pageID);
if($editPage->id && strpos($editPage->template->name, self::templateNamePrefix) === 0) {
// update field name to exclude the _repeater1234 part at the end, so that PageEdit recognizes it
$input->get->__set('field', $matches[1]);
}
}
if(!$this->wire('user')->isSuperuser()) {
$this->addHookAfter('PagePermissions::pageEditable', $this, 'hookPagePermissionsPageEditableAjax');
}
if(!$inEditor && !$user->isGuest() && !$isSuperuser && $user->hasPermission('page-edit')) {
// allow for front-end editor to also trigger an inEditor=true condition
if(strpos($page->url, $config->urls->admin) === false && $page->editable()) {
if($this->wire('modules')->isInstalled('PageFrontEdit')) $inEditor = true;
}
}
if($inEditor && !$isSuperuser) {
// need an extra hook to handle permissions
$this->addHookAfter('PagePermissions::pageEditable', $this, 'hookPagePermissionsPageEditableAjax');
}
$this->addHookBefore('PageFinder::getQuery', $this, 'hookPageFinderGetQuery');

View File

@@ -223,7 +223,17 @@ class PageFrontEdit extends WireData implements Module {
if(!$this->editorAllowed) return false;
if(!$this->inlineSupported($field)) return false;
// if(!in_array($field->id, $this->inlineEditFields) && $field->id != $this->inlineEditField) return false;
if(!$this->wire('user')->hasPermission('page-edit-front', $page)) return false;
/** @var User $user */
$user = $this->wire('user');
if($page->className() != 'Page' && wireInstanceOf($page, 'RepeaterPage')) {
/** @var RepeaterPage $page */
$forPage = $page->getForPage();
$forField = $page->getForField();
if(!$user->hasPermission('page-edit-front', $forPage)) return false;
if(!$forPage->editable($forField)) return false;
} else {
if(!$user->hasPermission('page-edit-front', $page)) return false;
}
if(!$page->editable($field)) return false;
return true;
}
@@ -964,7 +974,9 @@ class PageFrontEdit extends WireData implements Module {
} else {
// okay to make edits
try {
$this->wire('session')->CSRF->validate();
/** @var Session $session */
$session = $this->wire('session');
$session->CSRF->validate();
$data = $this->inlineProcessSaveEdits($fields, $data);
} catch(WireCSRFException $e) {
$data['error'] = "Failed CSRF check";