Jump to content

Make pages accessible depending on sub-domain


lenno
 Share

Recommended Posts

Dear all,

first of all - thank you to Ryan and everyone else involved in making this awesome CMS. I absolutely love it!

I want to make parts of my page visible depending on via which sub-domain the page is accessed (which both point to the same ProcessWire installation).

E.g.

boom.website.com

and

whoop.website.com

should result in certain pages being accessible/restricted.

I tried doing this by adding a global (= on every template) field to processwire called 'page_restricted'. The field is of type 'Option'. I now created a hook that intercepts Page::viewable.

The approach is similar to what is discussed here:

https://processwire.com/talk/topic/5174-define-permissions-by-category/

// Module with autoload enabled

[...]

public function init() {
  $this->addHookAfter('Page::viewable', $this, 'checkPage');
}

public function checkPage($event) {
  if(!$event->return) return; // if it was already determined page is not viewable

  $page = $event->object;
  if(!$page->page_restricted) return; // abort if the page has no page_restricted field

  $restriction = $page->page_restricted->id;

  if (!$restriction || $restriction === 1) return; // page_restricted has no value or is set to 1=All 

  $url= $_SERVER["HTTP_HOST"];
  $isBoom = strpos($url,'boom') !== false;
  if ($isBoom && ($restriction === 2)) {
    $event->return = true;
  } else {
    $event->return = false;
  }
}

This has the desired effect that Processwire shows a 404 page in case the page_restricted does not have the value 1=All or 2=Boom.

My problem now is that the regarding pages still show up on my search ($pages->find()) and listings ($page->children()).

How can I make this happen?

I tried adding another hook:

$this->addHookAfter('Page::listable', $this, 'checkPage');

Unfortunately that hook is never called for some reason. Am I not doing it right?

In case someone has a better/more elegant approach to reach the desired effect (show/hide pages depending on domain), please let me know!

Thanks in advance.  :)

René

Link to comment
Share on other sites

Thanks for the answer Nicolas,

maybe i should have added some more information:

Users will usually be guests, but it should also work for users which are logged in in the future.

The third module you posted looks pretty similar to what I am doing right now, it also hooks into Page::viewable. This works perfectly when accessing a page, resulting in a 404 (which is fine), but the page is still listed when doing e.g. $homepage->children() or $homepage->find(). I want the page to dissapear just as for a user who does not have view permissions.

I tried another hook:

$this->addHookBefore('ProcessPageList::find', $this, 'checkPage');

but it does never seem to be called. I am probably doing something wrong here  :rolleyes:

Edit:

Just tried something else:

 public function init() {
    $this->addHookBefore('Pages::find', $this, 'checkPage');
  }

  public function checkPage($event) {
    $event->arguments(0, $event->arguments(0) . ", page_restricted=2");
  }

So I tried to extend the selector for pages to always add 'page_restricted=2' at the end. But it gives me the following error:

Error: Exception: You do not have permission to execute this module - ProcessPageView (in [...]\wire\core\Modules.php line 1022)

#0 [...]\wire\core\Modules.php(940): Modules->getModule('ProcessPageView')
#1 [...]\index.php(233): Modules->get('ProcessPageView')
#2 {main}

This error message was shown because site is in debug mode ($config->debug = true; in /site/config.php). Error has been logged.

I think I am doing something terribly wrong here. 

Edit2:

Well, I found a solution that seems to work:

public function init() {
    $this->addHookAfter('Pages::find', $this, 'checkPage');
  }

  public function checkPage($event) {
    $url = $_SERVER["HTTP_HOST"];
    $isProbes = strpos($url,'probes') !== false;

    $pages  = $event->return;
    foreach ($pages as $page) {
      $x = $page->page_restricted;
      if ($x) {
        if (($x->id === 2 && $isProbes) || ($x->id === 3 && !$isProbes)) {
          $pages->remove($page) ;
        }
      }
    }
  }

If anyone has a better idea how to solve it, I would be glad to hear it.  :)

Link to comment
Share on other sites

Hm, I tried this in template file and I don't get error:

$pages->addHookBefore('find','before');
function before($event) {
    $event->arguments(0, $event->arguments(0) . ", limit=1");
}
echo $pages->find('template=basic-page')->count(); //return 1
Link to comment
Share on other sites

Yes Matjazp, I figured out later that the modification of the argument did not create the problem, but that my selector just didn't seem to have returned any results, which lead to the error message.

Hooking in after Pages->find and removing all the results that I don't want seems to be the better approach.

Other suggestions welcome! Otherwise I'll mark the question as answered in a few days.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...