mirror of
https://github.com/processwire/processwire.git
synced 2025-08-12 17:54:44 +02:00
Fix issue processwire/processwire-issues#1561 - non-superuser when uploading image in repeater was producing a "no access" error
This commit is contained in:
@@ -33,7 +33,7 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
return array(
|
return array(
|
||||||
'title' => __('Repeater', __FILE__), // Module Title
|
'title' => __('Repeater', __FILE__), // Module Title
|
||||||
'summary' => __('Maintains a collection of fields that are repeated for any number of times.', __FILE__), // Module Summary
|
'summary' => __('Maintains a collection of fields that are repeated for any number of times.', __FILE__), // Module Summary
|
||||||
'version' => 111,
|
'version' => 112,
|
||||||
'autoload' => true,
|
'autoload' => true,
|
||||||
'installs' => 'InputfieldRepeater'
|
'installs' => 'InputfieldRepeater'
|
||||||
);
|
);
|
||||||
@@ -54,7 +54,7 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
const loadingOff = 2;
|
const loadingOff = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Field names used by repeaters in format [ PW_instanceNum => [ 'field_name', 'field_name2' ] ];
|
* Field names used by repeaters in format [ PW_instanceID => [ 'field_name', 'field_name2' ] ];
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*
|
*
|
||||||
@@ -62,7 +62,7 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
static protected $fieldsUsedInRepeaters = array();
|
static protected $fieldsUsedInRepeaters = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Template IDs used by repeaters in format [ PW_instanceNum => [ 123, 456, 789 ] ]
|
* Template IDs used by repeaters in format [ PW_instanceID => [ 123, 456, 789 ] ]
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*
|
*
|
||||||
@@ -70,13 +70,29 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
static protected $templatesUsedByRepeaters = array();
|
static protected $templatesUsedByRepeaters = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has ready method been called? [ PW_instanceNum => true | false ]
|
* Has ready method been called? [ PW_instanceID => true | false ]
|
||||||
*
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static protected $isReady = array();
|
static protected $isReady = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fields that are initialized [ PW_instanceID => [ 'field_id' => true ] ]
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static protected $initFields = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProcessWire instance ID
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $instanceID = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When non-zero, a deletePageField function call occurred and we shouldn't re-create any repeater parents
|
* When non-zero, a deletePageField function call occurred and we shouldn't re-create any repeater parents
|
||||||
*
|
*
|
||||||
@@ -117,6 +133,8 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
require_once(dirname(__FILE__) . '/RepeaterPageArray.php');
|
require_once(dirname(__FILE__) . '/RepeaterPageArray.php');
|
||||||
|
|
||||||
$this->set('repeatersRootPageID', 0);
|
$this->set('repeatersRootPageID', 0);
|
||||||
|
|
||||||
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,6 +142,8 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function init() {
|
public function init() {
|
||||||
|
$this->instanceID = $this->wire()->getProcessWireInstanceID();
|
||||||
|
self::$initFields[$this->instanceID] = array();
|
||||||
$this->wire()->pages->addHookAfter('deleteReady', $this, 'hookPagesDelete');
|
$this->wire()->pages->addHookAfter('deleteReady', $this, 'hookPagesDelete');
|
||||||
$this->useLazy = $this->wire()->config->useLazyLoading;
|
$this->useLazy = $this->wire()->config->useLazyLoading;
|
||||||
parent::init();
|
parent::init();
|
||||||
@@ -136,34 +156,21 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
public function ready() {
|
public function ready() {
|
||||||
parent::ready();
|
parent::ready();
|
||||||
|
|
||||||
$instanceNum = $this->wire()->getInstanceNum();
|
if(!empty(self::$isReady[$this->instanceID])) return; // ensures everything below only runs only once (for extending types)
|
||||||
if(!empty(self::$isReady[$instanceNum])) return; // ensures everything below only runs only once (for extending types)
|
self::$isReady[$this->instanceID] = true;
|
||||||
self::$isReady[$instanceNum] = true;
|
|
||||||
|
|
||||||
if(!$this->useLazy) {
|
|
||||||
// make sure that all templates used by repeater pages enforce a Page type of RepeaterPage
|
|
||||||
// this was necessary when lazy loading option was disabled
|
|
||||||
$this->useLazy = true;
|
|
||||||
$repeaterFields = $this->wire()->fields->findByType('FieldtypeRepeater', array(
|
|
||||||
'inherit' => true,
|
|
||||||
'valueType' => 'field',
|
|
||||||
'indexType' => '',
|
|
||||||
));
|
|
||||||
foreach($repeaterFields as $field) {
|
|
||||||
$this->initField($field);
|
|
||||||
}
|
|
||||||
$this->useLazy = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$page = $this->wire()->page;
|
$page = $this->wire()->page;
|
||||||
$process = $page->process; /** @var Process|null $process */
|
$process = $page->process; /** @var Process|null $process */
|
||||||
$user = $this->wire()->user;
|
$user = $this->wire()->user;
|
||||||
$config = $this->wire()->config;
|
$config = $this->wire()->config;
|
||||||
$input = $this->wire()->input;
|
$input = $this->wire()->input;
|
||||||
|
|
||||||
$inEditor = $process == 'ProcessPageEdit' || $process == 'ProcessProfile';
|
$inEditor = $process == 'ProcessPageEdit' || $process == 'ProcessProfile';
|
||||||
$isSuperuser = $user->isSuperuser();
|
$isSuperuser = $user->isSuperuser();
|
||||||
|
|
||||||
|
// make sure that all templates used by repeater pages enforce a Page type of RepeaterPage
|
||||||
|
// this was necessary when lazy loading option was disabled
|
||||||
|
if(!$this->useLazy) $this->initAllFields();
|
||||||
|
|
||||||
if($inEditor) {
|
if($inEditor) {
|
||||||
// ProcessPageEdit or ProcessProfile
|
// ProcessPageEdit or ProcessProfile
|
||||||
$this->addHookBefore('ProcessPageEdit::ajaxSave', $this, 'hookProcessPageEditAjaxSave');
|
$this->addHookBefore('ProcessPageEdit::ajaxSave', $this, 'hookProcessPageEditAjaxSave');
|
||||||
@@ -174,12 +181,18 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
$fieldName = (string) $input->get('field');
|
$fieldName = (string) $input->get('field');
|
||||||
$pageID = (int) $input->get('id');
|
$pageID = (int) $input->get('id');
|
||||||
if($pageID && strpos($fieldName, '_repeater') && preg_match('/^(.+)_repeater\d+$/', $fieldName, $matches)) {
|
if($pageID && strpos($fieldName, '_repeater') && preg_match('/^(.+)_repeater\d+$/', $fieldName, $matches)) {
|
||||||
|
$this->initAllFields();
|
||||||
$editPage = $this->wire()->pages->get($pageID);
|
$editPage = $this->wire()->pages->get($pageID);
|
||||||
if($editPage->id && strpos($editPage->template->name, self::templateNamePrefix) === 0) {
|
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
|
// update field name to exclude the _repeater1234 part at the end, so that PageEdit recognizes it
|
||||||
$input->get->__set('field', $matches[1]);
|
$input->get->__set('field', $this->wire()->sanitizer->fieldName($matches[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// handle scenario of file upload or other ajax saved field
|
||||||
|
if(isset($_SERVER['HTTP_X_FIELDNAME'])) {
|
||||||
|
// initialize all repeater fields so RepeaterPage class names are active for access control
|
||||||
|
if(strpos($_SERVER['HTTP_X_FIELDNAME'], '_repeater')) $this->initAllFields();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$inEditor && !$user->isGuest() && !$isSuperuser && $user->hasPermission('page-edit')) {
|
if(!$inEditor && !$user->isGuest() && !$isSuperuser && $user->hasPermission('page-edit')) {
|
||||||
@@ -207,8 +220,10 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function initField(Field $field) {
|
public function initField(Field $field) {
|
||||||
if(!$this->useLazy) return;
|
if(!empty(self::$initFields[$this->instanceID][$field->id])) return;
|
||||||
parent::initField($field);
|
parent::initField($field);
|
||||||
|
if(!$this->useLazy) return;
|
||||||
|
self::$initFields[$this->instanceID][$field->id] = true;
|
||||||
/** @var FieldtypeRepeater $fieldtype */
|
/** @var FieldtypeRepeater $fieldtype */
|
||||||
$fieldtype = $field->type;
|
$fieldtype = $field->type;
|
||||||
if(!$fieldtype instanceof FieldtypeRepeater) return;
|
if(!$fieldtype instanceof FieldtypeRepeater) return;
|
||||||
@@ -222,6 +237,29 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
$template->save();
|
$template->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force initialize of all repeater fields, confirming their configuration settings are correct
|
||||||
|
*
|
||||||
|
* @since 3.0.199
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function initAllFields() {
|
||||||
|
if(!empty(self::$initFields['*'])) return;
|
||||||
|
self::$initFields['*'] = true;
|
||||||
|
$repeaterFields = $this->wire()->fields->findByType('FieldtypeRepeater', array(
|
||||||
|
'inherit' => true,
|
||||||
|
'valueType' => 'field',
|
||||||
|
'indexType' => '',
|
||||||
|
));
|
||||||
|
$useLazy = $this->useLazy;
|
||||||
|
$this->useLazy = true;
|
||||||
|
foreach($repeaterFields as $field) {
|
||||||
|
$this->initField($field);
|
||||||
|
}
|
||||||
|
$this->useLazy = $useLazy;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get class name to use Field objects of this type (must be class that extends Field class)
|
* Get class name to use Field objects of this type (must be class that extends Field class)
|
||||||
*
|
*
|
||||||
@@ -342,10 +380,9 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
/** @var PageFinder $pageFinder */
|
/** @var PageFinder $pageFinder */
|
||||||
$pageFinder = $event->object;
|
$pageFinder = $event->object;
|
||||||
$pageFinderOptions = $pageFinder->getOptions();
|
$pageFinderOptions = $pageFinder->getOptions();
|
||||||
$instanceNum = $this->wire()->getInstanceNum();
|
|
||||||
|
|
||||||
// determine which fields are used in repeaters
|
// determine which fields are used in repeaters
|
||||||
if(!isset(self::$fieldsUsedInRepeaters[$instanceNum])) {
|
if(!isset(self::$fieldsUsedInRepeaters[$this->instanceID])) {
|
||||||
$fieldNames = array('title' => 'title'); // title used by admin template (repeater parents)
|
$fieldNames = array('title' => 'title'); // title used by admin template (repeater parents)
|
||||||
$templates = $this->wire()->templates;
|
$templates = $this->wire()->templates;
|
||||||
$templateIds = array();
|
$templateIds = array();
|
||||||
@@ -358,12 +395,12 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
$fieldNames[$fieldName] = $fieldName;
|
$fieldNames[$fieldName] = $fieldName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self::$fieldsUsedInRepeaters[$instanceNum] = array_values($fieldNames);
|
self::$fieldsUsedInRepeaters[$this->instanceID] = array_values($fieldNames);
|
||||||
self::$templatesUsedByRepeaters[$instanceNum] = array_values($templateIds);
|
self::$templatesUsedByRepeaters[$this->instanceID] = array_values($templateIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
$fieldsUsedInRepeaters = self::$fieldsUsedInRepeaters[$instanceNum];
|
$fieldsUsedInRepeaters = self::$fieldsUsedInRepeaters[$this->instanceID];
|
||||||
$templatesUsedByRepeaters = self::$templatesUsedByRepeaters[$instanceNum];
|
$templatesUsedByRepeaters = self::$templatesUsedByRepeaters[$this->instanceID];
|
||||||
|
|
||||||
// did we find a field used by a repeater in the selector?
|
// did we find a field used by a repeater in the selector?
|
||||||
$found = false;
|
$found = false;
|
||||||
@@ -2228,6 +2265,7 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
*/
|
*/
|
||||||
protected function ___saveConfigInputfields(Field $field, Template $template, Page $parent) {
|
protected function ___saveConfigInputfields(Field $field, Template $template, Page $parent) {
|
||||||
if($parent) {} // ignore
|
if($parent) {} // ignore
|
||||||
|
$this->initAllFields();
|
||||||
$helper = $this->getRepeaterConfigHelper($field);
|
$helper = $this->getRepeaterConfigHelper($field);
|
||||||
$helper->saveConfigInputfields($template);
|
$helper->saveConfigInputfields($template);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user