-
Posts
4,928 -
Joined
-
Days Won
321
Everything posted by Robin S
-
Very slow boot time - please help me find the cause!
Robin S replied to sodesign's topic in General Support
Some thoughts... What about any auto-prepended _init.php and/or auto-appended _main.php - any code in there that would impact performance? Bear in mind that the PW debug mode and Tracy Debugger have their own memory usage, DB queries, etc. The Tracy overhead in particular could vary a lot depending on what panels are in use. To get a fair comparison across the EE and PW sites on the server you should disable PW debug mode and Tracy and use some consistent performance measurement technique/tool on both sites. -
Thanks @flydev, but that solution feels less than ideal - I think there is a better way. If you want to implement the AdminThemeUikit breadcrumbs in your custom theme (which you would have to in order for the Breadcrumb Dropdowns module to work) then you can just call AdminThemeUikit::renderBreadcrumbs() because it is a public method. So in your custom theme template files where you want to output the breadcrumbs you can do something like this: echo $modules->get('AdminThemeUikit')->renderBreadcrumbs();
- 79 replies
-
- 1
-
- breadcrumbs
- admin
-
(and 2 more)
Tagged with:
-
problem with identical named images and wireZipFile
Robin S replied to simonGG's topic in General Support
In theory yes, but in practice you will hit PHP memory and timeout limits at some point. Just try it and see how you get on. -
problem with identical named images and wireZipFile
Robin S replied to simonGG's topic in General Support
Probably one of the $sweepstake_children doesn't have any images. Probably best not to rename the images within the page because that results in the loss of potentially useful filename data and would break any links to the images within CKEditor fields. Instead you could copy the files to a temporary directory, renaming them in the process, then create the zip and download from there. Here is some code you can adapt for your purpose: // Create temp directory $td = $files->tempDir('to-zip'); $td_path = (string) $td; $files_to_zip = array(); foreach($page->children() as $child) { $image = $child->images->first(); // Continue if no image exists if(!$image) continue; // Set path including new filename as needed $new_path = $td_path . "{$child->id}.{$image->ext}"; // Copy image to new path $success = $files->copy($image->filename, $new_path); // Add new path to array if($success) $files_to_zip[] = $new_path; } // Set destination path for zip file $zip_path = $td_path . time() . '.zip'; // Create zip file $success = $files->zip($zip_path, $files_to_zip); // Send download if($success) $files->send($zip_path); // Optionally remove temp directory now rather than waiting for it to automatically expire $td->remove(); -
Not so long as you keep it outside of the /wire/ folder.
-
1. If you put your PHP file in the site root it won't be affected by the htaccess restrictions. You could also put it any other place besides those places with restricted access. 2. See the "Files" tab in the template settings: "Disable automatic prepend of file..." / "Disable automatic append of file..."
-
When output formatting is off the value of a Images field is a Pageimages object (WireArray). So you have to do: $page->pageBanner->first()->focus(10,10);
-
See Ryan's post here:
-
Repeater matrix – how to insert content from another field
Robin S replied to Tyssen's topic in API & Templates
You might find this module useful for that: https://modules.processwire.com/modules/restrict-repeater-matrix/ -
Repeater matrix – how to insert content from another field
Robin S replied to Tyssen's topic in API & Templates
You could create a Page Reference field that has the Repeater items as selectable pages. Hook for selectable items in /site/ready.php: $wire->addHookAfter('InputfieldPage::getSelectablePages', function(HookEvent $event) { $page = $event->arguments(0); if($event->object->hasField == 'select_repeater_item') { $event->return = $page->repeater; } }); Then create a matrix type that has this Page Reference field. But if the repeater items are to be output among the matrix items then I'm not sure why the repeater exists as a separate field. Wouldn't it be better to just have a matrix field alone and replace the repeater with a matrix type? -
Save page in PageTable field before close event on Add New modal.
Robin S replied to elabx's topic in General Support
Looks good. You could maybe simplify the first hook by using a str_replace(): $wire->addHookAfter('InputfieldPageTable::render', function (HookEvent $event) { $markup = $event->return; $markup = str_replace("&context=PageTable", "&context=PageTable&field_parent={$event->object->hasPage}", $markup); $event->return = $markup; }); -
Yes, it is about how you build the selector. When you are dealing with input coming from a search form you usually build up the selector in a string variable $selector, adding pieces to $selector for each populated GET variable. But before you try that start with something simpler. Rather than building up a selector string dynamically, experiment with writing out different selector strings and supplying the selector to $pages->find() to see if you get back the pages you expect. The selectors documentation is here: https://processwire.com/docs/selectors/ Each "clause" you add to the selector works with AND logic by default: field_1=foo, field_2=bar This matches pages where field_1=foo AND field_2=bar. For OR logic with different fields and values, check the documentation for OR-groups. (field_1=foo), (field_2=bar) This matches pages where field_1=foo OR field_2=bar. Regarding OR conditions for multiple values in a single field, or multiple fields with a single value, see the following sections: https://processwire.com/docs/selectors/#or-selectors1 https://processwire.com/docs/selectors/#or-selectors2 When you have sorted out what kind of selector you need to match the pages you want you can move on to building up the selector dynamically according to your GET variables.
-
Save page in PageTable field before close event on Add New modal.
Robin S replied to elabx's topic in General Support
Like you say, the PageTable page only belongs to the PageTable field when you save it. So you can get the container page as you save the page but not before then. Maybe this post helps: If your PageTable pages are set to be children of the container page it would be easier, but often for PageTable fields that's not the case. It's much easier to get the container page for Repeater fields, so I'd say a Repeater Matrix field is a better choice over a PageTable field for these kinds of things. If you are stuck with the PageTable field and there's no other solution then you could try something like hooking ProcessPageAdd and injecting some JS that checks for an iframe parent and gets the edited page ID from the parent URL, then saves it to a cookie or PHP session via AJAX, then you look for that page ID in the cookie/session in another hook before ProcessPageEdit. But that's hardly a straightforward solution. -
I've never needed to use ProcessPageClone but I would have expected the created/modified time to be set to the time the new page is cloned from the old page. Maybe there are use cases for cloning the created/modified times, so perhaps the issue could be a feature request for the option to determine what happens to created/modified times on the cloned page?
-
Hi @stuartsa, welcome to the PW forums. ? Publishing a new page that is created via the API is not an extra action because pages are published by default. Or more accurately, they are "not unpublished" by default, because being unpublished is an extra status that you may add to a page but is not present by default. When a page is created in the admin via ProcessPageAdd it gets the unpublished status added because the expectation is that the user probably wants to populate some fields in a following step before the page becomes accessible on the front-end, and also because new pages can be added by roles with more restricted permissions than superuser. But when you add pages via the API then you are an unrestricted superuser and so it is up to you to populate the page fields and set page statuses as you see fit. Yes.
- 1 reply
-
- 1
-
Get random items from repeater field from specific pages
Robin S replied to Tyssen's topic in API & Templates
Try: $result = new PageArray(); foreach($pages->getById([1049,1053,1055,1059,1152]) as $p) { $result->add($p->repeater_field->findRandom(3)); } $result->shuffle(); // Now do something with $result - foreach, etc. -
Using owner selector to determine if the owner page is published
Robin S replied to a-ok's topic in General Support
The status flags are bitwise so if you use a flag value directly to find published pages it would need to be like this: projects_awards.owner.status<2048 But for PageFinder selectors you can use a string for status: projects_awards.owner.status!=unpublished You would also want to exclude unpublished repeater pages because otherwise you can get unfilled "ready" repeater pages in your result. So your selector would be: template=repeater_projects_awards, projects_awards.owner.status!=unpublished, status!=unpublished, include=all -
Awesome that you are tackling this, but it goes way over my head I'm afraid so I don't think I'll be much help. I never see any of these gamma correction issues because all my sites use the ImageMagick resizer engine. Which raises the question: does ImageMagick not need gamma correction, or is it just not possible to do gamma correction with IM? Put another way: is the gamma correction a strength or weakness of the GD engine? If the IM engine avoids the gamma correction issue and is generally a better choice for resizing do you think the PW installer should check for IM support and automatically install the IM engine when IM is available?
-
@SebastianP, give this a try... 1. Remove the "lang_id=18712" portion of the selector string for the autocomplete field. 2. Add the following to the selector string for the autocomplete field: name!=12345 This part of the selector string is deliberately set to something that should always be true - in this case that the page name should not be "12345". The purpose of this is to let us identify the selector when it is sent in the AJAX request. 3. Add the following hook to /site/ready.php: $wire->addHookBefore('ProcessPageSearch::executeFor', function(HookEvent $event) { $input = $event->wire('input'); /// If this request is coming from the autocomplete field... if($input->get('name!') === '12345') { // ...then set the lang_id GET variable $input->get->lang_id = 18712; } });
-
Publish/Unpublish a page setting required to edit published pages
Robin S replied to adrian's topic in General Support
You still have the "Unpublished" checkbox on the Settings tab and the "Pub" action button in Page List to deal with. Plus to be extra sure you can hook Pages::publishReady to prevent publishing by any means. Some hooks... // Remove publish button and unpublished checkbox in Page Edit $wire->addHookAfter('ProcessPageEdit::buildForm', function(HookEvent $event) { /* @var InputfieldForm $form */ $form = $event->return; /* @var ProcessPageEdit $ppe */ $ppe = $event->object; $page = $ppe->getPage(); // Return early if user is not an agent or it's not a restricted page if(!$event->user->hasRole('agent') || $page->template != 'property') return; // Return early if page is published if(!$page->isUnpublished()) return; // Get status field /* @var InputfieldCheckboxes $status_field */ $status_field = $form->getChildByName('status'); // Remove unpublished checkbox $status_field->removeOption(2048); // Get publish button $publish_button = $form->getChildByName('submit_publish'); // Remove button $form->remove($publish_button); }); // Remove publish button from Page List $wire->addHookAfter('ProcessPageListActions::getExtraActions', function(HookEvent $event) { $page = $event->arguments(0); $extras = $event->return; // Return early if user is not an agent or it's not a restricted page if(!$event->user->hasRole('agent') || $page->template != 'property') return; // Return early if page is published if(!$page->isUnpublished()) return; // Remove publish action unset($extras['pub']); $event->return = $extras; }); // Prevent publishing by any means $pages->addHookAfter('publishReady', function(HookEvent $event) { $page = $event->arguments(0); // Return early if user is not an agent or it's not a restricted page if(!$event->user->hasRole('agent') || $page->template != 'property') return; // Return early if page is published if(!$page->isUnpublished()) return; // Throw exception throw new WireException('You do not have permission to publish this page'); }); -
@Tom., I tried resizing your original image and could see the banding issue when using GD for image resizing with the default gamma correction. The banding issue doesn't occur when using the ImageMagick resize engine, or when using the GD resize engine if gamma correction is disabled. Disable gamma correction for individual image resize: $page->image->size(1920, 1080, ['defaultGamma' => -1])->url Or disable gamma correction globally in /site/config.php $config->imageSizerOptions('defaultGamma', -1);
-
Selector to exclude categories not used - solved
Robin S replied to mel47's topic in General Support
Here is a hook method for /site/ready.php that gets the pages that are selected in a given Page Reference field: /** * Get pages selected in a Page Reference field * Use optional argument $options for limiting 'template' and/or 'parent_id', and to 'include_unpublished'. * Usage: $selected_pages = $fields->my_page_field->getSelectedPages(['template' => 'basic_page']); * The number of times each page is selected is available in a custom "occurrunces" property on each selected page. */ $wire->addHookMethod('Field(type=FieldtypePage)::getSelectedPages', function(HookEvent $event) { /* @var Field $field */ $field = $event->object; $options = $event->arguments(0); $get_options = []; if(isset($options['template'])) $get_options['template'] = $this->wire('templates')->get($options['template']); if(isset($options['parent_id'])) $get_options['parent_id'] = (int) $options['parent_id']; $table = $field->getTable(); $query = $this->wire('database')->query("SELECT data FROM $table"); $ids = $query->fetchAll(\PDO::FETCH_COLUMN); $count_values = array_count_values($ids); $items = $this->wire('pages')->getById(array_keys($count_values), $get_options); foreach($items as $item) { if(empty($options['include_unpublished']) && $item->status > Page::statusUnpublished) { $items->remove($item); } else { $item->occurrences = $count_values[$item->id]; } } $event->return = $items; }); The following is an example of how you would get the category pages that are selected in your category field. The number of times each category is selected is available in the custom "occurrences" property if you need it. // Get the selected category pages $selected_categories = $fields->categories->getSelectedPages(); // Demo output foreach($selected_categories as $selected_category) { echo "<p>Category {$selected_category->title} is selected in {$selected_category->occurrences} page(s).</p>"; } -
As per my previous reply and the module readme there are config options for dialog width and height. Or maybe I don't understand your question.
-
Sorry, I didn't understand the original issue properly before. You shouldn't have to activate the tooltip option for the append option to work for selects - I've fixed the logic in v0.1.2 so it should work as expected now.
-
Excellent tutorial, thanks! Just wondering: why do you write your own str_truncate and textToId functions instead of using core $sanitizer methods like truncate() and name()? (for the latter there are several different sanitizer methods that could be used to get an ID string)
- 2 replies
-
- 2
-
- twig
- templating
-
(and 2 more)
Tagged with: