Peter Falkenberg Brown Posted July 17, 2013 Share Posted July 17, 2013 Hi Folks, I've brought my front-end app to the point where I'm successfully adding single and multi-type FieldtypePage items to a new page, from input via a form, using this type of code (thanks, Soma, for your tips on this): $field_value = $input->post->$field_name; ... # set field values if ( is_array( $field_value ) ) { foreach( $input->post->$field_name as $pid ) { $new_page->$field->add( (int) $pid ); } } else { $new_page->set("$field_name", "$field_value"); }It works like a charm with single selects, radio buttons, multi-selects, multi-checkboxes, etc. However, in my app, I need to specifically set some field values (like drop down status fields, etc) that the user doesn't interact with. I tried this code, but got an error: "Call to a member function add() on a non-object...". $field = $fields->get("account_status"); # Trial = 1102 $selectors = "parent=/elements/custom_selects/account_status/," . "select_value=Trial," . "include=all"; $field_value_id = $pages->get("$selectors")->id; $new_page->account_status = $field_value_id; ## (THIS CODE WORKED) # $new_page->$field->add( (int) $field_value_id ); ## (THIS CODE DID NOT WORK) The odd thing is that the first block of code works, from a form, for that same field (a single select). I'd like to be able to programmatically set both single and multi-select fields, not via a form, for fields on a new page, or even on an existing page. Things like adding 4 or 5 checkbox values to a multi-checkbox field, etc. I'm sure that my lack of knowledge about PHP OOP is getting in the way, which I plan to rectify. But until then, any tips would be most appreciated. Thanks! Peter Link to comment Share on other sites More sharing options...
teppo Posted July 17, 2013 Share Posted July 17, 2013 Just a guess really, but have you tried $new_page->{$field->name}->add( (int) $field_value_id ); ? I'm guessing the problem might be that here your $field is an actual field (object), while what you really want is it's name. Link to comment Share on other sites More sharing options...
Peter Falkenberg Brown Posted July 17, 2013 Author Share Posted July 17, 2013 Dear Teppo, I haven't tried that, but I already know the name of the field, so with your example, I could write: $new_page->account_status->add( (int) $field_value_id ); I'm wondering why the code works when the values are coming from a form post.... Also, the error message was: "Call to a member function add() on a non-object...". Yours, Peter Link to comment Share on other sites More sharing options...
teppo Posted July 17, 2013 Share Posted July 17, 2013 @Peter: $field = $fields->get("account_status") returns a field object. This would in turn return field ID when converted to string. This explains the error you're getting: while $new_page->account_status returns field called "account_status" attached to that particular page, $new_page->123 (or whatever the ID of that field is) won't work (fields are called with their names, not ID values) and thus it returns an error when you try to use method "add" of this non-existent object. Am I making any sense here? Anyway, reading you post again, I must admit that I don't really get how your application works. There's just not enough data here, I'm afraid. For an example your first example gets field value from $input->post->$field_name but field name itself ($new_page->$field->...) seems to already exist at that point. This is why I'm having a bit of a hard time understanding the relation between these two code examples. 1 Link to comment Share on other sites More sharing options...
Peter Falkenberg Brown Posted July 17, 2013 Author Share Posted July 17, 2013 Dear Teppo, In the first example, with the $field_value input coming from a form post, I iterate over an array of field names, getting $field_name from that array. In the second example, the user has filled out a form, and the code in the first example parses most of the ordinary fields. Then, after that has been done, prior to saving the new page, I need to set the values on a small group of 'admin' type fields, like account_status. Account status is of FieldtypePage, (a single select dropdown). I'm trying to set the field to one of the values ('Trial'), which of course has a page ID. So, since I already know the field name, and the value, I just have to figure out the code to set the value. I want to be able to do the same thing for multi-selects or multi-checkboxes as well. I thought I had to add those values, using the $field->add function, as I did with the 1st example which process user form post input, but then I ran into that error. I'm sure I'm missing something obvious to an OOP expert, but I haven't figured it out yet. This whole thing is a front-end app for members, where they will add, edit and delete pages, all through the API in custom php files. I've got most things working... I'm just stuck on this little point, at the moment. I'm deliberately not using the form API, because I'm using HTML templates with field tags, and then replacing them with values or input fields. Yours, Peter 1 Link to comment Share on other sites More sharing options...
Soma Posted July 18, 2013 Share Posted July 18, 2013 If account_status is of single page select it won't have a add() method like PageArrays have. Multiple page select $new_page->$field->name->add(1023); // like $new_page->account_status->add(1023); // and also this (which seems to append db entry) guess makes sense? $new_page->account_status = 1023; Single page select $new_page->$field->name = 1023; // like $new_page->account_status = 1023; // but not $new_page->account_status->add(ID); // wrong So the page field can have different types based on the dereference settings multiple or single and behave slightly different. Single: it will only be a value of type page and page have no method add, multiple: will be a PageArray. PageArrays have the method add() to add pages, but also the field recognizes just ID's set to it, and it will save the entry and the others already saved or doublicates remain untouched. So to clear a multiple page field you have to call field->removeAll() first. You get this error because the value is most likely not an object (yet). If it dereferences as "single page or false if none selected (!)" .. so if the field is empty it will throw an error: Error: Call to a member function add() on a non-object If you would have already saved a value you would get this error instead, same code but different message because the field now has a page object set: Error: Exception: Method Page::add does not exist or is not callable in this context Hope this shares some light. 4 Link to comment Share on other sites More sharing options...
Peter Falkenberg Brown Posted July 18, 2013 Author Share Posted July 18, 2013 Dear Soma, This is really helpful. Thanks! So, based on what you wrote, it seems that this code worked with the form: if ( is_array( $field_value ) ) { foreach( $input->post->$field_name as $pid ) { $new_page->$field->add( (int) $pid ); } } because the add method was appropriate because the field was a multi. In other words, that code didn't click in when the field was a single (i.e. no array). Your comment about the Page and PageArrays was especially helpful: "Single: it will only be a value of type page and page have no methodadd, multiple: will be a PageArray. PageArrays have the method add() toadd pages, but also the field recognizes just ID's set to it, and itwill save the entry and the others already saved or doublicates remainuntouched." I'm wondering -- since this line: // and also this (which seems to append db entry) guess makes sense? $new_page->account_status = 1023; seems to work for BOTH cases, would you consider it a proper PW way to use that type of code for both single and multi fields? I believe that you imply above that one could even do this on a multi field, with the values (pages) getting appended one after the other: $new_page->account_status = 1023; $new_page->account_status = 1024: $new_page->account_status = 1025: This way, one doesn't have to test whether it's a single or multi field. Thanks so much for your help! Peter Link to comment Share on other sites More sharing options...
ryan Posted July 20, 2013 Share Posted July 20, 2013 $new_page->account_status = 1023; seems to work for BOTH cases, would you consider it a proper PW way to use that type of code for both single and multi fields? I believe that you imply above that one could even do this on a multi field, with the values (pages) getting appended one after the other: $new_page->account_status = 1023; $new_page->account_status = 1024: $new_page->account_status = 1025: This way, one doesn't have to test whether it's a single or multi field. While you may be able to use some of these syntactic tricks when it comes to setting a value, I think it's better to treat a Page as a Page and a PageArray as a PageArray, just as a matter of keeping your code readable. If I have code that needs to deal with either a Page or a PageArray, but it doesn't know ahead of time which it will be, I usually treat it like this: if($value instanceof Page) { // treat it as a Page } else if($value instanceof PageArray) { // treat it as a PageArray } Or I normalize it to one or the other. For instance: if($value instanceof Page) { $a = new PageArray(); $a->add($value); $value = $a; } // now we can assume $value is always a PageArray 3 Link to comment Share on other sites More sharing options...
Peter Falkenberg Brown Posted July 20, 2013 Author Share Posted July 20, 2013 Dear Ryan, Thanks, that makes sense; to keep the code clean. When I tried to integrate your suggestion into my form processing code (listed at the very top of this post), it didn't work. Specifically: # if ( $field_value instanceof PageArray ) # this didn't work if ( is_array( $field_value ) ) { foreach( $input->post->$field_name as $pid ) { $new_page->$field->add( (int) $pid ); } } whereas the "is_array" method did work. Once again, I'm grabbing field values like this: $field_value = $input->post->$field_name; In the case of Page type fields, I didn't use sanitize, since they were the result of dropdowns, etc. Do you think that the "is_array" method is solid enough, and is there something I'm missing with the "instanceof PageArray" method? Thanks, Peter Link to comment Share on other sites More sharing options...
apeisa Posted July 21, 2013 Share Posted July 21, 2013 For some reason your field_value is regular php array instead of PageArray or Page object. Ah, you are getting that directly from post, of course it cannot be page or pagearray then. Link to comment Share on other sites More sharing options...
Peter Falkenberg Brown Posted July 21, 2013 Author Share Posted July 21, 2013 Hi Antti, Yes, I guess that's the issue. I have to do some deep study of OOP. The Great and Mysterious OOP. Peter Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now