Jump to content

Robin S

Members
  • Posts

    4,791
  • Joined

  • Days Won

    303

Everything posted by Robin S

  1. Session Info Lists information about active sessions in a similar way to SessionHandlerDB, but for file-based sessions. Only install the module if you are not already using SessionHandlerDB. Installation 1. If you want to be able to see the pages that are being viewed by active sessions then set... $config->sessionHistory = 1; ...in /site/config.php If you have already set $config->sessionHistory to a higher number then you can leave it unchanged: 1 is the minimum needed for use in the Session Info module. 2. Install the Session Info module. A helper module named "Session Extras" will be automatically installed also. 3. If you want to be able to see the IP address and/or user agent for active sessions then visit the module config page for Session Extras and tick the relevant checkboxes. 4. You can now view information about active sessions at Access > Sessions. Screenshots With $config->sessionHistory set to 1 or higher: Additional information is listed when IP address and user agent tracking are enabled in Session Extras: https://github.com/Toutouwai/ProcessSessionInfo https://processwire.com/modules/process-session-info/
  2. When I modify a module that exists in the modules directory I put my initials in the module title or summary as a reminder, e.g. "Some Module: RPS mod". Then I disable the download button and add a notice to the "Download and Update" form just in case I forget. $wire->addHookAfter('ProcessModule::buildDownloadConfirmForm', function(HookEvent $event) { $data = $event->arguments(0); /* @var InputfieldForm $form */ $form = $event->return; $modules = $event->wire()->modules; // Return early if the module isn't already installed if(!$modules->isInstalled($data['class_name'])) return; // Get info about the installed module $info = $modules->getModuleInfoVerbose($data['class_name']); // Return early if special string doesn't occur in the title or summary if(strpos($info['title'], 'RPS mod') === false && strpos($info['summary'], 'RPS mod') === false) return; // Disable download button and add warning notice $update_button = $form->getChildByName('godownload'); if($update_button) { $update_button->value = 'Update disabled (RPS custom mod)'; $update_button->attr('style', 'opacity:0.5;'); $update_button->attr('disabled', 'disabled'); $this->warning('Module has custom RPS modifications: update disabled'); } $event->return = $form;
  3. The API documentation is the place to start. https://processwire.com/search/?q=render(&t=API
  4. There is a way to have pages returned by $pages->find(), $pages->findRaw(), etc, in the order of some supplied IDs. You use "id.sort" in the selector: https://processwire.com/blog/posts/pw-3.0.200/#pages-api-additions $data = $pages->findRaw('id.sort=1014|1|2', ['id', 'name', 'title', 'url']); You have to supply the IDs for all the pages you want to match: https://github.com/processwire/processwire-issues/issues/1581
  5. Oh right, of course it only appears when you have switched to a different user. I can't think of many cases where I would want to stay as the currently selected user without having the ability to switch back to superuser but nice to have the option in case it is needed.
  6. @bernhard, I think your Tracy Debugger might not be up to date. There is no "End Session" button in recent versions. You just can just click any user in the list and immediately change to that user. So it's pretty quick to toggle between two users - remember you can use the "Find user..." filter to find a user by name. The "Logout to Guest" lets you temporarily switch so you can view the front-end as a guest would, but with the debug bar still available even on production. But if you are using ProCache you would need to switch it off before using "Logout to Guest" because otherwise PHP will be bypassed altogether if a cache file exists.
  7. That sounds like the correct result. 1500 is greater than or equal to 1000 and less than or equal to 5000. That use of the pipe isn't valid selector string syntax. The pipe is used as an OR operator within the value... firstname=Mike|Steve ...or within the field... body|sidebar*=carbonated But in the example you give you would need to use OR groups. And as Ryan mentioned earlier you will want to use the @ operator too because you want conditions like "price_list.procedure_price>=1000, price_list.procedure_price<=5000" to be matched within a single repeater item, not a staff_profile page that has one price_list item where procedure_price>=1000 and a different item where procedure_price<=5000. template=staff_profile, staff_location=1119, (@price_list.procedure_price>=1000, @price_list.procedure_price<=5000), (@price_list.procedure_price>=10000, @price_list.procedure_price<=15000)
  8. I can see a couple of problems. The purpose of strtotime() is to "Parse about any English textual datetime description into a Unix timestamp". But you are supplying it with a variable that is already a Unix timestamp. So that will cause strtotime() to fail and return false. And then that false return value is then being supplied to strftime(), which instead needs to be supplied with a Unix timestamp. Also not sure that ucwords() would be needed, as I think the date string returned by strftime() should already be capitalised correctly. So probably it should be this: function dateToItalian($unixtimestamp) { setlocale(LC_TIME, "it_IT.utf8"); return strftime("%a %d %B %Y", $unixtimestamp); }
  9. This is likely to be the problem. As @ngrmm mentioned, selector operators like > and < depend on the fieldtype used, so for a price you would want to use an integer field if you only need whole dollars, or a decimal field for dollars and cents (the decimal field is the better choice for futureproofing).
  10. The ProcessPageList.js is pretty complex and there are things in it I don't understand. I had to do some some rather hacky stuff to get the module working, but the stakes are lower in a module because each person can decide if they want the functionality and are willing to install a beta module to get it. Whereas if I make changes to the core in a PR it might break something for everyone. So I'll wait a while to see if any issues crop up before considering a PR.
  11. The images field value will be a Pageimages object. So when you do... $page_add->field->add() ...this is Pageimages::add(), and according to the documentation for that method it accepts either a Pageimage object or a path to an image file. You can't supply a Pageimages object to Pageimages::add(). So the relevant part of your code would need to be: foreach($page->field as $pageimage) { $page_add->field->add($pageimage); }
  12. Page List Auto Expand Automatically expands the next adjacent page when moving a page in Page List. Usage As you are moving a page in Page List, if you position the yellow move placeholder above a Page List item for a configurable period of time (default is 1000 milliseconds) then that item will expand, allowing the moving page to be dropped as child page. Configuration In the module config you can set the delay before the Page List item adjacent to the move placeholder will be automatically expanded. Restricting the module to certain roles If you want to restrict the module functionality to only certain roles then create a new permission named page-list-auto-expand. If that permission exists then a user's role must have that permission or the module will not have an effect in Page List. https://github.com/Toutouwai/PageListAutoExpand https://processwire.com/modules/page-list-auto-expand/
  13. Tracy Debugger's Console panel can execute any PHP that you would otherwise run from a .php file. You can type code directly into the Console window, or if you prefer to code in your IDE you can save .php files to /site/templates/TracyDebugger/snippets/ and then run them from the Console panel. I also like to use custom actions for Admin Actions for more complicated or lengthy code, or for when I want to set various parameters using PW inputfields.
  14. Sometimes you need to execute a slow task after some event occurs in the PW admin, and normally you have to wait for this task to finish before you can continue using the admin. This is because PHP is "blocking", meaning that while one thing is executing nothing else can execute. There are potentially lots of different kinds of tasks that could be slow, but just as an example suppose you want to generate resized variations of images on a page, and there are a lot of images. You might have a hook like this so that any non-existing variations are created when the page is saved: $pages->addHookAfter('saveReady', function(HookEvent $event) { /** @var Page $page */ $page = $event->arguments(0); // When a gallery page is saved if($page->template == 'gallery') { // Create an image variation for each image foreach($page->images as $image) { $image->size(1200, 1200); } } }); When you save a gallery page in the PW admin, the admin will be unresponsive and will only load again after all the variations have been created. I wanted to find a way for slow tasks to be triggered by events in the PW admin and for the website editor not to have to wait for the task to finish before continuing with other work in the admin. Inspired by this StackOverflow answer I came up with the following solution that seems to work well. Using the image variations task above as an example... First we make use of the URL hooks feature to set up a URL that can trigger tasks to run when it is loaded: // A URL that will trigger tasks when loaded $wire->addHook('/run-task/', function($event) { $input = $event->wire()->input; // A simple check to avoid unauthorised access // You could implement more advanced checks if needed if($input->post('key') !== 'cTdPMBQ7x8b7') return false; // Allow the script to keep running even though we have set a short WireHttp timeout ignore_user_abort(true); // The "create variations" task if($input->post('task') === 'create-variations') { $page_id = (int) $input->post('page'); $p = $event->wire()->pages->get($page_id); // Create an image variation for each image foreach($p->images as $image) { $image->size(1200, 1200); } return true; } return false; }); Then in the Pages::saveReady hook we use WireHttp to load that URL and post parameters that define what task to run and anything else needed for the task (in this case the ID of the page that has been saved). $pages->addHookAfter('saveReady', function(HookEvent $event) { /** @var Page $page */ $page = $event->arguments(0); // When a gallery page is saved if($page->template == 'gallery') { // Load the /run-task/ URL using WireHttp $http = new WireHttp(); // Set a short timeout so we don't have to wait until the script finishes // Timeout values shorter than 1 second can be tried once a core issue is fixed // https://github.com/processwire/processwire-issues/issues/1773 $http->setTimeout(1); $url = $event->wire()->config->urls->httpRoot . 'run-task/'; $data = [ 'key' => 'cTdPMBQ7x8b7', 'task' => 'create-variations', 'page' => $page->id, ]; $http->post($url, $data, ['use' => 'curl']); } }); By doing it this way the task runs in a separate request and the website editor doesn't have to wait for it to finish before they can continue working in the PW admin.
  15. Yes, certain system pages are forced to the bottom of the list. See ProcessPageListRenderJSON.php
  16. Hi @netcarver, When ModuleReleaseNotes is installed the main admin headline gets removed in the config screen for ProFields InputfieldCombo and this makes the form layout a bit off too (FieldtypeCombo is similarly affected). Without ModuleReleaseNotes: With ModuleReleaseNotes: I had a quick look and traced it back to the module's hook after ProcessModule::executeEdit but nothing in there leaps out at me as the cause of the problem. Do you have ProFields so you can try and replicate? Cheers, Robin.
  17. In the newly released v0.3.0 you can also quickly toggle the "required" state of fields in a template, Repeater, etc, by clicking the asterisk icon next to the field label.
  18. @Tintifax, Ryan has fixed the issue. So to get ProcessDatabaseBackups working as normal: download PW 2.0.220 again to get the latest commits, update the wire folder of your site, uninstall ProcessDatabaseBackups if it is already installed and then reinstall ProcessDatabaseBackups.
  19. I can confirm the issue in PW 2.0.220. The problem seems to be with Modules::getModuleInfoVerbose(). I opened a GitHub issue here: https://github.com/processwire/processwire-issues/issues/1765
  20. You could use a hidden field in the template to store the title of the first repeater item, similar to this: Or you could match the repeater page by sort position and then get the containing page for each matched repeater page. $items = $pages->find("template=repeater_areas, title=$area, page.sort=0, check_access=0"); $results = new PageArray(); foreach($items as $item) { // Get root page that contains the repeater page $result = $item->getForPageRoot(); // Maybe do some checks on $result page here, for example if you only want pages that have a particular template $results->add($result); }
  21. I don't think there is anything about field templates that means they can't include a markup region. But you can't have nested markup regions (where your template output includes one markup region inside another markup region). So if you are using a markup region inside a field template you would not be able to render that field template inside another markup region, which is something you would often want to do. I think a better solution is to use a FilenameArray and add whatever JS files you need to it in your field template. In /site/templates/_init.php $config->siteJs = new FilenameArray(); In /site/templates/_main.php <?php foreach($config->siteJs as $jsFile): ?> <script src="<?= $jsFile ?>"></script> <?php endforeach; ?> In your field template $config->siteJs->add('/site/templates/js/myField.js'); Or you can follow the same general idea using an ordinary WireArray and include the whole "<script src..." string so you can optionally use "defer" or other attributes.
  22. Welcome to the PW forums @Tenzing 🙂 You can achieve this by setting the URL segments you want to $input before you render the page. E.g. $input->urlSegment1 = 'foo'; $input->urlSegment2 = 'bar'; echo $thepage->render();
  23. If the field value is being set from a FormBuilder form field (e.g. send form submission to PW pages) then you will need to set the noTrim setting for the FormBuilder field too. Again, there is no config field for this but I expect you will be able to hook into the form rendering and/or processing and set noTrim=1. Ryan should be able to help with this in the FormBuilder subforum if you're not sure how.
  24. I tested in 3.0.217 and when trying to rename a field to the same name as an existing field PW gave an error notice, did not change the field name, and no data was lost. So maybe it was a strange glitch, or it was an issue that was fixed between 3.0.165 and 3.0.217.
  25. InputfieldText (and other inputfield types that extend InputfieldText such as InputfieldTextarea) has a "noTrim" setting that is false by default, which is what causes leading and trailing whitespace to be trimmed out of the field value. This setting isn't included in the config options for text fields (not sure why, perhaps because it's rarely needed) but you can add a config option for it with a hook: $wire->addHookAfter('InputfieldText::getConfigInputfields', function(HookEvent $event) { /** @var InputfieldText */ $inputfield = $event->object; /** @var InputfieldWrapper $wrapper */ $wrapper = $event->return; $field = $inputfield->hasField; // Only for inputfields that are associated with a Field object if(!$field) return; // Add checkbox field to config to control noTrim setting /** @var InputfieldCheckbox $f */ $f = $event->wire()->modules->get('InputfieldCheckbox'); $f->name = 'noTrim'; $f->label = 'No trim'; $f->label2 = 'Do not trim whitespace from the field value'; $f->checked($field->noTrim); if(!$field->noTrim) $f->collapsed = Inputfield::collapsedYes; $wrapper->add($f); }); This will add a "No trim" checkbox to text fields, and if you tick the checkbox the field value won't be trimmed. Result:
×
×
  • Create New...