Leaderboard
Popular Content
Showing content with the highest reputation on 06/30/2023 in all areas
-
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.14 points
-
This week, work continued on our next main/master version with 8 issue fixes (see dev branch commit log). In addition, the WireHttp class was updated with new delete(), patch() and put() methods which correspond to http methods of the same name, These might be used by web services in addition to the more common GET and POST methods. In prior versions of WireHttp, you could still use delete, patch and put methods, but had to use WireHttp::send() with the $method argument set to one of them. Now that there are separate class methods for these http methods, it makes them a little simpler to use and more clear in code. It may be that you never need these methods, or it may also be that you use a web service that uses them extensively. The more web services I work with, the more I come across them, and figured it would be good for WireHttp to have more clear support for them. I know things slow down in the summer, but we haven't had many submissions to the sites directory lately. If you have launched any sites using ProcessWire in the last year or so, and haven't submitted them to our sites directory, please submit your websites to the directory when you can. We really enjoy seeing what what people are building in ProcessWire. Thanks and have a great weekend!8 points
-
@Jim Bailie In addition to the options you mentioned, if you put $myObject = new MyObject(); in your /site/templates/_init.php, then $myObject will also be available to all the page templates and the _main.php file, i.e. echo $myObject->value; As a benefit, it'll be automatically excluded from template files that don't use _init.php, such as the admin.php template file. If it's something that you might need on every page/template, but not necessarily, you may want to use it as a function in /site/ready.php that constructs it on first access, and then returns the same object on any later accesses to the function: function myObject() { static $myObject = null; if($myObject === null) $myObject = new MyObject(); return $myObject; } In this case, you'd use it like as a function with () appended rather than $ prepended, i.e. echo myObject()->value; This also has the benefit of using the same object (rather than creating another) if you happen to be calling $page->render(); on other pages in your template file(s). Another option: The way that ProcessWire does it is to use API variables, and you can add your own if you want. If you go that route, put in your /site/ready.php file: $wire->wire('myObject', new MyObject()); Then $myObject is available in any template files. The downside here is that it'll also be available to template files where you might not need it, such as the admin.php template file. So you may want to create it conditionally: if($page->template->name != 'admin') { $wire->wire('myObject', new MyObject()); }8 points
-
6 points
-
The simplest, quickest, and maybe most useful module I've ever built ? TextformatterJsonDecode: Passes the given text through json_decode(), returning the value (if valid) as a stdClass object. Didn't even bother with a README - does what it says on the tin. Ha need one for the modules repo... This is particularly useful if you are storing JSON from an API in a Page field and want to access it in a similar way to normal Page objects e.g. <?php /* The data { "fieldName": "value" } */ echo $page->api_data->fieldName; // value I'll be using this extensively over the next few weeks, looking forward to it ?4 points
-
Stores a GeoJSON FeatureCollection and its bounds drawn on a MapLibre map. Here's the README.2 points
-
Hi @flydev, Unfortunately we're not there yet with the scaling setup. However this is an interesting thread, this could be potentially related to https://processwire.com/talk/topic/26070-error-exception-unable-to-obtain-lock-for-session/ which we've never been able to figure out. Cheers, Chris2 points
-
Thanks for sharing! As always, your contribution to ProcessWire and its community rocks!2 points
-
Sorry I'm working in @gebeers RepeaterMatrix fork right now, but if you could add around 3200 in RockMigrations.module.php: (This is below the $key === "template_id" conditional test block.) if ($key === "template_ids") { foreach($val as $sub => $tpl_name) { if (is_string($tpl_name) and $tpl_name !== '') { $tpl = $this->getTemplate($tpl_name); if (!$tpl) throw new WireException("Invalid template_id"); $val[$sub] = $tpl->id; } $data[$key] = $val; continue; // early exit } } This would allow the 'Selectable Pages > Additional Templates' setting on Page Reference fields to migrate the 'template_ids' setting properly with template name references into of raw ids in a similar manner to the template_id setting conversion.1 point
-
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.1 point
-
1 point
-
It's not that wrong but maybe not the best option in this case here. I'd honestly go a totally different route and... create a template catalog_image or something create and add all necessary fields to that template create another template catalog_category create and add all necessary fields to that as well From there I would create all category pages and add those images under each one/where necessary or wanted. That way you can always move one image to another category, sort them way easier, disable, or clone one with ease. Oh... and it's probably way easier to maintain.1 point
-
When you have a Page Reference inputfield, there are two different template options settings: With the standard migrate() config array, the template_id setting gets processed fine if you use a template name instead of the template_id - the green checkmark. The template_ids setting does not get processed if you use template names. Nothing appears. Adding the processing block I wrote above allows template names to be used in that template_ids setting.1 point
-
There are basically two options here: Use a separate session storage. That could be MySQL (in which case you may need to beef it up even more), or it could be something else, e.g. Redis. Redis is relatively easy to configure as a session storage: set up a Redis server, make sure that you have Redis extension installed for PHP, and point PHP to the Redis server via settings in php.ini. Store files on shared disk. From what you're describing it sounds like the disk is not shared in this case, which is not going to work for session files. With AWS it would typically mean EFS, i.e. making sure that the location where session files are stored is mounted on EFS. If you were already using SessionHandlerDB, the easiest approach would probably be to keep using it, unless the scalability issue is basically instantaneous. Just make sure that session data is cleared automatically, so that the size of the session table won't become a bottleneck. The key thing here is that if you're, for an example, using Ubuntu (or similar setup) then PHP may have session garbage cleaning disabled by default and instead it is handled via cron job. This job will not automatically apply to SessionHandlerDB, so you would need to either a) tweak PHP settings and enable normal garbace cleaning (as Bernhard mentions in issue https://github.com/processwire/processwire-issues/issues/1760) or b) set up a custom cron job or something like that to clean up SessionHandlerDB database table manually.1 point
-
1 point
-
Ok, thanks for the information, I thought that you was talking about Azure Security Group which reminded me of the session handler issue (I missed the AWS details on one of your previous message). I understand now better about the logout issue you encounter with file handler and you should avoid it. I am not experienced with RDS, and maybe @nbcommunication could have a better insight regarding his scaling setup presented recently on the forum.1 point
-
1 point
-
HI, I am jumping in the thread. Just some questions. (By ASG did you mean Azure ?) - About the query SELECT GET_LOCK: What's is the database server version, model (MySQL or MariaDb) and the database server max_connection settings value ? - Using file system based sessions, ask the team details about: Value and permissions set of the php.session.save_path and the number of files in the target. Value of php.session.save_handler ? Edit: FI, I just checked on three setups using file system session with the bug-issue-1760, there is 4416, 7428 and 5651 session-files and growing without slowing down the system at this moment of writing. Edit2: @Nishant There is also an article that could be interesting and might help of tweaking the session database handling: https://processwire.com/blog/posts/pw-3.0.175/#read-only-and-db-driven-sessions1 point
-
I‘m not familiar with RockGrid but if I understand you correctly it can export pages? In that case, using a Collection panel should get you there. However I suspect what you‘re looking for is showing the RockGrid UI inside a panel — in that case you could look into rendering a template file inside a panel and implementing the custom logic there.1 point
-
If you stick with DB sessions you should see this pretty soon. If sessions are not cleared properly, data will likely just keep accumulating. I'm not sure if stale data remains viewable in admin, so might want to take a peek at the database as well, just in case.1 point
-
No, I'm getting just 1 email. I've only changed the 203 and 211 lines and everything seems to properly work. Thanks for the help.1 point
-
Adding translations to modules sucks. That's why I built RockLanguage: https://processwire.com/talk/topic/27199-rocklanguage-a-new-way-to-ship-processwire-modules-with-translation-files-%3F/ The idea is that the module author is responsible for the translations and that it's as simple as possible to translate everything and keep everything up to date. I have not used it for a while though and it never got any traction in the community, but I still think it is the best way to do it. The official way is by far too tedious. There are so many necessary steps for just translating a single string. And if something changes you have to do everything over and over again. Terrible. RockLanguage automates all that for you. If you find that anything does not work any more let me know and I'll fix it timely. If you want to help on developing the concept further let me know!1 point
-
Hey! A client wanted me to update their website to make it show dates in the form "1. - 3. Jän. 2023" instead of "1. Jän. 2023 - 3. Jän. 2023" It's a small change but not so easy to solve, especially if you want to make it locale aware etc... So I've created "HumanDates" library which is not a PW module but a standalone PHP class so that everybody can easily use it even outside of the PW universe: https://github.com/baumrock/HumanDates Usage is simple and the library can be used as a strftime replacement: // manual download require_once "/path/to/HumanDates.php"; // using composer // composer require baumrock/humandates require_once "/path/to/composer/autoload.php"; // create HumanDates instance $dates = new HumanDates(); echo $dates->format("2023-01-01"); // 1. Jan 2023 echo $dates->range("2023-01-01", "2023-01-03"); // 1. - 3. Jan 2023 If it is useful to you please let me know by giving it a star on github ? https://github.com/baumrock/HumanDates/stargazers PS: It will be available in RockFrontend in the next release simply by calling $rockfrontend->humandates() ?1 point
-
I am using RockMigrations for a while now (and am honestly in love with it!) and just recently ran into a problem that I had not encountered before. I am using the deployment features and a setup that automatically deploys the two (dev and main) branches in my Github repo to different locations. This works perfectly fine most of the time, however last time PHP ran out of memory and I did not notice it, because the job was marked as successful in Github actions. Running out of memory led to the current symlink not getting generated and the website being not accessible (without me noticing it). @bernhard and I already had a chat about it, but we were wondering whether you guys had ideas or suggestions on how to deal with errors and warnings during the deployment process and appreciate your input.1 point