/** * Does this page have the specified status number or template name? * * See status flag constants at top of Page class * * @param Page $page * @param int|string|Selectors $status Status number or Template name or selector string/object * @return bool * */ public function is(Page $page, $status) { if (is_int($status)) { return (bool) ($page->status & $status); } else { if (is_string($status) && wire('sanitizer')->name($status) == $status) { // valid template name or status name if ($page->template->name == $status) { return true; } } else { if ($page->matches($status)) { // Selectors object or selector string return true; } } } return false; }
/** * 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(); }
/** * Run maintenance for a page that was just saved or deleted * * @param Page $page * @return bool * */ protected function maintenancePage(Page $page) { if (is_null($this->cacheNameSelectors)) { // locate all caches that specify selector strings and cache them so that // we don't have to re-load them on every page save try { $query = $this->wire('database')->prepare("SELECT * FROM caches WHERE expires=:expire"); $query->bindValue(':expire', self::expireSelector); $query->execute(); $this->cacheNameSelectors = array(); } catch (Exception $e) { $this->trackException($e, false); $this->error($e->getMessage(), Notice::log); return false; } if ($query->rowCount()) { while ($row = $query->fetch(PDO::FETCH_ASSOC)) { $data = json_decode($row['data'], true); if ($data !== false && isset($data['selector'])) { $name = $row['name']; $selectors = new Selectors($data['selector']); $this->cacheNameSelectors[$name] = $selectors; } } } } else { // cacheNameSelectors already loaded once and is in cache } // determine which selectors match the page: the $clearNames array // will hold the selectors that match this $page $n = 0; $clearNames = array(); foreach ($this->cacheNameSelectors as $name => $selectors) { if ($page->matches($selectors)) { $clearNames["name" . ++$n] = $name; } } // clear any caches that expire on expireSave or specific page template $sql = "expires=:expireSave OR expires=:expireTemplateID "; // expire any caches that match names found in cacheNameSelectors foreach ($clearNames as $key => $name) { $sql .= "OR name=:{$key} "; } $query = $this->wire('database')->prepare("DELETE FROM caches WHERE {$sql}"); // bind values $query->bindValue(':expireSave', self::expireSave); $query->bindValue(':expireTemplateID', date(self::dateFormat, $page->template->id)); foreach ($clearNames as $key => $name) { $query->bindValue(":{$key}", $name); } $result = $query->execute(); $qty = $result ? $query->rowCount() : 0; if ($qty) { $this->log(sprintf($this->_('Maintenance expired %d cache(s) for saved page'), $qty)); } return $result; }