Jump to content

pages->get return Nullpage but Page exists ??


horst
 Share

Recommended Posts

Hhm, I stuck with something really confusing.

I add pages with API when importing data from ID3-tags of mp3 files. I have an album from amazon with large entries for some ID3-fields:
 

// for the Interpret / Artist it has: Sabine Meyer/Academy Of St Martin-In-The-Fields/Kenneth Sillito

$artist = 'Sabine Meyer/Academy Of St Martin-In-The-Fields/Kenneth Sillito';
$title = preg_replace('/[^a-zA-Z0-9 _-]/', '', $artist);

// the $title now contains 'Sabine MeyerAcademy Of St Martin-In-The-FieldsKenneth Sillito'


I can save the first song which also includes to save the artist with the above $title. This is successful.

NOW, when I try to import the second track from that album, it has the same artist (of course). I try to get an existing page with following code:

	public function getPage($template,$title) {
		$p = wire('pages')->get("template=$template,title=".wire('sanitizer')->selectorValue($title));
		if(0==$p->id) {
		    // create the page
		    $p = new Page();
		    $p->template = $template;
		    $p->title = $title;
		    $p->name = wire('sanitizer')->name($title);
		    $p->parent = wire('pages')->get('template='.strtoupper($template).'S');
		    $p->save();
		    $this->dbModified = true;
		}
		return $p;
	}


With the first line of code I should get the allready existing Page, but it returns a NullPage, and when executing the create-page-code afterwards, it crashes when trying to save() the page. The Error is:
 

    Error: Uncaught exception 'WireDatabaseException' with message 'Duplicate entry 'sabine_meyeracademy_of_st_martin-in-the-fieldskenneth_sillito-10' for key 'name_parent_id'' in ...\htdocs\wire\core\Database.php:118

   Stack trace:
   #0 ... \htdocs\wire\core\Pages.php(544): Database->query('INSERT INTO pag...')
   #1 [internal function]: Pages->___save(Object(Page))
   #2 ... \htdocs\wire\core\Wire.php(271): call_user_func_array(Array, Array)
   #3 ... \htdocs\wire\core\Wire.php(229): Wire->runHooks('save', Array)
   #4 ... \htdocs\wire\core\Page.php(1019): Wire->__call('save', Array)
   #5 ... \htdocs\wire\core\Page.php(1019): Pages->save(Object(Page))
   #6 ... \htdocs\LAFISS.phpl5(100): Page->save()
   #7 ... \htdocs\LAFISS.phpl5(127): LocalAudioFilesShellImporter->getPage('artist', 'Sabine MeyerAca...')
   #8 W:\WEB_MIRRORS\_Proc (line 118 of ... \htdocs\wire\core\Database.php)

   This error message was shown because you are using the command line API. Error has been logged.
 

SO, what is wrong? I have copied the title from the input-field of the artists-page and it is exactly stored as it was sanitized and so, it should match!?

Or do I something wrong? (e.g. the above code works well with around 3.000 other files, but not with this ones :( )

Link to comment
Share on other sites

Hi horst,

The exception says that there is already a page under this parent with the same name.

Just save the page without acutally setting the name. ProcessWire does this for you: The system builds

the name from the title and if a page with the name already exists, Pw appends -1,-2.....-n :)

$p->name = wire('sanitizer')->name($title); //uncomment or remove this line

Why getting the NullPage?

Maybe your title is not stored exactly the same way (spaces).

  • Like 1
Link to comment
Share on other sites

 $p->name = wire('sanitizer')->name($title); //uncomment or remove this line

Yeah! That does it!

Why getting the NullPage?

Maybe your title is not stored exactly the same way (spaces).

I think no, here are a screenshot of pages: post-1041-0-13494800-1367435282_thumb.jp

Link to comment
Share on other sites

Why getting the NullPage?

Maybe your title is not stored exactly the same way (spaces).

Hi Wanze,

I have checked it, all Titles are exactly the same. It ends up with 6 entries of the same Artist-Title, (but with upcounted name-fileds, -1 -2 -3 -4 -5).

