Jump to content

"Integrity constraint violation" while saving new page with non uniqe name


marc1n
 Share

Recommended Posts

Hello,

Ryan once said that PW will take care of creating a name for me and it will also number-increment the name (i.e. "page-name-2") if one already exists. But when I create in admin UI a new page with name 'test' (page with that name already exists) and click "Save" button I've got an error:

  • Session: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'test-1100' for key 'name_parent_id'

  •  TemplateFile: Unknown page

My new page and its fields data is lost!

It is a bug or a feature?

I use PW 2.5.26.

Link to comment
Share on other sites

I am not changing name by hand. It is automatically set to "test" and after clicking "Save" I have an error and my page disappear.

Below Name field PW displays: "The name entered is already in use. If you do not modify it, the name will be made unique automatically after you save.". So I do not modify it because of this promise.

Link to comment
Share on other sites

I discovered that in method Pages::savePageQuery calling executeQuery($query) does not throw exception at all (which is unexpected because catch block has code calculating new unique name):

do { 
	$result = false; 
	$errorCode = 0;

	try { 	
		$result = false;
		$result = $this->executeQuery($query);

	} catch(Exception $e) {

		$errorCode = $e->getCode();

		// while setupNew() already attempts to uniqify a page name with an incrementing
		// number, there is a chance that two processes running at once might end up with
		// the same number, so we account for the possibility here by re-trying queries
		// that trigger duplicate-entry exceptions 

		if($errorCode == 23000 && ($page->_hasAutogenName || $options['adjustName'])) {
			// Integrity constraint violation: 1062 Duplicate entry 'background-3552' for key 'name3894_parent_id'
			// attempt to re-generate page name
			$nameField = 'name';
			// account for the duplicate possibly being a multi-language name field
			if($this->wire('languages') && preg_match('/\b(name\d*)_parent_id\b/', $e->getMessage(), $matches)) $nameField = $matches[1]; 
			// get either 'name' or 'name123' (where 123 is language ID)
			$pageName = $page->$nameField;
			// determine if current name format already has a trailing number
			if(preg_match('/^(.+?)-(\d+)$/', $pageName, $matches)) {
				// page already has a trailing number
				$n = $matches[2]; 
				$pageName = $matches[1]; 
			}
			$page->name = $pageName . '-' . (++$n); 
			$query->bindValue(":$nameField", $page->name); 
			
		} else {
			// a different exception that we don't catch, so re-throw it
			throw $e;
		}
	}

} while($errorCode == 23000); 

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

×
×
  • Create New...