public function testConstruction() { $kirby = $this->kirbyInstance(); $site = $this->siteInstance($kirby); $page = new Page($site, '1-a'); $this->assertInstanceOf('Kirby', $page->kirby()); $this->assertEquals($kirby, $page->kirby()); $this->assertInstanceOf('Site', $page->site()); $this->assertEquals($site, $page->site()); $this->assertInstanceOf('Site', $page->parent()); $this->assertEquals($site, $page->parent()); $this->assertEquals('1-a', $page->dirname()); $this->assertEquals(1, $page->depth()); $this->assertEquals($kirby->roots()->content() . DS . '1-a', $page->root()); $this->assertEquals('1', $page->num()); $this->assertEquals('a', $page->uid()); $this->assertEquals('a', $page->id()); $this->assertEquals('1-a', $page->diruri()); $this->assertEquals('/a', $page->url()); $this->assertTrue($page->isCachable()); $this->assertEquals('a', $page->slug()); $this->assertTrue($page->is($page)); $this->assertTrue($page->equals($page)); $this->assertFalse($page->isSite()); $this->assertFalse($page->isActive()); $this->assertFalse($page->isOpen()); $this->assertTrue($page->isVisible()); $this->assertFalse($page->isInvisible()); $this->assertFalse($page->isHomePage()); $this->assertFalse($page->isErrorPage()); $this->assertEquals($page->id(), (string) $page); }
/** * Returns the parent page that has the template from which we get our role/access settings from * * @param Page $page * @return Page|NullPage Returns NullPage if none found * */ public function getAccessParent(Page $page) { if ($page->template->useRoles || $page->id === 1) { return $page; } $parent = $page->parent(); if ($parent->id) { return $this->getAccessParent($parent); } return new NullPage(); }
/** * Returns the parent page that has the template from which we get our role/access settings from * * @param Page $page * @param string Type, one of 'view', 'edit', 'create' or 'add' (default='view') * @param int $level Recursion level for internal use only * @return Page|NullPage Returns NullPage if none found * */ public function getAccessParent(Page $page, $type = 'view', $level = 0) { if (!in_array($type, $this->types)) { $type = $this->getType($type); } if ($page->template->useRoles || $page->id === 1) { // found an access parent if ($type != 'view' && $level > 0 && $page->template->noInherit != 0) { // access parent prohibits inheritance of edit-related permissions return new NullPage(); } return $page; } $parent = $page->parent(); if ($parent->id) { return $this->getAccessParent($parent, $type, $level + 1); } return new NullPage(); }
/** * Return all sibling pages before this one until matching the one specified * * @param Page $page * @param string|Page $selector May either be a selector string or Page to stop at. Results will not include this. * @param string $filter Optional selector string to filter matched pages by * @param PageArray|null $siblings Optional PageArray of siblings to use instead of all from the page. * @return PageArray * */ public function prevUntil(Page $page, $selector = '', $filter = '', PageArray $siblings = null) { if (is_null($siblings)) { $siblings = $page->parent()->children(); } else { if (!$siblings->has($page)) { $siblings->add($page); } } $siblings = $this->prevAll($page, '', $siblings); $all = new PageArray(); $stop = false; foreach ($siblings->reverse() as $sibling) { if (is_string($selector) && strlen($selector)) { if (ctype_digit("{$selector}") && $sibling->id == $selector) { $stop = true; } else { if ($sibling->matches($selector)) { $stop = true; } } } else { if (is_int($selector)) { if ($sibling->id == $selector) { $stop = true; } } else { if ($selector instanceof Page && $sibling->id == $selector->id) { $stop = true; } } } if ($stop) { break; } $all->prepend($sibling); } if (strlen($filter)) { $all->filter($filter); } return $all; }
/** * Auto-assign a page name to this page * * Typically this would be used only if page had no name or if it had a temporary untitled name. * * Page will be populated with the name given. This method will not populate names to pages that * already have a name, unless the name is "untitled" * * @param Page $page * @param array $options * - format: Optionally specify the format to use, or leave blank to auto-determine. * @return string If a name was generated it is returned. If no name was generated blank is returned. * */ public function ___setupPageName(Page $page, array $options = array()) { $defaults = array('format' => ''); $options = array_merge($defaults, $options); $format = $options['format']; if (strlen($page->name)) { // make sure page starts with "untitled" or "untitled-" if ($page->name != $this->untitledPageName && strpos($page->name, "{$this->untitledPageName}-") !== 0) { // page already has a name and it's not a temporary/untitled one // so we do nothing return ''; } // page starts with our untitled name, but is it in the exact format we use? if ($page->name != $this->untitledPageName) { $parts = explode('-', $page->name); array_shift($parts); // shift off 'untitled'; $parts = implode('', $parts); // put remaining back together // if we were left with something other than digits, // this is not an auto-generated name, so leave as-is if (!ctype_digit($parts)) { return ''; } } } if (!strlen($format)) { $format = $page->parent()->template->childNameFormat; } if (!strlen($format)) { if (strlen($page->title)) { // default format is title $format = 'title'; } else { // if page has no title, default format is date $format = 'Y-m-d H:i:s'; } } $pageName = ''; if (strlen($format)) { // @todo add option to auto-gen name from any page property/field if ($format == 'title') { if (strlen($page->title)) { $pageName = $page->title; } else { $pageName = $this->untitledPageName; } } else { if (!ctype_alnum($format) && !preg_match('/^[-_a-zA-Z0-9]+$/', $format)) { // it is a date format $pageName = date($format); } else { // predefined format $pageName = $format; } } } else { if (strlen($page->title)) { $pageName = $page->title; } else { // no name will be assigned } } if ($pageName == $this->untitledPageName && strpos($page->name, $this->untitledPageName) === 0) { // page already has untitled name, and there's no need to re-assign the untitled name return ''; } $name = ''; if (strlen($pageName)) { // make the name unique $pageName = $this->wire('sanitizer')->pageName($pageName, Sanitizer::translate); $numChildren = $page->parent->numChildren(); $n = 0; do { $name = $pageName; if ($n > 0) { $nStr = "-" . ($numChildren + $n); if (strlen($name) + strlen($nStr) > self::nameMaxLength) { $name = substr($name, 0, self::nameMaxLength - strlen($nStr)); } $name .= $nStr; } $n++; } while ($n < 100 && $this->count("parent={$page->parent}, name={$name}, include=all")); $page->name = $name; $page->set('_hasAutogenName', true); // for savePageQuery, provides adjustName behavior for new pages } return $name; }
/** * Return this page's parent Page, or the closest parent matching the given selector. * * @param string $selector Optional selector string. When used, it returns the closest parent matching the selector. * @return Page|NullPage Returns a Page or a NullPage when there is no parent or the selector string did not match any parents. * */ public function parent($selector = '') { if (!$this->parent) { return new NullPage(); } if (!strlen($selector)) { return $this->parent; } if ($this->parent->matches($selector)) { return $this->parent; } if ($this->parent->parent_id) { return $this->parent->parent($selector); } // recursive, in a way return new NullPage(); }
/** * Auto-populate some fields for a new page that does not yet exist * * Currently it does this: * - Sets up a unique page->name based on the format or title if one isn't provided already. * - Assigns a 'sort' value'. * * @param Page $page * */ public function ___setupNew(Page $page) { if (!$page->parent()->id) { // auto-assign a parent, if we can find one in family settings $parentTemplates = $page->template->parentTemplates; $parent = null; if (!empty($parentTemplates)) { $idStr = implode('|', $parentTemplates); $parent = $this->get("include=hidden, template={$idStr}"); if (!$parent->id) { $parent = $this->get("include=all, template={$idStr}"); } } if ($parent->id) { $page->parent = $parent; } } if (!$page->name) { // auto-assign a name if possible $format = $page->parent()->template->childNameFormat; $pageName = ''; if (strlen($format)) { if ($format == 'title') { if (strlen($page->title)) { $pageName = $page->title; } else { $pageName = $this->_('untitled'); } } else { if (!ctype_alnum($format) && !preg_match('/^[-_a-zA-Z0-9]+$/', $format)) { // it is a date format $pageName = date($format); } else { // predefined format $pageName = $format; } } } else { if (strlen($page->title)) { $pageName = $page->title; } else { // no name will be assigned } } if (strlen($pageName)) { // make the name unique $pageName = $this->wire('sanitizer')->pageName($pageName, Sanitizer::translate); $numChildren = $page->parent->numChildren(); $n = 0; do { $name = $pageName; if ($n > 0) { $name .= "-" . ($numChildren + $n); } $child = $page->parent->child("name={$name}, include=all"); // see if another page already has the same name $n++; } while ($child->id); $page->name = $name; $page->set('_hasAutogenName', true); // for savePageQuery, provides adjustName behavior for new pages } } if ($page->sort < 0) { // auto assign a sort $page->sort = $page->parent->numChildren(); } }