-
Posts
76 -
Joined
-
Last visited
-
Days Won
1
Everything posted by Inxentas
-
Adding / Removing items to a Multiple Pages PageArray through code
Inxentas replied to Inxentas's topic in General Support
Nevermind, I screwed up! I now see that I was using the find method instead of the get method! Such a noobie mistake... this topic can be closed. I found the answer a few moments after posting. -
I add some pages to a PageReferences field that I've set to Multiple Pages PageArray. I add stuff to it like this, which works fine. $user->of(false); $newfav = $pages->find($id); $user->favs->add($newfav); $user->save(); I'm trying to remove some items from it, but this doesn't seem to do anything. Here's the code: if($user->isLoggedin()) { $found = false; foreach($user->favs as $fav){ if($fav->id === $id){ $found = true; } } if($found){ $user->of(false); $newfav = $pages->find($id); $user->favs->remove($newfav); $user->save(); } } I already fixed an error where the $id variable wasn't an integer, I'm sure that I end up finding $newfav and that the save() method is called.
-
Hi all. I have a weird issue with a PW installation. When I try to visit https://seniorenwinkel.nl/admin/ (where the CMS is located) the page constantly refreshes itself, adding a "?/r=" plus a timestamp. I'm pretty sure it's line 24 of ProcessLoging.js that keeps doing this. Question is... why? The comment above it says "force refresh of login form if 5 minutes go by without activity", but it's refreshing every SECOND for me. AFAIK this project hasn't been touched in weeks. This ONLY happens on the LIVE server and my DEV server remains unaffected. Does anyone know what is even going on? 😅 And how I could fix this?
-
Leaving the field empty IS the choice here. It's just that the choice is binary, but you're also opting to use 3 templates, making me think you just need a "pick between multiple" mechanic. Why not add a template that represents just that bit of text (let's call it a Sentence page for now), make three Sentence pages with it (each with a different bit of text), and then in your original template make a Page Reference field that filters out only Sentence pages: now you can pick which sentence you want to use every time you make a new page with your original template. If you ever need a 4rth Sentence you just make a new Sentence page.
-
I have used ProcessWireUpgrade for years over a decade without any issues. I do have to admit that I can work at least annually on most of the sites I run. Only once did I have any problems with it, when UIKit became part of the core and I had to update a website that I built in 2012. That's over a decade ago! That was the only instance where I had to upgrade PW manually, for which I followed this process which wasn't all too difficult. Basically came down to renaming some files so I could revert back in case I'd screw up. Aside from that it basically came down to uploading a new wire folder and refreshing the backend. Quite simple.
-
I too like to organize everything as if templates are classes and pages are instances, and do things as OOP / DRY as possible. The ArtistProfile (template) could have page reference field in which one Artist (page instance) can be selected. The profile then encapsulates the artist. In order to make grabbing the image easier later down the line, I like to use Page Classes (these are "on" by default these days, I believe). I would add methods to the PageArtistProfile (page class) that returns field values from the Artist it encapsulates. In the ArtistProfile template, I could then do stuff like: $page->getArtistPortrait(); You can off course add arguments to these methods should you so desire. Same with the partners. I would just make a big "box" of Partner pages. I would probably make a Partners (plural) page under which to collect them all, so I have "one source of truth". In order to subsequently use them on other pages, I would just use a Repeater field with a Page Reference field that filters out only Partners. That way an admin can put them in any order they like as Partners are now also encapsulated in the ArtistProfile, just in a plural form. In my opinion Media Managers tend to be a bit archaic, I prefer to treat media as if they were member values of class instances.
-
I;m sorry, this has been so long I don't remember which project this was exactly. Probably not the same hosting provider, as all the hosts our clients use are local Dutch companies. Most of them are fine but some make changes to their server structure and inform only the client... who them often neglects to inform us. Unfortunately we're not a full service internet bureau so I often find myself dealing with (surmountable) server differences. In that regard PW has been the right choice for me.
-
Can I ask why that is not an option? Perhaps that issue is solved more easily.
-
While this is a very unrefined script and I could always offload that line count to a method, I still think I'm abusing page class constructors a bit too much. Essentially treating them as MVC controllers. So when I got back this morning and had my What The Hell Was I Thinking experience I fully agree with that. However, I would like to handle incoming $input on a per-template basis so I'll move this code into some file and prepend it to the template. What I learned from this is that it's a hassle to get scope on API variables from these constructors. The intent here is to treat the actual template file as a "do whatever you want with it" file after install, so that's why I wanted to move parsing forms on the frontend anywhere but in the actual template file.
-
I would recommend you keep your iframe seperate from your other content. Make two fields. Check the Settings for each. For the iframe, use a Textarea without any Text Formatters. You can echo this on the frontend and get the exact HTML code you put in that field. For content with HTML markup, use a Textarea with the HTML Entity Encoder Text Formatter. I use this approach all the time for any kind of embed codes. You can treat iFrames in a similar manner.
-
I've taken a look at the actual line in PagesEditor.php that throws this error. It's in the isDeleteable() method, the first line of this snippet: } else if($page->id === $this->wire()->page->id && $this->wire()->config->installedAfter('2019-04-04')) { $error = "it is the current page being viewed, try \$pages->trash() instead"; }
-
Problems upgrading from 3.0.98 to latest (Stable)
Inxentas replied to louisstephens's topic in General Support
I had a very similar issue not too long ago, which pointed to some issue with the AdminUIKit module while upgrading an old site. You can find the topic here. Perhaps going through these steps will help figuring out what tweaks you might have forgotten. This assumes you've got the ProcessWireUpgrade module installed. -
I'm having a little trouble deleting pages from a page class context. My approach might be screwy as well, but I'm open for critique. I am very much aware I'm doing no validaton yet. My page class PageAccountPage has an extended constructor that runs through a switch in order to centrally parse forms from it's template. Afterwards it sets a couple of variables, such as $this->addresses (which will store all addresses associated with the users account). This all works pretty well and ensures all form data is parsed before the page is rendered. However, I run into trouble when I delete a page in the switch under the deleteAddress case. I get the following error: Notice: Trying to get property 'id' of non-object in C:\wamp\www\mydomain.com\public_html\wire\core\PagesEditor.php on line 317 This implies the PagesEditor class is trying to grab a page by id that no longer existst due to it's deletion in the switch case. I assign $this->addresses after the switch, at the very end when everything should be parsed. I've also removed it to check whether it was causing the issue, but a little var_dump-ing points out that the error is thrown after the $a->delete line within the switch. A small note: the template has a prepend file set under Files named _webshop.php. Here is the full code: <?php namespace ProcessWire; /** * This is the class tied to the page-account template. */ class PageAccountPage extends WebshopPage { public $addresses; public function __construct(Template $tpl = null) { if($this->input->post->action) { $id = (int)$this->input->post->id; $title = (string)$this->sanitizer->text($this->input->post->title); $street = (string)$this->sanitizer->text($this->input->post->street); $house_nr = (string)$this->sanitizer->text($this->input->post->house_nr); $house_nr_suffix = (string)$this->sanitizer->text($this->input->post->house_nr_suffix); $zipcode = (string)$this->sanitizer->text($this->input->post->zipcode); $city = (string)$this->sanitizer->text($this->input->post->city); $phone = (string)$this->sanitizer->text($this->input->post->phone); $email = (string)$this->sanitizer->email($this->input->post->email); // switch actions switch($this->input->post->action) { case 'updatePassword': $password = (string)$page->input->post->password; $this->user->pass = $password; $this->user->save(); break; case 'loginAccount': $email = (string)$page->input->post->email; $password = (string)$page->input->post->password; $existingUser = $page->users->get("email=$email"); if($existingUser){ $page->session->login($existingUser->name, $password); } break; case 'createAccount': $name = (string)$page->input->post->email . '-' . time(); $email = (string)$page->input->post->email; $password = (string)$page->input->post->password; $existingUser = $page->users->find("name=$name"); if(!$existingUser){ $new = new User(); $new->of(false); $new->name = $name; $new->email = $email; $new->pass = $password; $new->save(); // TODO: Implement email validation and login through link? $page->session->login($new->name, $password); } else { // User exists, cannot remake the account. // TODO: consider a safe implementation of this case. } break; case 'updateAddress': // find page $a = $this->pages->get($id); $a->of(false); $a->title = $title; // populate fields $a->webshop_address_street = $street; $a->webshop_address_house_nr = $house_nr; $a->webshop_address_house_nr_suffix = $house_nr_suffix; $a->webshop_address_zipcode = $zipcode; $a->webshop_address_city = $city; $a->webshop_address_phone = $phone; $a->webshop_address_email = $email; // save page $a->save(); break; case 'deleteAddress': $a = $this->pages->get($id); $a->of(false); $a->delete(); break; case 'addAddress': // create page $new = new Page(); $new->of(false); $new->name = $title; $new->parent = $this->pages->find("template=page-addresses"); $new->template = $this->templates->get('page-address'); $new->name = $title; $new->title = $title; $new->save(); // populate fields $new->webshop_address_street = $street; $new->webshop_address_house_nr = $house_nr; $new->webshop_address_house_nr_suffix = $house_nr_suffix; $new->webshop_address_zipcode = $zipcode; $new->webshop_address_city = $city; $new->webshop_address_phone = $phone; $new->webshop_address_email = $email; // save page $new->save(); break; } } $parent = $this->pages->get("template=page-addresses"); $selector = "template=page-address,created_users_id=" . $this->user->id . ",parent=" . $parent->id; $this->addresses = $this->pages->find($selector); parent::__construct($tpl); } }
-
@OllieM Not long at all. Following the steps above (which is basically just doing the smart thing and backup up old files) it took me a couple of minutes at most.
-
Ah, got the bugger! I was setting the Page template using a string rather then grabbing a full instance of the template. I think this used to work in a previous version or something, but this is way cleaner anyway: $new->template = $this->templates->get('page-address');
-
$_POST is an associative array of variables passed to the current script via the HTTP POST method when using application/x-www-form-urlencoded or multipart/form-data as the HTTP Content-Type in the request. Not when using application/json. For json, you'd typically do something like this: $data = json_decode(file_get_contents('php://input'), true); AJAX is Javascript, and Javascript libraries often use the JSON method. I'm not sure if jQuery does, but I had the same issue when working with AngularJS in the past.
-
I'm writing a class file for an Account page that parses a form whenever a certain 'action' is set in $input->post. The template contains forms to save an existing address, and one to add a new address. Saving the address works great, but my code bugs out the moment I attempt to create a new one. Here is the code I am using in the class file: <?php namespace ProcessWire; /** * This is the class tied to the page_account template. */ class PageAccountPage extends WebshopPage { public $addresses; public function __construct($page) { if($page->input->post->action) { $id = (int)$page->input->post->id; $title = (string)$page->input->post->title; $street = (string)$page->input->post->street; $zipcode = (string)$page->input->post->zipcode; $city = (string)$page->input->post->city; $phone = (string)$page->input->post->phone; $email = (string)$page->input->post->email; switch($page->input->post->action) { case 'save': // find page $a = $this->pages->get($id); $a->of(false); $a->title = $title; // populate fields $a->webshop_address_street = $street; $a->webshop_address_zipcode = $zipcode; $a->webshop_address_city = $city; $a->webshop_address_phone = $phone; $a->webshop_address_email = $email; // save page $a->save(); break; case 'add': // create page $new = new Page(); $new->name = $title; $new->parent = $this->user; $new->template = 'page-address'; $new->save(); // populate fields $new->title = $title; $new->webshop_address_street = $street; $new->webshop_address_zipcode = $zipcode; $new->webshop_address_city = $city; $new->webshop_address_phone = $phone; $new->webshop_address_email = $email; // save page $new->save(); break; } } $this->addresses = $this->user->children("template=page-address"); parent::__construct($page); } } The problem sits in the add case of the switch. I get the following error: Trying to get property 'fieldgroup' of non-object in C:\wamp\www\fransvanberendonk.com\vendor\processwire\processwire\wire\core\PagesEditor.php on line 370 To be clear, the template 'page-address' is one that gets created on module install through code. That code also modifies the User template to allow children in the form of 'page-address' pages. 'page-address' can have a 'user' as a parent. I'm not sure if it's relevant (since it all seems fine from the backend), but here is the code that does that: // set relationships for page_address $page_address->parentTemplates([$page_order, $user]); $page_address->noChildren = 1; $page_address->save(); // set relationships for user $user->noChildren = 0; $children = $user->childTemplates; $children[] = $page_address; $user->childTemplates($children); $user->save(); I also get a message in the CMS after the page bugs out: PagesLoader: You must assign a template to the page before setting field values (title__data) [pageClass=ProcessWire\Page, template=] Which a weird message because the pageClass of the page I'm trying to save is PageAccountPage, which inherits from WebshopPage, which interits from Page. I tried not setting the title before the first save() and filling the name value instead, but to no avail. I'm not sure what goes wrong here. DISCLAIMER: I am aware I should sanitize data first. I wanted to get the thing working first, this code is WIP off course.
-
New post – All about output formatting in ProcessWire
Inxentas replied to ryan's topic in News & Announcements
Thank you Ryan! I have been dilligently but blindly turning Output Formatting on and off in my code for years now, it's nice to know how it all works below the hood. ? -
Yeah I'm still debating where it belongs, I just thought it nice to encapsulate them into the page classes. Why did I not think of using it as a static property? That seems a good idea. That way I can still have the constructors be responsible for it's auto-instantiation on every page that extends WebshopPage ? but be sure there is only one instance.
-
I have a weird issue regarding page classes. For my module, I'm using a couple of those. For clarity, class names are in bold while template names are in italic. The WebshopPage class extends the Page class and is the class from which the others extend. PageCheckOutPage is the class for the CheckoutPage template and extends WebShopPage. Now I've added the following constructor to WebshopPage, in order to make sure every page that extends it has scope on an instance of the (custom) Cart class: public function __construct($page) { $this->cart = new Cart($this->session); parent::__construct($page); var_dump( get_class($this) ); } Now what happens is that the constructor of the Cart class is called twice when I view a page with the CheckoutPage template. Yet the PageCheckoutPage class doesn't have a constructor of it's own, so I would have expected it to fire it's base class constructor once. Yet with the var_dump above, I get the following result: C:\wamp\www\webshop.com\public_html\site\classes\Cart.php:14:string 'Cart constructor' (length=16) C:\wamp\www\webshop.com\public_html\site\classes\WebshopPage.php:16:string 'ProcessWire\PageCheckoutPage' (length=28) C:\wamp\www\webshop.com\public_html\site\classes\Cart.php:14:string 'Cart constructor' (length=16) C:\wamp\www\webshop.com\public_html\site\classes\WebshopPage.php:16:string 'ProcessWire\PageWebshopPage' (length=27) Instead of the extended class simply using the base class constructor as I would have expected, both the base class as the extended class fire a constructor seperately. Now I have a hunch that this happens because each page's parent is also instantiated, and thus it's constructor is ran. I can tell from nesting pages and then using var_dump($page->name) instead. Is this assumption correct? Perhaps there is a better way to ensure that all pages that extend WebshopPage have scope on an instance of the Cart class? I'd rather not have this constructor run as many times as a given page has parents.
-
Admin/Login Page 500 Internal Error - Can't login :(
Inxentas replied to orchardheightsdental's topic in General Support
Ah, my bad. But that does mean this solution should work. The second-last post in that topic tells you exactly what to do. As other people pointed out, it's probably a good idea to make a backup of the files and the database before you do. I do agree though, PW is a fantastic piece of software that rarely runs into these kind of issues, especially if you keep upgrading your website like... once a year. This is also a reason why I vastly prefer it over Wordpress, which is likely to whine about one of it's many plugins needing an upgrade every few weeks. PW has most of that "plugin" stuff in the core already. I can serve most of my clients without using any custom modules: I only install the ProcessUpgrade module for my own convenience. The AdminThemeUikit issue on some old sites is the only instance of PW ever making me manually update anything on the backend. I regularly say no thanks to well-paying development jobs on LinkedIn because I want to keep using ProcessWire. That says something. -
Admin/Login Page 500 Internal Error - Can't login :(
Inxentas replied to orchardheightsdental's topic in General Support
Heyyyy https://www.orchardheightsdental.com/ is back up! I dunno what you did, but it worked! Nice! ? -
Module Development: Inline Frontend Applications?
Inxentas replied to Inxentas's topic in General Support
Thanks for your replies, dear people! I am going to take a look at the suggested JS libraries / frameworks and see what's most suitable for the application. Your descriptions of Alpine and htmx's features were very helpful. It sounds like Alpine would be something I could learn quite easily, but htmx's SEO advantage might be something I end up liking very much. One last question though: do module developers usually supply the JS code with the module, or do module devs tend to lean on a CDN? Performance and footprint is less important to me, but I like the idea of having the module work "out of the box" without requiring code from a CDN, and offering alternate solutions for client who want custom designs for everything. -
Admin/Login Page 500 Internal Error - Can't login :(
Inxentas replied to orchardheightsdental's topic in General Support
I get this error all the time on my development server. 9 out of 10 times I had simply forgotten to change config.php, and my site would try to access the database using my local config! Could it be that you've accidentally overwritten that file with your local version? I ended up implementing a switch in config.php that checks what domain we're on, and sets the config variables according to the current domain. Should it be an upgrade issue, you can get into some trouble when upgrading through the ProcessUpdate module because the JS files for AdminThemeUikit are missing! I had this issue a while back with a bunch of sites that were suddenly running on PHP8 due to a decision of the hosting provider, and some friendly people on this forum helped me update ProcessWire manually to get around this issue. You can find the topic here.