apeisa Posted February 9, 2011 Share Posted February 9, 2011 I have page field called "supporters" and it allows multiple pages. How I add multiple pages through API? Usually this is done like this: $gig->supporters = $page; This of course doesn't work with multiple pages. I tried this (found from current docs, used in images): $gig->supporters->add($page); But it doesn't work. Link to comment Share on other sites More sharing options...
ryan Posted February 9, 2011 Share Posted February 9, 2011 The syntax in your second example is correct. When you say it didn't work, can you describe further? Was there an error message? Link to comment Share on other sites More sharing options...
apeisa Posted February 9, 2011 Author Share Posted February 9, 2011 Thanks Ryan. No error msg so tt must be an error on my shell script. Link to comment Share on other sites More sharing options...
ryan Posted February 9, 2011 Share Posted February 9, 2011 Is there a $gig->save(); somewhere? (to make sure the change was saved) Link to comment Share on other sites More sharing options...
ryan Posted February 9, 2011 Share Posted February 9, 2011 If you want, feel free to email me the script and I can track it down more easily being able to see it all. Link to comment Share on other sites More sharing options...
apeisa Posted February 9, 2011 Author Share Posted February 9, 2011 It works now. I am creating cron script that get's gig information from last.fm api. Problem was that I checked if I already have current support artist in database, if not, create new one. Also add new page to $supporter_pages array so I can later add it to related gig. This last part (adding to array) was only done when creating new pages, not if I already had it in database. if (count($wire->pages->find('template=artist, title="'.$supporter.'"'))) { $support = $wire->pages->find('template=artist, title="'.$supporter.'"'); $supporter_pages[] = $support; // <-- THIS WAS MISSING } else { $support = new Page(); .... Those selectors aren't probably best ones (title), I think it should be better to use $get and url? Is get faster? Link to comment Share on other sites More sharing options...
ryan Posted February 9, 2011 Share Posted February 9, 2011 For something like this, I usually prefer to use the name field over the title field just because there's no worry about escaping quotes, whitespace, etc. But if your $supporter is never going to have double quotes in it, then you are probably fine to use title. Speed wise, I don't think you are paying any penalty by using the title--it should have a full index in the DB, which will keep it just as fast as name. However, I do think you could improve this by only doing one call to $pages->find(). In addition, yo should probably use $pages->get() rather than $pages->find() since your $supporter_pages[] = $support seems to assume that $support is a Page rather than a PageArray. Here is what I would change it to: <?php $support = $wire->pages->get('template=artist, title="' . $supporter . '"'); if($support->id) { $supporter_pages[] = $support; } else { $support = new Page(); ... } If you want to use the name field instead of the title field (though it may not be necessary), you could do this: <?php $name = $wire->sanitizer->pageName($supporter); $support = $wire->pages->get("template=artist, name=$name"); ... Link to comment Share on other sites More sharing options...
apeisa Posted February 9, 2011 Author Share Posted February 9, 2011 Thanks Ryan. I will change my selectors to name, I think it is cleaner in many ways. I don't know if it's good idea to code while being ill (common cold). I mean my script is a monster Link to comment Share on other sites More sharing options...
ryan Posted February 9, 2011 Share Posted February 9, 2011 Using name may be better just because it can only consist of these ascii characters: -_.a-z0-9. Meaning it's easy to validate, and easy to use as a urlSegment or GET variable. If all of your artists are in one dir, then you can also change your selector to: $support = $wire->pages->get("/artists/$name/"); There may not necessarily be any advantage to doing that over what you were doing, but it's just an alternate approach. Nothing wrong with coding while ill, just drink Dayquil rather than Nyquil (I speak from experience). (if they have that cold medicine in Finland?). Or better yet, coffee, or both. Link to comment Share on other sites More sharing options...
apeisa Posted February 9, 2011 Author Share Posted February 9, 2011 Thanks. I have something that my wife calls "ällöjuoma" -> "ugly drink" to support me I changed all to use name. It seems to work well mostly, but it gives me this error in one event. Only difference I can think of is that this name is rather long.. Uncaught exception 'WireDatabaseException' with message 'Duplicate entry 'project-decay-nor-w-viisikko-fleshpress-1751059-6984' for key 'name_parent_id'' in /srv/www/keikalle.com/public_html/wire/core/Database.php:72 Stack trace: #0 /srv/www/keikalle.com/public_html/wire/core/Pages.php(355): Database->query('INSERT INTO pag...') #1 [internal function]: Pages->___save(Object(Page)) #2 /srv/www/keikalle.com/public_html/wire/core/Wire.php(241): call_user_func_array(Array, Array) #3 /srv/www/keikalle.com/public_html/wire/core/Wire.php(203): Wire->runHooks('save', Array) #4 [internal function]: Wire->__call('save', Array) #5 /srv/www/keikalle.com/public_html/wire/core/Page.php(733): Pages->save(Object(Page)) #6 /srv/www/keikalle.com/cron/query_lastfm.sh(172): Page->save() #7 /srv/www/keikalle.com/cron/query_lastfm.sh(6): get_data(1, Object(ProcessWire)) #8 {main} thrown (line 72 of /srv/www/keikalle.com/public_html/wire/core/Database.php) This error message was shown because you are logged in as a Superuser. Here is some of my code: $gigName = $event['title'] . '-' . $event['id']; $gigNameUrl = $wire->sanitizer->pageName($gigName); $gig = $wire->pages->get("template=gig, name=$gigNameUrl"); if ($gig->id) { echo $gig->title . ": gig is already in database, we only update \n"; } else { $gig = new Page(); $gig->template = 'gig'; $gig->parent = $gig_parent; } $gig->title = $event['title']; // We dont use $gigName here because we don't want last.fm id to title $gig->datetime = $event['startDate']; $gig->venue = $venue; $gig->lastfmid = $event['id']; $gig->headliner = $head; foreach($supporter_pages as $supporter) { $gig->supporters->add($supporter); } unset($supporter_pages); $gig->name = $gigNameUrl; // Here we want to use gigNameUrl since there is also last.fm id (there are same names for different gigs) $gig->save(); Link to comment Share on other sites More sharing options...
apeisa Posted February 9, 2011 Author Share Posted February 9, 2011 Original title is: PROJECT DECAY (NOR) w/ VIISIKKO & FLESHPRESS-1751059 It must be / or & doing bad things here? Link to comment Share on other sites More sharing options...
ryan Posted February 9, 2011 Share Posted February 9, 2011 Actually this is a duplicate entry error. I've setup MySQL to maintain a unique index between the page name and the parent_id, so that it's impossible to have two pages with the same name under the same parent. So the error you got here is from MySQL telling you that you are attempting to insert a page with the same name as one that's already there. Can you check if a page named "project-decay-nor-w-viisikko-fleshpress-1751059" is already there? Link to comment Share on other sites More sharing options...
apeisa Posted February 9, 2011 Author Share Posted February 9, 2011 It is there, but shouldn't this do update in this case? I try to look if the page is already there, if not, then create new page, else update info & save. Link to comment Share on other sites More sharing options...
apeisa Posted February 9, 2011 Author Share Posted February 9, 2011 Here is the problematic part of the code: $gigName = $event['title'] . '-' . $event['id']; $gigNameUrl = $wire->sanitizer->pageName($gigName); $gig = $wire->pages->get("template=gig, name=$gigNameUrl"); if ($gig->id) { echo $gig->title . ": gig is already in database, we only update \n"; } else { $gig = new Page(); $gig->template = 'gig'; $gig->parent = $gig_parent; } ... update values ... $gig->name = $gigNameUrl; $gig->save() It works on other events, but for some reason not for this one... Somehow if($gig->id) returns false, but then I set the exact same value ($gigNameUrl) as name and still duplicate... Link to comment Share on other sites More sharing options...
ryan Posted February 9, 2011 Share Posted February 9, 2011 I think I might know what the deal is. Try changing this line: $gigNameUrl = $wire->sanitizer->pageName($gigName); To this: $gigNameUrl = $wire->sanitizer->pageName($gigName, true); The second param "true", tells it to beautify (remove doubled chars and stuff). I forgot that the Page class uses that beautify option, so adding the "true" will ensure it's consistent in how it generates the page name. I bet this will fix the problem. Link to comment Share on other sites More sharing options...
apeisa Posted February 9, 2011 Author Share Posted February 9, 2011 I commented $gig->save() on this one and tested rest of the script. Similar situation also fails on artist called: Super8 & Tab. There is also ampersand, so it is probably the reason. It get's manipulated in some point - probably on db save. This is the code that fails when $supporter = "Super8 & Tab" $supporterNameUrl = $wire->sanitizer->pageName($supporter); $support = $wire->pages->get("template=artist, name=$supporterNameUrl"); if (!$support->id) { $support = new Page(); $support->template = 'artist'; $support->parent = $artist_parent; $support->title = $supporter; $support->name = $supporterNameUrl; $support->save(); } Link to comment Share on other sites More sharing options...
apeisa Posted February 9, 2011 Author Share Posted February 9, 2011 I think I might know what the deal is. Try changing this line: $gigNameUrl = $wire->sanitizer->pageName($gigName); To this: $gigNameUrl = $wire->sanitizer->pageName($gigName, true); The second param "true", tells it to beautify (remove doubled chars and stuff). I forgot that the Page class uses that beautify option, so adding the "true" will ensure it's consistent in how it generates the page name. I bet this will fix the problem. You bet right, it works like a dream. Thank you (again) very much! You will be first person to play with our app when we get it ready. It is gonna be supersweet (mobile html5 app)! Link to comment Share on other sites More sharing options...
ryan Posted February 9, 2011 Share Posted February 9, 2011 Great! glad that fixed it. I look forward to checking out your app! Link to comment Share on other sites More sharing options...
apeisa Posted February 9, 2011 Author Share Posted February 9, 2011 Hah, I got one more problem. Though I fully understand why (but I don't know best way to handle it yet...). I have artist called: ギルガメッシュ So after sanitizer it goes very nice: (this space intentionally left empty) And saving currently gives error: Uncaught exception 'WireException' with message 'Can't save page 0: /artisti/0/: It has an empty 'name' field' Link to comment Share on other sites More sharing options...
ryan Posted February 9, 2011 Share Posted February 9, 2011 Wow, good question. It looks like PHP iconv has no equivalent conversion to ascii for those characters (understandable). Are there any other properties to that artist that could be used as a name... for instance their last.fm id or something like that? The "name" field can be anything, it doesn't necessarily have to be related to the title. If the ID numbers you are getting out of last FM are unique per artist, then it may be best just to use those... that would solve these cases of titles that are not translatable to ascii. Link to comment Share on other sites More sharing options...
apeisa Posted February 9, 2011 Author Share Posted February 9, 2011 My first idea was this: if ($headlinerNameUrl == '') { $headlinerNameUrl = $wire->sanitizer->pageName(urlencode($headlinerName), true); } And it gives us nice url: e3-82-ae-e3-83-ab-e3-82-ac-e3-83-a1-e3-83-83-e3-82-b7-e3-83-a5 I'll live with that now, since it really doesn't matter in this point. There probably could be something much nicer for this one, but this is "rock solid" Link to comment Share on other sites More sharing options...
apeisa Posted February 9, 2011 Author Share Posted February 9, 2011 The "name" field can be anything, it doesn't necessarily have to be related to the title. If the ID numbers you are getting out of last FM are unique per artist, then it may be best just to use those... There is artist id also from last.fm, but I am only querying events (and it only gives artist name, id:s only for events). So that would require another request from last.fm api. Link to comment Share on other sites More sharing options...
ryan Posted February 9, 2011 Share Posted February 9, 2011 I think you've got the right approach there, checking to see if pageName returned something blank. Very creative to use urlencode here. Using that same approach, you could also try md5($headlinerName) rather than (or in addition to) urlencode() as a shorter option... it will always be 32 characters regardless of the title's length. Link to comment Share on other sites More sharing options...
ryan Posted February 9, 2011 Share Posted February 9, 2011 There is artist id also from last.fm, but I am only querying events (and it only gives artist name, id:s only for events). So that would require another request from last.fm api. Is there any possibility that two different artists will have the same name? (with different IDs at last.fm?) Link to comment Share on other sites More sharing options...
apeisa Posted February 9, 2011 Author Share Posted February 9, 2011 Universally there are many bands with the same name. I'm not sure how Last.fm API handles those - their site usually outputs country in parenthesis in case of duplicates (or more). I am not worried about those: in our case it doesn't really matter that much. Good idea with md5. It will be cleaner for sure! 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