protected function getQueryAllowedTemplates(DatabaseQuerySelect $query, $options)
{
static $where = null;
static $where2 = null;
static $leftjoin = null;
$hasWhereHook = self::isHooked('PageFinder::getQueryAllowedTemplatesWhere()');
// if a template was specified in the search, then we won't attempt to verify access
// if($this->templates_id) return;
// if findOne optimization is set, we don't check template access
if ($options['findOne']) {
return;
}
// if access checking is disabled then skip this
if (!$this->checkAccess) {
return;
}
$user = $this->wire('user');
// no need to perform this checking if the user is superuser
if ($user->isSuperuser()) {
return;
}
// if we've already figured out this part from a previous query, then use it
if (!is_null($where)) {
if ($hasWhereHook) {
$where = $this->getQueryAllowedTemplatesWhere($query, $where);
$where2 = $this->getQueryAllowedTemplatesWhere($query, $where2);
}
$query->where($where);
$query->where($where2);
$query->leftjoin($leftjoin);
return;
}
// array of templates they ARE allowed to access
$yesTemplates = array();
// array of templates they are NOT allowed to access
$noTemplates = array();
$guestRoleID = $this->wire('config')->guestUserRolePageID;
if ($user->isGuest()) {
// guest
foreach ($this->wire('templates') as $template) {
if ($template->guestSearchable || !$template->useRoles) {
$yesTemplates[$template->id] = $template;
continue;
}
foreach ($template->roles as $role) {
if ($role->id != $guestRoleID) {
continue;
}
$yesTemplates[$template->id] = $template;
break;
}
}
} else {
// other logged-in user
$userRoleIDs = array();
foreach ($user->roles as $role) {
$userRoleIDs[] = $role->id;
}
foreach ($this->wire('templates') as $template) {
if ($template->guestSearchable || !$template->useRoles) {
$yesTemplates[$template->id] = $template;
continue;
}
foreach ($template->roles as $role) {
if ($role->id != $guestRoleID && !in_array($role->id, $userRoleIDs)) {
continue;
}
$yesTemplates[$template->id] = $template;
break;
}
}
}
// determine which templates the user is not allowed to access
foreach ($this->wire('templates') as $template) {
if (!isset($yesTemplates[$template->id])) {
$noTemplates[$template->id] = $template;
}
}
$in = '';
$yesCnt = count($yesTemplates);
$noCnt = count($noTemplates);
if ($noCnt) {
// pages_access lists pages that are inheriting access from others.
// join in any pages that are using any of the noTemplates to get their access.
// we want pages_access.pages_id to be NULL, which indicates that none of the
// noTemplates was joined, and the page is accessible to the user.
$leftjoin = "pages_access ON (pages_access.pages_id=pages.id AND pages_access.templates_id IN(";
foreach ($noTemplates as $template) {
$leftjoin .= (int) $template->id . ",";
}
$leftjoin = rtrim($leftjoin, ",") . "))";
$query->leftjoin($leftjoin);
$where2 = "pages_access.pages_id IS NULL";
if ($hasWhereHook) {
$where2 = $this->getQueryAllowedTemplatesWhere($query, $where2);
}
$query->where($where2);
}
if ($noCnt > 0 && $noCnt < $yesCnt) {
$templates = $noTemplates;
$yes = false;
} else {
$templates = $yesTemplates;
$yes = true;
}
foreach ($templates as $template) {
$in .= (int) $template->id . ",";
}
$in = rtrim($in, ",");
$where = "pages.templates_id ";
if ($in && $yes) {
$where .= "IN({$in})";
} else {
if ($in) {
$where .= "NOT IN({$in})";
} else {
$where = "<0";
// no match possible
}
}
// allow for hooks to modify or add to the WHERE conditions
if ($hasWhereHook) {
$where = $this->getQueryAllowedTemplatesWhere($query, $where);
}
$query->where($where);
}