mirror of
https://github.com/processwire/processwire.git
synced 2025-08-09 08:17:12 +02:00
Refactoring in ProcessPageClone.module and related hooks and multi-language support, plus some improvements to new PagesNames class.
This commit is contained in:
@@ -566,11 +566,14 @@ class PagesEditor extends Wire {
|
|||||||
protected function savePageQueryException(Page $page, $query, $exception, array $options) {
|
protected function savePageQueryException(Page $page, $query, $exception, array $options) {
|
||||||
|
|
||||||
$errorCode = $exception->getCode();
|
$errorCode = $exception->getCode();
|
||||||
|
|
||||||
|
// 23000=integrity constraint violation, duplicate entry
|
||||||
if($errorCode != 23000) return false;
|
if($errorCode != 23000) return false;
|
||||||
|
|
||||||
if(!$this->pages->names()->hasAutogenName($page) && !$options['adjustName']) return false;
|
if(!$this->pages->names()->hasAutogenName($page) && !$options['adjustName']) return false;
|
||||||
|
|
||||||
// account for the duplicate possibly being a multi-language name field
|
// account for the duplicate possibly being a multi-language name field
|
||||||
|
// i.e. “Duplicate entry 'bienvenido-2-1001' for key 'name1013_parent_id'”
|
||||||
if($this->wire('languages') && preg_match('/\b(name\d*)_parent_id\b/', $exception->getMessage(), $matches)) {
|
if($this->wire('languages') && preg_match('/\b(name\d*)_parent_id\b/', $exception->getMessage(), $matches)) {
|
||||||
$nameField = $matches[1];
|
$nameField = $matches[1];
|
||||||
} else {
|
} else {
|
||||||
@@ -1025,28 +1028,15 @@ class PagesEditor extends Wire {
|
|||||||
|
|
||||||
if(is_string($options)) $options = Selectors::keyValueStringToArray($options);
|
if(is_string($options)) $options = Selectors::keyValueStringToArray($options);
|
||||||
if(!isset($options['recursionLevel'])) $options['recursionLevel'] = 0; // recursion level
|
if(!isset($options['recursionLevel'])) $options['recursionLevel'] = 0; // recursion level
|
||||||
|
if($parent === null) $parent = $page->parent;
|
||||||
|
|
||||||
if(isset($options['set']) && isset($options['set']['name'])) {
|
if(isset($options['set']) && isset($options['set']['name']) && strlen($options['set']['name'])) {
|
||||||
$name = $options['set']['name'];
|
$name = $options['set']['name'];
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// if parent is not changing, we have to modify name now
|
$name = $this->pages->names()->uniquePageName(array(
|
||||||
if(is_null($parent) || $parent->id == $page->parent->id) {
|
'name' => $page->name,
|
||||||
$parent = $page->parent;
|
'parent' => $parent
|
||||||
$n = 1;
|
));
|
||||||
$name = $page->name . '-' . $n;
|
|
||||||
} else {
|
|
||||||
$name = $page->name;
|
|
||||||
$n = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure that we have a unique name
|
|
||||||
while(count($parent->children("name=$name, include=all"))) {
|
|
||||||
$name = $page->name;
|
|
||||||
$nStr = "-" . (++$n);
|
|
||||||
if(strlen($name) + strlen($nStr) > Pages::nameMaxLength) $name = substr($name, 0, Pages::nameMaxLength - strlen($nStr));
|
|
||||||
$name .= $nStr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$of = $page->of();
|
$of = $page->of();
|
||||||
|
@@ -40,6 +40,14 @@ class PagesNames extends Wire {
|
|||||||
*/
|
*/
|
||||||
protected $delimiter = '-';
|
protected $delimiter = '-';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max length for page names
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $nameMaxLength = 128;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct
|
* Construct
|
||||||
*
|
*
|
||||||
@@ -51,6 +59,7 @@ class PagesNames extends Wire {
|
|||||||
$pages->wire($this);
|
$pages->wire($this);
|
||||||
$untitled = $this->wire('config')->pageNameUntitled;
|
$untitled = $this->wire('config')->pageNameUntitled;
|
||||||
if($untitled) $this->untitledPageName = $untitled;
|
if($untitled) $this->untitledPageName = $untitled;
|
||||||
|
$this->nameMaxLength = Pages::nameMaxLength;
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,17 +233,34 @@ class PagesNames extends Wire {
|
|||||||
* date() format, PHP strftime() format, as well as some other predefined options.
|
* date() format, PHP strftime() format, as well as some other predefined options.
|
||||||
*
|
*
|
||||||
* @param Page $page
|
* @param Page $page
|
||||||
* @param string $format Optional format. If not specified, pulls from $page’s parent template.
|
* @param string|array $format Optional format. If not specified, pulls from $page’s parent template.
|
||||||
*
|
* @param array $options Options to modify behavior. May also be specified in $format argument.
|
||||||
|
* - `language` (Language|string): Language to use
|
||||||
|
* - `format` (string): Optional format to use, if $options were specified in $format argument.
|
||||||
* @return string
|
* @return string
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function pageNameFromFormat(Page $page, $format = '') {
|
public function pageNameFromFormat(Page $page, $format = '', array $options = array()) {
|
||||||
|
|
||||||
|
$defaults = array(
|
||||||
|
'format' => '',
|
||||||
|
'language' => null,
|
||||||
|
);
|
||||||
|
|
||||||
|
if(is_array($format)) {
|
||||||
|
$options = $format;
|
||||||
|
$format = empty($options['format']) ? '' : $options['format'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$options = array_merge($defaults, $options);
|
||||||
if(!strlen($format)) $format = $this->defaultPageNameFormat($page);
|
if(!strlen($format)) $format = $this->defaultPageNameFormat($page);
|
||||||
$format = trim($format);
|
$format = trim($format);
|
||||||
$name = '';
|
$name = '';
|
||||||
|
|
||||||
|
if($options['language']) {
|
||||||
|
$this->wire('languages')->setLanguage($options['language']);
|
||||||
|
}
|
||||||
|
|
||||||
if($format === 'title' && !strlen(trim((string) $page->title))) {
|
if($format === 'title' && !strlen(trim((string) $page->title))) {
|
||||||
$format = 'untitled-time';
|
$format = 'untitled-time';
|
||||||
}
|
}
|
||||||
@@ -285,10 +311,16 @@ class PagesNames extends Wire {
|
|||||||
$name = $format;
|
$name = $format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(strlen($name) > $this->nameMaxLength) $name = $this->adjustNameLength($name);
|
||||||
|
|
||||||
$utf8 = $this->wire('config')->pageNameCharset === 'UTF8';
|
$utf8 = $this->wire('config')->pageNameCharset === 'UTF8';
|
||||||
$sanitizer = $this->wire('sanitizer');
|
$sanitizer = $this->wire('sanitizer');
|
||||||
$name = $utf8 ? $sanitizer->pageNameUTF8($name) : $sanitizer->pageName($name, Sanitizer::translate);
|
$name = $utf8 ? $sanitizer->pageNameUTF8($name) : $sanitizer->pageName($name, Sanitizer::translate);
|
||||||
|
|
||||||
|
if($options['language']) {
|
||||||
|
$this->wire('languages')->unsetLanguage();
|
||||||
|
}
|
||||||
|
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,35 +335,61 @@ class PagesNames extends Wire {
|
|||||||
* The returned value is not yet assigned to the given $page, so if it is something different than what
|
* The returned value is not yet assigned to the given $page, so if it is something different than what
|
||||||
* is already on $page, you’ll want to assign it manually after this.
|
* is already on $page, you’ll want to assign it manually after this.
|
||||||
*
|
*
|
||||||
* @param string|Page $name Name to make unique, or Page to pull it from.
|
* @param string|Page|array $name Name to make unique
|
||||||
* @param Page||string|null You may optionally specify Page or name in this argument if not in the first.
|
* You may optionally substitute the $page argument or $options arguments here, if that is all you need.
|
||||||
* Note that specifying a Page here or in the first argument is important if the page already exists, as it is used
|
* @param Page||string|null|array Page to exclude from duplicate check and/or to pull $name or parent from (if not otherwise specified).
|
||||||
* as the page to exclude when checking for name collisions, and we want to exclude $page from that check.
|
* Note that specifying a Page is important if the page already exists, as it is used as the page to exclude when checking for
|
||||||
|
* name collisions, and we want to exclude $page from that check. You may optionally substitute the $options or $name arguments
|
||||||
|
* here, if that is all you need. If $parent or $name are specified separately from this $page argument, they will override
|
||||||
|
* whatever parent or name settings are on this $page argument.
|
||||||
* @param array $options
|
* @param array $options
|
||||||
* - `parent` (Page|null): Optionally specify a different parent if $page does not currently have the parent you want to use.
|
* - `parent` (Page|null): Optionally specify a different parent if $page does not currently have the parent you want to use.
|
||||||
* - `language` (Language|int): Get unique for this language (if multi-language page names active).
|
* - `language` (Language|int): Get unique for this language (if multi-language page names active).
|
||||||
|
* - `page` (Page|null): If you specified no $page argument, you can optionally bundle it in the $options array.
|
||||||
|
* - `name` (string): If you specified no $name argument, you can optionally bundle it in the $options array.
|
||||||
* @return string Returns unique name
|
* @return string Returns unique name
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function uniquePageName($name = '', $page = null, array $options = array()) {
|
public function uniquePageName($name = '', $page = null, array $options = array()) {
|
||||||
|
|
||||||
$defaults = array(
|
$defaults = array(
|
||||||
|
'name' => '',
|
||||||
'page' => null,
|
'page' => null,
|
||||||
'parent' => null,
|
'parent' => null,
|
||||||
'language' => null
|
'language' => null
|
||||||
);
|
);
|
||||||
|
|
||||||
$options = array_merge($defaults, $options);
|
// handle argument substitutions
|
||||||
|
if(is_array($page)) {
|
||||||
if($name instanceof Page) {
|
// options specified in $page argument
|
||||||
|
$options = $page;
|
||||||
|
$page = !empty($options['page']) ? $options['page'] : null;
|
||||||
|
} else if(is_array($name)) {
|
||||||
|
// options specified in $name argument
|
||||||
|
$options = $name;
|
||||||
|
$name = !empty($options['name']) ? $options['name'] : '';
|
||||||
|
} else if($name instanceof Page) {
|
||||||
|
// $page argument specified in $name argument
|
||||||
$_name = is_string($page) ? $page : '';
|
$_name = is_string($page) ? $page : '';
|
||||||
$page = $name;
|
$page = $name;
|
||||||
$name = $_name;
|
$name = $_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$options = array_merge($defaults, $options);
|
||||||
|
|
||||||
|
if(empty($page) && !empty($options['page'])) $page = $options['page'];
|
||||||
|
if(empty($name) && !empty($options['name'])) $name = $options['name'];
|
||||||
|
|
||||||
if($page) {
|
if($page) {
|
||||||
if($options['parent'] === null) $options['parent'] = $page->parent();
|
if($options['parent'] === null) $options['parent'] = $page->parent();
|
||||||
|
if(!strlen($name)) {
|
||||||
|
if($options['language']) {
|
||||||
|
$name = $page->get("name$options[language]");
|
||||||
if(!strlen($name)) $name = $page->name;
|
if(!strlen($name)) $name = $page->name;
|
||||||
|
} else {
|
||||||
|
$name = $page->name;
|
||||||
|
}
|
||||||
|
}
|
||||||
$options['page'] = $page;
|
$options['page'] = $page;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +400,7 @@ class PagesNames extends Wire {
|
|||||||
'fallbackFormat' => $page->id ? 'random' : 'untitled-time',
|
'fallbackFormat' => $page->id ? 'random' : 'untitled-time',
|
||||||
'parent' => $options['parent']
|
'parent' => $options['parent']
|
||||||
));
|
));
|
||||||
$name = $this->pageNameFromFormat($page, $format);
|
$name = $this->pageNameFromFormat($page, $format, array('language' => $options['language']));
|
||||||
} else {
|
} else {
|
||||||
$name = $this->uniqueRandomPageName();
|
$name = $this->uniqueRandomPageName();
|
||||||
}
|
}
|
||||||
@@ -352,6 +410,8 @@ class PagesNames extends Wire {
|
|||||||
$name = $this->incrementName($name);
|
$name = $this->incrementName($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(strlen($name) > $this->nameMaxLength) $name = $this->adjustNameLength($name);
|
||||||
|
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,7 +425,7 @@ class PagesNames extends Wire {
|
|||||||
*/
|
*/
|
||||||
public function adjustNameLength($name, $maxLength = 0) {
|
public function adjustNameLength($name, $maxLength = 0) {
|
||||||
|
|
||||||
if($maxLength < 1) $maxLength = Pages::nameMaxLength;
|
if($maxLength < 1) $maxLength = $this->nameMaxLength;
|
||||||
if(strlen($name) <= $maxLength) return $name;
|
if(strlen($name) <= $maxLength) return $name;
|
||||||
|
|
||||||
$trims = implode('', $this->delimiters);
|
$trims = implode('', $this->delimiters);
|
||||||
@@ -415,16 +475,22 @@ class PagesNames extends Wire {
|
|||||||
list($namePrefix, $n) = $this->nameAndNumber($name);
|
list($namePrefix, $n) = $this->nameAndNumber($name);
|
||||||
|
|
||||||
if($namePrefix !== $name) {
|
if($namePrefix !== $name) {
|
||||||
|
// name already had an increment
|
||||||
if($num) {
|
if($num) {
|
||||||
|
// specific number was supplied
|
||||||
$num = (int) $num;
|
$num = (int) $num;
|
||||||
$name = $namePrefix . $this->delimiter . $num;
|
$name = $namePrefix . $this->delimiter . $num;
|
||||||
} else {
|
} else {
|
||||||
|
// no number supplied
|
||||||
|
// make sure that any leading zeros are retained before we increment number
|
||||||
$zeros = '';
|
$zeros = '';
|
||||||
while(strpos($name, $namePrefix . $this->delimiter . "0$zeros") === 0) $zeros .= '0';
|
while(strpos($name, $namePrefix . $this->delimiter . "0$zeros") === 0) $zeros .= '0';
|
||||||
|
// increment the number
|
||||||
$name = $namePrefix . $this->delimiter . $zeros . (++$n);
|
$name = $namePrefix . $this->delimiter . $zeros . (++$n);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(!is_int($num)) $num = 1;
|
// name does not yet have an increment, so make it "name-1"
|
||||||
|
if(!is_int($num) || $num < 1) $num = 1;
|
||||||
$name = $namePrefix . $this->delimiter . $num;
|
$name = $namePrefix . $this->delimiter . $num;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,13 +500,15 @@ class PagesNames extends Wire {
|
|||||||
/**
|
/**
|
||||||
* Is the given name is use by a page?
|
* Is the given name is use by a page?
|
||||||
*
|
*
|
||||||
|
* If the `multilang` option is used, it checks if the page name exists in any language.
|
||||||
|
* IF the `language` option is used, it only checks that particular language (regardless of `multilang` option).
|
||||||
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param array $options
|
* @param array $options
|
||||||
* - `page` (Page|int): Ignore this Page or page ID
|
* - `page` (Page|int): Ignore this Page or page ID
|
||||||
* - `parent` (Page|int): Limit search to only this parent.
|
* - `parent` (Page|int): Limit search to only this parent.
|
||||||
* - `multilang` (bool): Check other languages if multi-language page names supported? (default=false)
|
* - `multilang` (bool): Check other languages if multi-language page names supported? (default=false)
|
||||||
* - `language` (Language|int): Limit check to only this language [also implies multilang option] (default=null)
|
* - `language` (Language|int): Limit check to only this language (default=null)
|
||||||
*
|
|
||||||
* @return int Returns quantity of pages using name, or 0 if name not in use.
|
* @return int Returns quantity of pages using name, or 0 if name not in use.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -465,9 +533,9 @@ class PagesNames extends Wire {
|
|||||||
if($languages) {
|
if($languages) {
|
||||||
foreach($languages as $language) {
|
foreach($languages as $language) {
|
||||||
if($options['language'] && "$options[language]" !== "$language") continue;
|
if($options['language'] && "$options[language]" !== "$language") continue;
|
||||||
$property = $language->isDefault() ? 'name' : 'name' . (int) $language->id;
|
$property = $language->isDefault() ? "name" : "name" . (int) $language->id;
|
||||||
$wheres[] = "$property=:name$language->id";
|
$wheres[] = "$property=:$property";
|
||||||
$binds[":name$language->id"] = $name;
|
$binds[":$property"] = $name;
|
||||||
}
|
}
|
||||||
$wheres = array('(' . implode(' OR ', $wheres) . ')');
|
$wheres = array('(' . implode(' OR ', $wheres) . ')');
|
||||||
} else {
|
} else {
|
||||||
|
@@ -854,17 +854,21 @@ class LanguageSupportPageNames extends WireData implements Module, ConfigurableM
|
|||||||
|
|
||||||
/** @var Page $page */
|
/** @var Page $page */
|
||||||
$page = $event->arguments[0];
|
$page = $event->arguments[0];
|
||||||
|
|
||||||
/** @var Pages $pages */
|
/** @var Pages $pages */
|
||||||
$pages = $event->object;
|
$pages = $event->object;
|
||||||
|
|
||||||
|
/** @var Sanitizer $sanitizer */
|
||||||
|
$sanitizer = $this->wire('sanitizer');
|
||||||
|
|
||||||
|
/** @var array $extraData */
|
||||||
$extraData = $event->return;
|
$extraData = $event->return;
|
||||||
if(!is_array($extraData)) $extraData = array();
|
|
||||||
$alwaysActiveTypes = array('User', 'Role', 'Permission', 'Language');
|
$alwaysActiveTypes = array('User', 'Role', 'Permission', 'Language');
|
||||||
$pageNameCharset = $this->wire('config')->pageNameCharset;
|
$pageNameCharset = $this->wire('config')->pageNameCharset;
|
||||||
|
$isCloning = $pages->editor()->isCloning();
|
||||||
|
|
||||||
$defaultN = 1;
|
if(!is_array($extraData)) $extraData = array();
|
||||||
if($pages->cloning && preg_match('/^(.+)-(\d+)$/', $page->name, $matches)) {
|
|
||||||
$defaultN = (int) $matches[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($this->wire('languages') as $language) {
|
foreach($this->wire('languages') as $language) {
|
||||||
|
|
||||||
@@ -873,21 +877,20 @@ class LanguageSupportPageNames extends WireData implements Module, ConfigurableM
|
|||||||
|
|
||||||
// populate a name123 field for each language
|
// populate a name123 field for each language
|
||||||
$name = "name$language_id";
|
$name = "name$language_id";
|
||||||
$value = $this->wire('sanitizer')->pageNameUTF8($page->get($name));
|
$value = $sanitizer->pageNameUTF8($page->get($name));
|
||||||
if(!strlen($value)) {
|
if(!strlen($value)) {
|
||||||
$value = 'NULL';
|
$value = 'NULL';
|
||||||
} else if($pages->cloning) {
|
} else if($isCloning) {
|
||||||
// this save is the result of a clone() operation
|
// this save is the result of a clone() operation
|
||||||
// make sure that the name is unique for other languages
|
// make sure that the name is unique for other languages
|
||||||
$newValue = $value;
|
$value = $pages->names()->uniquePageName(array(
|
||||||
while($page->parent->children("$name=$newValue, include=all")->count() > 0) {
|
'name' => $value,
|
||||||
$newValue = $value . "-$defaultN";
|
'page' => $page,
|
||||||
$defaultN++;
|
'language' => $language,
|
||||||
}
|
));
|
||||||
$value = $newValue;
|
|
||||||
}
|
}
|
||||||
if($pageNameCharset == 'UTF8') {
|
if($pageNameCharset == 'UTF8') {
|
||||||
$extraData[$name] = $this->wire('sanitizer')->pageName($value, Sanitizer::toAscii);
|
$extraData[$name] = $sanitizer->pageName($value, Sanitizer::toAscii);
|
||||||
} else {
|
} else {
|
||||||
$extraData[$name] = $value;
|
$extraData[$name] = $value;
|
||||||
}
|
}
|
||||||
|
@@ -6,12 +6,16 @@
|
|||||||
* For more details about how Process modules work, please see:
|
* For more details about how Process modules work, please see:
|
||||||
* /wire/core/Process.php
|
* /wire/core/Process.php
|
||||||
*
|
*
|
||||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
* ProcessWire 3.x, Copyright 2018 by Ryan Cramer
|
||||||
* https://processwire.com
|
* https://processwire.com
|
||||||
*
|
*
|
||||||
* Optional GET variables:
|
* Optional GET variables:
|
||||||
* - redirect_page (int): Contains ID of page to redirect to after clone.
|
* - redirect_page (int): Contains ID of page to redirect to after clone.
|
||||||
*
|
*
|
||||||
|
* @method InputfieldForm buildForm()
|
||||||
|
* @method string render()
|
||||||
|
* @method void process()
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class ProcessPageClone extends Process {
|
class ProcessPageClone extends Process {
|
||||||
@@ -20,7 +24,7 @@ class ProcessPageClone extends Process {
|
|||||||
return array(
|
return array(
|
||||||
'title' => __('Page Clone', __FILE__),
|
'title' => __('Page Clone', __FILE__),
|
||||||
'summary' => __('Provides ability to clone/copy/duplicate pages in the admin. Adds a "copy" option to all applicable pages in the PageList.', __FILE__),
|
'summary' => __('Provides ability to clone/copy/duplicate pages in the admin. Adds a "copy" option to all applicable pages in the PageList.', __FILE__),
|
||||||
'version' => 103,
|
'version' => 104,
|
||||||
'autoload' => "template=admin", // Note: most Process modules should not be 'autoload', this is an exception.
|
'autoload' => "template=admin", // Note: most Process modules should not be 'autoload', this is an exception.
|
||||||
'permission' => 'page-clone',
|
'permission' => 'page-clone',
|
||||||
'permissions' => array(
|
'permissions' => array(
|
||||||
@@ -39,6 +43,8 @@ class ProcessPageClone extends Process {
|
|||||||
/**
|
/**
|
||||||
* The page being cloned
|
* The page being cloned
|
||||||
*
|
*
|
||||||
|
* @var Page|null
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
protected $page;
|
protected $page;
|
||||||
|
|
||||||
@@ -73,6 +79,8 @@ class ProcessPageClone extends Process {
|
|||||||
/**
|
/**
|
||||||
* Hook into ProcessPageListActions::getExtraActions to return a 'copy' action when appropriate
|
* Hook into ProcessPageListActions::getExtraActions to return a 'copy' action when appropriate
|
||||||
*
|
*
|
||||||
|
* @param HookEvent $event
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public function hookPageListActions(HookEvent $event) {
|
public function hookPageListActions(HookEvent $event) {
|
||||||
$page = $event->arguments[0];
|
$page = $event->arguments[0];
|
||||||
@@ -113,13 +121,12 @@ class ProcessPageClone extends Process {
|
|||||||
public function ___execute() {
|
public function ___execute() {
|
||||||
$this->headline($this->_('Copy Page')); // Headline
|
$this->headline($this->_('Copy Page')); // Headline
|
||||||
$error = $this->_("Unable to load page");
|
$error = $this->_("Unable to load page");
|
||||||
$id = (int) $this->wire('input')->get->id;
|
$id = (int) $this->wire('input')->get('id');
|
||||||
if(!$id) throw new WireException($error);
|
if(!$id) throw new WireException($error);
|
||||||
$this->page = $this->wire('pages')->get($id);
|
$this->page = $this->wire('pages')->get($id);
|
||||||
if($this->page->id < 2) throw new WireException($error);
|
if($this->page->id < 2) throw new WireException($error);
|
||||||
if(!$this->hasPermission($this->page)) throw new WirePermissionException($error);
|
if(!$this->hasPermission($this->page)) throw new WirePermissionException($error);
|
||||||
if($this->wire('input')->post->submit_clone) $this->process();
|
if($this->wire('input')->post('submit_clone')) $this->process();
|
||||||
//if($this->wire('config')->ajax && $_SERVER['REQUEST_METHOD'] == 'POST') return $this->processAjax();
|
|
||||||
return $this->render();
|
return $this->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,16 +139,19 @@ class ProcessPageClone extends Process {
|
|||||||
*/
|
*/
|
||||||
public function hasPermission(Page $page) {
|
public function hasPermission(Page $page) {
|
||||||
$user = $this->user;
|
$user = $this->user;
|
||||||
|
$parent = $page->parent();
|
||||||
|
$parentTemplate = $parent->template;
|
||||||
|
$pageTemplate = $page->template;
|
||||||
|
|
||||||
if($page->hasStatus(Page::statusSystem) || $page->hasStatus(Page::statusSystemID)) return false;
|
if($page->hasStatus(Page::statusSystem) || $page->hasStatus(Page::statusSystemID)) return false;
|
||||||
if($page->parent->template->noChildren) return false;
|
if($parentTemplate->noChildren) return false;
|
||||||
if($page->template->noParents) return false;
|
if($pageTemplate->noParents) return false;
|
||||||
|
|
||||||
if(count($page->parent->template->childTemplates) && !in_array($page->template->id, $page->parent->template->childTemplates)) return false;
|
if(count($parentTemplate->childTemplates) && !in_array($pageTemplate->id, $parentTemplate->childTemplates)) return false;
|
||||||
if(count($page->template->parentTemplates) && !in_array($page->parent->template->id, $page->template->parentTemplates)) return false;
|
if(count($pageTemplate->parentTemplates) && !in_array($parentTemplate->id, $pageTemplate->parentTemplates)) return false;
|
||||||
|
|
||||||
if($user->isSuperuser()) return true;
|
if($user->isSuperuser()) return true;
|
||||||
if($user->hasPermission('page-create', $page) && $user->hasPermission('page-clone', $page) && $page->parent->addable()) return true;
|
if($user->hasPermission('page-create', $page) && $user->hasPermission('page-clone', $page) && $parent->addable()) return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -149,91 +159,119 @@ class ProcessPageClone extends Process {
|
|||||||
/**
|
/**
|
||||||
* Return array with suggested 'name' and 'title' elements for given $page
|
* Return array with suggested 'name' and 'title' elements for given $page
|
||||||
*
|
*
|
||||||
* @param $page
|
* @param Page $page
|
||||||
* @return array
|
* @return array
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function getSuggestedNameAndTitle($page) {
|
protected function getSuggestedNameAndTitle(Page $page) {
|
||||||
$n = 0;
|
|
||||||
$name = '';
|
/** @var Pages $pages */
|
||||||
do {
|
$pages = $this->wire('pages');
|
||||||
$n++;
|
|
||||||
$name = $page->name;
|
$name = $pages->names()->uniquePageName(array(
|
||||||
$nStr = "-$n";
|
'name' => $page->name,
|
||||||
if(strlen($name) + strlen($nStr) > Pages::nameMaxLength) $name = substr($name, 0, Pages::nameMaxLength - strlen($nStr));
|
'parent' => $page->parent()
|
||||||
$name .= $nStr;
|
));
|
||||||
} while($this->wire('pages')->count("parent=$page->parent, include=all, name=$name"));
|
|
||||||
$copy = $this->_('(copy)');
|
$copy = $this->_('(copy)');
|
||||||
$copyN = $this->_('(copy %d)');
|
$copyN = $this->_('(copy %d)');
|
||||||
$title = $page->title;
|
$title = $page->title;
|
||||||
// @todo support multi-language titles
|
|
||||||
|
$n = (int) $pages->names()->hasNumberSuffix($name);
|
||||||
if(strpos($title, $copy) !== false) $title = str_replace(" $copy", '', $title);
|
if(strpos($title, $copy) !== false) $title = str_replace(" $copy", '', $title);
|
||||||
$regexCopyN = str_replace('%d', '[0-9]+', $copyN);
|
$regexCopyN = str_replace('%d', '[0-9]+', $copyN);
|
||||||
$regexCopyN = str_replace(array('(', ')'), array('\\(', '\\)'), $regexCopyN);
|
$regexCopyN = str_replace(array('(', ')'), array('\\(', '\\)'), $regexCopyN);
|
||||||
$title = preg_replace("/$regexCopyN/", '', $title);
|
$title = preg_replace("/$regexCopyN/", '', $title);
|
||||||
$title .= ' ' . ($n > 1 ? sprintf($copyN, $n) : $copy);
|
$title .= ' ' . ($n > 1 ? sprintf($copyN, $n) : $copy);
|
||||||
$result = array('name' => $name, 'title' => $title, 'n' => $n);
|
|
||||||
|
$result = array(
|
||||||
|
'name' => $name,
|
||||||
|
'title' => $title,
|
||||||
|
'n' => $n
|
||||||
|
);
|
||||||
|
|
||||||
if($this->wire('modules')->isInstalled('LanguageSupportPageNames')) {
|
if($this->wire('modules')->isInstalled('LanguageSupportPageNames')) {
|
||||||
foreach($this->wire('languages') as $language) {
|
foreach($this->wire('languages') as $language) {
|
||||||
if($language->isDefault()) continue;
|
if($language->isDefault()) continue;
|
||||||
$value = $page->get("name$language");
|
$value = $page->get("name$language");
|
||||||
if(strlen($value)) $result["name$language"] = $value . '-' . $n;
|
if(!strlen($value)) continue;
|
||||||
|
$result["name$language"] = $pages->names()->incrementName($value, $n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a form asking for information to be used for the new cloned page.
|
* Render a form asking for information to be used for the new cloned page.
|
||||||
*
|
*
|
||||||
|
* @return InputfieldForm
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
protected function ___buildForm() {
|
protected function ___buildForm() {
|
||||||
|
|
||||||
|
/** @var Page $page */
|
||||||
|
$page = $this->page;
|
||||||
|
|
||||||
|
/** @var InputfieldForm $form */
|
||||||
$form = $this->modules->get("InputfieldForm");
|
$form = $this->modules->get("InputfieldForm");
|
||||||
$form->attr('action', './?id=' . $this->page->id);
|
$form->attr('action', './?id=' . $page->id);
|
||||||
$form->attr('method', 'post');
|
$form->attr('method', 'post');
|
||||||
$form->description = sprintf($this->_("This will make a copy of %s"), $this->page->path); // Form description/headline
|
$form->description = sprintf($this->_("This will make a copy of %s"), $page->path); // Form description/headline
|
||||||
$form->addClass('InputfieldFormFocusFirst');
|
$form->addClass('InputfieldFormFocusFirst');
|
||||||
|
|
||||||
$suggested = $this->getSuggestedNameAndTitle($this->page);
|
$suggested = $this->getSuggestedNameAndTitle($page);
|
||||||
|
|
||||||
|
/** @var InputfieldPageTitle $titleField */
|
||||||
$titleField = $this->modules->get("InputfieldPageTitle");
|
$titleField = $this->modules->get("InputfieldPageTitle");
|
||||||
$titleField->attr('name', 'clone_page_title');
|
$titleField->attr('name', 'clone_page_title');
|
||||||
$titleField->attr('value', $suggested['title']);
|
$titleField->attr('value', $suggested['title']);
|
||||||
$titleField->label = $this->_("Title of new page"); // Label for title field
|
$titleField->label = $this->_("Title of new page"); // Label for title field
|
||||||
|
|
||||||
|
/** @var InputfieldPageName $nameField */
|
||||||
$nameField = $this->modules->get("InputfieldPageName");
|
$nameField = $this->modules->get("InputfieldPageName");
|
||||||
$nameField->attr('name', 'clone_page_name');
|
$nameField->attr('name', 'clone_page_name');
|
||||||
$nameField->attr('value', $suggested['name']);
|
$nameField->attr('value', $suggested['name']);
|
||||||
$nameField->parentPage = $this->page->parent;
|
$nameField->parentPage = $page->parent;
|
||||||
|
|
||||||
|
/** @var Languages $languages */
|
||||||
$languages = $this->wire('languages');
|
$languages = $this->wire('languages');
|
||||||
$useLanguages = $languages;
|
$useLanguages = $languages;
|
||||||
if($useLanguages) {
|
if($useLanguages) {
|
||||||
/** @var Field $title */
|
/** @var Field $title */
|
||||||
$title = $this->wire('fields')->get('title');
|
$title = $this->wire('fields')->get('title');
|
||||||
$titleUseLanguages = $title
|
$titleUseLanguages = $title
|
||||||
&& $this->page->template->fieldgroup->hasField($title)
|
&& $page->template->fieldgroup->hasField($title)
|
||||||
&& $title->getInputfield($this->page)->getSetting('useLanguages');
|
&& $title->getInputfield($page)->getSetting('useLanguages');
|
||||||
$nameUseLanguages = $this->wire('modules')->isInstalled('LanguageSupportPageNames');
|
$nameUseLanguages = $this->wire('modules')->isInstalled('LanguageSupportPageNames');
|
||||||
if($titleUseLanguages) $titleField->useLanguages = true;
|
if($titleUseLanguages) $titleField->useLanguages = true;
|
||||||
if($nameUseLanguages) $nameField->useLanguages = true;
|
if($nameUseLanguages) $nameField->useLanguages = true;
|
||||||
foreach($languages as $language) {
|
foreach($languages as $language) {
|
||||||
if($language->isDefault()) continue;
|
if($language->isDefault()) continue;
|
||||||
if($titleUseLanguages) {
|
if($titleUseLanguages) {
|
||||||
$value = $this->page->title->getLanguageValue($language);
|
/** @var LanguagesPageFieldValue $pageTitle */
|
||||||
|
$pageTitle = $page->title;
|
||||||
|
$value = $pageTitle->getLanguageValue($language);
|
||||||
$titleField->set("value$language->id", $value);
|
$titleField->set("value$language->id", $value);
|
||||||
}
|
}
|
||||||
if($nameUseLanguages) {
|
if($nameUseLanguages) {
|
||||||
$value = $this->page->get("name$language->id");
|
$value = $page->get("name$language->id");
|
||||||
if(strlen($value)) $nameField->set("value$language->id", $value . '-' . $suggested['n']);
|
if(strlen($value)) {
|
||||||
|
if(!empty($suggested["name$language"])) {
|
||||||
|
$nameLang = $suggested["name$language"];
|
||||||
|
} else {
|
||||||
|
$nameLang = $value . '-' . $suggested['n'];
|
||||||
|
}
|
||||||
|
$nameField->set("value$language->id", $nameLang);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->page->template->fieldgroup->hasField('title')) $form->add($titleField);
|
if($page->template->fieldgroup->hasField('title')) $form->add($titleField);
|
||||||
$form->add($nameField);
|
$form->add($nameField);
|
||||||
|
|
||||||
|
/** @var InputfieldCheckbox $field */
|
||||||
$field = $this->modules->get("InputfieldCheckbox");
|
$field = $this->modules->get("InputfieldCheckbox");
|
||||||
$field->attr('name', 'clone_page_unpublished');
|
$field->attr('name', 'clone_page_unpublished');
|
||||||
$field->attr('value', 1);
|
$field->attr('value', 1);
|
||||||
@@ -242,7 +280,8 @@ class ProcessPageClone extends Process {
|
|||||||
$field->description = $this->_("If checked, the cloned page will be given an unpublished status so that it can't yet be seen on the front-end of your site.");
|
$field->description = $this->_("If checked, the cloned page will be given an unpublished status so that it can't yet be seen on the front-end of your site.");
|
||||||
$form->add($field);
|
$form->add($field);
|
||||||
|
|
||||||
if($this->page->numChildren && $this->user->hasPermission('page-clone-tree', $this->page)) {
|
if($page->numChildren && $this->user->hasPermission('page-clone-tree', $page)) {
|
||||||
|
/** @var InputfieldCheckbox $field */
|
||||||
$field = $this->modules->get("InputfieldCheckbox");
|
$field = $this->modules->get("InputfieldCheckbox");
|
||||||
$field->attr('name', 'clone_page_tree');
|
$field->attr('name', 'clone_page_tree');
|
||||||
$field->attr('value', 1);
|
$field->attr('value', 1);
|
||||||
@@ -253,14 +292,17 @@ class ProcessPageClone extends Process {
|
|||||||
$form->add($field);
|
$form->add($field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @var InputfieldSubmit $field */
|
||||||
$field = $this->modules->get("InputfieldSubmit");
|
$field = $this->modules->get("InputfieldSubmit");
|
||||||
$field->attr('name', 'submit_clone');
|
$field->attr('name', 'submit_clone');
|
||||||
$form->add($field);
|
$form->add($field);
|
||||||
|
|
||||||
if(isset($_GET['redirect_page'])) {
|
$redirectPageID = (int) $this->wire('input')->get('redirect_page');
|
||||||
|
if($redirectPageID) {
|
||||||
|
/** @var InputfieldHidden $field */
|
||||||
$field = $this->wire('modules')->get('InputfieldHidden');
|
$field = $this->wire('modules')->get('InputfieldHidden');
|
||||||
$field->attr('name', 'redirect_page');
|
$field->attr('name', 'redirect_page');
|
||||||
$field->attr('value', (int) $_GET['redirect_page']);
|
$field->attr('value', $redirectPageID);
|
||||||
$form->add($field);
|
$form->add($field);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,6 +312,8 @@ class ProcessPageClone extends Process {
|
|||||||
/**
|
/**
|
||||||
* Render a form asking for information to be used for the new cloned page.
|
* Render a form asking for information to be used for the new cloned page.
|
||||||
*
|
*
|
||||||
|
* @return string
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
protected function ___render() {
|
protected function ___render() {
|
||||||
$form = $this->buildForm();
|
$form = $this->buildForm();
|
||||||
@@ -284,18 +328,19 @@ class ProcessPageClone extends Process {
|
|||||||
|
|
||||||
$page = clone $this->page;
|
$page = clone $this->page;
|
||||||
$input = $this->input;
|
$input = $this->input;
|
||||||
|
|
||||||
$originalName = $page->name;
|
$originalName = $page->name;
|
||||||
|
|
||||||
$this->session->CSRF->validate();
|
$this->session->CSRF->validate();
|
||||||
$form = $this->buildForm();
|
$form = $this->buildForm();
|
||||||
$form->processInput($this->wire('input')->post);
|
$form->processInput($input->post);
|
||||||
|
|
||||||
if($input->post->clone_page_unpublished) $page->addStatus(Page::statusUnpublished);
|
|
||||||
$cloneTree = $input->post->clone_page_tree && $this->user->hasPermission('page-clone-tree', $this->page);
|
|
||||||
|
|
||||||
$titleField = $form->get('clone_page_title');
|
$titleField = $form->get('clone_page_title');
|
||||||
$nameField = $form->get('clone_page_name');
|
$nameField = $form->get('clone_page_name');
|
||||||
|
$cloneTree = $input->post('clone_page_tree') && $this->user->hasPermission('page-clone-tree', $this->page);
|
||||||
|
|
||||||
|
if($input->post('clone_page_unpublished')) {
|
||||||
|
$page->addStatus(Page::statusUnpublished);
|
||||||
|
}
|
||||||
|
|
||||||
if($nameField->useLanguages) {
|
if($nameField->useLanguages) {
|
||||||
foreach($this->wire('languages') as $language) {
|
foreach($this->wire('languages') as $language) {
|
||||||
@@ -305,38 +350,48 @@ class ProcessPageClone extends Process {
|
|||||||
$page->set($nameAttr, $value);
|
$page->set($nameAttr, $value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$page->name = $nameField->value;
|
$page->name = $nameField->attr('value');
|
||||||
}
|
}
|
||||||
|
|
||||||
set_time_limit(3600);
|
set_time_limit(3600);
|
||||||
|
|
||||||
$clone = $this->pages->clone($page, $page->parent, $cloneTree);
|
$clone = $this->pages->clone($page, $page->parent, $cloneTree);
|
||||||
if(!$clone->id) throw new WireException(sprintf($this->_("Unable to clone page %s"), $page->path));
|
|
||||||
|
if(!$clone->id) {
|
||||||
|
throw new WireException(sprintf($this->_("Unable to clone page %s"), $page->path));
|
||||||
|
}
|
||||||
|
|
||||||
if($titleField->getSetting('useLanguages') && is_object($clone->title)) {
|
if($titleField->getSetting('useLanguages') && is_object($clone->title)) {
|
||||||
foreach($this->wire('languages') as $language) {
|
foreach($this->wire('languages') as $language) {
|
||||||
$valueAttr = $language->isDefault() ? "value" : "value$language->id";
|
$valueAttr = $language->isDefault() ? "value" : "value$language->id";
|
||||||
$value = $titleField->get($valueAttr);
|
$value = $titleField->get($valueAttr);
|
||||||
$clone->title->setLanguageValue($language, $value);
|
/** @var LanguagesPageFieldValue $cloneTitle */
|
||||||
|
$cloneTitle = $clone->title;
|
||||||
|
$cloneTitle->setLanguageValue($language, $value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$clone->title = $titleField->value;
|
$clone->title = $titleField->value;
|
||||||
}
|
}
|
||||||
$clone->save();
|
|
||||||
|
$this->wire('pages')->save($clone, array('adjustName' => true));
|
||||||
|
|
||||||
$this->message(sprintf($this->_('Cloned page "%1$s" to "%2$s"'), $originalName, $clone->name));
|
$this->message(sprintf($this->_('Cloned page "%1$s" to "%2$s"'), $originalName, $clone->name));
|
||||||
|
|
||||||
$redirectURL = null;
|
$redirectURL = null;
|
||||||
if(isset($_POST['redirect_page'])) {
|
$redirectID = (int) $input->post('redirect_page');
|
||||||
$redirectPageID = (int) $_POST['redirect_page'];
|
|
||||||
if($redirectPageID > 0) {
|
if($redirectID) {
|
||||||
$redirectPage = $this->wire('pages')->get((int) $_POST['redirect_page']);
|
$redirectPage = $this->wire('pages')->get($redirectID);
|
||||||
if($redirectPage->viewable()) $redirectURL = $redirectPage->url;
|
if($redirectPage->viewable()) {
|
||||||
} else {
|
$redirectURL = $redirectPage->url();
|
||||||
$redirectURL = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(is_null($redirectURL)) $redirectURL = $this->wire('config')->urls->admin . 'page/list/';
|
|
||||||
if($redirectURL) $redirectURL .= "?open=$clone->id";
|
if(!$redirectURL) {
|
||||||
|
$redirectURL = $this->adminUrl . "page/list/";
|
||||||
|
}
|
||||||
|
|
||||||
|
$redirectURL .= "?open=$clone->id";
|
||||||
|
|
||||||
$this->session->redirect($redirectURL);
|
$this->session->redirect($redirectURL);
|
||||||
}
|
}
|
||||||
@@ -353,34 +408,18 @@ class ProcessPageClone extends Process {
|
|||||||
*/
|
*/
|
||||||
public function processAjax(Page $original = null, $returnArray = false) {
|
public function processAjax(Page $original = null, $returnArray = false) {
|
||||||
|
|
||||||
if(is_null($original)) $original = $this->page;
|
|
||||||
$page = clone $original;
|
|
||||||
$originalName = $original->name;
|
|
||||||
$suggested = $this->getSuggestedNameAndTitle($page);
|
|
||||||
$cloneOptions = array(
|
|
||||||
'set' => array(
|
|
||||||
// keep original $page modified date and user id, since ajax mode doesn't
|
|
||||||
// give the user the option to edit the page before cloning it
|
|
||||||
'modified' => $original->modified,
|
|
||||||
'modified_users_id' => $original->modified_users_id,
|
|
||||||
// pages cloned in ajax are always unpublished
|
|
||||||
'status' => $page->status | Page::statusUnpublished,
|
|
||||||
'title' => $suggested['title'],
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$cloneTree = false; // clone tree mode now allowed in ajax mode
|
|
||||||
$error = null;
|
$error = null;
|
||||||
|
if($original === null) $original = $this->page;
|
||||||
|
|
||||||
try {
|
if($this->hasPermission($original)) {
|
||||||
$clone = $this->wire('pages')->clone($page, $page->parent, $cloneTree, $cloneOptions);
|
$clone = $this->cloneAjax($original, $error);
|
||||||
} catch(\Exception $e) {
|
} else {
|
||||||
$error = $e->getMessage();
|
$clone = new NullPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = array(
|
$result = array(
|
||||||
'action' => 'clone',
|
'action' => 'clone',
|
||||||
'success' => $clone->id > 0 && $clone->id != $page->id && is_null($error),
|
'success' => $clone->id > 0 && $clone->id != $original->id && empty($error),
|
||||||
'message' => '',
|
'message' => '',
|
||||||
'page' => $clone->id,
|
'page' => $clone->id,
|
||||||
);
|
);
|
||||||
@@ -401,6 +440,59 @@ class ProcessPageClone extends Process {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a clone during ajax request
|
||||||
|
*
|
||||||
|
* @param Page $original Page to clone
|
||||||
|
* @param string $error Variable to populate error message in
|
||||||
|
* @return Page|NullPage
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected function cloneAjax(Page $original, &$error) {
|
||||||
|
|
||||||
|
$page = clone $original;
|
||||||
|
$suggested = $this->getSuggestedNameAndTitle($page);
|
||||||
|
|
||||||
|
$cloneOptions = array(
|
||||||
|
'set' => array(
|
||||||
|
// keep original $page modified date and user id, since ajax mode doesn't
|
||||||
|
// give the user the option to edit the page before cloning it
|
||||||
|
'modified' => $original->modified,
|
||||||
|
'modified_users_id' => $original->modified_users_id,
|
||||||
|
// pages cloned in ajax are always unpublished
|
||||||
|
'status' => $page->status | Page::statusUnpublished,
|
||||||
|
'title' => $suggested['title'],
|
||||||
|
'name' => $suggested['name'],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if($this->wire('languages')) {
|
||||||
|
foreach($this->wire('languages') as $language) {
|
||||||
|
if($language->isDefault()) continue;
|
||||||
|
if(!empty($suggested["name$language"])) {
|
||||||
|
$cloneOptions['set']["name$language"] = $suggested["name$language"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$cloneTree = false; // clone tree mode not allowed in ajax mode
|
||||||
|
|
||||||
|
try {
|
||||||
|
$clone = $this->wire('pages')->clone($page, $page->parent, $cloneTree, $cloneOptions);
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
$error = $e->getMessage();
|
||||||
|
$clone = new NullPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Page being cloned
|
||||||
|
*
|
||||||
|
* @return null|Page
|
||||||
|
*
|
||||||
|
*/
|
||||||
public function getPage() {
|
public function getPage() {
|
||||||
return $this->page;
|
return $this->page;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user