Jump to content
Noel Boss

Best Practice to determine if admin from init method?

Recommended Posts

👋 PW Pros…

I have some hooks that I need to bind at the init phase (or even __construct) and I was wondering, and I couldn't find a good and simple way to determine if I'm in the admin. Would be nice if there is a reliable short option to do so, but I can't seem to find one… Is there a coherent way to tell this no matter where I am?

Right now, I use the following method inside one of my modules:

public function isAdmin($page = null)
	{

		if (
			strpos($this->input->url, $this->urls->admin) !== false
			|| $this->process instanceof ProcessPageList
			|| $this->process instanceof ProcessPageEdit
			|| ($page instanceof Page && $page->rootParent->id == $this->config->adminRootPageID)
		) {
			return true;
		}
		return false;
	}

@ryan wouldn't it be nice to have something like wire()->isAdmin(); like wire()->user->isLoggedin(); to tell if we are in admin – very early on (probably even in __construct() phase of modules?

  • Like 1

Share this post


Link to post
Share on other sites

Doesn't this work?

if ($this->page->template == 'admin') {
    echo "in admin";
} else {
    echo "not in admin";
}

It surely works in ready.php. (Maybe you'd have to alter the syntax a bit... wire instead of this)

Just tried this inside one of my modules, and it works as expected:

    public function init() {
        parent::init();
        if ($this->page->template == 'admin') {
            $this->wire->message("in admin");
        } else {
            $this->wire->message("not in admin");
        }
    }

 

Edited by dragan
added module example code
  • Like 2

Share this post


Link to post
Share on other sites

@Noel Boss

I'm using this code in hooks to Templatefile::render and didn't have any issues with it. 

	if (strpos($_SERVER['REQUEST_URI'], $this->wire('config')->urls->admin) === 0 || $this->wire('page')->template->name == 'admin') return;

 

  • Like 2

Share this post


Link to post
Share on other sites

Thanks four your suggestions… However, I'm talking about the init() method inside a module, not ready and not render (for render, the page needs to be there, so ready is already fired) – this is early in the boot process, no page and no template is available at that stage… sometimes not even a process… (at least wherever I tested it) – also parent::init throws an error.I am also not talking about the init.php – this might be different…

4 hours ago, dragan said:

Doesn't this work?

Nope 😉 

2115815220_Screenshot2019-09-29at18_30_08.png.ca4999d379d12ea053ffe88c44de71b8.png

 

@Zeka – thats about what I do with the first and the last test from my example, but it feels very much like a hack for my taste…

I currently use a Hook to extend wire that looks the following:

public function __construct() {
		$this->addHookMethod('Wire::isAdmin', $this, 'isAdminHook');
}


public function isAdminHook(HookEvent $event) {
		$event->return = false;

		if (
			$this->process instanceof ProcessPageList // Admin Page List
			|| $this->process instanceof ProcessPageEdit // Edit Screen
			|| strpos($this->input->url, $this->urls->admin) !== false // determine from Admin url…
			|| ($event->arguments(0) instanceof Page && $event->arguments(0)->rootParent->id == $this->config->adminRootPageID) // if a page is passed…
		) {
			$event->return = true;
		}
}

 

Share this post


Link to post
Share on other sites

Hi @Noel Boss, - I haven't understand why you need init() and why you are not able to use ready(). (Maybe, because you haven't told 😉

But what about testing with prioritizing your hook(s)? Maybe with init() it may run lately, or in ready() (as one of the early birds), will do what you are after??

Links:

https://processwire.com/docs/modules/hooks/#hook-priority

and

 

Share this post


Link to post
Share on other sites

@horst – I need init to bind hooks that can only be bound before ready fires – for example render, or viewable … Therefore, hook priorities don’t help me. I could just bind the hooks anyway, but I only want to bind the hooks, when I really need them… My goal is to not bloat the system with hooks … I use tons of them, but I only wan’t to invoke them wenn really needed.

For example. some of the hooks are access related and since PW does not provide a robust and native way to hook into page access features [viewable about the only option, or filtering find queries, both not great options but it's what you get…] I have to be very early in to boot process, sometimes earlier than init ( __construct() ) … These hooks are costly since I have to check for all pages with related pages and then get a blacklist from ID’s that I can then later use filter my results so I don’t get wrong page counts when requesting pages…

@ryan it would really be great to be able to hook into the access system on a lower api level… (not directly on sql…) you’ve built some nice modules, but they all are on top of the current system and don’t work for find queries…

Share this post


Link to post
Share on other sites
2 hours ago, Noel Boss said:

 @ryan it would really be great to be able to hook into the access system on a lower api level… (not directly on sql…) you’ve built some nice modules, but they all are on top of the current system and don’t work for find queries…

That's not really true. Ryan's Dynamic Roles module does add additional sql clauses to ensure dynamic roles are fully resolved at the database level. Sadly is the module is not very well maintained and it could also be build a bit more flexible (e.g. matching on calculated values instead of just "membership"), but it is possible.

2 hours ago, Noel Boss said:

For example. some of the hooks are access related and since PW does not provide a robust and native way to hook into page access features [viewable about the only option, or filtering find queries, both not great options but it's what you get…] I have to be very early in to boot process, sometimes earlier than init ( __construct() ) … These hooks are costly since I have to check for all pages with related pages and then get a blacklist from ID’s that I can then later use filter my results so I don’t get wrong page counts when requesting pages…

This to me sounds like a very hacky workaround. You initially said you don't want to bloat the system with hooks. Blacklisting IDs and filtering them at runtime is very likely to be way worse for performance than a handful or two more hooks.

Share this post


Link to post
Share on other sites

Hi @LostKobrakai – we are diverting from the subject 😉

My business logic is a bit complicated. I have many organisations, and an organisation have different memberships and depending on these memberships, the users assigned to the organusation can view different pages … and the users themselves have different roles inside the organisation and some pages are blocked or unlocked based on the role in the organisation. I could not find any module or core functionality that let me handle this use case with elegance. So what I do is i get all the pages blocked by a specific selector based on language, membership and role (and sometimes login state etc.) and cache the resulting ids based on these attributes [so they are only fetched once per membership-role combo-language until a page matching relevant template or the user or the organisation changes … complicated eh 😉], this needs to happen very early so I don't miss any query operations later on. I then filter using a hook by appending the id's as a id!=1|2|3 selector … thats the most efficient way I found. – I tried most of the modules out there, not sure if I found this one you mentioned @LostKobrakai – I'll have a look at it, thanks!

Also, I just recently found the ___getQueryAllowedTemplatesWhere() hook in PageFinder.php … I might investigate this one a bit more… (thats the one Dynamic Roles uses as well)

So, back to the topic, I use hooks here, and elsewhere for other purposes inside the init() method and it would be nice to have a consistent and simple way to check if we are in admin or not 🙂

Share this post


Link to post
Share on other sites
2 hours ago, Noel Boss said:

So, back to the topic, I use hooks here, and elsewhere for other purposes inside the init() method and it would be nice to have a consistent and simple way to check if we are in admin or not

I guess this is a bit of a chicken and egg problem. The admin in processwire is hardly anything special based on what the core knows about it. It's a bunch of pages, which just happens to be tightly access controlled and forwarding their handling to process modules instead of rendering templates. So before knowing the page you're on there's not really a good way to know if the request is going to serve an "admin page" or not. To query the current page a lot of things already need to be started, and I guess you want to hook into those before any pages are queried, at best by already knowing the context, which is not going to work.

A good example is the function you've shown in your initial post. It's a good heuristic for determining if the user is in the admin, but also not bullet prove, as there can be normal pages as children of $this->config->adminRootPageID as well. It might rarely happen, but it's possible. The only way to be sure is actually having $page queried.

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Hardoman
      Hello community,
      we have a website running version 3.0.118. The owner would like to have a watermark merged to the images, that are being uploaded in the CKEditor as a requirement.
      Image upload besides the CKEditor within galleries and single images works as a charm already. We also use croppable image 3 there. (PIM2)
      To realize this requirement, I thought of using a hook in the admin area. So, I read a lot in our forums and tested this by adding a hook into the ready.php file.
      $this->addHookAfter('InputfieldFile::fileAdded',function(HookEvent$event){ wire('log')->save('test','Image upload works'); ... The log entry is being created correctly. But when I try to use the pim/watermark-function like in a template, he cannot find the watermark-image anymore. Furthermore, when I try to get the page-id, it does not seem to be accessible, because the application does not seem to know how to reference it, or I dont know the right way to do so…
      So my questions are:
       
      Is this the right attempt at all or will there be another, better workaround? It seems, I cannot access the page object (of the content page) within this scope or file but I would need it to save the processed image inside the right files/id folder Would it be better to place the hook into the admin-template? (or admin.php)
        Thanks for any hints in advance. 🙂
    • By martind
      hi,
      is it possible to change field parent_id from InputfieldPageListSelect to InputfieldPageAutocomplet by addHookAfter('ProcessPageEdit::buildFormContent')?
      thanks,
      martin
       
    • By Noel Boss
      Admin Theme Boss
      A light and clear theme based on Uikit 3
      Features
      Five unique color options Beautifully redesigned login screens Modern typography using Roboto Condensed Extended breadcrumb with edit links Extends AdminThemeUikit, so you can continue using all current and future AdminThemeUikit features Option to activate theme for all users Compatibility with AdminOnStreoids and other third party modules   Updated and Releases
      There is a shiny new release page where you can subscribe to updates for new releases of AdminThemeBoss.   Color Variants:
      ProcessWire Blue


       
      Dark Black


       
      Vibrant Blue

       
      Happy Pink

      Smooth Green *new with 0.6.1*

       
      Requirements
      Requires a current ProcessWire version with AdminThemeUikit installed and activated.
      Installation
      Make sure AdminThemeUikit is activated Go to “Modules > Site > Add New“ Paste the Module Class Name “AdminThemeBoss“ into the field “Add Module From Directory“ Click “Download And Install“ On the overview, click “Download And Install“ again… On the following screen, click “Install Now“

      Manual Installation
      Make sure the above requirements are met Download the theme files from GitHub or the ProcessWire Modules Repository. Copy all of the files for this module into /site/modules/AdminThemeBoss/ Go to “Modules > Refresh” in your admin Click “Install“ on the “AdminThemeBoss“ Module
    • By Clément Lambelet
      Hey!
      I've been working on a Processwire installation (3.0.123) for a few days now and I must have made a big mistake this morning because the links in the admin's main menu no longer appear.
      This is not related to the admin theme, because the bug occurs with all themes (Default, Reno, Uikit).
      I tried to reinstall with the dev version (3.0.136), but the problem is still there. I also uninstalled all the modules I had added, without success. There is no error in the js console. 
      I still can access/view/edit the pages  by going through the admin/page list.
      Thanks in advance for your help!


    • By MateThemes
      Hello everyone!
      I have searched the forum for quite a long time and I tried some solutions for my topic but nothing seems to work.
      I need to create a Settings Page and for a native feeling I want to create it under the main navigation on top. The settings page should hold the Main Logo, some styling and other settings. As I said nothing seems to work for me. I tried to create a Page under Admin with Admin Template and ProcessPageEdit but then I can't assign an image field. 
      I don't want to write a module because it is to much work for only 3 settings.
      I hope someone of the forum could help me out!
      Have a nice day!
×
×
  • Create New...