Jump to content

Project design: main shop + hundreds of affiliates


tpr
 Share

Recommended Posts

I'm asking for some help/advice here on my next project.

There is one main shop and many affiliates (their exact number is unknown but ranges from 50 to about 1000, at max). 

Each affiliate should have a few own pages (e.g. "about us"), and some that inherit content from the main shop (e.g. "products").  All of them would have their own domain. They wouldn't be so complicated (no multi-language, ecommerce and such). 

I would like to use only one PW installation with a page structure like this:

— MAIN SHOP
— — news
— — products

— AFFILIATES

— — AFFILIATE 1
— — — about us
— — — services
— — — products (inherited)
— — — news (inherited)

— — AFFILIATE 2
— — — about us
— — — services
— — — products (inherited)
— — — news (inherited)
...

The idea is to restrict admin access for affiliates so that they could edit/see only their own branch. I've made some quick checks and it seems to work.

We don't expect too much traffic but with that high numbers pages will inevitably go up after a while. I know PW scales well but I just want to make sure. The other systems I know would require much more time and effort, at least it seems so atm.

Do you think this setup is feasible or should I look for another solution?

Link to comment
Share on other sites

I ended up using 1st level pages for the main shop:

(MAIN SHOP)
 news
 products

 about-us

 services

— AFFILIATES

— — AFFILIATE 1
— — — about-us
— — — services

— — AFFILIATE 2
— — — about-us
— — — services

This way the urls are fixed (/products, /services, etc). However, these urls are loading the affiliate's matching pages. Subpage are served using url segments.

Internal links would contain the full url, inlcuding the main shop's too, which is overriden using a Page::path hook in the ready.php file. The nice thing is that this change seems fully global, so far I haven't found a link where it failed, including the admin pages. So if one affiliate's editor edit its "about-us" page and click on the "View" tab, it will navigate to "/about-us" instead of "/affiliates/affiliate2/about-us/", which is just fine.

On template level I have pre-defined variables for the different levels:

- $page

- $affiliate (the active one that will be determined by domain name later)

- $currentPage (determined by the url segment, if any)

I'm really happy so far that I'm using PW for this site. There's still a ton of work to be done but it seems it will work. To be honest I don't know how I would do this without PW, but now I can roll out the very first demo in about a week (including front-end development), which is so cool.

  • Like 2
Link to comment
Share on other sites

The idea is to restrict admin access for affiliates so that they could edit/see only their own branch. I've made some quick checks and it seems to work.

Hi @tpr - I am curious how you set this up - I have a similar situation and went with the Dynamic Roles module, but I am not super happy with this approach, so I'll probably end up with a custom hook to further limit access to specific page trees (given that each page tree shares the same templates).

Anyway, I'd like to hear how you accomplished this, as I am sure would others.

Link to comment
Share on other sites

Branch visibility will be implemented only in a later phase, but I used "Page Edit Per User" module plus another one, "Admin Page Hider" (not 100% sure, I tried a few similar, found here on the forums). I just quickly checked if this thing could work and though it wasn't perfect, it looked feasible. I've also set permissions at template level, of course.

DynamicRoles seemed the ultimate way to accomplish this but there was always something that didn't work the way I planned.

I may put only front-end edit links to editors (using FEEL) to disallow full access to admin. This way I could connect editor to a specific branch (1:1) and simply redirect or show 404 if he tries to access other pages (with a hook). Plus front-end editing can be advertised as an extra addition so chances are this will be the way.

I'll come back if this part will be done (and also if not :)). However, the project first needs to gain enough interest to be started.

Link to comment
Share on other sites

Thanks for the details. I have also been using Admin Page Hider ( since I built it :) ), and it is working well at my end. However I am tempted to make it optionally work in reverse so that all pages are hidden from all users unless the user's role is listed in the Admin Page Hider settings for that parent page - or something along those lines. Would make it much more efficient than having to hide all new branches as they are added. Any thoughts on this?

Link to comment
Share on other sites

Just been playing around with limiting branch visibility and have something that seems to be working quite well - please test carefully for your needs though - I already had one false start with this!
 
This lets a user only see a branch with the top parent "name" equal to the name of their role. For example if you give the users of each affiliate a role like: affiliate-1 this will match the name of the Affiliate 1 parent page (of course: affiliate-1) and that will be the only branch of the tree that will be visible.
 
Providing a GET id variable limits the listed page tree to just the branch with that parent. Using this hook forces it to that all the time.
 
As I said, I am not yet sure how safe/stable this is, but so far I like the results, although I am not sure about overriding $_GET['id'] like this. There is likely a better way!

if(!wire('user')->isSuperuser() && !isset($_GET['id'])) {

    $this->addHookBefore('ProcessPageList::execute', null, 'setTreeRoot');

    function setTreeRoot() {
        foreach(wire('user')->roles as $role){
            $p = wire('pages')->get("has_parent!=admin, name={$role->name}");
            if($p->id) {
                $pid = $p->id;
                break;
            }
        }
        $_GET['id'] = $pid;
        if(isset($_GET['open']) && $_GET['open'] == $pid) wire('input')->get->open = null;
    }

}
I am currently using this along with a modified version of the PageEditPerUser module which now works to also match the user's role to the parent page. 

So far so good, but I am expecting there is something I have overlooked - will keep things updated here.

Edited by adrian
Fix a tree doubling bug when "open" is set and matches the branch parent.
  • Like 4
Link to comment
Share on other sites

Thanks, I will definitely try this when the time comes - it will be only in the second phase (if ever).

I would tie user name instead of role to a branch. If I get it right your code requires setting each user a new role, which is I guess unnecessary, and an overkill on a larger user (editor) base.

Ideally I would add a new field to users, eg. "home_branch", where the superuser could select the user's own tree.

  • Like 1
Link to comment
Share on other sites

Thanks, I will definitely try this when the time comes - it will be only in the second phase (if ever).

I would tie user name instead of role to a branch. If I get it right your code requires setting each user a new role, which is I guess unnecessary, and an overkill on a larger user (editor) base.

Ideally I would add a new field to users, eg. "home_branch", where the superuser could select the user's own tree.

I guess I am not understanding how selecting a "home_branch" for each user is easier than giving them a role. I am also using the role to control editing permissions for some pagetable templates as well, so in my case I think it is the logical approach, but obviously the home_branch field could work equally well or better with different requirements. 

Link to comment
Share on other sites

In my setup I may need hundreds of editors so creating hundreds of roles seems an overkill. I would give them the same role and select the tree they can edit - one user, one page (and its subpages).

So if a new affiliate is added, I would add one new editor and select one page that he can see in the admin and edit.

I have no pagetables so perhaps that's why I see my idea better for this purpose.

  • Like 2
Link to comment
Share on other sites

Right - sorry I understand - I didn't realize that there would only be one user/editor per branch. In my case there will be several per branch which is why the role approach makes sense to me, but in your situation, that makes perfect sense :)

  • Like 1
Link to comment
Share on other sites

Looks like just what the doctor ordered, thanks! I can't test it on the site I need this because it is demoed to the client. But on another site works beautifully at first sight. 

One thing: "$page->editable()" returns false even if the page is under the selected branch and the user could edit it otherways. I did try "$page->parent()->editable()" too but no success.

Is there a way to check the editability of the page? My FEEL module currently fails because of this.

Link to comment
Share on other sites

One thing: "$page->editable()" returns false even if the page is under the selected branch and the user could edit it otherways. I did try "$page->parent()->editable()" too but no success.

If I understand correctly, I don't think I am seeing that issue here, so I am probably not understanding. Here is a screenshot of my restricted branch - you can see that the EDIT action button is available:

post-985-0-98062100-1447974909_thumb.png

Sorry - what am I missing? Can you send me a screenshot showing editable not being available in the restricted branch?

Thanks for your help testing!

Link to comment
Share on other sites

@tpr - I just discovered something that was probably impacting the interaction of this module with FEEL - I had it set to autoload only in the admin. I just committed a new version that also autoloads on the front-end. Of course you will need to refresh modules (I think that is enough) or uninstall/reinstall to get the autoload to change.

