Jump to content

Robin S

Members
  • Posts

    4,928
  • Joined

  • Days Won

    321

Everything posted by Robin S

  1. Use the main menu to go to Modules > Configure > FieldtypeFile In the "Allowed Fieldtype modules for custom fields" field, tick the checkbox for URLLanguage. It says it may not be 100% compatible with custom fields but it seems to work fine for me.
  2. This gets the inputfield name, not the field name. The inputfield name will have a suffix when it appears inside a repeater, so checking it against a particular field name is not a reliable way to identify the field. The settings for a Page Reference field gives you an example hook for when you want to use the "Custom PHP code" option. The example shows that the best way to identify the field is via the hasField property. So for your hook: $wire->addHookAfter('InputfieldPage::getSelectablePages', function (HookEvent $event) { $page = $event->arguments('page'); if($event->object->hasField == 'refStep') { // Your hook code here... } });
  3. @adrian you probably saw already that there's a flag you can add to the rewrite rule in htaccess to allow the encoded question mark: https://httpd.apache.org/docs/current/rewrite/flags.html#flag_unsafe_allow_3f But who wants to reopen a fixed security hole? It seems like this Apache change will affect a lot of websites as the built-in URL encoding functions in JS and PHP don't make any special exception for the question mark character, and it's surely not that rare to pass an encoded URL as a GET parameter. So it seems like the options are to specifically replace the encoded question mark with ? after getting the return value from a URL encoding function, or to use a completely different encoding like Base64 if all or part of a URL needs to be used in a GET parameter. Edit: I've created a topic in the ProDevTools support forum to draw Ryan's attention to this discussion. Oh, you already PMd him so that probably wasn't necessary.
  4. Weird that you saw it on the old version, because like you say it's probably related to the changes in Apache 2.4.60 https://httpd.apache.org/security/vulnerabilities_24.html https://www.cve.org/CVERecord?id=CVE-2024-38474
  5. I haven't experienced the issue (I get normal 200 responses for User Activity requests) but it sounds like some sort of pre-emptive security blocking. If you're running WireRequestBlocker see my topic here because the default rules are quite broad. Or maybe your host has introduced some security software without notifying you? I had an irritating situation like this with Cloudways recently (thankfully resolved now).
  6. I'd like to second this. It would be great if the new/improved admin theme was built with maximum customisability in mind. One use case is so that we can more easily offer a "mostly-frontend" user an admin experience that's radically different to what a superuser or site administrator gets in the uncustomised admin. Another admin customisation issue I've struck recently is when you want to customise markup for InputfieldWrapper. There's InputfieldWrapper::setMarkup() but this is marked as internal and isn't that practical to use because InputfieldWrapper::markup is static. That means any custom markup you set there persists for all InputfieldWrappers that are subsequently rendered, when what I want to do is customise markup for a specific instance of InputfieldWrapper. Edit: pull request When the admin theme is revisited it would be great to ask of each component that's rendered, "Is there an opportunity to make this rendering customisable?"
  7. Inspired by @horst's helpful post above, here is some code for preventing guests from accessing original images that leverages more of the PW API... In .htaccess, just after "RewriteEngine On" # When original images are requested, rewrite for PHP user verification # If a matching file exists RewriteCond %{REQUEST_FILENAME} -f # And the file is within the /site/assets/files/ directory RewriteCond %{REQUEST_FILENAME} (^|/)site/assets/files/(.*?)/ # And the file extension is for an image type that we want to restrict access to RewriteCond %{REQUEST_FILENAME} \.(jpg|jpeg|gif|png)$ [NC] # And the filename portion of the path contains less than two dots (i.e. is not an image variation) RewriteCond %{REQUEST_FILENAME} !^(.+\/)?[^\/]+\.[^\/]+\.[^\/]+$ [NC] # Then rewrite to a hooked URL for user verification RewriteRule ^(.*)$ index.php?it=/original-image/ [L,QSA] In /site/ready.php // A URL hook for verifying that the user is allowed to view original images $wire->addHook('/original-image/', function($event) { $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); $ext = pathinfo($path, PATHINFO_EXTENSION); $filename = $event->wire()->config->paths->root . ltrim($path, '/'); $allowed_exts = ['jpg', 'jpeg', 'png', 'gif']; // Optional: get the Pageimage and the Page it belongs to // if this affects whether the user is allowed to view the file // $pm = $event->wire()->pages(1)->filesManager; // $pageimage = $pm->getFile($filename); // $page = $pageimage->page; // Send the file if the user is allowed to view it if( // The file extension must be one of the allowed extensions in_array($ext, $allowed_exts) && // The user must be logged in $event->wire()->user->isLoggedin() && // The file must exist is_file($filename) ) { $event->wire()->files->send($filename); } // Otherwise, return a 403 Forbidden response header('HTTP/1.0 403 Forbidden'); die('403 Forbidden'); });
  8. Logs JSON Viewer Formats JSON data in ProcessLogger for improved readability. Because log files can only contain strings, it's a common practice to use json_encode() to convert an array to a string when you want to save the data to a log file. But the resulting JSON is not as readable as it could be when viewing the log in ProcessLogger. The Logs JSON Viewer module uses the json-viewer library to improve the readability of JSON data in ProcessLogger and add some useful features. Before: After: Configuration You can set the config options for json-viewer in a textarea field. See the json-viewer readme for information about the options. There is also an option to set the width of the column that contains the JSON data. This setting exists because otherwise the column jumps around in an inconsistent and distracting way when changing from log to log or between paginations. Features You can switch the view of the JSON data between formatted and unformatted using the toggle button at the bottom of the data. The viewer has a number of useful features such as: Progressively expand or collapse levels in the data. View the count of child items and the data type of each item. Search for a string within the data. Copy all or part of the data to the clipboard (requires the HTTPS protocol). https://github.com/Toutouwai/LogsJsonViewer https://processwire.com/modules/logs-json-viewer/
  9. Thanks, and I just noticed the HelloWorld panel too. Very helpful ? That's a good solution, thanks. I missed that there is now a JSON viewing feature. That's what my upcoming module does too. Still worth releasing I think because it has some extra features and config options.
  10. Thanks. Good call, I didn't think about that panel. You don't want to be making changes and additions to Tracy Debugger for the sake of other modules. The appeal of CustomLogs might be quite niche so I'll wait for a bit, but I could perhaps look at including a panel for Tracy within the CustomLogs module. I think I remember reading somewhere that you've allowed for third-party panels - can you refresh my memory on this? And could there be a way to hook into the ProcessWire Logs panel rendering (if there isn't already)? I have another log-related module to release and I could potentially add a feature so that it applies to the Logs panel too.
  11. Custom Logs When you use the core $log->save() method you can only save a single string of text. When you view the log in the core ProcessLogger the columns and their header labels are predetermined. The Custom Logs module is different in that it lets you write and view log files with the number of columns and the column header labels you specify in the module configuration. Configuration In the "Custom logs" textarea field, enter custom logs, one per line, in the format... name: column label, column label, column label ...with as many comma-separated column labels as needed. The log name must be a word consisting of only [-._a-z0-9] and no extension. If you prefix a URL column label with {url} then the value in the column will be rendered as a link in the log viewer. The date/time will automatically be added as the first column so you do not need to specify it here. Writing to a custom log Use the CustomLogs::save($name, $data, $options) method to save data to a custom log file. $cl = $modules->get('CustomLogs'); $cl->save('my-log', $my_data); Arguments $name Name of log to save to (word consisting of only [-._a-z0-9] and no extension). $data An array of strings to save to the log. The number and order of items in the array should match the columns that are configured for the log. $options (optional) Options for FileLog::save(). Normally you won't need to use this argument. Example of use Custom log definition in the module configuration: visits: {url}URL, IP Address, User Agent, {url}Referrer Saving data to the log: $cl = $modules->get('CustomLogs'); $data = [ $_SERVER['REQUEST_URI'] ?? '', $_SERVER['REMOTE_ADDR'] ?? '', $_SERVER['HTTP_USER_AGENT'] ?? '', $_SERVER['HTTP_REFERER'] ?? '', ]; $cl->save('visits', $data); Viewing the resulting log in Setup > Logs > visits: https://github.com/Toutouwai/CustomLogs https://processwire.com/modules/custom-logs/
  12. @joe_g, you could use a similar approach to that used by the Repeater Images module. Demo... Repeater Matrix field config: Hook in /site/ready.php: $wire->addHookBefore('Pages::saveReady', function(HookEvent $event) { /** @var Page $page */ $page = $event->arguments(0); if($page->template == 'demo_matrix_upload') { // File extension to Repeater Matrix type and subfield mapping $matrix_types = [ 'jpg' => [ 'type' => 'jpg', 'subfield' => 'image', ], 'mp4' => [ 'type' => 'mp4', 'subfield' => 'file', ], ]; // For each file in the "Upload files to Matrix" field foreach($page->upload_files_to_matrix as $pagefile) { // Skip file if it does not have an allowed file extension // It also makes sense to configure the upload field to only allow // the extensions you have matrix types for if(!isset($matrix_types[$pagefile->ext])) continue; // Add a Repeater Matrix item of the matching type for the file $item = $page->matrix_files->getNewItem(); $item->setMatrixType($matrix_types[$pagefile->ext]['type']); // Save the item so it is ready to accept files $item->save(); // Add the file $item->{$matrix_types[$pagefile->ext]['subfield']}->add($pagefile->filename); // Save the item again $item->save(); } // Remove all the uploaded files from the upload field $page->upload_files_to_matrix->removeAll(); } }); Result:
  13. I don't have a good sense of what you're doing in your code, but AFAIK Process module permissions should only be applicable to viewing the page of the Process module. I would have thought you would be able to do something like this... $m = $modules->get('MyModule'); echo $m->myMethod($foo, $bar); ...regardless of if the current user is guest or not. But great that you've found a solution.
  14. I suggest using URL hooks for any requests coming from the front-end. It wouldn't be ideal to have front-end requests going to a Process module page in any case because that would decrease site security by publicly revealing the admin login URL.
  15. Awesome module @ryan! Could the module include an option to style custom children differently to genuine children? Or maybe add a special class to custom children items so we can target them in custom admin CSS. And for advanced cases, a hookable method so custom children items could be identified and potentially modified when rendered in Page List.
  16. If you are doing something like this... // Get poi page from Page Reference field $poi_page = $page->my_page_reference_field; // Render poi page echo $poi_page->render(); ...then you can pass variables to the template file of the poi page via the $options array argument. See docs: https://processwire.com/api/ref/page-render/render-page/ // Get poi page from Page Reference field $poi_page = $page->my_page_reference_field; // Render poi page echo $poi_page->render(['rendered_from' => $page]); And in the poi template file: if(!empty($options['rendered_from'])) { $rendered_from = $options['rendered_from']; //... } You can also use the $options['pageStack'] value in the template file. It's mentioned in the docs page linked to above, but probably easiest to understand if you just dump it and see what it contains.
  17. See this recent reply to a similar question: I think render() is too late to apply collapsedHidden so hook InputfieldXXX::renderReadyHook() instead, but the same ideas apply. You can get the page being edited via the ID in $input.
  18. I think you could use an inputfield dependency for this, with the "forpage" keyword: https://github.com/processwire/processwire/pull/255
  19. I didn't study your post in detail, but maybe this gives you an idea: $wire->addHookBefore('InputfieldText::render', function(HookEvent $event) { /** @var InputfieldText $inputfield */ $inputfield = $event->object; // The Field object associated with the inputfield, so the name isn't affected by any repeater suffix $field = $inputfield->hasField; // The Page that the inputfield is in so you can check its template // to see if it belongs to the relevant repeater field $page = $inputfield->hasPage; if(!$field || !$page) return; if($field->name === 'text_1' && $page->template == 'repeater_test_repeater') { $inputfield->appendMarkup('hello'); } });
  20. For the title field you can enable access control in template context to limit editability by role. For deletion you can revoke the delete permission per template per role. For the settings tab there is a $template->noSettings property: https://github.com/processwire/processwire/blob/38a5320f612a4b38a7353265343219f224f20e6d/wire/core/Template.php#L100 You can conditionally set this with a hook for non-superusers: $wire->addHookBefore('ProcessPageEdit::execute', function(HookEvent $event) { /** @var ProcessPageEdit $ppe */ $ppe = $event->object; /** @var Page $page */ $page = $ppe->getPage(); if($page->template == 'my_template' && !$event->wire()->user->isSuperuser()) { $page->template->noSettings = 1; } });
  21. Check the files in the folder at: /wire/modules/Inputfield/InputfieldDatetime/types/ It sounds like might you have a file named "._InputfieldDatetimeText.php" in there. That file should not exist. There should only be the three files shown here:
  22. You could try the latest dev (3.0.239) to see if it's an issue that has been fixed since 3.0.229 was released. If it's still present in the latest dev then please open a GitHub issue so Ryan can investigate.
  23. System templates have the Template::flagSystem flag. So the "proper" way: $non_system_templates = new TemplatesArray(); foreach($templates as $template) { // Skip templates with the system flag if($template->flags & Template::flagSystem) continue; $non_system_templates->add($template); } The lazy way that is likely to work 99.9% of the time: $non_system_templates = $templates->find("flags=0"); For some reason templates that are used for the custom fields for files/images feature don't have the system flag, so you will have to exclude those separately if you have any. The name of such templates starts with "field-".
  24. I don't know for sure but it looks like a problem with your Imagick configuration or file permissions. The module won't be able to solve that but if you update to the newly released v0.2.2 there is an option in the module config where you can choose to use GD for the conversion instead.
  25. I do it essentially the same as what @TomPich said, but on the first move from local to remote I find it's a lot faster and more reliable to compress all the website files to a ZIP archive, upload that to the remote server, then extract it on the server. If you're using cPanel then the included File Manager is a convenient way to upload and extract. And when using a host that doesn't include a file manager I like to use TinyFileManager, although you need to take due care with security - as extra protection I rename the containing folder to include a dot prefix to prevent access when I'm not actively using it.
×
×
  • Create New...