That is not what I want. :(

And I really do not understand why it behaves that way. Seems not logical to me.

$p = wire('pages')->get("template=$template,title=".wire('sanitizer')->selectorValue($title));

This should get the page, or not? :wacko:

Link to comment
Share on other sites

What is the tracklist of that album?

Hi Apeisa, there is no tracklist as children for albums, I have 4 independent branches (GENRES, ARTISTS, ALBUMS, TRACKS) which contain each of them only children of one type (genre, artist, album, track).

The parent of an artist-page is ARTISTS. (And an artist-page has no children!)

And when the error occures first, there is only one track (the first one) of that album saved.

Hope you understand what I try to say?.?

Link to comment
Share on other sites

Ah, ok, here a screenshot from explorer: (there are some chars in it, that I wouldn't put there, but that shouldn't affect anything because all strings will be sanitized before they go to the getPage-function)


post-1041-0-40289900-1367439586_thumb.jp

Link to comment
Share on other sites

I have ran this code:
 

<?php

// three selector queries
$title = 'Sabine MeyerAcademy Of St Martin-In-The-FieldsKenneth Sillito';
$template = 'artist';

$p = wire('pages')->get("template=$template,title=".wire('sanitizer')->selectorValue($title));
echo $p->id;
echo "\n\n";

$p = wire('pages')->get("title=".wire('sanitizer')->selectorValue($title));
echo $p->id;
echo "\n\n";

$p = wire('pages')->get("title=$title");
echo $p->id;
echo "\n\n";

// and one direct query
$q = "SELECT pages_id FROM pw5.field_title WHERE data='$title'";
$r = wire('db')->query($q);
if($row = $r->fetch_row()) {
	echo $row[0];
}

the output of all 3 selector queries is 0

the output of the direct query is 40813 (the id of the page)

So, any ideas?

Link to comment
Share on other sites

post-1041-0-59019800-1367530514_thumb.jp
No, there isn't anything hidden or unpublished. As I've said before I have run this with ~ 5000 files and there are some (~30) where it behaves like this.
 
I also have set up a new fresh DB with my SiteProfile of the MP3-DB and imported only 6 files whereas 3 of them are from that album. Same strange behave as before!
 
Here is the install.sql () from the fresh DB including the 6 imported tracks. If someone want to check it he can change the install.sql from SiteProfile against this one.


---------------------------------------------

EDIT:   I have on another PW-Install (BasicProfile) created a single page just

with the title "Sabine MeyerAcademy Of St Martin-In-The-FieldsKenneth Sillito"

and on another page I have ran that code: (Template: basic-page.php)

<?php
if('Child Page 4'===$page->title)
{
echo "<p>";
	$title = 'Sabine MeyerAcademy Of St Martin-In-The-FieldsKenneth Sillito';

	$p = wire('pages')->get("title=".wire('sanitizer')->selectorValue($title));
	echo $p->id;
	echo "<br />";

	$p = wire('pages')->get("title=$title");
	echo $p->id;
	echo "<br />";

	// a direct query
	$q = "SELECT pages_id FROM field_title WHERE data='$title'";
	$r = wire('db')->query($q);
	if($row = $r->fetch_row()) {
		echo $row[0];
		echo "<br />";
	}
echo "</p>";
}

post-1041-0-96212400-1367532850_thumb.jp

Would be nice if someone could test this, too. (it drives me crazy)

Link to comment
Share on other sites

Sorry if it's a stupid question, but why do you have pages with the same title? Something seems wrong or it's just me. :)

I can imagine if you search for title with a get() and there's multiple to be found... usually it would just return the first found... 

Not sure if it would make a difference but what if you use

$pages->find("title=$title")->first();

?

Link to comment
Share on other sites

Or since the title is fulltext search? 

$pages->get("title%=$title");

I recently think stumbled over something similar.

I installed your db and get it to work with using %= or ^=. Not exactly sure what it's all about.

  • Like 1
Link to comment
Share on other sites

Sorry if it's a stupid question, but why do you have pages with the same title? Something seems wrong or it's just me. :)

Hi Soma, it's not a stupid question at all, but it isn't the thema here. If you look to the very first post of this thread I describe that I have used the query

$p = wire('pages')->get("template=$template,title=".wire('sanitizer')->selectorValue($title));

