Jump to content
chrizz

Check for page duplicates with the same parent

Recommended Posts

I recently upgraded one of my projects to 3.0.148 and I got screwed by the new "unique" flag for pages introdueced here. Until now I was relying on PW's internal logic to throw an exception if a page with the same name already exists using the same parent page. 

Now I am trying to find a clever and easy to use method which can bring back that functionality. Is there maybe a config option I am not aware of? Because I need this duplicate check in many places of the project I want to find a solution which reduces code duplication. 

So, is there by chance a config for this? If not: ideas are welcome how this could be solved :) 

 

Cheers!
chrizz

 

Share this post


Link to post
Share on other sites
4 hours ago, chrizz said:

Until now I was relying on PW's internal logic to throw an exception if a page with the same name already exists using the same parent page. 

That new unique flag shouldn't impact this - PW still shouldn't allow duplicate names under the same parent. If for some reason it is, it sounds like a bug.

Are you creating pages via the Admin or API?

  • Like 1

Share this post


Link to post
Share on other sites

okay - maybe then it's some weird other co-incidence:

Originally I was creating pages via API. Based upon your question I tested the behavior in Admin and guess what: The UI warns me that a page with this name already exists but then adds it's own number at the end. It seems as if PW adds a numbering and checks which first (lowest) number is not already taken yet:

image.thumb.png.9f37d276f4975332d4e874d7fe896e99.png

A quick research showed that this is wanted behavior. PW takes care of the name automatically. *BUT* How can I avoid this? What I need is a way that duplicates are not created. I want PW do a lot of things, but not in this case 😉

The following code behaves differently based on the PW version. 

$title = "mytitle";

$channel = new Page();
$channel->template = "basic-page";
$channel->parent = $pages->get("/styleguide/");
$channel->title = $title;
$channel->name = $this->sanitizer->pageName($title);
$channel->save();

with PW 3.0.123 it runs once - a second run results in an SQL exception: Error: Exception: SQLSTATE[23000]: Integrity constraint violation:

with PW3.0.148 the code runs as often as you want and generates page names on it's own. 

 

So... bug or feature? ^^

 

 

Share this post


Link to post
Share on other sites
Posted (edited)

In a rush, so only a quick response. Usually when adding a page via the API, it's best to leave the "name" empty and let PW handle that if you simply want it converted from the title.

When adding pages via the API, you can do your own check to see if a page with that title already exists:

if(!$pages->has('parent=xxxx, title=myTitle')) {

That uses the brand new 3.0.153 has() method, but you can also do it with find or count.

If you want to prevent duplicates being added via the admin, then you probably want to hook into Pages::setupNew or Pages::add - I have used the latter many times, but not the former so without looking in more detail, I am not sure if it will work as I don't know if it has the new page name yet. 

Hopefully that gets you going, or someone else will come along with a more complete example.

Edited by horst
changed pw version from 3.0.135 to 3.0.153, to avoid confusion. The OP uses 3.0.148
  • Like 2

Share this post


Link to post
Share on other sites
27 minutes ago, adrian said:

if you simply want it converted from the title

that's exactly what I don't want 😞

I guess there's no other way than hooking into these methods (same would apply for page updates (if the name changes as well). Maybe someone knows why/when this chnage has been implemented and/or why I experience differences between the two PW versions. 

Share this post


Link to post
Share on other sites
2 minutes ago, chrizz said:
54 minutes ago, adrian said:

if you simply want it converted from the title

that's exactly what I don't want 😞

Just a quick comment - that is exactly what you are doing here anyway 🙂

$channel->name = $this->sanitizer->pageName($title);

 

  • Like 1

Share this post


Link to post
Share on other sites

@chrizz

If you want to create a page but it already exists, than you cannot create it.

So you first simply need to check if there is one or not: 

$title = "mytitle";
$pagename = $this->sanitizer->pageName($title);
$parent = $pages->get("/styleguide/");
if(0 == $pages->get("parent.id={$parent->id}, name={$pagename}")->id) {  // the selector also can check for parent and title, instead of parent and name
    // no page with that name exists here, so create it here
    $channel = new Page();
    $channel->template = "basic-page";
    $channel->parent = $parent;
    $channel->title = $title;
    $channel->name = $pagename;
    $channel->save();
} else {
    // A page with that name is already there, what to do now? Throw an exception? Drink a beer?
    ...
}

 

  • Like 1

Share this post


Link to post
Share on other sites

hey guys - thanks again for your valuable input! 

I think I got just confused by the fact that the same code behaves differently in the last to master versions. Nevertheless, I am going to refactor a bit and take care of my own that an exception is thrown as soon as the page name already exists. 

thanks again!

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...