Jump to content

MarkE

Members
  • Posts

    1,090
  • Joined

  • Last visited

  • Days Won

    12

Everything posted by MarkE

  1. ALTER DATABASE databasename CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ALTER TABLE tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; Just need to change the field tables which need to hold emoticons
  2. I have enabled the emoticons plugin for TinyMCE. It appears to work when editing the page but, after saving, the emoticon just appears as ???? Any suggestions?
  3. Prompted by @ryan's recent enhancement of the page tree display, I wanted to display an alphabetical index of pages rather than a numerical one, so I built a hook after MarkupPagerNav::render. You can see the result here: https://ncorchards.co.uk/main/fruit-orchards/apples/ Basically the hook just replaces render() with a modified version. The key modifications are to select all the items without limit: $items = $event->arguments(0); //PageArray $itemSelector = $items->getSelectors(true); // true returns the string rather than the object $noLimit = preg_replace('/,\s*limit=-?\d+/i', '', $itemSelector); and then to modify the pager: $pagerNav = new PagerNav($object->totalItems, $object->itemsPerPage, $object->pageNum); $pagerNav->setLabels($objectOptions['previousItemLabel'], $objectOptions['nextItemLabel']); $pagerNav->setNumPageLinks($object->numPageLinks); $pager = $pagerNav->getPager(); $allItems = $this->find($noLimit)->explode('title'); $itemsPerPage = $object->itemsPerPage; foreach($pager as $key => $item) { if(!ctype_digit("$item->label")) continue; $index = (int) $item->label; $itemTitle = $allItems[($index - 1) * $itemsPerPage]; $item->label = substr($itemTitle, 0, 2); } If anyone wants the full hook code, let me know, but you will probably want to modify it for your own use anyway and the above are the key bits.
  4. v0.4.0 adds the ability to break out of the modal into a full page view. This is useful for admins who might require full page access but should not be used when the modal is called from the front end. It is enabled by showing a button in the modal.
  5. See my post re the context Now that I know the cause, my solution is to build a selector that always operates on the DB, by merging the user's selector with the one that was used to generate the Page Array: /** * Find the first generation of children that matches the given selector. * * This method traverses the children of the given parent page, generation by generation, * and returns the matches in first generation that has matches for the provided selector. * * @param Page $parentPage The parent page whose children are to be searched. * @param string $selector The selector to match against the children. * @return PageArray Returns a PageArray of the first generation that has matches, or an empty PageArray if no matches are found. */ public function findFirstMatchingGeneration(Page $parentPage, string $selector) { $currentGeneration = $parentPage->children(); $count = 1; while($currentGeneration->count()) { $currentSelector = $currentGeneration->getSelectors(true); $matching = $this->pages()->find("$currentSelector, $selector"); if($matching->count()) { return $matching; // Return the first generation that has matches } // Move to the next generation $nextGeneration = new PageArray(); foreach($currentGeneration as $child) { $nextGeneration->add($child->children()); } $count += 1; $currentGeneration = $nextGeneration; } return new PageArray(); // Return an empty PageArray if no matches are found }
  6. AKA 'bugs'? Are these documented somewhere. I'm wondering if it is possible to apply a sanitizer hook to fix them.
  7. I know this seems fairly basic, but I'm a bit stumped. I have a Selector field that returns something like "template=198" in response to the user selecting a template (i.e. it returns the id, not the name). Another field on the same page selects a parent page, say "parent=20940". If I use $pages->find("parent=20940, template=198") then the correct pages are found. If I do $subPages = $pages->find('parent=20940'); d($subPages); $subPages = $subPages->find('template=198'); d($subPages); then the second dump is an empty array. This can be fixed by using 'template.id=198' in the second selector. However, at least in my context, it is not really feasible to hack the selector that is returned from the Selector field. I have no idea what the selector might be. (BTW, the context, in case it is relevant, is that I am iterating the selector test down the page tree, starting at the parent page's children and stopping at the first level that finds a match). Any ideas?
  8. Yeah. That’s what I’m doing. I just wondered….
  9. This may seem like a really stupid question, but is there anywhere a really simple guide for completely non-technical editors explaining the basics of ProcessWire. The sort of things that might be covered are: what are pages and fields and templates adding new pages - title and name (including dealing with duplicate names) different types of fields - including page references publish vs unpublished the page tree and actions thereon trash vs delete but not covering editing fields or templates or any coding html or css stuff.
  10. So much to agree with in all of the above. My brief contribution: I came to ProcessWire having used WordPress and CodeIgniter. WP was fine if you just wanted a really simple website, but rapidly got frustrating if you needed something a bit more (adding a bookings capability to my holiday let website involved all sorts of contortions). CodeIgniter (ok, a bit passé now, I know) worked ok but needed a lot of coding and was a bit of a straitjacket. I looked at a whole load of CMS alternatives - Drupal etc. - but only ProcessWire had the right balance between CMS and CMF based on a really simple and intuitive concept (everything is a page). Completely unopinionated, but quick to get something working which can then be built on as necessary. As your needs grow, so you realise that PW grows with you.
  11. Hi @Juergen. I've hit another issue that seems to be related to your module. I have what I believe to be 2 identical environments for dev and live. However, after adding a new page, the dev environment (when in superuser) shows 2 buttons: 'Publish' and 'Save & keep unpublished', but the live environment (or not as superuser) just has 'Publish' and 'Save'. Any ideas what might be causing that (the dev superuser version is more helpful, I think). For this particular page, I don't want the 'Publish' button to be available unless certain criteria are met, so I added a hook: public function afterPageEditBuildForm(HookEvent $event) { $form = $event->arguments(0); // Get the form $page = $event->object->getPage(); // Get the page being edited if($page->template->name == 'NewsItem' && (!$page->final || !$page->approved)) { foreach($form->children as $field) { if($field->name == 'submit_publish') { $form->remove($field); } } } } That removes the 'Publish' button OK. However, if I am not superuser, clicking the 'Save' button does actually publish the page, even though the 'Publish' button was removed. If I am superuser, clicking 'save' saves it as unpublished. In order to make the hook work in all instances, I have to add: $page->addStatus('unpublished'); $page->of(false); $page->save(); but that really ought not to be necessary. The page in question is selected to 'add fields to templates' in your module but the fields are left blank. If I deselect the template then everything works correctly, but the helpful 'Save & keep unpublished' is just replaced by 'Save' (and of course, I no longer have the functionality). All a bit confusing!
  12. Ta @adrian. Posted an issue at https://github.com/processwire/processwire-issues/issues/2039
  13. When I switch a user and view the page tree, I get the following error. Any idea what is causing it? Not a big deal as it is only a warning, but it repeats hundreds of times. (PHP 8.1, Core 3.0.244 and Tracy 4.26.64). ErrorException: trim(): Passing null to parameter #1 ($string) of type string is deprecated in /var/www/html/wire/core/DatabaseQuery.php:468 Stack trace: #0 [internal function]: Tracy\Bar->Tracy\{closure}(8192, 'trim(): Passing...', '/var/www/html/w...', 468) #1 /var/www/html/wire/core/DatabaseQuery.php(468): trim(NULL, ', ') #2 /var/www/html/wire/core/PageFinder.php(2294): ProcessWire\DatabaseQuery->__call('where', Array) #3 /var/www/html/wire/core/PageFinder.php(1956): ProcessWire\PageFinder->getQueryAllowedTemplates(Object(ProcessWire\DatabaseQuerySelect), Array) #4 /var/www/html/wire/core/Wire.php(419): ProcessWire\PageFinder->___getQuery(Object(ProcessWire\Selectors), Array) #5 /var/www/html/wire/core/WireHooks.php(968): ProcessWire\Wire->_callMethod('___getQuery', Array) #6 /var/www/html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\PageFinder), 'getQuery', Array) #7 /var/www/html/wire/core/PageFinder.php(803): ProcessWire\Wire->__call('getQuery', Array) #8 /var/www/html/wire/core/Wire.php(419): ProcessWire\PageFinder->___find(Object(ProcessWire\Selectors), Array) #9 /var/www/html/wire/core/WireHooks.php(968): ProcessWire\Wire->_callMethod('___find', Array) #10 /var/www/html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\PageFinder), 'find', Array) #11 /var/www/html/wire/core/PagesLoader.php(424): ProcessWire\Wire->__call('find', Array) #12 /var/www/html/wire/core/Pages.php(290): ProcessWire\PagesLoader->find('include=unpubli...', Array) #13 /var/www/html/wire/core/Wire.php(419): ProcessWire\Pages->___find('include=unpubli...', Array) #14 /var/www/html/wire/core/WireHooks.php(968): ProcessWire\Wire->_callMethod('___find', Array) #15 /var/www/html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\Pages), 'find', Array) #16 /var/www/html/wire/core/PagesLoader.php(2032): ProcessWire\Wire->__call('find', Array) #17 /var/www/html/wire/core/Pages.php(245): ProcessWire\PagesLoader->count('include=unpubli...', Array) #18 /var/www/html/wire/modules/PagePermissions.module(1083): ProcessWire\Pages->count('include=unpubli...') #19 /var/www/html/wire/core/WireHooks.php(1094): ProcessWire\PagePermissions->moveable(Object(ProcessWire\HookEvent)) #20 /var/www/html/wire/core/Wire.php(484): ProcessWire\WireHooks->runHooks(Object(ProcessWire\DefaultPage), 'moveable', Array) #21 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/panels/RequestInfoPanel.php(573): ProcessWire\Wire->__call('moveable', Array) #22 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Bar/Bar.php(143): RequestInfoPanel->getPanel() #23 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Bar/Bar.php(115): Tracy\Bar->renderPanels('-ajax:e7cdf9f77...') #24 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Bar/Bar.php(78): Tracy\Bar->renderPartial('ajax', '-ajax:e7cdf9f77...') #25 /var/www/html/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Debugger/DevelopmentStrategy.php(123): Tracy\Bar->render(Object(Tracy\DeferredContent)) #26 /var/www/html/site/assets/cache/FileCompiler/site/modules/TracyDebugger/tracy-2.10.x/src/Tracy/Debugger/Debugger.php(314): Tracy\DevelopmentStrategy->renderBar() #27 [internal function]: Tracy\Debugger::shutdownHandler() #28 {main}
  14. v2.0.26 released. This fixes an issue with roles not migrating properly. It also permits migrations between sites with different admin urls - this can be useful if exporting a bunch of components to use in a different site. I have moved the module from alpha to beta as it has been trouble-free on my sites for a while now. However, YMMD, so always do a database backup before installing, upgrading or installing a migration. As ever, I am happy to take questions, but please do read the (extensive) documentation first (see the help section at the bottom of the module config or https://metatunes.github.io/DbMigrate/help.html).
  15. Yeah, with PipeEmailToPage you don't need a password, because it is 'push' not 'pull'. You can keep the existing mailboxes or just use the default forwarder.
  16. v1.0.4 is now available in the modules library. This is a major enhancement of the original with SPF/DKIM checking and a lot of functionality built into the admin page (see screenshots below). As mentioned before, there were two motivations for this - partly to move off ProcessEmailToPage which relied on the no-longer-supported flourish library but, more importantly, to allow all email forwarding to be handled in the PW back end rather than having to set up forwarders in cPanel. The users of my 'club membership' app needed to be able to redirect forwarders, but I did not want to give them access to cPanel! This version is now in use in two live sites and seems reasonably robust, so I have upgraded it to 'beta' status, but please do test and monitor. The module is designed to fit in to your own custom web app. It does not do anything interesting unless you have designed the 'parent' and 'mail received' templates and programmed what you want to happen after mails are stored. That said, the admin page does provide a simplified 'inbox'. I will be looking to add a 'reply' capability shortly, but again that will only work if you have an email template defined and a way of sending emails (WireSmtp or similar). The module readme is fairly comprehensive, so refer there for full configuration and usage details. Below are a few illustrative screens. Module config screen (part 1): Defines the 'parents' templates and the email field to match with incoming emails. Plus the email template for pages to store the emails (under the related parent). Config screen part 2: Black/white lists, SPF/DKIM checking, email file retention periods (i.e. retention of the raw incoming email file) and listerpro lister if available. Example admin page. This shows mails which have been successfully processed to pages under parents. The other tabs are for 'unprocessed' emails. ...for example, the quarantine tab shows emails that have failed SPF/DKIM checks, blacklists or the hookable checkSender() method: The maintenance/troubleshooting section separately shows processed emails with no matching page ('orphans') which may occur if the page has been trashed or deleted. It also shows (not in this illustration) if any emails are stuck in the processing queue (this may happen if an error - whether in this module or elsewhere - has caused LazyCron to lock) and provides a button to unblock it. Please ask if you have any questions (but not before reading the readme 😉) and report any bugs.
  17. That’s great. Just what I need to implement a sensible pagination of a member name list. Would that be available for any paginated array?
  18. Hi @Juergen. This is a nice module, but unfortunately it becomes unusable when there are a lot of pages. This is because on every page edit it autoloads and runs getParentPages() which has the following: return wire('pages')->find('id!=' . $exclude_pages . ',templates_id=' . $templates); On one site of mine this takes 20 seconds to run - so that's how long it takes to load a page in the back end. I'm only using the publish/unpublish functionality, so I disabled everything else and it loaded in a flash. However, that's not a solution if you want an 'after' action, so I looked into it a bit more. On my problem site, I have lots of parents and templates but I am only using the module on 2 templates which have a total of 47 pages, so I would have thought it would be possible to write it more efficiently. The problem seems to be that the above code is run on every page edit, not just pages of templates where the 'jk_...' fields are enabled. That means that, unless restricted parents are defined for every parent, the 'find' will run across all pages, with a large template array to match. I suggest adding the following after line 224 if(!in_array($this->page->template->id, array_keys($this->input_templates))) { return new PageArray(); } Then if, for the relevant templates, the allowed parents are set, it all runs pretty swiftly. EDIT: Ideally it might be nice to use this, as then the jk_move_child field could be removed from the template if not required and there would be no need to specify allowable parent templates (which may not be desirable for other reasons) if(!in_array($this->page->template->id, array_keys($this->input_templates)) || !$this->page->hasField('jk_move_child')) { return new PageArray(); } However, re-submitting the module will reinstate the jk_move_child field. A bit more flexibility here would be nice. It would be better if 'move child' was an optional extra.
  19. That works very well. Thanks very much @elabx. It will be incorporated in the next version of PipeEmailToPage.
  20. Simple question: Is there an easy way to have pagination within a MarkupAdminDataTable, or do I have to hand code something?
  21. Module now released - see Interested in any feedback @BitPoet
  22. Season's greetings ProcessWirers. My gift to you is a new module called PipeEmailToPage which you can get from GitHub here: https://github.com/MetaTunes/PipeEmailToPage/tree/main. Fairly 'alpha' at the moment, but I have been using it successfully on a live site for a week or so. I'll test it some more before releasing it to the modules library. I designed this as a replacement for ProcessEmailToPage, which relies on the flourish library which is no longer maintained. It also has a fundamentally different method of operation in that it is 'push' rather than 'pull'. The email addresses are created 'virtually' in the sense that they are not necessarily real email addresses but are held in pages whose templates are linked in the module config. The module works when emails are piped to a script (emailpipe.php) on the server which processes the email and creates the page. The pipe needs to be defined in your hosting service's cPanel or similar. If you define the pipe in the 'Default address' in cPanel, all emails sent to the domain will be processed unless they are specified separately. The 'to' addresses will be matched against the email addresses defined in 'parent' pages holding the virtual addresses. If you define the pipe for a specific email address, only emails sent to that address will be processed (but you can define the same pipe for multiple addresses). A major advantage of the module is that the email addresses can be defined entirely within PW. This means that they can be maintained by someone with no access to cPanel once the developer has set up the pipe. Further details are in the readme. I suggest you test thoroughly before using (and take careful note of the 'points to note' in the readme). Turn on some of the logging statements if you wish. Also, check your mail delivery in cPanel to look for errors there. If you report errors to me, I will do my best to hunt them, but please include as much info as possible. I will also be grateful for any suggested code improvements and/or PRs. 🎄
  23. Apologies to anyone ( @BitPoet, @teppo ?) who may have downloaded the module - I left some code in by mistake which crashed it. Now hopefully fixed.
×
×
  • Create New...