Jump to content

thetuningspoon

Members
  • Posts

    691
  • Joined

  • Last visited

  • Days Won

    6

Posts posted by thetuningspoon

  1. I just ran into this same issue. I tried to make a field dependent on one of the roles and it broke the profile, even though neither the roles field or the dependent field were visible in the profile at all.

    I created a copy of the ProcessProfile module under /site/modules/ and replaced this:

    if(count($form->getErrors())) {
      $this->error($this->_("Profile not saved")); 
      return;
    }

    With this:

    $errors = $form->getErrors();
    if(count($errors)) {
      if(count($errors) == 1 && strpos($errors[0], 'showIf') !== false) {
      	// Everything is okay
      }
      else {
        $this->error(implode('; ', $errors)); // Show the actual errors instead of just a generic message
        return;
      }
    }

    This way if there is only one error message and it is related to a 'showIf' field dependency, the form will save anyway.

    • Like 1
  2. I did try turning off SessionHandlerDB and using php's session_write_close() and that didn't seem to help either. I think I also tried $session->close() (which just calls php's function).

    Moreover, there are a couple ajax requests which do need to be able to write to the session, so a blanket session_write_close if $config->ajax is true wouldn't solve my issue :(

    Edit: I am going to try Redis. Will let you know how it goes.

  3. I am having trouble with executing multiple AJAX requests at the same time. The response is very slow and seems to be synchronous instead of asynchronous. I am using jQuery's ajax() function, so I don't think there's any issue on the client side. I think it is an issue with Session locking/blocking.  I read somewhere that SessionHandlerDB would resolve this issue, but enabling it has not improved the situation any. I just want to confirm whether or not SessionHandlerDB is designed to handle concurrent requests efficiently, so I know what to rule out.

  4. @ukyo Is it possible to send each email individually, as with the base WireMail class?  I tried the following, but it still includes all recipients in the email headers of each email that gets sent:

     

    foreach($recipients as $recipient) {
      $m->to(null);
      $m->to($recipient);
      $m->send();
    }

     

  5. On 7/21/2017 at 4:37 PM, cpx3 said:

    Hi there,

    using the PHPMailerModule I want to send an embedded image but always get the error-message that this function does not exist. When I send the message directly via PHPMailer from another website it works fine. What am I doing wrong?


    Thanks in advance,

    Bernhard

    How are you calling WireMail? If you are using "$mail = new WireMail()" then I don't think it knows to use the WireMailPHPMailer module and will use the default WireMail() instead. Use "$mail = wireMail()" instead.

  6. 46 minutes ago, szabesz said:

    This post by Ryan partially answers your questions:

     

     

    Thanks for that. I've read it over a few times now but I'm not quite getting it.

    Quote

    Having page-view, page-edit, page-create, page-add in the template access is actually unnecessary for us, but it does reduce the quantity of permissions and roles necessary to achieve a particular access control scenario 

    How is this unnecessary? How else would one determine where each permission is applicable? Does he mean you could create a separate permission for each template, e.g. page-edit-home page-edit-basic-page, etc.?

     

    Quote

    I'd rather go in the opposite direction and reduce what permissions can be assigned at the template (by default), but make it definable. Imagine going to Modules > Process > ProcessTemplate > [edit module settings] and selecting from an asmSelect which permissions should be assignable at the template level -- a nice power user option?

    Yes, yes, yes... THIS sounds like the type of solution I would expect from ProcessWire. Simple, powerful, and un-opinionated. What became of this?

    • Like 2
  7. Here is a simple hook I put together to allow for a custom redirect when a page is not viewable:

    /**
     * Automatically redirects users to the login page if they do not have view access to a page. To use, set "Show a 404 Page" in your template's Access settings.
     */
    wire()->addHookBefore('ProcessPageView::pageNotFound', function($e) {
    	$page = $e->arguments[0];
    	if($page === null || $page instanceof NullPage) return; // This was a real 404, not caused by page access (have to check for NullPage, not just null as implied in ProcessPageView docs)
    
    	$e->session->redirect($this->pages->get(1)->url, false); // Redirect to the home page (login)
    });

    This solves my immediate need. I can then hook Page::viewable() as needed and let PW take care of the rest.

    I'm hoping @ryan may have some guidance on all of this.

    • Like 1
  8. An update:

    I missed something in my last post. It is possible to use a page ID instead of a URL for the redirect in the template Access tab, which solves the subfolder issue.

    However! For some strange reason, ProcessPageView::checkAccess specifically disallows using the home page (ID of 1) for the page ID here, silently overwriting it with page ID of the admin login form. This is unfortunate and ironic, as the enforced requirement of making the home page viewable to guests makes it a logical choice to serve as the login page for my application!

    The other strange behavior here is that if you do use a page ID instead of a URL, ProcessWire does not actually do a $session->redirect() to the page at all, but just renders the content of the alternate page at the original requested URL. This seems to be how ProcessWire's admin login works as well. Perhaps a way to keep the user on the original requested page after they login? This was a surprise to me, as it's not mentioned in the UI.

    I also found it interesting to discover that ProcessWire's own admin application shuns its own permissions system (or at least the template-level access part of it). If you look at the access settings for the Admin template, no view permissions are granted at all to any of the roles. Instead they are granted, I believe, based on the presence or absence of a single permission with the name of the process module associated with that page. This leads me to believe that I would be better off doing something similar in my own application.

     

    The more I dive into this more confused I'm becoming. This is really the only part of ProcessWire that seems unintuitive to me. I get the permissions -> roles -> users bit, but the template level access permissions seem arbitrary to me. For example:

     

    1. Why are only certain permissions available to set on a per-template basis?

    2. Why are four of these permissions displayed prominently in a table while the rest are in the "additional edit permissions and overrides" section? 

    3. What is it exactly that determines which permissions are special, and how do I create my own special permissions like these?

    4. Why does the page-edit permission have 'sub-permissions' underneath it, but no other permission does?  Is there a way of structuring my own custom permissions in the same fashion?

  9. I've been getting more and more into building full fledged web apps using PW as a framework. I use PW for data modeling and storage, user management, etc., and extend the Page class for different templates to add functionality to specific types of pages/data models. It is a very simple and powerful way to develop. 

    However, one thing that I have struggled with is finding the right way to approach page view access for users of an application (This would also apply to a password-protected area of any PW site). I'm going to try and boil this down to the most simple, common scenario, and go from there:

     

    I am building an app where every page in the app (except for the login screen) should be password protected. Should I...

     

    1. Turn off page view access in the template access settings for the guest user and use the settings to redirect the user to a login page.

    This has the drawback that you cannot disable guest view of the home page (a built-in PW limitation that seems a bit arbitrary). You are also limited in how you can define what to do when the page is not viewable (you must use the options provided in the admin interface), and you do not have the option of continuing to load the page with an alternate view (for example, a login form). Also, sometimes it requires configuring a lot of settings for a lot of different templates.  It also doesn't give you page-specific access control.

     

    2. Leave the access settings wide open but write some code at the top of my template files, init.php, or ready.php to redirect users who are not logged in.

    This has the disadvantage that it only applies if ProcessWire gets that far into the page load process, and it doesn't effect any other aspect of ProcessWire (for example, whether the page is available in a $pages->find()). If I wanted, I could allow anyone to reach any page and just show/hide the content based on the user's permissions or role. If the user doesn't have permission, I could keep them on the same page but show the login. Once they logged in, they'd be on the page they were originally looking for.

     

    3. Write my own hook before or after Page::viewable and/or ProcessPageView::execute (or somewhere else?) to switch access on or off and redirect based on my own requirements.

    This should be more reliable and secure than #2 and more flexible than #1, but it feels kind of like reinventing the wheel. Maybe the best approach is some combination of #1 and #3, with #2 reserved only for showing and hiding individual sections of a page that is already viewable.

     

    I'd be very interested to hear how others are handling this.

  10. Hi @Mike Rockett -- @melody and I took a look at this this morning. It looks like this is an issue with 0000-00-00 00:00:00 null dates in our strict MySQL environment. After replacing the NULL_DATE constant at the top of the module file with 'CURRENT_TIMESTAMP' and replacing the 0000-00-00 00:00:00 dates in Blueprints/schema-update-v2.sql and Blueprints/schema-update-v3.sql with the same, the problem went away after re-installing the module.

    Hope that helps.

    • Like 1
  11. @zoaked and I are working on this project together. There is one other important quirk that I don't think was mentioned above, and that is that the only fields that are not being saved when the hook is in place are Page fields (FieldtypePage). It does not matter which Inputfield type (asmselect, checkboxes, etc.) the Page field is using.

    So, to very broadly summarize:

    1. Page 1 is saved
    2. Hook before Pages::saveReady() is fired
    3. New page (Page 2) is created and saved inside the hook (there is a template check to prevent recursion)
    4. Hook finishes and the save on Page 1 is allowed to complete

    Page 2 is created as expected, no problem. The unexpected result is that any changes made to any FieldtypePage fields on Page 1 are not saved. All other field types (text inputs, at least) save correctly. If the hook is removed, Page 1 saves everything correctly again.

    I have tested this on another one of our sites which uses the same site profile (our own custom profile we have created) and the same issue is present.

    I can also confirm zoaked's finding that the issue is not present on a fresh ProcessWire installation using the Minimal Site Profile.

    Could this be caused by some sort of database difference between a fresh install and an older profile which has undergone a few upgrades? We are on the verge of having to start from scratch on this project.

    • Like 1
  12. I'm working on an application in ProcessWire which allows users to have their own publicly accessible storefronts. I'm struggling to figure out how this should be represented in the URL/page tree.

    The ideal finished product would put the user's storefront at a unique url like https://www.example.com/username/store/

    The cart, checkout, and products pages would follow the same structure:

    https://www.example.com/username/store/cart/

    https://www.example.com/username/store/checkout/

    https://www.example.com/username/store/product/

    And so on...

    The problem is that I don't want to have to create a whole new section of the page tree for each new user. So, in effect, I want a url segment (the /username/ bit) that appears before the page name rather than after it. As far as I know, this isn't possible in PW.

    Another approach would be to use a query string variable to identify the user (e.g. https://www.example.com/store/?user=1234 ). This solves the problem of having to create a different tree for every user, but the URL is not nearly as convenient for customers, and it would require passing the parameter through all of my links.

    I suppose I could use query string parameters but then provide a more friendly URL to redirect there, but that doesn't feel quite right to me either.

     

    Anyway, I'm sort of thinking out loud here.  Any other ideas?

  13. I know this is an old thread, but I ran into a similar issue today. I was trying to select a row in a profields Table by the contents of its text field, but selectorValue() was stripping out the "#" character from the selector value, preventing the match from being found.

    I had always sort of assumed that selectorValue just escaped the value to make it safe for a selector, without actually altering the value. But now I see that this isn't the case (and it also limits the length to 100 characters by default).

    It looks like the only way to achieve what I'm looking to do is to strip out double quotes from within the input string that I get and then wrap the whole string in double quotes (as Ryan describes above). If I understand correctly, this would be a safe way to escape the input.

    The only problem with this is that double quotes then cannot be used in the text field, which could be an issue.

    Is there any way to create a safe selector that can handle double quotes in addition to commas, hashes, and the other characters that selectorValue() strips out?

    • Like 1
×
×
  • Create New...