/** * Is the given page in a state where it can be saved? * * @param Page $page * @param string $reason Text containing the reason why it can't be saved (assuming it's not saveable) * @param string $fieldName Optional fieldname to limit check to. * @param array $options Options array given to the original save method (optional) * @return bool True if saveable, False if not * */ public function isSaveable(Page $page, &$reason, $fieldName = '', array $options = array()) { $saveable = false; $outputFormattingReason = "Call \$page->setOutputFormatting(false) before getting/setting values that will be modified and saved. "; $corrupted = array(); if ($fieldName && is_object($fieldName)) { $fieldName = $fieldName->name; } if ($page->hasStatus(Page::statusCorrupted)) { $corruptedFields = $page->_statusCorruptedFields; foreach ($page->getChanges() as $change) { if (isset($corruptedFields[$change])) { $corrupted[] = $change; } } // if focused on a specific field... if ($fieldName && !in_array($fieldName, $corrupted)) { $corrupted = array(); } } if ($page instanceof NullPage) { $reason = "Pages of type NullPage are not saveable"; } else { if ((!$page->parent || $page->parent instanceof NullPage) && $page->id !== 1) { $reason = "It has no parent assigned"; } else { if (!$page->template) { $reason = "It has no template assigned"; } else { if (!strlen(trim($page->name)) && $page->id != 1) { $reason = "It has an empty 'name' field"; } else { if (count($corrupted)) { $reason = $outputFormattingReason . " [Page::statusCorrupted] fields: " . implode(', ', $corrupted); } else { if ($page->id == 1 && !$page->template->useRoles) { $reason = "Selected homepage template cannot be used because it does not define access."; } else { if ($page->id == 1 && !$page->template->hasRole('guest')) { $reason = "Selected homepage template cannot be used because it does not have the required 'guest' role in it's access settings."; } else { $saveable = true; } } } } } } } // check if they could corrupt a field by saving if ($saveable && $page->outputFormatting) { // iternate through recorded changes to see if any custom fields involved foreach ($page->getChanges() as $change) { if ($fieldName && $change != $fieldName) { continue; } if ($page->template->fieldgroup->getField($change) !== null) { $reason = $outputFormattingReason . " [{$change}]"; $saveable = false; break; } } // iterate through already-loaded data to see if any are objects that have changed if ($saveable) { foreach ($page->getArray() as $key => $value) { if ($fieldName && $key != $fieldName) { continue; } if (!$page->template->fieldgroup->getField($key)) { continue; } if (is_object($value) && $value instanceof Wire && $value->isChanged()) { $reason = $outputFormattingReason . " [{$key}]"; $saveable = false; break; } } } } // FAMILY CHECKS // check for a parent change and whether it is allowed if ($saveable && $page->parentPrevious && $page->parentPrevious->id != $page->parent->id && empty($options['ignoreFamily'])) { // page was moved if ($page->template->noMove && ($page->hasStatus(Page::statusSystem) || $page->hasStatus(Page::statusSystemID) || !$page->isTrash())) { // make sure the page's template allows moves. only move laways allowed is to the trash, unless page has system status $saveable = false; $reason = "Pages using template '{$page->template}' are not moveable (template::noMove)"; } else { if ($page->parent->template->noChildren) { $saveable = false; $reason = "Chosen parent '{$page->parent->path}' uses template that does not allow children."; } else { if ($page->parent->id && $page->parent->id != $this->config->trashPageID && count($page->parent->template->childTemplates) && !in_array($page->template->id, $page->parent->template->childTemplates)) { // make sure the new parent's template allows pages with this template $saveable = false; $reason = "Can't move '{$page->name}' because Template '{$page->parent->template}' used by '{$page->parent->path}' doesn't allow children with this template."; } else { if (count($page->template->parentTemplates) && $page->parent->id != $this->config->trashPageID && !in_array($page->parent->template->id, $page->template->parentTemplates)) { $saveable = false; $reason = "Can't move '{$page->name}' because Template '{$page->parent->template}' used by '{$page->parent->path}' is not allowed by template '{$page->template->name}'."; } else { if (count($page->parent->children("name={$page->name}, id!={$page->id}, include=all"))) { $saveable = false; $reason = "Chosen parent '{$page->parent->path}' already has a page named '{$page->name}'"; } } } } } } return $saveable; }
public function renderChild(Page $page) { $outputFormatting = $page->outputFormatting; $page->setOutputFormatting(true); $class = ''; $type = ''; $note = ''; $label = ''; $icons = array(); if (in_array($page->id, $this->systemIDs)) { $type = 'System'; if ($page->id == $this->config->http404PageID) { $label = $this->_('404 Page Not Found'); } else { if ($page->id == $this->config->adminRootPageID) { $label = $this->_('Admin'); } else { if ($page->id == $this->config->trashPageID && isset($this->actionLabels['trash'])) { $label = $this->actionLabels['trash']; } } } // Label for 'Trash' page in PageList // Overrides page title if used // if label is not overridden by a language pack, make $label blank to use the page title instead if (in_array($label, array('Trash', 'Admin', '404 Page Not Found'))) { $label = ''; } } if ($page->getAccessParent() === $page && $page->parent->id) { $accessTemplate = $page->getAccessTemplate(); if ($accessTemplate && $accessTemplate->hasRole('guest')) { $accessTemplate = $page->parent->getAccessTemplate(); if ($accessTemplate && !$accessTemplate->hasRole('guest') && !$page->isTrash()) { $class .= ' PageListAccessOn'; $icons[] = 'key fa-flip-horizontal'; } } else { $accessTemplate = $page->parent->getAccessTemplate(); if ($accessTemplate && $accessTemplate->hasRole('guest')) { $class .= ' PageListAccessOff'; $icons[] = 'key'; } } } if ($page->id == $this->config->trashPageID) { $note = "< " . $this->_("Trash open: drag pages below here to trash them"); // Message that appears next to the Trash page when open $icons = array('trash-o'); // override any other icons } else { if ($page->hasStatus(Page::statusTemp)) { $icons[] = 'bolt'; } if ($page->hasStatus(Page::statusLocked)) { $icons[] = 'lock'; } if ($page->hasStatus(Page::statusDraft)) { $icons[] = 'paperclip'; } } if (!$label) { $label = $this->getPageLabel($page); } if (count($icons)) { foreach ($icons as $n => $icon) { $label .= "<i class='PageListStatusIcon fa fa-fw fa-{$icon}'></i>"; } } $a = array('id' => $page->id, 'label' => $label, 'status' => $page->status, 'numChildren' => $page->numChildren(1), 'path' => $page->template->slashUrls || $page->id == 1 ? $page->path() : rtrim($page->path(), '/'), 'template' => $page->template->name, 'actions' => array_values($this->getPageActions($page))); if ($class) { $a['addClass'] = trim($class); } if ($type) { $a['type'] = $type; } if ($note) { $a['note'] = $note; } $page->setOutputFormatting($outputFormatting); return $a; }