to get an allready existing page. Because the query returns a NullPage, I want to create a new one (assuming that there is no one stored in the DB, because the query doesn't returns one). Then, when trying to save() the new created page it crashes with an Error.

It currently runs with creating multiple pages of the same (title) artist is just to avoid the unhandled errors! That's not the behave I want.

But what is just weird is that the Selector-query doesn't return the page not any, even if there are more than one!

Link to comment
Share on other sites

Maybe someone else more clever can explaing this behaviour, but wanted to say the doing this with title search maybe also isn't the best way. Why not use the page name when importing? This is more a reliable way as the name can't be duplicates and isn't fulltext.

$title = "Sabine MeyerAcademy Of St Martin-In-The-FieldsKenneth Sillito";
$name = $sanitizer->pageName($title);
$p = $pages->get("name=$name");
  • Like 1
Link to comment
Share on other sites

Or since the title is fulltext search? 

$pages->get("title%=$title");

I recently think stumbled over something similar.

I installed your db and get it to work with using %= or ^=. Not exactly sure what it's all about.

Hhmm ?? :blink:  (böhmische Dörfer ??)

I have tried %= and it works, ^= work's too.

But I do not understand why I have to do it this way ?   (wait, go looking into DB, okay I'll be back:)

DB says Datatype of field is TEXT, hmm. 

%= looks for text somewhere in the field

^= matches if fieldtext begins with it,

so $= should match too, but doesn't !?? (why not?)

And at least, I cannot really understand why it not matches with the simple =

as of data='complete title string with spaces-and-dashes' will work.

----------------------

Ah, - and many thanks for testing Soma, - and for finding a solution! :)^-^

Link to comment
Share on other sites

Maybe someone else more clever can explaing this behaviour, but wanted to say the doing this with title search maybe also isn't the best way. Why not use the page name when importing? This is more a reliable way as the name can't be duplicates and isn't fulltext.

$title = "Sabine MeyerAcademy Of St Martin-In-The-FieldsKenneth Sillito";
$name = $sanitizer->pageName($title);
$p = $pages->get("name=$name");

This is exactly what I've tried after I run into the unwanted duplicate titles. But I got errors that looks much like the first ones with other files and (I think I was to confused) that I have not look close enough to it and have discarded it.

It will have to do something with that I run the same function for 4 different pagetypes, whereas three of them have to be unique but the 4'th could have duplicate titles (Tracks with same title but on different Albums). I think that has generated the Errors I haven't looked to, and not when trying to get a page of artist.

So, now, besides all the facts about DB and Selectors, I have learned something new, too: Also if it looks weird, keep a cool head :grin:

Great that it is solved!

Link to comment
Share on other sites

Yeah I think there's maybe some strange hidden chars but it's not. :)

Just found out by try and error, that if the title has more than 50 chars it will break a title=string search...

If you strip the title of the page(s) to 50 chars this it works:

$title = "Sabine MeyerAcademy Of St Martin-In-The-FieldsKenn";

So, there's maybe some internal title searching that strips title in the query.

But anyway, nice to know, still you should try working with names. :)

  • Like 1
Link to comment
Share on other sites

Yeah I think there's maybe some strange hidden chars but it's not. :)

I have sanitized with:

$artist = 'Sabine Meyer/Academy Of St Martin-In-The-Fields/Kenneth Sillito';
$title = preg_replace('/[^a-zA-Z0-9 _-]/', '', $artist);

 Just found out by try and error, that if the title has more than 50 chars it will break a title=string search...

It break ??   = drop the rest

               or = wrap into lines ??

EDIT: Ah, you have edited your post when I was allready answering!

Link to comment
Share on other sites

... 

If you strip the title of the page(s) to 50 chars this it works:

$title = "Sabine MeyerAcademy Of St Martin-In-The-FieldsKenn";
So, there's maybe some internal title searching that strips title in the query.

But anyway, nice to know, still you should try working with names.

was looking into DB: pages.name is VARCHAR with length 128

Thank's Soma!

Link to comment
Share on other sites

It's not a db thing, hence your direct query is working, it somewhere hidden in the page finder I guess :)

If you do a

$title = "Sabine MeyerAcademy Of St Martin-In-The-FieldsKenneth Sillito";
$p = $pages->get("title=$title");

foreach($db->getQueryLog() as $l) echo $l . "<hr>";

You'll see the queries PW does on the request:

... SELECT pages.id,pages.parent_id,pages.templates_id FROM `pages` JOIN field_title AS field_title ON field_title.pages_id=pages.id AND (((field_title.data='Sabine MeyerAcademy Of St Martin-In-The-FieldsKenn' ) )) ...



Or install my ChromePhp Logger module and see it in the js console :D

  • Like 2
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...