-
Posts
1,331 -
Joined
-
Last visited
-
Days Won
61
Everything posted by BitPoet
-
That message comes from within PagesEditor::saveField. The only place in the blog module that I am aware of that calls save() on a single page field is in BlogPublishDate. You could try and uninstall that one temporarily to see if it is indeed the culprit. If the error still persists, it's probably triggered by another module or hook.
-
Subpage URLs don't work when using port number
BitPoet replied to simonsays's topic in Getting Started
In that case, you should probably check with your hoster whether .htaccess can be used and mod_rewrite is available at all. -
There's a mixup of variables in the log output in removeExpiredDirs, namely $path and $pathname in lines 278 and 291 that got switched around. The empty value is output because there's no subdirectory to delete in the temp dir so $pathname never gets a value. Otherwise, the path of the last subdirectory in the loop would be (wrongly) logged. I have opened an issue.
-
Apache/PHP "hangs up" when $config->debug = true;
BitPoet replied to theo's topic in General Support
What I have sometimes found helpful in such cases is to bootstrap PW and render the page in question from the command line, i.e. something like php -r 'namepsace ProcessWire; include("index.php"); $p = $pages->get("ID_OR_PATH_OF_YOUR_PAGE"); $p->render();' since PHP CLI is usually a bit more talkative when things go haywire. Might be worth a try. -
Subpage URLs don't work when using port number
BitPoet replied to simonsays's topic in Getting Started
Running PW on non-standard ports shouldn't be an issue. Did you develop in a subdirectory? If yes, there might be a leftover RewriteBase entry in .htaccess interfering with URL rewrites. -
Permissions are much more involved both in the core code and in the database than roles. There are real (e.g. page-edit, always installed), runtime (e.g. page-create, not present in the database) and optional (also called "delegated", e.g. page-publish, used if installed, otherwise replaced with page-edit) permissions. The current implementation of hasPermission also uses the same code path both for global checks and contextual ($page, $template) lookups. Of course, that doesn't prevent implementation of a multi-permissions check per se. BUT. Since code and database are much more involved, running lots of individual permission checks can quickly become a performance killer. IMHO it is in often better to add your own permission (or role) than to run multiple consecutive permission checks in code. I know, that's not a solution, but I'm not aware of a built-in shortcut. Adding a User::hasOnePermission hook method that splits on the pipe symbol and calls $user->hasPermission for each term should be straight-forward though.
-
First: You know what $event->object is because it is an object of the very class you're hooking onto. In the linked docs, the hook is on Pages::saved, so the event object is an instance of Pages (not a PageArray). In your code, you're hooking Page::price, so $event->object is a Page object. If your hook was InputfieldText::firstWord, it would be an InputfieldText instance. Second: I'd avoid passing $event around to other methods. It kills readability so $event should only be used in the hooks themselves, not in further methods or functions. Yes, you can manipulate arguments. The syntax is in the docs section you linked, in your case it would be $event->arguments(2, $unitprice). But that is mostly meant for before hooks where you want to change the behavior of the original, hooked method. It would be better though to pass all necessary arguments to tierprice and addVat one by one instead of manipulating the "magic thing" that is $event, i.e. something like: $unitprice = $this->tierprice($page, $quantity); Best practice to keep code readable is to use a pattern with a public hook method that decorates your hooked class and a couple of private methods which do the work. <?php /* The usual module stuff... */ public function init() { $this->addHook("Page::price", $this, "hookPrice"); } public function hookPrice(HookEvent $event) { $page = $event->object; $quantity = $event->arguments(0); $vat = $event->arguments(1) ?? false; $unitprice = $this->tierprice($page, $quantity); if($vat) $unitprice = $this->addVat($unitprice); $event->return = true; } private function tierprice($page, $quantity) { /* do whatever calculations and return the result */ } /* ... */
-
Wiremail problem with charset and german umlauts
BitPoet replied to Juergen's topic in General Support
There's an issue with from headers that I still have on the back burner, so I'll take a look at encoding options when I tackle that. Might be a few weeks though, as I'm up to my neck in work since we switched ERP systems at my workplace yesterday. -
No need for thanks. I hit my head on that problem a few times myself, so it's pure self-preservation in the long run My approach above, as I figured out just a little too late, won't work out anyway, since it might not be original object that starts the recursion.
-
That would only catch flat recursion though. The only way to catch deeper nesting I can think of would be to pass the starting object along. Something like this (untested): public function resetTrackChanges($trackChanges = true, $startingObj = null) { parent::resetTrackChanges($trackChanges); if(!$startingObj) $startingObj = $this; foreach($this->data as $key => $value) { if(is_object($value) && $value instanceof Wire && $value !== $startingObj) $value->resetTrackChanges($trackChanges, $startingObj); } return $this; } Of course, that method signature and logic might have to be implemented by all Wire derived classes that implement their own resetTrackChanges method. On second thought, that doesn't help either. You're spot on with keeping track of seen pages outside of recursion. On the other hand, multiple resetTrackChanges calls might happen in the same program run, so there needs to be a mechanism that cleans up the tracking list.
-
You might find out more if you print out the names ($key) of all properties of type page and their value's (page) ids. There should be some kind of repeating pattern then that leads from subscriber to tester back to subscriber, but their might be (quite) some hops in between.
-
Question about selectors in sort settings for children
BitPoet replied to KarlvonKarton's topic in General Support
You can use page.fieldname on the right hand side in your selector, so you need something like this: parent=/hotels/, template=hotel, hotel_country=page.destination_country, sort=title There's a discussion with a similar setup here: -
You can find the answer in this thread:
- 1 reply
-
- 3
-
-
I think your files shouldn't be compiled (or at least the compiled files not used) at all. Does moving the namespace declaration to the very first line of your php files change anything? How you specify the include files' paths might also be relevant if you use different approaches in your class files and templates.
-
Have you tried adding /*NoCompile*/ to the require_once() inside Master_Order.class.php?
-
That's what I'm thinking too. I'd like to add a few neat things though before I actively go for more spotlight on it on the web. Auto save is a neat feature but probably not wanted in all scenarios, so I want to make it optional, and another feature I definitely want to get "wired" in is lool's revision history. Currently, it's far too easy to overwrite a perfectly fine document with no way back.
-
Brilliant! I only now got a chance to reply, and you have already changed things around just the way I imagined. I'll take your module on a test drive in our intranet on Monday.
-
I have only recently started to work on something similar, only streamlined for frontend editing, so kudos for tackling that topic I'm likely going to peek inside the code and steal a few pieces. The only nitpick I have is that the behavior of the replacement option might not be clear to end users. The field should probably be a little more verbose and tell the user that description and/or tags are replaced by those of the selected file, or they might assume it's the other way round. Perhaps a "Replace with" option would be even more intuitive (use the selected file and keep the rest as is). It's how I'd write it as a user story - "I have a file entry on the page with a description and tags and just want to replace the old file with a new one in that entry". Just playing devil's advocate here, as I'm thinking of my 50+ intranet editors who only update their pages a few times every year.
-
ProcessWire supports that out of the box. See here for a getting started documentation.
-
Yes, you'll probably have to hook before Pages::trash.
-
There are different possible approaches, but this should work: create a subdirectory in your web root for every domain, named exactly like the domain make sure ownership is correct add a rewrite rule in .htaccess before #12 that prepends the requested host name to the path: RewriteCond %{REQUEST_URI} ^/?\.well-known RewriteRule "(^|/)(.*)$" $1%{HTTP_HOST}/$2 [L] start letsencrypt with webroot option pointing to /path/to/pw/domain-in-question for every domain enjoy
-
profields page table "count()" error when editing field
BitPoet replied to neosin's topic in General Support
If you add the error line to https://github.com/processwire/processwire-issues/issues/408 Ryan will no doubt make short work of it. -
Update 11/4/2018: Locking is implemented (though I haven't seen any hints that CODE uses it). Probably needs some serious testing. Editing has now to be enabled on a per-field basis (Details tab in file field configuration). Template context is supported. Added more inline comments to the code and did some cleanup.