Jump to content

Robin S

  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by Robin S

  1. 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?
  2. 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:
  3. 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']); // ... } });
  4. 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');
  5. 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.
  6. 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) }; }); }); });
  7. 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/'); } } });
  8. @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.
  9. 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
  10. 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");
  11. No, but you can use a "fake" PageArray to paginate other things, as described by Ryan here:
  12. 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.
  13. 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.
  14. v0.2.0 released, which makes the stubs directory path configurable and includes a checkbox in the module config to manually regenerate all stub files if needed (thanks @teppo).
  15. That's a better location for the stub files - I've switched to that in v0.1.8.
  16. I've added support for these sorts of remote files in v0.2.1.
  17. I don't have any fixes for this module, but I created a similar module that I have now released:
  18. This module is inspired by and similar to the Template Stubs module. The author of that module has not been active in the PW community for several years now and parts of the code for that module didn't make sense to me, so I decided to create my own module. Auto Template Stubs has only been tested with PhpStorm because that is the IDE that I use. Auto Template Stubs Automatically creates stub files for templates when fields or fieldgroups are saved. Stub files are useful if you are using an IDE (e.g. PhpStorm) that provides code assistance - the stub files let the IDE know what fields exist in each template and what data type each field returns. Depending on your IDE's features you get benefits such as code completion for field names as you type, type inference, inspection, documentation, etc. Installation Install the Auto Template Stubs module. Configuration You can change the class name prefix setting in the module config if you like. It's good to use a class name prefix because it reduces the chance that the class name will clash with an existing class name. The directory path used to store the stub files is configurable. There is a checkbox to manually trigger the regeneration of all stub files if needed. Usage Add a line near the top of each of your template files to tell your IDE what stub class name to associate with the $page variable within the template file. For example, with the default class name prefix you would add the following line at the top of the home.php template file: /** @var tpl_home $page */ Now enjoy code completion, etc, in your IDE. Adding data types for non-core Fieldtype modules The module includes the data types returned by all the core Fieldtype modules. If you want to add data types returned by one or more non-core Fieldtype modules then you can hook the AutoTemplateStubs::getReturnTypes() method. For example, in /site/ready.php: // Add data types for some non-core Fieldtype modules $wire->addHookAfter('AutoTemplateStubs::getReturnTypes', function(HookEvent $event) { $extra_types = [ 'FieldtypeDecimal' => 'string', 'FieldtypeLeafletMapMarker' => 'LeafletMapMarker', 'FieldtypeRepeaterMatrix' => 'RepeaterMatrixPageArray', 'FieldtypeTable' => 'TableRows', ]; $event->return = $event->return + $extra_types; }); Credits Inspired by and much credit to the Template Stubs module by mindplay.dk. https://github.com/Toutouwai/AutoTemplateStubs https://modules.processwire.com/modules/auto-template-stubs/
  19. You could change your Select Options fields to Page Reference fields. Page Reference fields are more powerful and flexible and the better choice in most cases. One of the advantages is that users can edit, sort, add and remove options for fields simply by working with the pages that represent the options. You can create a References branch in your page tree to hold the option pages for your Page Reference fields, and the Page Field Select Creator module is useful for quickly setting up new fields.
  20. v0.1.6 released. Adds module config options to override the requirements coming from the password inputfield, so the generator can create stronger passwords than the inputfield requires.
  21. v0.2.0 released, which adds support for File fields so that file URLs can be added the same as with Image fields. Thanks to @gmclelland for the idea. I've also submitted the module to the directory now seeing as it seems to be working well without any significant issues reported.
  22. Hi @ryan, I see that when FileValidatorImage is installed it is automatically employed by all InputfieldImage and InputfieldFile inputfields. I assume this means that there is no downside to having this validation so there is no need to allow the user to choose which fields it applies to (e.g. only specific inputfields used on the front-end by non-trusted users). But if it's all upside and no downside then wouldn't it be better to have this module installed by default in the PW core and not as a separate non-core module?
  23. Prefix the name with \ to specify the global space: $foo = new \SimpleXMLElement($data);
  • Create New...