Leaderboard
Popular Content
Showing content with the highest reputation on 10/26/2022 in all areas
-
@Guy Incognito, as a general debugging tip: you should use a debugging tool like TracyDebugger rather than relying on message() because if some code somewhere does an exit() or die() then you might not see any visible message. For example, Session::redirect() calls exit(0) and maybe other core methods too. TracyDebugger has a Dumps Recorder panel that can capture any dumps that otherwise might get missed. And when you're troubleshooting and trying to narrow down an issue you don't want any non-essential code executing. In your example you have: public function upgrade($fromVersion,$toVersion) { $this->___install(); $this->wire()->message('Upgrade method called'); } But it would be better not to call ___install() before your debugging message because something might be happening in ___install() that prevents your message. So probably this would be a good way to check if the upgrade method is being called: public function ___upgrade($fromVersion, $toVersion) { bd($fromVersion, "fromVersion"); bd($toVersion, "toVersion"); } As for the problem itself, I tested here and can report: 1. The method name must be ___upgrade() and not upgrade(). The docs for Module make it sound like it is optional whether the method is made hookable with the underscore prefix but that seems to be incorrect because I can't see the method firing if the underscores are missing. So either that's a bug or the docs need to be updated. 2. The method is called when the module is next loaded, not necessarily when you do a Modules > Refresh. The core message gives a hint about this: If your module has autoload set to true then it will be loaded immediately after the refresh (and on every other page load). But if it's not autoload and you want to see the ___upgrade() method called then you can force the module to load like this: $modules->get('YourModuleName'); This isn't a bug as whatever actions you are taking in ___upgrade() will get applied in time for the next usage.5 points
-
Just a quote from Ryan from the past (I forgot to jot down the source of the original, sorry...) "In order to run an upgrade/download process, the module must be loaded and its upgrade() method called. With the exception of "autoload" modules, ProcessWire loads modules on demand, as requested from the API. This is an intended behavior. When you do a "Modules > Refresh", it should tell you about version changes it found and also indicate that it will apply those when the module is next loaded. Module changes are applied when the module is next loaded, so it's not a matter of scheme (http, etc.) but rather just whether the module is needed and thus loaded for the request. Many modules are only used for rendering http requests (such as Process) modules, so it may have that appearance that http is required for some. It's best that updates are only applied when a module is actually going to be used, since it is the module's own upgrade() method that is called to perform the upgrade. And loading a module in a context where it wouldn't typically be used might be problematic or cause errors. But if you have a need for to do this, you could try doing a foreach $modules and load each module individually $modules->getModule($name)... updates will be applied as each is loaded. Again though I think it may be potentially problematic to do that since this is not the way it's designed to apply upgrades."3 points
-
If you have the core ProcessPageClone module installed you can copy a page via Page List: But sometimes I don't want to hunt around through Page List to find the page I want to copy, and instead I have found the page via the admin search and have it open in Page Edit. So I used this hook in /site/ready.php to add a "Clone this page" button to the bottom of the Settings tab. // Add a clone button to the Settings tab of Page Edit if this page is allowed to be cloned $wire->addHookAfter('ProcessPageEdit::buildFormSettings', function(HookEvent $event) { $wrapper = $event->return; $modules = $event->wire()->modules; $page = $event->process->getPage(); /** @var ProcessPageClone $ppc */ $ppc = $modules->get('ProcessPageClone'); if($page && $ppc->hasPermission($page)) { /** @var InputfieldButton $f */ $f = $modules->get('InputfieldButton'); $f->value = 'Clone this page'; $f->href = $event->wire()->config->urls->admin . 'page/clone/?id=' . $page->id; $wrapper->add($f); } }); Maybe somebody else has this need and finds this useful.1 point
-
1 point
-
By trial and error I managed to solve the issue. I had a 'qrcode' field on the product template and for some reason that didn't work. By removing the field in the PW template and the php file and even removing the module the error was gone. No idea what one had to do with the other but anyway, problem solved.1 point
-
Thanks @szabesz that adds good context as to why it works like it does and it makes perfect sense.1 point
-
Sorry to say that this error still occurs in my multilang install using PW 3.0.200 on PHP 7.4 both outside and inside repeaters. Required option set either in field or template context yields the same result. Problem seems to be with the isEmpty() method in InputfieldMediaManager.module. Specifcally with get_class($value) == 'MediaManagerArray'. In my install get_class($value) returns 'ProcessWire\MediamanagerArray'. If I replace the check with if(is_object($value) && $value instanceof MediaManagerArray && count($value)) $empty = false; the error is gone.1 point
-
This is something I recently picked back up to try to finish, it's a bit tedious depending on how many modules/features you want to cover. I wrapped styles in a .dark style rule in my less so that I could get the added specificity I wanted rather than use !important to override. It doesn't work for all modules (as some create pretty specific rules themselves that need a slightly different approach - like AdminOnSteroids - that are higher in the DOM than your typical rules.) Sometimes I have to insert the .dark selector deeper than a style applied to html, for example in a given rule. I included the dark class in the body tag in my _main.php override. When I stopped I also recall there was quite a bit of !important css rules set in the image editing popups and image fields styles in core - I started making headway with it and then had to step away. I haven't gone back to see if that has improved. I'm doing a bit of refactoring now to try to consolidate rules and get the options that I want. The uk-inverse is not exactly what it appears to be. It gets used when you need light content in spaces where you otherwise get dark content by default - particularly in nested cards/sections/overlays and such. There are global inverse color rules that have a uk-inverse wrapper similar to the dark wrapper I described above, but it can be unpredictable in nested elements sometimes. In our case, though, with the content bring generally light, uk-inverse would provide dark text and assumes a lighter primary color IIRC. I really like the toggle idea. In theory you could then just include the .dark class wrapper conditionally in the template override. EDIT: Looking at different approaches, I guess I was approaching the toggle as more of a real-time DOM class change with jquery, but maybe it is better to have different variable sets that load for different color options. I'm going to play around some more with it.1 point
-
This is what I am using: $this->wire->addHookAfter('ProcessPageEdit::getSubmitActions', function($event) { $page = $event->process->getPage(); if($page->template != "foo") return; $actions = $event->return; unset($actions['next']); $actions['clone'] = [ 'value' => 'clone', 'icon' => 'clone', 'label' => 'Save + create copy', ]; $event->return = $actions; }); $this->wire->addHookAfter('ProcessPageEdit::processSubmitAction', function($event) { $action = $event->arguments(0); // action name, i.e. 'hello' $page = $event->process->getPage(); // Page that was edited/saved if($page->template != 'foo') return; if($action === 'clone') { $copy = $this->wire->pages->clone($page); $copy->title .= ' (copy ' . uniqid() . ')'; $copy->save(); $this->wire->session->redirect($copy->editUrl); } });1 point
-
Also, I want to open the page in Page Edit after it is cloned. Here is a hook for that: // Edit the cloned page after it is created $wire->addHookBefore('ProcessPageClone::execute', function(HookEvent $event) { $event->wire()->addHookBefore('Session::redirect', function(HookEvent $event) { $url = $event->arguments(0); $id = (int) filter_var($url, FILTER_SANITIZE_NUMBER_INT); $redirect_url = $event->wire()->config->urls->admin . 'page/edit/?id=' . $id; $event->arguments(0, $redirect_url); }); });1 point
-
I was also getting the same warning for a dual English/French install I'm working on. First time using multi-language. I had setlocale(LC_ALL, "en_GB.utf8"); in site/config.php, and had set the values in LanguageSupport "C" fields as the error requests (en_GB.utf8 & fr_FR.utf8). Still getting the error message on login. SSH checked the locales using locale -a, and they were listed. Hmm... Tried a few things, but what worked for me was putting setlocale(LC_ALL, "en_GB.utf8", "fr_FR.utf8"); in site_ready.php. Error message now gone - hurrah!1 point
-
Absolutely! Here is a simple, but functional example for both login and logout templates. You would want to replace the markup with your own markup or includes. Likewise you'd want to change the redirects to redirect to whatever page you want them to go to after completing a login. /site/templates/login.php: <?php if($user->isLoggedin()) { // user is already logged in, so they don't need to be here $session->redirect("/somewhere/"); } // check for login before outputting markup if($input->post->user && $input->post->pass) { $user = $sanitizer->username($input->post->user); $pass = $input->post->pass; if($session->login($user, $pass)) { // login successful $session->redirect("/somewhere/"); } } ?> <html> <head> <title>Login</title> </head> <body> <form action='./' method='post'> <?php if($input->post->user) echo "<h2 class='error'>Login failed</h2>"; ?> <p><label>User <input type='text' name='user' /></label></p> <p><label>Password <input type='password' name='pass' /></label></p> <p><input type='submit' name='submit' value='Login' /></p> </form> </body> </html> /site/templates/logout.php: <?php $session->logout(); ?> <html> <head> <title>Logout</title> </head> <body> <h1>You have logged out</h1> </body> </html>1 point