Jump to content

MarkE

Members
  • Posts

    1,051
  • Joined

  • Last visited

  • Days Won

    12

Everything posted by MarkE

  1. The module can be found at https://github.com/MetaTunes/AdminInModal Use at your own risk! The hook is specific to my app, but I hope the following gives the general idea: wire()->addHookAfter('User::hasPagePermission', function(HookEvent $event) { // Get the object the event occurred on, if needed $user = $event->object; // An 'after' hook can retrieve and/or modify the return value $return = $event->return; // Get values of arguments sent to hook (if needed) $permission = $event->arguments(0); $p = $event->arguments(1); /* Your code here, perhaps modifying the return value */ // Is it a page we need to customise access for? $templates = ['Membership', 'Member', 'Profile', 'Subscription', 'Payment', 'MemberShop', 'Booking', 'NewsItem']; $permissions = ['page-edit', 'page-add']; if ($p and in_array($p->template, $templates) and $permission and in_array($permission, $permissions)) { // Get the member-user $currentUser = $this->users->getCurrentUser(); if ($currentUser and $currentUser->isLoggedin()) { if ($currentUser->hasRole('member')) { $email = $currentUser->email; $memberPage = $this->pages->get("has_parent=/memberships/, template=Member, email=$email"); if ($currentUser->memberOnly) $return = false; // Member-only users can only access pages as defined below if ($memberPage->id) { $membershipPage = $memberPage->parent; //... and a lot more like that ($profilePage etc.) ... $editablePages = new PageArray(); $addablePages = new PageArray(); $editablePages = $editablePages->add($membershipPage)->add($profilePage)->add($siblings)->add($currentSub)->add($shops)->add($subsPaymentPages)->add($draftNewsPages)->add($bookingPages); $addablePages = $addablePages->add($membershipPage)->add($memberPage); // pages where creation of children is allowed if ($editablePages->has($p) and $permission == 'page-edit') $return = true; if ($addablePages->has($p) and $permission == 'page-add') $return = true; } } } } // Populate back return value, if you have modified it $event->return = $return; });
  2. The pageload is about 3 seconds, but the hook doesn't seem to affect it. Because fancybox loads almost instantly and displays a rotating wheel, I don't think the wait is a problem. The module checks page-editable before rendering. The hook then adds the permission.
  3. Obviously the user needs page-edit rights for the page in question. My approach to this was to write a hook after User::hasPagePermission which only gives them page-edit / page-add permission for the specific pages to which they are allowed access (i.e. in my app, their own membership records). If they try and access any other pages (e.g. directly in a browser, assuming they know the page-id or name, as the page in fancybox has modal=1, so no menu), they get a "You don't have access to edit" message.
  4. Fancybox works well on Windows and iOS. I have built a small module around it (a bit like a cut-down FEEL).
  5. Parallel to the approach I described above, I have also tried uikit's modal with an embedded iframe. This works adequately (and fixes the iPad issue with uk-overflow-auto), but there are a couple of snags - no doubt due to my incompetence: I can't work out how to make the modal/iframe height match the height of the embedded admin page - I can set the iframe width to 100%, but have to set a "hard" pixel height of, say 800, which may then leave whitespace for a small page. Because the target page for the iframe can vary (a range of pages may be edited), multiple modals/iframes are created via a loop (with toggle ids keyed to page ids). These then take about 15-20 seconds to load, which is not really acceptable. No doubt there is some clever way of avoiding this using jQuery, but I haven't worked it out yet. I will try some of the other suggestions as well. I also tried using the FEEL module, but that has the iPad problem too - see As mentioned there, I am not able to debug an iPad because I don't have a Mac. Similarly, @bernhard, I have no idea how to do a screencast on an iPad, but I can report the bug with a text description.
  6. Actually this seems to be a problem with the admin theme generally - for example, the tree panel in the uikit theme does not scroll on an iPad either. So looks like a bug.
  7. Well, whaddya know? Replace 'modal' by 'panel' and it works ... on a PC. But the iPad scrolling issue still persists (scrolls the background rather than the panel).
  8. Maybe, maybe not. If I could do an admin panel in the front end then I might be able to have an opinion ?
  9. This post is related to but is a different way of tackling the problem. The idea is to use the JqueryUI.module in the front end to present a restricted access admin page in a modal (class pw-modal). However the JqueryUI module doesn't seem to work properly in the front end (I have it working in the back end OK). I'm guessing that this is because the front end page has not loaded all the .js that is needed (that would normally be loaded in the back end). My _main.php loads the following from the core at the moment: 'wire/modules/AdminTheme/AdminThemeUikit/uikit/dist/js/uikit.min.js' 'wire/modules/AdminTheme/AdminThemeUikit/uikit/dist/js/uikit-icons.min.js' 'wire/modules/Jquery/JqueryCore/JqueryCore.js' 'wire/modules/Jquery/JqueryUI/JqueryUI.js' Any ideas what else I need, or have I got hold of the wrong end of the stick?
  10. Thanks - that's what I was looking for. Here is my final code for the hook: $p->name = $this->pages->names()->uniquePageName($p->name); $p->parent = pages()->get('/news/'); $event->arguments(0, $p); Works a treat!
  11. Thanks - that's effectively what I was doing, except in a before Pages::save hook, thus: $p = $event->arguments(0); //..some code here ..// $p->parent = pages()->get('/news/'); $event->arguments(0, $p); It works fine so long as the name does not already exist under the new parent. I seem to recall that the core uses a routine to add -1, -2 etc. but I can't find it.
  12. I've googled a fair bit but can't find anywhere an API method to move a page to be under a new parent. Obviously this would have to handle naming conflicts. Is there one? Or a module? Or just a code snippet ? Thanks
  13. Almostly certainly. I have to press on with the rest of the site now, but will try and come back to this when I have time as I prefer the lightbox interface. (However, I don't have an Apple Mac to use the iPad developer tools, so maybe if someone here does, they would have a better chance of tracking down the problem)
  14. Re the scrolling issue, there is a wider problem in that installing FEEL disables scrolling in the iPad after switching from back-end to front-end (regardless of whether a modal has been opened). Unfortunately, this means that I have had to uninstall FEEL and use a simpler home-built module.
  15. UPDATE: This seems to be a much more general problem than my OP implies. In fact it occurs whenever switching from back-end to front-end on the iPad. For example - when in the back-end, I select "view site" and the site page will not scroll. However, it is clearly just an issue with my site (it doesn't happen with the processwire demo site) but I'm not sure where to look for the problem. Any ideas? UPDATE 2: The problem described in this post is a side-effect of having FEEL installed - so the work-round in my OP works provided FEEL is uninstalled. I've posted the bug on the other thread.
  16. This is a bit complicated to explain, so bear with me ... Essentially my problems seem to be with the way that iPads (and presumable all IOS devices) deal with modals. I started by implementing the @tpr's FrontEndEditLightbox module in order to provide a controlled method for editing pages while in the front end. This all worked beautifully in development and when testing it on my Windows PC. However, on an iPad, it ran into a problem: the modal would not scroll - only the background scrolled. I vaguely recall having come across this "feature" once before, but can't remember how I resolved it (e.g. a fix or a work-round). There is a separate thread on the FEEL-specific issue: Pending a solution there, I tried doing a simple module of my own. Having previously, successfully, used pw-modal and the JqueryUI module in the backend, I tried using it to open a back-end modal from the frontend. However, it seems that it doesn't operate in this mode (e.g. data-href attribute is not passed). So, taking the line of least resistance, I just supplied a href attribute (see code at foot), with ?modal=1. This opens a "full screen" modal-type page, which would be fine for my purposes and, again, works on the PC. (I also supplied a custom button on the admin page to return to the frontend page.) On the iPad what happens is: On touching the button, the admin page opens in a "full-screen" modal (i.e. no background and no menus/headers) - just like the PC - and scrolls too ? On returning to the front-end page, all scrolling is disabled, even after refreshing or going to another page in the same site ? I am at a loss to work out what is going on and it seems that you need a desktop Apple mc to operate developer debug tools on an iPad ? Any fixes, work-rounds or even just vague clues would be much appreciated! Thanks. Code: $this->wire('modules')->get('JqueryUI')->use('modal'); $btn = $this->wire('modules')->get("InputfieldButton"); if ($settings['mode'] == 'page-add') { $btn->attr('href', wire('config')->urls->admin . "page/add/?parent_id=" . $p->id . "&template_id=" . $template->id . "&open=" . $settings['open'] . "&back=1&modal=1&name=MF" . $today); } else { $btn->attr('href', wire('config')->urls->admin . "page/edit/?id=" . $p->id . "&open=" . $settings['open'] . "&back=1&modal=1"); } (Note: $p is the current page; the 'back' parameter is just to load the back button - to the front end - on the admin page; the 'open' parameter configures how the front-end page will display on returning to it) EDIT: PS - the problem (i.e. no scrolling in front-end on return) is not resolved by removing modal=1 (i.e. just opening in a normal admin page). PPS - the problem can be cleared by closing and re-loading safari, so maybe it is something to do with cached css?
  17. Hi @tpr, are you happy with the code above? Also, I have a couple of issues which may or may not be bugs: Sometimes the "lightbox" opens as a page not a modal - this only happens the first time after the page containing the feel() is loaded. Scrolling doesn't work on a ipad - the background scrolls rather than the modal. Otherwise it all seems to work nicely. EDIT - I suspect (1) may be because the js has not loaded
  18. The following seems to work: In $defaults (below line 46) add 'template' => '', Below line 265 (now 266) add $template = !empty($settings['template']) ? $this->templates->get($settings['template']) : null; $template_id = $template ? '&template_id=' . $template->id : ''; Amend line 267 (now 270) to $editUrl = $this->wire('config')->urls->admin . 'page/add/?parent_id=' . $parent . $lang . $fields . $template_id;
  19. This module seems really useful for the club membership system I am building - it allows members to easily edit their own records without access to the rest of the back-end. However, I also need to use page-add mode and I can't get this to work fully. It seems like there is a "parent" but no "template" setting for page-add so, if a parent has a family of more than one template allowed, there is no API to select the right template. I think I can see how to hack FrontEndEditLightbox.module to fix this, but I wonder if I am missing something, or whether it would be better for @tpr to update the module? Thanks.
  20. The hook is on Pages::added. I tried it on Pages::saved as well. I also tried saving the page (in the first hook, not the second ? ). All the other fields were present and correct, it was just the images that were missing as they were not saved at the time the hook ran, The bar dumps indicated that the path to the files had been set, but that there were no files in that directory. Immediately afterwards (by inspection, and as picked up by my LazyCron), the files appeared.
  21. UPDATE: I think I have found the problem (and a sort of solution). The problem seems to be that the file system has not saved the image files when the hook is run. I suspect that it makes no difference what hook is used as they will all execute before the files have been saved. So my sort-of-solution is to take the code out of the hook and instead execute it from a LazyCron (everyMinute). That's timely enough for what I need. After executing, the source page is removed so that it does not execute again. If anybody has any better ideas, I'd be interested to know.
  22. Hmm. I can see that the array I have is actually the array defining the FieldtypeImage rather than an array of a FieldtypeImage object! EDIT Some more clues: The copying is within an addHookAfter('Pages::added',...) hook. It seems that the path for the images is set, but that the actual images are not saved to the files directory until a later stage. So maybe I need to move the whole code to another hook? However, I only want the code to execute when the new page (with the images) is added (it is created by FormBuilder).
  23. Yes - no luck with that. I've now found the docs on Pageimages (e.g. https://processwire.com/api/ref/pageimages/add/) which implies I can add a filename string or an existing Pageimage type. My field ('images') is FieldtypeImage which seems (on debugging) to be an array, but not of images, rather something like this: [gif jpg jpeg png, 1, InputfieldImage, 0, 1, 6, Array, 1, 0, 0, sitemap, Site, 0, 0, grid, on, 0, 90, 0, 0] I'm struggling to find what property of FieldtypeImage I should use to add to another FieldtypeImage.
  24. I have a function which copies (selected) fields from one page to another. This was working fine until I added a field of type FieldtypeImage. I can't get this to copy across. The original code (before adding the image type) was foreach ($foundPage->fields as $field) { if (!in_array($field->name, $unwantedFields)) { $foundPage->$field = $p->$field; } } where $foundPage is a matching page for $p (same template) and $unwantedFields is an array of field names not to be copied. When the image field was added to the template, no errors were reported, but the image field would not copy over. The field $p->images seemed to be empty. So I tried this code: foreach ($foundPage->fields as $field) { $fieldName = $field->name; $updateField = $p->getFields()->get("name=$fieldName"); if (!in_array($field->name, $unwantedFields)) { $foundPage->$field = $updateField; } } That did populate the $updateField with the image field and showed it as a type FieldtypeImage, but I got the message "Item added to ProcessWire\Pageimages is not an allowed type" Given that the images field is an array (and actually I would prefer to merge rather than replace the contents), I tried adding in something like: if ($field->type == 'FieldtypeImage') { foreach ($updateField as $image) { $foundPage->$field->add($image); } } but that did nothing (nor threw any errors). Obviously there's something I don't quite understand about FieldtypeImage and/or WireArray. I read https://processwire.com/docs/fields/images/, but that didn't seem to cover it. Any ideas what I am doing wrong? Thanks.
  25. I've been using this field type for a while and very good it is too, but now I am scratching my head: I have a runtime_markup field ('runtime_markup_expiryDate') with PHP as follows return ($page->parent->name == 'memberships' and $page->latestSubscription()->id) ? date('d/m/Y', $page->latestSubscription()->subsEndDate) : 'Non-subscriber'; This works well in the back-end, but gives the wrong result in the API. If I retrieve the field in the API, it just gives 01/01/1970. However, if I remove the formatting in the PHP, thus: return ($page->parent->name == 'memberships' and $page->latestSubscription()->id) ? $page->latestSubscription()->subsEndDate : 'Non-subscriber'; it works correctly in the API (gives the right date, e.g. 30/09/2019) but obviously just gives the integer in the back end (e.g. 1569798000). The curious thing is that, in this case I can't work out where the formatting is applied in the API (which might be related to the cause of the problem) What is going on? Any suggestions for a fix or work-round? Thanks.
×
×
  • Create New...