Skip to content

Commit 3175df1

Browse files
authored
Merge pull request #83 from strata/hotfix/82
Fix when WordPress API returns multiple pages for one page by slug
2 parents 5c17c98 + 712d070 commit 3175df1

4 files changed

Lines changed: 226 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [0.6.7] - 2020-02-28
8+
### Fixed
9+
- Fix issue #82 with WordPress returning multiple page when get page by slug
10+
711
## [0.6.6] - 2020-02-13
812
### Added
913
- Add excerpt and build_version Twig filters

src/Frontend/Cms/Wordpress.php

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -265,16 +265,25 @@ public function getPageByUrl(string $url)
265265

266266
// Get content
267267
$results = $this->api->listPosts($this->getContentApiEndpoint(), 1, ['slug' => $slug]);
268-
if ($results->getPagination()->getTotalResults() != 1) {
268+
if (empty($results->getPagination()->getTotalResults())) {
269269
throw new NotFoundException(sprintf('Page not found for requested URL: %s, slug: %s', $url, $slug), 404);
270270
}
271+
$data = null;
271272

272-
// Get single result
273-
$data = $results->getResponseData()[0];
273+
if ($results->getPagination()->getTotalResults() === 1) {
274+
$data = $results->getResponseData()[0];
274275

275-
// Check this page matches requested URL, if not return 404
276-
$pageUrlParts = parse_url($data['link']);
277-
if (rtrim($pageUrlParts['path'], '/') != rtrim($parts['path'], '/')) {
276+
} else {
277+
// WP may return multiple results since does a LIKE search on slug on API request
278+
foreach ($results->getResponseData() as $item) {
279+
$pageUrlParts = parse_url($item['link']);
280+
if (rtrim($pageUrlParts['path'], '/') === rtrim($parts['path'], '/')) {
281+
$data = $item;
282+
}
283+
}
284+
}
285+
286+
if ($data === null) {
278287
throw new NotFoundException(sprintf('Page URL %s does not match for requested URL: %s, slug: %s', $pageUrlParts['path'], $url, $slug), 400);
279288
}
280289

tests/Frontend/Cms/WordPressTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,4 +633,35 @@ public function testRelationArray()
633633
$x++;
634634
}
635635
}
636+
637+
public function testDuplicatePageSlugInWordPress()
638+
{
639+
// Create a mock and queue responses
640+
$mock = new MockHandler([
641+
new Response(
642+
200,
643+
['X-WP-Total' => 2, 'X-WP-TotalPages' => 2],
644+
file_get_contents(__DIR__ . '/../responses/acf/pages.2.json')
645+
),
646+
new Response(
647+
200,
648+
[],
649+
file_get_contents(__DIR__ . '/../responses/acf/users.1.json')
650+
),
651+
]);
652+
653+
$handler = HandlerStack::create($mock);
654+
$client = new Client(['handler' => $handler]);
655+
656+
$contentModel = new ContentModel(__DIR__ . '/config/acf/content_model.yaml');
657+
$wordpress = new Wordpress('something', $contentModel);
658+
$wordpress->setContentType('page');
659+
$wordpress->setClient($client);
660+
661+
// Test it!
662+
$page = $wordpress->getPageByUrl('/health/');
663+
664+
$this->assertEquals(85, $page->getId());
665+
$this->assertEquals('Lorem ipsum page test 2', $page->getTitle());
666+
}
636667
}
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
[
2+
{
3+
"id": 50,
4+
"date": "2019-02-15T15:19:17",
5+
"date_gmt": "2019-02-15T15:19:17",
6+
"guid": {
7+
"rendered": "http://localhost/?page_id=50"
8+
},
9+
"modified": "2019-02-15T15:19:17",
10+
"modified_gmt": "2019-02-15T15:19:17",
11+
"slug": "lorem-ipsum-page-test",
12+
"status": "publish",
13+
"type": "page",
14+
"link": "http://localhost/team/health/",
15+
"title": {
16+
"rendered": "Lorem ipsum page test 1"
17+
},
18+
"content": {
19+
"rendered": "<p>This is an example page lorem ipsum dolor sit amet et do lorem this is the page content in here from the main WYSIWYG editor.</p>\n",
20+
"protected": false
21+
},
22+
"excerpt": {
23+
"rendered": "<p>This is an example page lorem ipsum dolor sit amet et do lorem this is the page content in here from the main WYSIWYG editor.</p>\n",
24+
"protected": false
25+
},
26+
"author": 1,
27+
"featured_media": 0,
28+
"parent": 0,
29+
"menu_order": 0,
30+
"comment_status": "closed",
31+
"ping_status": "closed",
32+
"template": "page-template.php",
33+
"meta": [],
34+
"acf": [],
35+
"_links": {
36+
"self": [
37+
{
38+
"href": "http://localhost/wp-json/wp/v2/pages/85"
39+
}
40+
],
41+
"collection": [
42+
{
43+
"href": "http://localhost/wp-json/wp/v2/pages"
44+
}
45+
],
46+
"about": [
47+
{
48+
"href": "http://localhost/wp-json/wp/v2/types/page"
49+
}
50+
],
51+
"author": [
52+
{
53+
"embeddable": true,
54+
"href": "http://localhost/wp-json/wp/v2/users/1"
55+
}
56+
],
57+
"replies": [
58+
{
59+
"embeddable": true,
60+
"href": "http://localhost/wp-json/wp/v2/comments?post=85"
61+
}
62+
],
63+
"version-history": [
64+
{
65+
"count": 1,
66+
"href": "http://localhost/wp-json/wp/v2/pages/85/revisions"
67+
}
68+
],
69+
"predecessor-version": [
70+
{
71+
"id": 86,
72+
"href": "http://localhost/wp-json/wp/v2/pages/85/revisions/86"
73+
}
74+
],
75+
"wp:attachment": [
76+
{
77+
"href": "http://localhost/wp-json/wp/v2/media?parent=85"
78+
}
79+
],
80+
"curies": [
81+
{
82+
"name": "wp",
83+
"href": "https://api.w.org/{rel}",
84+
"templated": true
85+
}
86+
]
87+
}
88+
},
89+
{
90+
"id": 85,
91+
"date": "2019-02-15T15:19:17",
92+
"date_gmt": "2019-02-15T15:19:17",
93+
"guid": {
94+
"rendered": "http://localhost/?page_id=85"
95+
},
96+
"modified": "2019-02-15T15:19:17",
97+
"modified_gmt": "2019-02-15T15:19:17",
98+
"slug": "lorem-ipsum-page-test",
99+
"status": "publish",
100+
"type": "page",
101+
"link": "http://localhost/health/",
102+
"title": {
103+
"rendered": "Lorem ipsum page test 2"
104+
},
105+
"content": {
106+
"rendered": "<p>This is an example page lorem ipsum dolor sit amet et do lorem this is the page content in here from the main WYSIWYG editor.</p>\n",
107+
"protected": false
108+
},
109+
"excerpt": {
110+
"rendered": "<p>This is an example page lorem ipsum dolor sit amet et do lorem this is the page content in here from the main WYSIWYG editor.</p>\n",
111+
"protected": false
112+
},
113+
"author": 1,
114+
"featured_media": 0,
115+
"parent": 0,
116+
"menu_order": 0,
117+
"comment_status": "closed",
118+
"ping_status": "closed",
119+
"template": "page-template.php",
120+
"meta": [],
121+
"acf": [],
122+
"_links": {
123+
"self": [
124+
{
125+
"href": "http://localhost/wp-json/wp/v2/pages/85"
126+
}
127+
],
128+
"collection": [
129+
{
130+
"href": "http://localhost/wp-json/wp/v2/pages"
131+
}
132+
],
133+
"about": [
134+
{
135+
"href": "http://localhost/wp-json/wp/v2/types/page"
136+
}
137+
],
138+
"author": [
139+
{
140+
"embeddable": true,
141+
"href": "http://localhost/wp-json/wp/v2/users/1"
142+
}
143+
],
144+
"replies": [
145+
{
146+
"embeddable": true,
147+
"href": "http://localhost/wp-json/wp/v2/comments?post=85"
148+
}
149+
],
150+
"version-history": [
151+
{
152+
"count": 1,
153+
"href": "http://localhost/wp-json/wp/v2/pages/85/revisions"
154+
}
155+
],
156+
"predecessor-version": [
157+
{
158+
"id": 86,
159+
"href": "http://localhost/wp-json/wp/v2/pages/85/revisions/86"
160+
}
161+
],
162+
"wp:attachment": [
163+
{
164+
"href": "http://localhost/wp-json/wp/v2/media?parent=85"
165+
}
166+
],
167+
"curies": [
168+
{
169+
"name": "wp",
170+
"href": "https://api.w.org/{rel}",
171+
"templated": true
172+
}
173+
]
174+
}
175+
}
176+
]

0 commit comments

Comments
 (0)