Jump to content

Robin S

Members
  • Posts

    5,007
  • Joined

  • Days Won

    333

Everything posted by Robin S

  1. What sort of field is user_id? If it's an integer or text field that only stores the ID (I assume it is because of the name and way you are getting the user page via the ID) then you should change to a "user_page" Page Reference field that will hold the actual User page object. On the Advanced tab of the settings for the user_page field tick the Autojoin checkbox. That way the User object associated with each portfolio-detail page will automatically be loaded in a single database query when you do... $profiles = $pages->find("template=portfolio-detail"); ...rather than needing multiple database queries within the foreach. In the foreach you will get the field values from the User object like this: echo $portfolio->user_page->firstname;
  2. I just tested here and no problems with either of those things, but it might depend on what panels you have activated. Maybe some JS error in the browser console will give you a clue?
  3. I can confirm, and it seems like a bug. Please open an issue in the repo so that Ryan can investigate.
  4. I think you must have something else going on that's causing the problem, because using a page ID does work in PW v3 and it's included as an example in the documentation. // Get a page by ID $p = $pages->get(1234);
  5. I would question why you are going down the road of a Process module rather than the standard way of entering and storing data in PW, which is via pages and the Page Edit interface. I expect you will want to store the data that your users are entering, and the simplest way to do that is in pages. And when it comes to providing edit forms for that data Page Edit is going to have a lot of advantages: You probably already understand how fields are added to templates and how fields are presented in Page Edit, so there's less to learn. You can add/sort/arrange fields via the admin GUI rather than in code. You get access control for editing out-of-the-box. You can use the full range of PW fieldtypes and inputfields, many of which wouldn't be usable within a Process module (Repeater, ProFields Table, etc). Is there something in particular you are wanting to do that you don't think would be possible via pages and Page Edit?
  6. You can use a hook to AccessByQueryString::replacementMarkup (see the readme for more info) and do a redirect inside your hook, e.g. $event->wire()->session->redirect('/your-login-page/'); I imagine that these pages are subject to view restrictions by role, i.e. you have to be logged in with a particular role to view those pages. The AccessByQueryString module isn't going to override any existing view restrictions you already have in place - it's only going to add additional restrictions. So if you have existing restrictions like that then you'll have to log your users in somehow ($session->forceLogin ?) but then if you're doing that you don't need AccessByQueryString to restrict/grant view access. So probably this module isn't going to suit your use case.
  7. Info: https://processwire.com/blog/posts/introducing-iftrunner-and-the-story-behind-it/ GitHub repo: https://github.com/ryancramerdesign/IftRunner I don't know if it was ever available via the PW modules directory.
  8. The email notifications for subscribed topics now seem to be truncated when they used to include the full post. @Pete, is it possible to change a setting so that emails are not truncated?
  9. The issue occurs because both InputfieldURL and FieldtypeURL put the value through $sanitizer->url(), and by default the "convertEncoded" option is true. It would be good if this option was configurable for InputfieldURL/FieldtypeURL. As a quick fix you could copy the modules to /site/modules/ and edit usages of $santizer->url() to set convertEncoded false, and maybe open a GitHub issue/request to have that added as a configurable option.
  10. I found this in Account Settings (click the user dropdown in the forum header):
  11. Yes, $config->ajax will be true if the current request is AJAX.
  12. There's no simple way to do this because when a page is moved the page list is updated via AJAX, whereas the core message() / warning() / error() methods require a normal page load in order to appear. But I had fun exploring some workarounds. Maybe one of these will suit or maybe not. In these examples a message is shown whenever a page is moved but of course you would add your own logic show your message more selectively. Option 1: queue a warning() to appear at the next page load via $session->warning(), and use some JS to automatically reload ProcessPageList whenever a page is sorted or moved. In some custom admin JS (you can add this with a hook or by using AdminOnSteroids): // When a page is moved in ProcessPageList $(document).on('pageMoved', '.PageListItem', function() { // Reload location.reload(); }); In /site/ready.php // When a page is moved $wire->addHookAfter('Pages::moved', function(HookEvent $event) { $page = $event->arguments(0); // Show a warning $event->wire()->session->warning("Page '{$page->title}' was moved to parent '{$page->parent->title}'."); }); Result: Option 2: Make use of the fact that when an exception is thrown ProcessPageList will show this as an alert. The below assumes that you only want to show a warning when a page is moved to a new parent and not when it is sorted within its existing parent. If that distinction doesn't matter then you could simplify this by only hooking after ProcessPageSort::execute(). In /site/ready.php // Optional: use Vex for nicer alerts in ProcessPageList $wire->addHookBefore('ProcessPageList::execute', function(HookEvent $event) { $event->wire()->modules->get('JqueryUI')->use('vex'); }); // Before ProcessPageSort::execute $wire->addHookBefore('ProcessPageSort::execute', function(HookEvent $event) { $pps = $event->object; $move_id = (int) $event->wire()->input->post->id; $moved = $event->wire()->pages->get($move_id); // Store original parent ID on the ProcessPageSort object $pps->original_parent_id = $moved->parent->id; }); // After ProcessPageSort::execute $wire->addHookAfter('ProcessPageSort::execute', function(HookEvent $event) { $pps = $event->object; $input = $event->wire()->input; $pages = $event->wire()->pages; $parent_id = (int) $input->post->parent_id; $move_id = (int) $input->post->id; $parent = $pages->get($parent_id); $moved = $pages->get($move_id); // Check if the parent ID has changed from the original (i.e. the page has moved) if($parent->id !== $pps->original_parent_id) { // Show an alert by making use of how exceptions are handled in ProcessPageList throw new WireException("Page '{$moved->title}' was moved to parent '{$parent->title}'."); } }); Result: Option 3: do it all in JavaScript. Whether this is viable depends on what sort of logic you need. With a bit of extra faffing around (not shown here) you can get things like the page IDs and template names from the class names of the page list items which might help. Optionally add the Vex library as in option 2. And then in some custom admin JS: // When a page is moved in ProcessPageList $(document).on('pageMoved', '.PageListItem', function() { var moved_title = $(this).find('.label_title').text(); var $parent = $(this).parent('.PageList').prev('.PageListItem'); var parent_title = $parent.find('.label_title').text(); var $from = $('#PageListMoveFrom').prev('.PageListItem'); if($from.length) { // Page was moved to a different parent var from_title = $from.find('.label_title').text(); ProcessWire.alert('Page "' + moved_title + '" was moved to parent "' + parent_title + '" from parent "' + from_title + '"'); } else { // Page was sorted within its existing parent ProcessWire.alert('Page "' + moved_title + '" was sorted within parent "' + parent_title + '"'); } }); Result:
  13. GET variables are automatically added to MarkupPagerNav links when they are set to $input->whitelist(). In this case you are dealing with an array value, so the input variables should probably be passed through $sanitizer->array() first before you do anything else with them. $y = $sanitizer->array($input->get('y')); // There are also other ways you can apply sanitizers to input variables If you do that then the sanitizer will give you an an array value from input in the format of "y[]=bar&y[]=baz" or "y=bar,baz" (these should be encoded when in a URL though). Then you would set: $input->whitelist('y', $y); By default MarkupPagerNav uses the comma separated form in its links, but if you prefer the square brackets then you can set: echo $results->renderPager(['arrayToCSV' => false]); But you won't get the exact format you showed because square brackets are typically encoded in URLs.
  14. Hi @adrian, Do you think that it would a good idea to add options for some automatic pruning and cleanup of the log files and exception HTML files that Tracy writes to /site/assets/logs/tracy/? It doesn't occur to me to look in this folder very often for remote sites, but I see that error.log in particular has the potential to grow quite large. For instance on one site I have around 50,000 lines in error.log, most of which relate to minor issues in an older version of Tracy itself... "Undefined offset: 0 on line: 11 in Tracy Console Panel" (this seems to be resolved in newer versions because I'm not seeing it recently) ...or possibly relate to issues in the PW core... "PHP Notice: Undefined index: path in .../wire/core/WireInput.php:985 @ https://mydomian.com//xmlrpc.php?rsd" (does this look like a core issue to you or is it related to Tracy error screens?) So far I haven't had any real problems with either the size of the Tracy logs or the number of exception HTML files but if these have the potential to grow indefinitely then perhaps it could become a problem in some cases if users don't remember to check the Tracy logs directory. If you decide it would be worthwhile to have options to automatically prune the Tracy logs then maybe it would make sense to have these logs conform to the file extension and delimiters used by the core PW logs, and that way you could make use of the prune methods in WireLog.
      • 4
      • Like
  15. Yes, it's because if you specify a field then behind the scenes setAndSave() calls $pages->saveField(), and that doesn't trigger a Pages::saved hook. Whereas saving a property of the page that isn't a field (e.g. its name, status, etc) does require the saving of the page itself and therefore triggers a Pages::saved hook. But rather than having to remember these kinds of details I think in most cases you are better off using hooks to methods with "ready" in their name, e.g. Pages::saveReady, Pages::saveFieldReady and then you don't need to perform that same save action inside your hook. It should be possible to set "locked" status in a Pages::saveReady hook - it's working for me here.
  16. You have an endless loop happening - you're hooking Pages::saved, and then saving the page inside the hook, which calls Pages::saved, which saves the page, etc. So you need some extra logic to exclude the page you are saving in the hook. In this case you can identify the page you want to exclude by checking if it is locked. if ($page->template == "invoice" && !$page->isLocked()) { //... Alternatively you can hook Pages::saveReady, then you don't need to worry about endless loops because you are hooking just before the page is about to be saved and therefore you don't need to save within the hook itself. $wire->addHookAfter("Pages::saveReady", function($event) { $page = $event->arguments(0); if ($page->template == "invoice") { // lock page if inv_status = paid (1034) or cancelled (1038) if ($page->inv_status == 1034 || $page->inv_status == 1038) { $page->addStatus("locked"); } } });
  17. @ryan, thanks for the cool new InputfieldTextTags! Could the inputfield styling be tweaked slightly to bring it into line with other PW inputfields? 1. The input height is slightly shorter than the standard PW text and select inputs. It would be good if the height matched. 2. When used for single item selections it would be good if the font size was the same as standard text inputs and selects. For multiple item selections the font size should probably stay smaller because there is extra tag UI that has to fit inside the input. 3. When used for single item selections the dropdown caret icon is a different style and position than that used for existing selects and AsmSelects. 4. When used for single item selections the containing inputfield expands slightly when the tag dropdown is shown. 5. The border radius applied to the top left and right of input when the tag dropdown is shown is a change from the existing PW UI style. Small stuff I know but it all subtly feeds into the user's confidence in the system (sub-conscious thought: "With such attention to detail this is clearly a well-maintained and reliable product") Edit: some SCSS that could be a starting point... .InputfieldTextTags { .selectize-input { &.dropdown-active { border-radius:0; } } .selectize-control.single { .selectize-input { font-size:16px; height:40px; background-image:url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2224%22%20height%3D%2216%22%20viewBox%3D%220%200%2024%2016%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%20%20%3Cpolygon%20fill%3D%22%23354b60%22%20points%3D%2212%201%209%206%2015%206%22%20%2F%3E%0A%20%20%20%20%3Cpolygon%20fill%3D%22%23354b60%22%20points%3D%2212%2013%209%208%2015%208%22%20%2F%3E%0A%3C%2Fsvg%3E%0A"); background-repeat:no-repeat; background-position:100% 50%; padding:10px 10px 0; &:after { content:none; } } } }
  18. Yep, a pro module from Ryan himself: https://processwire.com/store/login-register-pro/
  19. @ryan, maybe this update needs to automatically trigger a modules refresh? Because when trying to use InputfieldTextTags (in a module config) the assets URLs were wrong: In the line in InputfieldTextTags::renderReady()... $url = $config->urls($this->className()); ...$url was null. Doing Modules > Refresh fixed the problem.
  20. Sounds like a problem with backing up the database rather than the version you are trying to update to. Are you able to do a manual database backup (via ProcessDatabaseBackups) or do you get the same CPU issue? I recently had an issue with database backups but it was causing a memory issue rather than CPU. Turned out it was due to having SessionHandlerDB installed and the sessions were never getting deleted, resulting in a massive sessions table as described in this topic (along with the fix): Unless you have SessionHandlerDB installed this won't be the problem in your case, but it would still be good to check your database in PhpMyAdmin or Adminer to see if there are any very large tables that could be taxing the CPU during a backup.
  21. @PWaddict, when you change the bookmark in the module config, save, and then check the Lister results, are you doing this each time via the flyout menu? In case it's not obvious, the settings for a bookmark are communicated to the Lister via the bookmark URL. The selector and columns are encoded into the "bm" parameter: When you change a bookmark and save the module config the link in the bookmarks flyout menu changes to use the updated "bm" parameter. This means that if you navigated to the module config from a previous bookmark you can't use the browser back button to see the updated bookmark results in the Lister because you'll be returning to the old URL. Likewise, you can't have the Lister open in one tab and change the bookmark settings in another tab and then just refresh the Lister tab. If this doesn't solve your issue I'll need to get some steps to follow for a test case that will let me reproduce the issue.
  22. There's no overhead to pages that is worth worrying about. In my opinion Page Reference fields are a better choice than Select Options fields in 90% of cases - they're more powerful, flexible and future-proof. They're very easy to set up thanks to @adrian's wonderful Page Field Select Creator module. And they do what you're wanting out of the box - via the core "Allow new pages to be created from field?" setting, or via Page Field Edit Links if your referenced pages evolve to contain multiple fields and you want to fill those out as new pages/options are created.
  23. I can't reproduce that. Please explain in more detail.
  24. In v0.1.2 I've added support for columns to be saved in bookmarks. See the updated readme for details, and the screenshot for how you can easily copy/paste a bookmark string from the bottom of the Lister Selector results. Are you able to do this in the core Lister or Lister Pro? This module uses Lister/ListerPro internally and doesn't do anything different with the results section. So maybe a question for the general forum or Lister Pro board rather than for this module thread.
  25. @MarkE, if you are sorting when getting pages from the database (as opposed to sorting a PageArray in memory) you can only sort by properties that have a corresponding column in the database. By default PW doesn't store paths for each page in the database, which is why you can't sort by path. But if you install the core PagePaths module then PW will store paths in the database and so I think you should then be able to sort by path. Another way to do this when you have two levels of pages in your results is to do "sort=parent.sort, sort=sort".
×
×
  • Create New...