
MarkE
Members-
Posts
1,098 -
Joined
-
Last visited
-
Days Won
12
Everything posted by MarkE
-
Released: Street Address Fieldtype + Inputfield
MarkE replied to netcarver's topic in Modules/Plugins
A bug? (version 1.1.2) On selecting a subfield in a lister and typing in the value to match, I get the error "Call to a member function isEmpty() on string" for line 55 of FieldtypeStreetAddress.module -
Released: Street Address Fieldtype + Inputfield
MarkE replied to netcarver's topic in Modules/Plugins
This is a really useful module. I have only had one issue so far - the default country setting in the field config page does not seem to work in the API. I have to set (e.g.) $this->address->origin_iso = 'GB'; for it to be effective. -
Module Module: RuntimeMarkup Fieldtype & Inputfield
MarkE replied to kongondo's topic in Modules/Plugins
Hi @xportde. I have noticed the same thing. I assume this is important to you because you have some hook or other that you only want to operate if fields have changed. What I do is simply catch and exclude any field changes that I'm not interested in. E.g. in a Pages::saved hook: $excludeFields = ['runtime_markup_parent', etc.......]; $changes = array_diff($event->arguments(1), $excludeFields); -
One 'gotcha' that gets me more than I'd like is that if a session has expired, PW gives you no warning. Scenario - you are editing a page and go away to do something else for a bit (you saved it first of course ? ). Then you come back to the page and do some more edits and save - whoa! your edits are irretrievably lost because the session had timed out without telling you. I try and get into the habit of refreshing before I start work again, but don't always remember ? .
-
I've used Lazy Cron successfully elsewhere, combined with a Cron job to trigger it. However on my current project it is not working. The reason seems to be that it is not giving a normal response type. The Cron job is wget --quiet no-cache -O - https://domainname... It runs each time with an error-free response, but does not trigger Lazy Cron. If I paste the url https://domainname... into the browser it does trigger LazyCron. With a bit of debugging, the reason is clear - the Cron job gives responseTypeAjax = 2 which is bypassed by Lazy Cron, but the browser gives responseTypeNormal = 1 which is processed by Lazy Cron. Any ideas why and how to fix it (other than hacking LazyCron.module)? The triggered page is just a simple template with a response of "echo 'Hello from ' . $page->title;" EDIT: Please ignore this - I think I have mis-diagnosed the problem - will sleep on it!! EDIT2: Nothing wrong with LazyCron. Problem was not assigning permissions to the cron job -i.e. the triggered function did not operate properly with "guest" role.
-
- 1
-
-
I have a temporary work-round, although less than ideal. I capture the form details and save it as a page in admin_instance (that works fine, using $config->admin_site). Then a LazyCron in the admin site picks up new forms and sends the emails. (I tried to use a hook after Pages::added, but it seems that this is not triggered when the page is added from another instance.) When the LazyCron runs, it is of course running in the admin instance. EDIT: Actually there are pros and cons of the work-round method, so I will stick with it for now. Thanks for the comments @horst.
-
Yes. It is used extensively elsewhere in Availability.php and works fine. Config ($config->admin_site outputs ProcessWire 3.0.153 dev #1) No the host page is in site-web, which I think you are calling website_instance. No. It is in admin_instance, where the runtime markup field with Availability.php is.
-
Sorry - I forgot to say that I had tried various other things, including your suggestion. I've now done those things again (with $mailOwner rather than $mail - I'd forgotten that was predefined) and recorded the error in each case. These are reproduced below as a pair of lines - code followed by error: $mailOwner = $config->admin_site->wire('mail'); Could not get the right WireMail-Module (WireMailSmtp); found: WireMailTools [My debugging line] $mailOwner = $config->admin_site->mail->new(); require_once(./WireMailSmtpAdaptor.php): failed to open stream: No such file or directory in M:\laragon\www\BawdHall\site\assets\cache\FileCompiler\site\modules\WireMailSmtp\WireMailSmtp.module on line 290 The second of these seems to be calling the right module (WireMailSmtp) but can't find the file because $config is always for instance_A. This seems similar to the issue we had with Runtime Markup.
-
Yes. The php for that field is Availability.php, which is in instance_B, and calls mail as described above. Not sure what more info you want re "where and how". Abbreviated code for this script is below: <?php namespace ProcessWire; $headers = getallheaders(); $permittedNonPW = array_map('trim', array_map('strip_tags', explode(',', $page->bodyTop))); $permittedPW = array_map('trim', array_map('strip_tags', explode(',', $page->bodyFoot))); // If site is a PW site, then need to deal with the different instances if (in_array($headers['Host'], $permittedPW)) { $site = $config->admin_site; $config->sitePages = $config->admin_site->pages; } else { $site = wire(); $config->sitePages = $pages; } ///////////////////////////////////////////////////////// // Process any form results: /////////////////////////////////////////////////////////// // define variables and set to empty values $name = $email_address = $phone = $fromToDate = $adults = $children = $pets = $provbooking = $message = $spambot = ""; $fromerror = $toerror = $radioerror = $propertyName = ""; function test_input($data) { //......... return $data; } if (isset($_GET["submit"])) { $out = ''; if ($_SERVER["REQUEST_METHOD"] == "POST") { $propertyName = test_input($_POST["property"]); //...... //fill variables } //...... $mail = wireMail(); if($mail->className != 'WireMailSmtp') { wire()->log->save('debug', 'Could not get the right WireMail-Module (WireMailSmtp); found: ' . $mail->className); } else { $mail->to($to) ->from($myemail) ->subject($email_subject) ->bodyHTML($email_body_top . $email_body); $numsent = $mail->send(); if ($numsent > 0) { //..... $out .= '<script>alert("Your request has been submitted - you should receive an automated email acknowledgement shortly.")</script>'; //..... $url = strtok($_SERVER['REQUEST_URI'], '?'); $out .= '<script>window.location.assign("' . $url . '");</script>'; return $out; } /////////////////////////////////////////////// /////////////// MAIN PAGE //////////////////// ////////////////////////////////////////////// $currentPath = $files->currentPath(); $out = ... // Fills the availability table ... ////////////////////Don't forget the form itself////////////////////////////// if (in_array($headers['Host'], $permittedPW)){ wire()->log->save('debug', 'Calling booking form sitePages = ' . $config->sitePages->get('/')->title . ', $headers["Host"] is ' . $headers["Host"]); $out .= $config->admin_site->files->render($currentPath . 'booking_form.php'); } else { $out .= wire()->files->render($config->paths->templates . 'RuntimeMarkup/booking_form.php'); } //////////////////FINALLY RETURN THE OUTPUT!!!/////////////////////////// return $out; This works fine for $permittedNonPW but not for $permittedPW.
-
In your terminology, lets say instance_B is "site" and instance_A is "site-web". Both sites sit under the same root, sharing the same wire/ (i.e. a multi-site installation). in _init.php (part of the template rendering) in instance_A: $config->admin_site = new ProcessWire($config->paths->root . 'site/'); I use $config->admin_site so that it can be accessed anywhere (assuming the current context is instance_A). Ah, that's a bit (!) more complicated. Instance_A accesses a runtime markup field in instance_B thus: $adminPage = $config->admin_site->pages->get("template=Availability, name=bawd-hall-availability"); $availabilityTable = $adminPage->runtime_markup_availability; This field renders php in the file Availability.php, which lives in instance_B ("site") Availability.php renders a form thus: $out .= $config->admin_site->files->render($currentPath . 'booking_form.php'); where $currentPath is $files->currentPath(); - i.e. booking_form is a sibling of Availability. (BTW, Availability.php checks the host name in the headers to determine whether it is being called as a second instance or not). booking_form's action is $_SERVER['REQUEST_URI'] (i.e. the original page, thus running Availability.php again). Availability.php tests (isset($_GET["submit"]) ) and if true processes the POST variables from the form. After validation, the mail is constructed from these variables with $mail = wireMail(); etc. For more background (if you really want ? ) you can see here, where @kongondo was extremely helpful getting the RuntimeMarkup Fields module working in a multi-instance environment.
-
I've used this module a number of times and it works well. Now I am trying to use it in a multi-instance environment and am a bit stuck. Is this possible at all? To explain: I have two sites (in a PW multi-site setup - although I think the issue would be the same even if they were completely separate). "site" is a private admin site and "site-web" is a public website. "site-web" accesses "site" via an instance as described in https://processwire.com/blog/posts/multi-instance-pw3/. "site" has a contact form which is accessed by "site-web" and has WireMailSmtp installed. When completed, an email is sent using $mail=wireMail(). This works fine when the public site is not a PW site. However, when it is a PW site (as "site-web" is), the context for WireMail is "site-web", not "site", so $mail returns a WireMail class, not a WireMailSmtp class. I cannot find a way to call WireMail in the right instance context. If I try and call WireMailSmtp directly, it is operating in the wrong context and fails. I guess I could install a copy of WireMailSmtp on "site-web", but then I need to maintain the config on both sites. Besides it seems counter-intuitive that using a non-PW site for the public site should be easier than doing it in PW! I'd be grateful for any ideas or insights.
-
Module Module: RuntimeMarkup Fieldtype & Inputfield
MarkE replied to kongondo's topic in Modules/Plugins
Nor me. It seems like PT calls the RM PHP file more than once. The first time it works properly with a Pageimage, but then later calls submit a string/integer/boolean. The code to bypass the latter has the side effect that the RM field now has nothing in it - hence the need for the reload. All pretty messy! I've tried various debugging routes, but can't work out how the multiple calls are happening. -
Module Module: RuntimeMarkup Fieldtype & Inputfield
MarkE replied to kongondo's topic in Modules/Plugins
Agnostic. Probably instanceof is better. -
This seems to fix it: https://github.com/furf/jquery-ui-touch-punch
-
Module Module: RuntimeMarkup Fieldtype & Inputfield
MarkE replied to kongondo's topic in Modules/Plugins
Here's my complete work-round for the problem with runtime markup images in a Page Table field. Something that prevents the problem occurring in the first instance would be better though! 1. Add the following condition for images rendered in the runtime markup: if (is_a($image, '\ProcessWire\Pageimage')) $out .= '<img src="' . $image->url . '"/>'; 2. Add the following to admin.js (the 2 functions are lifted from InputfieldPageTable.js): /*******************************************************************************************************************/ /* Work-round to reload and re-enable sorting of Page Table field, which includes runtime markup, after modal edit */ /*******************************************************************************************************************/ $(document).on('pw-modal-closed', function(event) { var wrap = $(this).find('.InputfieldPageTable'); if ($(wrap).attr('id')) $('#' + wrap.attr('id')).load(document.URL + ' #' + wrap.attr('id') + '> *'); // To just load the inner html of wrap - avoiding duplicating it }); $('.InputfieldPageTable').mouseenter(function () { if (!$('tbody').hasClass("ui-sortable")) { var $table = $('tbody').closest('table'); InputfieldPageTableSortable($table); } }); function InputfieldPageTableUpdate($table) { var value = ''; if(!$table.is('tbody')) $table = $table.find('tbody'); $table.find('tr').each(function() { var pageID = $(this).attr('data-id'); if(value.length > 0) value += '|'; value += pageID; }); var $container = $table.parents('.InputfieldPageTableContainer'); var $input = $container.siblings('.InputfieldPageTableSort'); $input.val(value); } function InputfieldPageTableSortable($table) { $table.find('tbody').sortable({ axis: 'y', start: function(event, ui) { var widths = []; var n = 0; $table.find('thead').find('th').each(function() { widths[n] = $(this).width(); n++; }); n = 0; ui.helper.find('td').each(function() { $(this).attr('width', widths[n]); n++; }); }, stop: function(event, ui) { InputfieldPageTableUpdate($(this)); } }); } /*******************************************************************************************************************/ -
Module Module: RuntimeMarkup Fieldtype & Inputfield
MarkE replied to kongondo's topic in Modules/Plugins
Putting this: $(document).on('pw-modal-closed', function(event) { var wrap = $(this).find('.InputfieldPageTable'); if ($(wrap).attr('id')) $('#' + wrap.attr('id')).load(document.URL + ' #' + wrap.attr('id')); }); in the admin js avoids the need to hack the InputfieldPageTable.js. Again, there may be side effects that I haven't noticed. One side-effect I have noticed is that, after closing the modal, the rows in the Page Table can no longer be sorted by dragging - a full window refresh is still required for that. -
Module Module: RuntimeMarkup Fieldtype & Inputfield
MarkE replied to kongondo's topic in Modules/Plugins
To make this work inside a page table, I had to hack the InputfieldPageTable.js as follows: function InputfieldPageTableDialog() { var $a = $(this); var url = $a.attr('data-url'); var title = $a.attr('data-title'); var closeOnSave = true; var $container = $(this).parents('.InputfieldPageTableContainer'); var wrap = $(this).closest('.InputfieldPageTable'); // MDE added var dialogPageID = 0; var noclose = parseInt($container.attr('data-noclose')); var modalSettings = { close: function(event, ui) { if(dialogPageID > 0) { var ajaxURL = $container.attr('data-url') + '&InputfieldPageTableAdd=' + dialogPageID; var sort = $container.siblings(".InputfieldPageTableSort").val(); if(typeof sort != "undefined" && sort.length) ajaxURL += '&InputfieldPageTableSort=' + sort.replace(/\|/g, ','); $.get(ajaxURL, function(data) { $container.html(data); $container.find(".Inputfield").trigger('reloaded', ['InputfieldPageTable']); $container.effect('highlight', 500, function() { var $table = $container.find('table'); $table.find('tbody').css('overflow', 'visible'); InputfieldPageTableSortable($table); // restore appearnace of any items marked for deletion var deleteIDs = $container.siblings("input.InputfieldPageTableDelete").eq(0).val().split('|'); if(deleteIDs.length) { for(var n = 0; n < deleteIDs.length; n++) { var deleteID = deleteIDs[n]; $table.find("tr[data-id=" + deleteID + "]") .addClass('InputfieldPageTableDelete ui-state-error-text ui-state-disabled'); } } }); }); if ($(wrap).attr('id')) $('#' + wrap.attr('id')).load(document.URL + ' #' + wrap.attr('id')); // MDE added } } } .... The new lines are the ones annotated "MDE added" I haven't found any unwanted side-effects (so far ..) but obviously I'm a bit unhappy about amending core code unless it warrants a PR, so I would be grateful for any thoughts on this, or other ideas. -
Module Module: RuntimeMarkup Fieldtype & Inputfield
MarkE replied to kongondo's topic in Modules/Plugins
Great module, but I'm having a couple of minor issues (unrelated, I think). The first issue seems intermittent and I can't work out why : In some cases, I can't get the inclusion of .js and .css to work. I've triple-checked all the naming etc. but the files just don't seem to load. My work-round (easy enough) is just to load the files in the php. The second issue may be because I am stretching the fieldtype's capability! I am using it within a PageTable field as follows. The PageTable field ("panelled_carousel") has a template "Panelled_carousel" which has fields "title", "imagePages" (a page reference field linking to a page with template "Image" and an image field "image_single") and "runtime_markup_images" (a runtime markup field with php file "RuntimeMarkup/Images.php"). The php file is (including a bit of debugging): $imagePages = $page->imagePages; bd($page, 'page with carousel'); $out = ''; wire()->log->save('debug', 'Page is ' . $page->title); foreach ($imagePages as $imagePage) { bd($imagePage, 'imagePage'); foreach ($imagePage->image_single as $image) { bd($image, 'image'); if (is_a($image, '\ProcessWire\Pageimage')) $out .= '<img src="' . $image->pia("width=200")->url . '"/>'; } } return $out; The RM field is updated when the imagePages field changes by javascript/AJAX : When editing the Page Table field, this all works well - any changes in the imagePages (add/re-order/delete etc) are immediately reflected in the RM field. However, when saving the Page Table Field and returning to the host page, the RM PHP throws an error unless I catch it with the condition - is_a($image, '\ProcessWire\Pageimage') - in the code above. The reason is that in some cases $image seems to be taking a string, integer or boolean value, even though $imagePage has class Page and the dump shows it is the right page. Trapping this error means that the images in the table are all blank after the save. However refreshing the page puts everything right again. So not a deal-breaker but a bit odd. To illustrate, here is the top page with the page table (including images): Clicking on "Blue" to edit an item we get: Then, clicking save and returning to the top page, the images do not render: The debugging shows that this is not because Images.php has not run, but because $image is of the wrong type (as described above). Refreshing the page restores the images. Any ideas? EDIT: I should add that the problem does not seem to be related to my .js script, or even RuntimeMarkup specifically as exactly the same issue happens in a Page Table with @Robin S's RuntimeOnly module with no js attached to it. So it seems to be something to do with how the runtime markup is interacting with the page table display. -
That's because it was caused by a bit of rogue code on my part!! Cleaned it up now - sorry for the diversion. I'm actually having some (unrelated?) issues with the RM module at the moment. I'll investigate further and post on the module thread if there is a real problem.
-
Sorry, the answer to that is a bit complicated. I am not using the RM module to refer to the css file. It is linked in the PHP script. This detects whether the host site (site 2) is on a permitted list stored in the availability page in site 1 which contains the RM field. There are two such lists - one for non-PW sites and one for PW sites. The script grants the permissions required for it to access the templates/fields it needs and also passes the css as an in-line style. So I just had to make sure that the path was correct for the css (and js) like this: } elseif (in_array($headers['Host'], $permittedPW)) { $currentPath = $files->currentPath(); $calendarUser = $config->admin_site->users->get("name=calendar"); // calendar has role that only allows access to the availability page $config->admin_site->users->setCurrentUser($calendarUser); $cssText = file_get_contents($currentPath . 'styles/Availability.less.css'); if ($cssText) { $out .= '<style>' . $cssText . '</style>'; } $js = file_get_contents($currentPath . 'scripts/Availability.js'); if ($js) { $out .= '<script>' . $js . '</script>'; } } else { Maybe a bit hacky - but works ? It makes no difference - I get the error from site 1 if the RM module is not in site 2, or from site 2 if it is in both.
-
I fixed the css and it all works. I'm getting PHP notice from Tracy: PHP Notice: Object of class ProcessWire\DefaultPage could not be converted to int in ...\FieldtypeRuntimeMarkup.module:536 That line is $root = $mode == 2... in public function getDefaultPath($defaultPath, $mode=1) { $config = $this->wire('config'); $root = $mode == 2 ? $config->urls : $config->paths; if(2 === (int) $defaultPath) $defaultPath = $root->siteModules;// /site/modules/ else $defaultPath = $root->templates;// /site/templates/ return $defaultPath; } Doing a bd(), it would seem that $mode is the host page for the RM field, not an integer! Not causing a problem in my case, since $root = $config->paths is OK, but odd. I wasn't getting this error with the previous version (or my hacked copy).
-
Many thanks for that @kongondo. Any reason for that? I need it on both sites (a really useful module ? ). A quick test seems to indicate that it works OK if installed on one or both sites, but I will investigate more. As you say, my css isn't working properly after this but hopefully I can fix that. I'll spend some time with it and let you know of any issues. Thanks again!
-
Here's what I have: public function getDefaultPath($defaultPath, $page, $mode=1) { bd($page, 'page'); $config = $this->wire('config'); if ($mode == 2) { $rootUrl = preg_replace('/assets.*/m','',$page->filesUrl()); $config->setUrl('templates_RM', $rootUrl . 'templates/'); $config->setUrl('siteModules_RM', $rootUrl . 'modules/'); $root = $config->urls; } else { $rootPath = preg_replace('/assets.*/m', '', $page->filesPath()); $config->setPath('templates_RM', $rootPath . 'templates/'); $config->setPath('siteModules_RM', $rootPath . 'modules/'); $root = $config->paths; } if(2 === (int) $defaultPath) $defaultPath = $root->siteModules_RM;// /site/modules/ else $defaultPath = $root->templates_RM;// /site/templates/ return $defaultPath; }
-
No. I can't use $site->config->paths->site inside your module, just $config->paths->site. But if I hooked it there would be more flexibility. Sorry, I missed that. I did originally add the domain parameter, but I got an "overloaded" error message, so I removed it. Here's the code: $config->admin_site = new ProcessWire($config->paths->root . 'site/'); Using $config means it's available everywhere in site 2 (which is actually called site-web).
-
You would need to add $page as a parameter to make it usable in the way I describe. That always returns site 2, so no use. It needs to be something that takes $page as its reference point.