Source of file SiteDataService.php
Size: 6,274 Bytes - Last Modified: 2021-12-23T10:07:53+00:00
/var/www/docs.ssmods.com/process/src/code/services/SiteDataService.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 | <?php /** * Capture / cache some commonly used data elements for each page * * @author marcus */ class SiteDataService { protected $items = array(); protected $mapped = array(); /** * * @var string */ public $itemClass = 'DataObjectNode'; /** * * @var string */ public $baseClass = 'SiteTree'; /** * * @var string */ public $itemSort = 'ParentID ASC, Sort ASC'; /** * The field to use for parent ordering * * @var string */ public $parentField = 'ParentID'; /** * Additional fields to be queried from the SiteTree/Page tables * * @var array */ public $additionalFields = array( 'Title', 'MenuTitle', 'URLSegment', 'ParentID', 'CanViewType', 'Sort', 'ShowInMenus', ); /** * Needed to create the menu item objects * * @var Injector */ public $injector; public function __construct() { } public function getItem($id) { $this->getItems(); return isset($this->items[$id]) ? $this->items[$id] : null; } public function getItems() { if (!$this->items) { $this->generateMenuItems(); } return $this->items; } public function generateMenuItems() { $all = array(); $allids = array( ); $public = $this->getPublicNodes(); foreach ($public as $row) { $allids[$row['ID']] = true; $all[] = $row; } // and private nodes $private = $this->getPrivateNodes(); foreach ($private as $row) { $allids[$row['ID']] = true; $all[] = $row; } $others = $this->getAdditionalNodes(); foreach ($others as $row) { $allids[$row['ID']] = true; $all[] = $row; } $deferred = array(); $final = array(); $hierarchy = array(); $counter = 0; $this->iterateNodes($final, $all, $allids, 0); $ordered = ArrayList::create(); // start at 0 if (isset($final[0]['kids'])) { foreach ($final[0]['kids'] as $id) { $node = $final[$id]; $this->buildLinks($node, null, $ordered, $final); } } } protected function queryFields() { $fields = array( '"' . $this->baseClass .'"."ID" AS ID', 'ClassName', 'Created', 'LastEdited', ); foreach ($this->additionalFields as $field) { $fields[] = $field; } return $fields; } protected function getPublicNodes() { $fields = $this->queryFields(); $query = new SQLQuery($fields, '"' . $this->baseClass .'"'); $query = $query->setOrderBy($this->itemSort); // if the user is logged in, we only exclude nodes that have a specific permission set on them if (Member::currentUserID()) { $query->addWhere('"CanViewType" NOT IN (\'OnlyTheseUsers\')'); } else { $query->addWhere('"CanViewType" NOT IN (\'LoggedInUsers\', \'OnlyTheseUsers\')'); } $this->adjustPublicNodeQuery($query); $this->adjustForVersioned($query); $results = $query->execute(); return $results; } protected function adjustPublicNodeQuery(SQLQuery $query) { } /** * Get private nodes, assuming SilverStripe's default perm structure * @return SS_Query */ protected function getPrivateNodes() { if (!Member::currentUserID()) { return array(); } $groups = Member::currentUser()->Groups()->column(); if (!count($groups)) { return $groups; } $fields = $this->queryFields(); $query = new SQLQuery($fields, '"'.$this->baseClass.'"'); $query = $query->setOrderBy($this->itemSort); $query->addWhere('"CanViewType" IN (\'OnlyTheseUsers\')'); if (Permission::check('ADMIN')) { // don't need to restrict the canView by anything } else { $query->addInnerJoin('SiteTree_ViewerGroups', '"SiteTree_ViewerGroups"."SiteTreeID" = "SiteTree"."ID"'); $query->addWhere('"SiteTree_ViewerGroups"."GroupID" IN (' . implode(',', $groups) . ')'); } $this->adjustPrivateNodeQuery($query); $this->adjustForVersioned($query); $sql = $query->sql(); $results = $query->execute(); return $results; } protected function adjustForVersioned(SQLQuery $query) { $ownerClass = $this->baseClass; $stage = Versioned::current_stage(); if ($stage && ($stage != 'Stage')) { foreach ($query->getFrom() as $table => $dummy) { // Only rewrite table names that are actually part of the subclass tree // This helps prevent rewriting of other tables that get joined in, in // particular, many_many tables if (class_exists($table) && ($table == $ownerClass || is_subclass_of($table, $ownerClass) || is_subclass_of($ownerClass, $table))) { $query->renameTable($table, $table . '_' . $stage); } } } } protected function adjustPrivateNodeQuery(SQLQuery $query) { } protected function getAdditionalNodes() { return array(); } protected function buildLinks($node, $parent, $out, $nodemap) { $kids = isset($node['kids']) ? $node['kids'] : array(); $node = $this->createMenuNode($node); $out->push($node); $node->Link = ltrim($parent ? rtrim(($parent->Link == '' ? 'home' : $parent->Link), '/') . '/' . $node->URLSegment : $node->URLSegment, '/'); if ($node->Link == 'home') { $node->Link = ''; } foreach ($kids as $id) { $n = $nodemap[$id]; $this->buildLinks($n, $node, $out, $nodemap); } } /** * Creates a menu item from an array of data * * @param array $data * @returns MenuItem */ public function createMenuNode($data) { $cls = $this->itemClass; $node = $cls::create($data, $this); $this->items[$node->ID] = $node; return $node; } protected function iterateNodes(&$final, $remaining, $ids, $lastcount) { $deferred = array(); foreach ($remaining as $row) { // orphan if ($row[$this->parentField] && !isset($ids[$row[$this->parentField]])) { continue; } if (!isset($final[$row['ID']])) { $final[$row['ID']] = $row; } if ($row[$this->parentField] && !isset($final[$row[$this->parentField]])) { $deferred[$row['ID']] = $row; } else { // add to the hierarchy of things $existing = isset($final[$row[$this->parentField]]['kids']) ? $final[$row[$this->parentField]]['kids'] : array(); $existing[] = $row['ID']; $final[$row[$this->parentField]]['kids'] = $existing; } } if (count($deferred) == $lastcount) { return; } $lastcount = count($deferred); if (count($deferred)) { $this->iterateNodes($final, $deferred, $ids, $lastcount); } } } |