However, I am not sure if this fixes what you were seeing or not. I am actually using FREDI (I need to try FEEL) on the site I just deployed to this to and the problem was actually the opposite to what I think you were seeing. My restricted user was getting the FREDI edit link because the $page->editable() was returning true, because this module was not being loaded to restrict it and return false.

Anyway, hopefully when you read this you can let me know more and I can fix any issue you might still be having.

Link to comment
Share on other sites

Sorry, no success so far. I have updated the module, refresh, uninstall and then install but $page->editable() doesn't return true. If I make it literally true in FEEL then the edit link appears and the lightbox shows the admin page, so the page is editable to the user.

Autoload seemed the culprit but somehow it doesn't work. I will investigate the issue later, maybe it's something on my side. Thanks for the help!

Link to comment
Share on other sites

Weird - I feel :) like there must be something on your end confounding things. Take a look at these screenshots.

post-985-0-73560300-1447993839_thumb.png

post-985-0-63132900-1447993837_thumb.png

These are based on this code:

if($page->editable()) {
    echo 'editable';
}
else {
    echo 'not editable';
}

in the template code. Both Branch One and Branch Two are on the same template. The user is restricted to the Branch One branch using the module.

Any other modules that might be interfering? 

What version of PW?

PS If you think it might be an autoload issue, try a log statement from the module to confirm, or load the module manually in the template?

PPS I just tried FEEL (which looks great btw) and the edit link shows up:

post-985-0-40823400-1447994748_thumb.png

using:

if($page->editable()) {
    echo 'editable
    <script src="https://raw.githubusercontent.com/rolandtoth/FEEL/master/FEEL.min.js"></script>
    <a href="'.$page->editUrl.'" class="feel feel-inline">Edit</a>
    ';
}
else {
    echo 'not editable';
}
Link to comment
Share on other sites

I have no issues in the admin, PW edit links appear fine and visibility is OK. Using PW 2.70.

Are you using an older version of FEEL? It has been rewritten as a module and usage was changed to $page->feel($options). The module render edit links to the page only if the page is editable, which should be the case according to your findings. I guess there's something with FEEL, I will try to track it down when I will have a larger screen in front of me

Link to comment
Share on other sites

Just to clarify, those screenshots are from the front-end - just the standard PW template. I am linking directly to the min.js version of FEEL on your Github account - you'll see that in my code when your at a bigger screen :)

I didn't try using the optional helper function that you mention on Github, but I think that is probably why you are having an issue. Is your _funct.php file being included from _init.php ? If it is, then that is the problem since AdminRestrictBranch is being called from ready(), not init() which is after your FEEL check for $page->editable().

I can probably change it to init() though which should solve your problem. I'll take a look and make sure everything works as expected and then commit a new version.

Link to comment
Share on other sites

Thanks for the link to the new repo - you should update the first post of the support thread as well :)

Yes, I hook to init in Feel. The question is that I really need that so perhaps your module shouldn't be changed. 

Not sure exactly what you are saying here - do you need it in init() or not? Sounds like if you do, then I need mine to change. Regardless I just committed a new version just before your message came through - the editable hook is now in init() so I think it should work just fine with FEEL. I will try your new version now, but I think it should work perfectly now.

Link to comment
Share on other sites

Just checked with your new FEEL and it's working great here.

Just a side note, you have a: Notice: Undefined offset: 0 in /Users/ajones/Sites/pwtest/site/modules/FrontEndEditLightbox/FrontEndEditLightbox.module on line 203

Let me know if it's working at your end now too.

Link to comment
Share on other sites

I wish I could say AdminRestrictBranch works great but...

IT WORKS F***** GREAT! :)

Unfortunately that's not entirely true for FEEL. I found a mistake that haven't show up so far because I was mainly testing with superuser rights. I was checking if the actual page was editable and added FEEL js/css if yes. Now on pages that included edit links targeting other pages and the "hosting" page itself was not editable, assets weren't added. Obviously with superadmin the current page was always editable. Now I modified my module and it uses only Page hooks, so perhaps it was working with your previous module version too.

Thanks for the other FEEL reports, will check them.

  • Like 1
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...