Jump to content

Robin S

  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by Robin S

  1. You need to create a database and a user for the database before you complete that part of the PW installation process. Then you will know the database name, user name, and password for the user. I'm not a XAMPP user but I'm pretty sure that it comes bundled with phpMyAdmin. So you open phpMyAdmin in your browser (probably at http://localhost/phpmyadmin) and then the quickest way is to create the user and database in one step at User accounts > Add user account After you have created the user/database then you will know the user name, database name (which will be the same as the user name) and the password so you can complete the PW installation process.
  2. Thanks for the report. PHP 7.3 apparently makes some changes to the regex engine and so an update to the bundled Simple HTML Dom Parser was needed. Done now in v0.1.6 of this module.
  3. Very helpful, thanks! I see the module gives a warning if a tag is created that has the same name as an existing template. Tags added to a template via the core way on the Advanced tab don't give this warning. Is there a catch to watch out for if a tag name is also a template name? Also, it's only a small thing but maybe this module only needs to autoload in the PW admin ("autoload" => "template=admin") rather than for the front-end also.
  4. Hi @bernhard, I gave this module a try to see if it might be a good way to get data for a CSV download (on the front-end). But I'm having trouble getting off the ground. I installed the module, put some demo code in my template file... $rf = new RockFinder2(); $rf->find("id>2, limit=5"); $rf->addColumns([ 'title', 'modified', ]); ...and I get this error: Call to a member function __invoke() on null The same code seems to execute in the Tracy Console in the back-end without an error. Is this module only for use in the PW admin? I had trouble understanding the GitHub readme - are those just notes to yourself? It wasn't clear to me how the SQL examples at the top of the readme relate to the module, and several of the code examples use "new RockFinder()" when this module class is RockFinder2. Update: fixed as per post below
  5. @adrian, there is already a config option for that:
  6. @Jens Martsch - dotnetic, @rjgamer, @teppo, @szabesz, @erikvanberkum, @dragan, @Lutz, @eydun, @psy, @horst, @cstevensjr, @tpr Just tagging in those who have reacted/responded to this topic in order to bring your attention to the notice above. Please don't uninstall but update to v0.2.1 or greater ASAP. Again, my apologies for the error. The intention was to have the module clean up after itself on uninstall but it's just too risky.
  7. IMPORTANT NOTICE TO ALL USERS OF THIS MODULE! I just discovered that the uninstall routine in v0.2.0 can inadvertently delete directories that it shouldn't depending on the module configuration. If you have v0.2.0 installed please DO NOT UNINSTALL but instead update the module to the recently released v0.2.1 as soon as possible. The module can be safely uninstalled from v0.2.1 or higher. To update the module, visit the module config page, expand the Module Information section and click "check for updates". I apologise for this error.
  8. This maybe? if(!isset($options['findAll'])) $options['findAll'] = true; https://processwire.com/api/ref/pages/find/ findAll (boolean): Find all pages with no exclusions, same as "include=all" option (default=false).
  9. Not really. Could you explain why you want to do this? Rather than modifying asmSelect.js and needing to make changes to the Connect Page Fields module I think it might be better to adapt to how PW handles the sorting of newly added pages by default and reverse the sort order of the Page Reference field when you get it via the API. Example:
  10. There's nothing in the core dependent selects feature that dictates how you organise your pages. A parent/child relationship to define categories and subcategories is just one that suits many scenarios, and if I understand right it's the way that was specified in the original question. The thing that determines how it works is this: So you can use "page.page_reference_field_name" in the selector string setting for the dependent field in any way that suits you. You could have all your subcategories under one parent and connect them with one or more categories using a "category" page reference field in the subcategory template. Then the selector string for the subcategory field could include "category=page.category" to limit the subcategories according to what is selected in the category field on the currently edited page. AsmSelect works with the core dependent selects, but it certainly would be nice if the range of compatible inputfield types could be expanded.
  11. I just tested this by creating a new template named "_test" and the stub file was created normally. I can't think of any reason why a template name starting with an underscore would behave differently with this module. It's common to create a file named "_main.php" that is auto-appended to template files if you are using a delayed output strategy, but in that case the file does not correspond to any PW template. Maybe that's the case for you. Are you sure you actually have a template named "_main" in Setup > Templates?
  12. It does, it's just not documented unfortunately. I linked to information about it in my earlier post above. Here is a demo... Page structure: Field settings for subcategory field: "page.category" will be replaced with the ID of the page selected in the Category inputfield in Page Edit, whenever that field changes. The "has_parent" part is just to avoid unwanted pages appearing in the Subcategory inputfield if the Category inputfield is changed to empty (no page selected). Result:
  13. Yeah, makes me wonder if it would have been better if the Pages::trashed method was called immediately before saving the trashed page rather than after. Maybe Ryan has a good reason for doing it that way. I still think it's better to hook after Pages::trashed if you want to know for sure which pages are trashed because when hooking Pages::trash there are still instances where the trashing can fail. For example, there might be another Pages::trash hook in a module that deliberately prevents trashing of particular pages. If you hook Pages::trashed you can parse the parent page ID (and some other info) from the name of the page in the trash: $pages->addHookAfter('trashed', function(HookEvent $event) { $page = $event->arguments(0); $pages = $event->object; /* @var PagesTrash $trasher */ $trasher = $pages->trasher(); $name_info = $trasher->parseTrashPageName($page->name); if(!empty($name_info['parent_id'])) { $parent = $pages($name_info['parent_id']); // ... } });
  14. An alternative is to use $files->render($filename). See the documentation about where the file is allowed to be. $emailBody = $files->render('/path/to/emailbody.inc');
  15. For anyone wanting to trace how it is that Pages::trash is called twice... Pages::trash (first call) calls PagesTrash::trash, and when the "save" argument is true (as it is when trashing via the admin) then Pages:save is called, which calls PagesEditor::save. And if that saved page is in the trash then Pages::trash is called (second call) with the "save" argument false. As to whether this second Pages::trash call is necessary and correct, I don't know. Best thing is to hook Pages::trashed as suggested above - this method only fires if the page is successfully trashed, which is probably what is wanted in most cases.
  16. You might want to also validate the date when the page is saved as @BitPoet suggests, but it is possible to limit the datepicker to only future dates with some custom admin JS. The relevant option is minDate. The core sets the datepicker options on focus, so to ensure the custom option doesn't get overwritten I've found that the most reliable way to apply it is by using a beforeShow function. For a Datetime field named "crondate": $(function() { $('#Inputfield_crondate').on('focus', function() { $(this).datepicker('option', 'beforeShow', function() { return { minDate: 0 }; }); }); }); Edit: just noticed you want a minimum time also. Try this: $(function() { $('#Inputfield_crondate').on('focus', function() { $(this).datepicker('option', 'beforeShow', function() { return { minDate: 0, minDateTime: new Date(new Date().getTime() + 30 * 60000) }; }); }); });
  17. You can hook Session::redirect and check the redirect URL and the current process. Not perfect, but as far as I can see the deletePage() method uses a redirect URL that is unique in ProcessPageEdit and is therefore identifiable as coming from that method. $wire->addHookBefore('Session::redirect', function(HookEvent $event) { $url = $event->arguments(0); if($this->process == 'ProcessPageEdit') { $admin_url = $event->wire('config')->urls->admin; if(strpos($url, $admin_url . 'page/?open=') === 0) { $event->arguments(0, '/your/custom/url/'); } } });
  18. @matjazp, that's strange. The link is to the Single version of ProMailer, which I can see in the store: Maybe that option is only visible to purchasers of ProDevTools, because when ProMailer launched Ryan said that he would provide a Single version of ProMailer to ProDevTools users on request (perhaps he sends a coupon code?) But it might instead be an access glitch so I suggest that anyone interested in purchasing the single version contact Ryan to ask about it.
  19. This was due to $config->fileContentTypes not having up-to-date MIME types. I created an issue here and decided it would be better to make the MIME type > file extension mapping configurable in v0.2.2 rather than using $config->fileContentTypes. Please update the module and the problem should be fixed. P.S. This page is a useful resource if anyone wants to set additional MIME type mappings: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types
  20. Here's some updated code to try: // Find IDs of users that have been active in the last $mins number of minutes function onlineUserIDs($mins, $limit = 500) { $table = SessionHandlerDB::dbTableName; $seconds = $mins * 60; $sql = "SELECT user_id " . "FROM `$table` " . "WHERE ts > DATE_SUB(NOW(), INTERVAL $seconds SECOND) " . "AND user_id!=40 " . // exclude guest "ORDER BY ts DESC LIMIT $limit"; $query = wire('database')->prepare($sql); $query->execute(); $results = $query->fetchAll(\PDO::FETCH_COLUMN); return $results; } // User IDs active in the last hour $online_user_ids = onlineUserIDs(60); // Convert to string for use in selector $online_user_ids = implode('|', $online_user_ids); // Online users $online_users = $users->find("id=$online_user_ids"); // Offline users excluding guest user $offline_users = $users->find("id!=$online_user_ids, roles.count>1");
  21. No, but you can use a "fake" PageArray to paginate other things, as described by Ryan here:
  22. Sort of. This does the job but is somewhat hacky: $wire->addHookBefore('InputfieldRepeater::render', function(HookEvent $event) { $inputfield = $event->object; $session = $event->wire('session'); // Existing open IDs from core (e.g. items that contain errors) $existing_open_ids = $session->getFor('InputfieldRepeater', 'openIDs') ?: []; // Find the IDs of items you want to render in open state $open_ids = $inputfield->value->find("images.count>1")->explode('id'); // Merge IDs $open_ids = array_unique(array_merge($existing_open_ids, $open_ids)); // Set open IDs to session $session->setFor('InputfieldRepeater', 'openIDs', $open_ids); }); $wire->addHookBefore('InputfieldRepeater::processInput', function(HookEvent $event) { // Clear open IDs from session $event->wire('session')->removeFor('InputfieldRepeater', 'openIDs'); }); Would be nice to have a proper API method to do this.
  23. If you only need the count of $progretti then you can use the more efficient $pages->count() method. And you might find the Connect Page Fields module useful to create two-way connections between the pages in your Page Reference fields. This can help avoid the need for additional PageFinder queries inside the foreach because the projects for each supplier can be stored in a Page Reference field in the supplier template. Also, please use code blocks when posting code in the forum to make it more readable.
  • Create New...