Last active
October 5, 2017 10:22
-
-
Save andrerom/b93332d7e27445ce7fe392d0f596db83 to your computer and use it in GitHub Desktop.
DEBUG SPI Persistence Cache issues on eZ Publish 5.x / eZ Platform 1.x SPI + patches
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// CASE 1: Current version number becomes inconsistent | |
// STATUS: Not identified, but there is a proactive attempt at solving it in EZP-28008 (patches attached, so try these first!!) | |
// DEBUG: Look for inconsistencies between `currentVersionNo` property of the different dumped objects, take note of which one it | |
// was in the array as it will give a clue to what is not properly cleared somwhere. | |
/** | |
* @var Stash\Pool $pool | |
*/ | |
$pool = $container->get('ezpublish.cache_pool'); | |
// Content id, remote id and version number to investigate cache data for, UPDATE THE VALUES TO FIT YOUR PROBLEM! | |
$contentId = 200; | |
$remoteId = "afsriofgoj4tjt94jertm"; | |
$versionNo = 6; | |
$translationsKey = 'ger-DE';// format: $translationsKey = empty($translations) ? 0 : implode('|', $translations); | |
var_dump( | |
$pool->getItems([ | |
"ez_spi/content/info/{$contentId}", | |
"ez_spi/content/info/remoteId/{$remoteId}", | |
"ez_spi/content/{$contentId}/{$versionNo}/0", | |
"ez_spi/content/{$contentId}/{$versionNo}/{$translationsKey}" | |
]) | |
); | |
// CASE 2: Access deined issues, earlier tought to be issues with the cached permission data | |
// Status: Not identified, however: | |
// 1. A provided stacktrace on slack gave this clue: | |
// eZ\\Publish\\Core\\Base\\Exceptions\\UnauthorizedException(code: 401): | |
// User does not have access to 'versionread' 'content' with: contentId '405751', versionNo '' | |
// at /var/www/sites/example.com/vendor/ezsystems/ezpublish-kernel/eZ/Publish/Core/Repository/ContentService.php:337 | |
// | |
// Code in question: | |
// if ( | |
// $content->getVersionInfo()->status !== APIVersionInfo::STATUS_PUBLISHED | |
// && !$this->repository->canUser('content', 'versionread', $content) | |
// ) { | |
// throw new UnauthorizedException('content', 'versionread', array('contentId' => $contentId, 'versionNo' => $versionNo)); | |
// } | |
// 2. "versionNo ''" means the currently published version was asked for, but the backend returned a draft | |
// making the code check "versionread", a permissions only editors should have | |
// 3. Thus this issue seems to be the same as CASE 1, so try the attached patch and report back if it works, if it does not use the code | |
// above to debug |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/eZ/Publish/Core/Persistence/Cache/ContentHandler.php b/eZ/Publish/Core/Persistence/Cache/ContentHandler.php | |
index f63230c6f3..5cdbe039ca 100644 | |
--- a/eZ/Publish/Core/Persistence/Cache/ContentHandler.php | |
+++ b/eZ/Publish/Core/Persistence/Cache/ContentHandler.php | |
@@ -146,11 +146,17 @@ public function updateMetadata($contentId, MetadataUpdateStruct $struct) | |
{ | |
$this->logger->logCall(__METHOD__, array('content' => $contentId, 'struct' => $struct)); | |
- $this->cache | |
- ->getItem('content', 'info', $contentId) | |
- ->set($contentInfo = $this->persistenceHandler->contentHandler()->updateMetadata($contentId, $struct))->save(); | |
+ $contentInfo = $this->persistenceHandler->contentHandler()->updateMetadata($contentId, $struct); | |
$this->cache->clear('content', $contentId, $contentInfo->currentVersionNo); | |
+ $this->cache->clear('content', 'info', $contentId); | |
+ | |
+ if ($struct->remoteId) { | |
+ // remote id changed | |
+ $this->cache->clear('content', 'info', 'remoteId'); | |
+ } else { | |
+ $this->cache->clear('content', 'info', 'remoteId', $contentInfo->remoteId); | |
+ } | |
return $contentInfo; | |
} | |
@@ -163,10 +169,6 @@ public function updateContent($contentId, $versionNo, UpdateStruct $struct) | |
$this->logger->logCall(__METHOD__, array('content' => $contentId, 'version' => $versionNo, 'struct' => $struct)); | |
$content = $this->persistenceHandler->contentHandler()->updateContent($contentId, $versionNo, $struct); | |
$this->cache->clear('content', $contentId, $versionNo); | |
- $this->cache | |
- ->getItem('content', $contentId, $versionNo, self::ALL_TRANSLATIONS_KEY) | |
- ->set($content) | |
- ->save(); | |
return $content; | |
} | |
diff --git a/eZ/Publish/Core/Persistence/Cache/Tests/ContentHandlerTest.php b/eZ/Publish/Core/Persistence/Cache/Tests/ContentHandlerTest.php | |
index 24ead4709e..330606eacd 100644 | |
--- a/eZ/Publish/Core/Persistence/Cache/Tests/ContentHandlerTest.php | |
+++ b/eZ/Publish/Core/Persistence/Cache/Tests/ContentHandlerTest.php | |
@@ -374,25 +374,25 @@ public function testUpdateMetadata() | |
->expects($this->once()) | |
->method('updateMetadata') | |
->with(2, $this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content\\MetadataUpdateStruct')) | |
- ->will($this->returnValue(new ContentInfo(array('id' => 2)))); | |
+ ->willReturn(new ContentInfo(array('id' => 2, 'currentVersionNo' => 3, 'remoteId' => 'o34'))); | |
- $cacheItemMock = $this->getMock('Stash\Interfaces\ItemInterface'); | |
$this->cacheMock | |
- ->expects($this->once()) | |
- ->method('getItem') | |
- ->with('content', 'info', 2) | |
- ->will($this->returnValue($cacheItemMock)); | |
+ ->expects($this->at(0)) | |
+ ->method('clear') | |
+ ->with('content', 2, 3) | |
+ ->willReturn(null); | |
- $cacheItemMock | |
- ->expects($this->once()) | |
- ->method('set') | |
- ->with($this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content\\ContentInfo')) | |
- ->will($this->returnValue($cacheItemMock)); | |
+ $this->cacheMock | |
+ ->expects($this->at(1)) | |
+ ->method('clear') | |
+ ->with('content', 'info', 2) | |
+ ->willReturn(null); | |
- $cacheItemMock | |
- ->expects($this->once()) | |
- ->method('save') | |
- ->with(); | |
+ $this->cacheMock | |
+ ->expects($this->at(2)) | |
+ ->method('clear') | |
+ ->with('content', 'info', 'remoteId', 'o34') | |
+ ->willReturn(null); | |
$handler = $this->persistenceCacheHandler->contentHandler(); | |
$handler->updateMetadata(2, new MetadataUpdateStruct()); | |
@@ -437,24 +437,6 @@ public function testUpdateContent() | |
->with('content', 2, 1) | |
->will($this->returnValue(null)); | |
- $cacheItemMock = $this->getMock('Stash\Interfaces\ItemInterface'); | |
- $this->cacheMock | |
- ->expects($this->once()) | |
- ->method('getItem') | |
- ->with('content', 2, 1, ContentHandler::ALL_TRANSLATIONS_KEY) | |
- ->will($this->returnValue($cacheItemMock)); | |
- | |
- $cacheItemMock | |
- ->expects($this->once()) | |
- ->method('set') | |
- ->with($this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content')) | |
- ->will($this->returnValue($cacheItemMock)); | |
- | |
- $cacheItemMock | |
- ->expects($this->once()) | |
- ->method('save') | |
- ->with(); | |
- | |
$handler = $this->persistenceCacheHandler->contentHandler(); | |
$handler->updateContent(2, 1, new UpdateStruct()); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/eZ/Publish/Core/Persistence/Cache/ContentHandler.php b/eZ/Publish/Core/Persistence/Cache/ContentHandler.php | |
index c8e3832ea..c39c1bea5 100644 | |
--- a/eZ/Publish/Core/Persistence/Cache/ContentHandler.php | |
+++ b/eZ/Publish/Core/Persistence/Cache/ContentHandler.php | |
@@ -150,12 +150,17 @@ public function setStatus($contentId, $status, $version) | |
public function updateMetadata($contentId, MetadataUpdateStruct $struct) | |
{ | |
$this->logger->logCall(__METHOD__, array('content' => $contentId, 'struct' => $struct)); | |
- | |
- $this->cache | |
- ->getItem('content', 'info', $contentId) | |
- ->set($contentInfo = $this->persistenceHandler->contentHandler()->updateMetadata($contentId, $struct)); | |
+ $contentInfo = $this->persistenceHandler->contentHandler()->updateMetadata($contentId, $struct); | |
$this->cache->clear('content', $contentId, $contentInfo->currentVersionNo); | |
+ $this->cache->clear('content', 'info', $contentId); | |
+ | |
+ if ($struct->remoteId) { | |
+ // remote id changed | |
+ $this->cache->clear('content', 'info', 'remoteId'); | |
+ } else { | |
+ $this->cache->clear('content', 'info', 'remoteId', $contentInfo->remoteId); | |
+ } | |
return $contentInfo; | |
} | |
@@ -168,9 +173,6 @@ public function updateContent($contentId, $versionNo, UpdateStruct $struct) | |
$this->logger->logCall(__METHOD__, array('content' => $contentId, 'version' => $versionNo, 'struct' => $struct)); | |
$content = $this->persistenceHandler->contentHandler()->updateContent($contentId, $versionNo, $struct); | |
$this->cache->clear('content', $contentId, $versionNo); | |
- $this->cache | |
- ->getItem('content', $contentId, $versionNo, self::ALL_TRANSLATIONS_KEY) | |
- ->set($this->cloneAndSerializeXMLFields($content)); | |
return $content; | |
} | |
diff --git a/eZ/Publish/Core/Persistence/Cache/Tests/ContentHandlerTest.php b/eZ/Publish/Core/Persistence/Cache/Tests/ContentHandlerTest.php | |
index b4a27f7d2..ff8dfea1d 100644 | |
--- a/eZ/Publish/Core/Persistence/Cache/Tests/ContentHandlerTest.php | |
+++ b/eZ/Publish/Core/Persistence/Cache/Tests/ContentHandlerTest.php | |
@@ -362,19 +362,25 @@ public function testUpdateMetadata() | |
->expects($this->once()) | |
->method('updateMetadata') | |
->with(2, $this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content\\MetadataUpdateStruct')) | |
- ->will($this->returnValue(new ContentInfo(array('id' => 2)))); | |
+ ->willReturn(new ContentInfo(array('id' => 2, 'currentVersionNo' => 3, 'remoteId' => 'o34'))); | |
- $cacheItemMock = $this->getMock('Stash\Interfaces\ItemInterface'); | |
$this->cacheMock | |
- ->expects($this->once()) | |
- ->method('getItem') | |
+ ->expects($this->at(0)) | |
+ ->method('clear') | |
+ ->with('content', 2, 3) | |
+ ->willReturn(null); | |
+ | |
+ $this->cacheMock | |
+ ->expects($this->at(1)) | |
+ ->method('clear') | |
->with('content', 'info', 2) | |
- ->will($this->returnValue($cacheItemMock)); | |
+ ->willReturn(null); | |
- $cacheItemMock | |
- ->expects($this->once()) | |
- ->method('set') | |
- ->with($this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content\\ContentInfo')); | |
+ $this->cacheMock | |
+ ->expects($this->at(2)) | |
+ ->method('clear') | |
+ ->with('content', 'info', 'remoteId', 'o34') | |
+ ->willReturn(null); | |
$handler = $this->persistenceCacheHandler->contentHandler(); | |
$handler->updateMetadata(2, new MetadataUpdateStruct()); | |
@@ -419,18 +425,6 @@ public function testUpdateContent() | |
->with('content', 2, 1) | |
->will($this->returnValue(null)); | |
- $cacheItemMock = $this->getMock('Stash\Interfaces\ItemInterface'); | |
- $this->cacheMock | |
- ->expects($this->once()) | |
- ->method('getItem') | |
- ->with('content', 2, 1, ContentHandler::ALL_TRANSLATIONS_KEY) | |
- ->will($this->returnValue($cacheItemMock)); | |
- | |
- $cacheItemMock | |
- ->expects($this->once()) | |
- ->method('set') | |
- ->with($this->isInstanceOf('eZ\\Publish\\SPI\\Persistence\\Content')); | |
- | |
$handler = $this->persistenceCacheHandler->contentHandler(); | |
$handler->updateContent(2, 1, new UpdateStruct()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment