Skip to content

Commit 3caca79

Browse files
committed
1.8.0 Release
Add path indexing behaviour. All paths will be indexed nightly, if a path doesn't exist in the index it will return a 404.
1 parent 97be6b5 commit 3caca79

File tree

31 files changed

+932
-13
lines changed

31 files changed

+932
-13
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Skywire\WordpressApi\Api\Data\Index;
4+
5+
/**
6+
* @method string getType();
7+
* @method self setType(string $type);
8+
* @method string getPath();
9+
* @method self setPath(string $path);
10+
* @method string getSlug();
11+
* @method self setSlug(string $slug);
12+
*
13+
*/
14+
interface PathInterface
15+
{
16+
17+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
4+
namespace Skywire\WordpressApi\Api\Index;
5+
6+
7+
use Magento\Framework\Exception\NoSuchEntityException;
8+
use Skywire\WordpressApi\Api\Data\Index\PathInterface;
9+
10+
interface PathRepositoryInterface
11+
{
12+
13+
/**
14+
* @param string $path
15+
*
16+
* @return PathInterface
17+
* @throws NoSuchEntityException
18+
*/
19+
public function getByPath(string $path): PathInterface;
20+
21+
public function slugExists(string $slug, string $type = null): bool;
22+
23+
public function pathExists(string $path): bool;
24+
25+
/**
26+
* Create or update the path.
27+
*
28+
* Checks if path exists before creating a new entity
29+
*
30+
* @param PathInterface $path
31+
*
32+
* @return PathInterface
33+
*/
34+
public function create(PathInterface $path): PathInterface;
35+
36+
public function save(PathInterface $path): PathInterface;
37+
}

src/Controller/Router.php

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ class Router
5757
/**
5858
* @var array
5959
*/
60-
protected $_matchers = array(
60+
protected $_matchers = [
6161
'post' => '_matchPost',
6262
'page' => '_matchPage',
6363
'category' => '_matchCategory',
64-
);
64+
];
6565

6666
/**
6767
* @param \Magento\Framework\App\ActionFactory $actionFactory
@@ -113,7 +113,6 @@ public function match(\Magento\Framework\App\RequestInterface $request)
113113
}
114114

115115
return $this->actionFactory->create(\Magento\Framework\App\Action\Forward::class);
116-
117116
}
118117
}
119118

@@ -127,9 +126,11 @@ public function match(\Magento\Framework\App\RequestInterface $request)
127126
*/
128127
protected function _matchPost($identifier)
129128
{
130-
$posts = $this->postApi->getCollection([
131-
'slug' => $identifier
132-
]);
129+
$posts = $this->postApi->getCollection(
130+
[
131+
'slug' => $identifier,
132+
]
133+
);
133134

134135
if (!$posts || !$posts->getSize()) {
135136
return false;
@@ -145,9 +146,11 @@ protected function _matchPost($identifier)
145146
*/
146147
protected function _matchPage($identifier)
147148
{
148-
$pages = $this->pageApi->getCollection([
149-
'slug' => $identifier
150-
]);
149+
$pages = $this->pageApi->getCollection(
150+
[
151+
'slug' => $identifier,
152+
]
153+
);
151154

152155
if (!$pages || !$pages->getSize()) {
153156
return false;
@@ -163,9 +166,11 @@ protected function _matchPage($identifier)
163166
*/
164167
protected function _matchCategory($identifier)
165168
{
166-
$categories = $this->categoryApi->getCollection([
167-
'slug' => $identifier
168-
]);
169+
$categories = $this->categoryApi->getCollection(
170+
[
171+
'slug' => $identifier,
172+
]
173+
);
169174

170175
if (!$categories || !$categories->getSize()) {
171176
return false;

src/Model/Index/ApiClient.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Skywire\WordpressApi\Model\Index;
4+
5+
use Skywire\WordpressApi\Model\Api\ApiAbstract;
6+
7+
class ApiClient extends ApiAbstract
8+
{
9+
protected function _getRoute($id = '')
10+
{
11+
return '/';
12+
}
13+
}

src/Model/Index/Indexer.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Skywire\WordpressApi\Model\Index;
4+
5+
use Skywire\WordpressApi\Api\Index\PathRepositoryInterface;
6+
use Skywire\WordpressApi\Model\ResourceModel\Index\Path as Resource;
7+
8+
class Indexer
9+
{
10+
/**
11+
* @var Resource
12+
*/
13+
protected $resource;
14+
15+
/**
16+
* @var PathRepositoryInterface
17+
*/
18+
private $repository;
19+
20+
/**
21+
* @var Spider
22+
*/
23+
private $spider;
24+
25+
public function __construct(PathRepositoryInterface $repository, Spider $spider, Resource $resource)
26+
{
27+
$this->repository = $repository;
28+
$this->spider = $spider;
29+
$this->resource = $resource;
30+
}
31+
32+
public function collectPaths(): void
33+
{
34+
$paths = $this->spider->getPaths();
35+
36+
$this->resource->getConnection()->delete($this->resource->getMainTable());
37+
38+
foreach ($paths as $path) {
39+
$this->repository->create($path);
40+
}
41+
}
42+
}

src/Model/Index/Path.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Skywire\WordpressApi\Model\Index;
4+
5+
use Magento\Framework\DataObject\IdentityInterface;
6+
use Magento\Framework\Model\AbstractModel;
7+
use Skywire\WordpressApi\Api\Data\Index\PathInterface;
8+
9+
/**
10+
* @method \Skywire\WordpressApi\Model\ResourceModel\Index\Path getResource()
11+
* @method \Skywire\WordpressApi\Model\ResourceModel\Index\Path\Collection getCollection()
12+
* @method string getType();
13+
* @method self setType(string $type);
14+
* @method string getPath();
15+
* @method self setPath(string $path);
16+
* @method string getSlug();
17+
* @method self setSlug(string $slug);*
18+
*/
19+
class Path extends AbstractModel implements PathInterface, IdentityInterface
20+
{
21+
const CACHE_TAG = 'skywire_wordpressapi_path';
22+
23+
protected $_cacheTag = 'skywire_wordpressapi_path';
24+
25+
protected $_eventPrefix = 'skywire_wordpressapi_path';
26+
27+
protected function _construct()
28+
{
29+
$this->_init('Skywire\WordpressApi\Model\ResourceModel\Index\Path');
30+
}
31+
32+
public function getIdentities()
33+
{
34+
return [self::CACHE_TAG . '_' . $this->getId()];
35+
}
36+
}

src/Model/Index/PathRepository.php

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
namespace Skywire\WordpressApi\Model\Index;
4+
5+
use Magento\Framework\Exception\NoSuchEntityException;
6+
use Skywire\WordpressApi\Api\Data\Index\PathInterface;
7+
use Skywire\WordpressApi\Api\Index\PathRepositoryInterface;
8+
use Skywire\WordpressApi\Model\ResourceModel\Index\Path as PathResource;
9+
use Skywire\WordpressApi\Model\ResourceModel\Index\Path\CollectionFactory;
10+
11+
class PathRepository implements PathRepositoryInterface
12+
{
13+
/**
14+
* @var PathResource
15+
*/
16+
private $resource;
17+
18+
/**
19+
* @var PathFactory
20+
*/
21+
private $pathFactory;
22+
23+
/**
24+
* @var CollectionFactory
25+
*/
26+
private $collectionFactory;
27+
28+
public function __construct(PathResource $resource, CollectionFactory $collectionFactory, PathFactory $pathFactory)
29+
{
30+
$this->resource = $resource;
31+
$this->pathFactory = $pathFactory;
32+
$this->collectionFactory = $collectionFactory;
33+
}
34+
35+
public function getByPath(string $path): PathInterface
36+
{
37+
$model = $this->pathFactory->create();
38+
39+
$this->resource->load($model, $path, 'path');
40+
41+
if ($model->getId()) {
42+
return $model;
43+
}
44+
45+
throw new NoSuchEntityException();
46+
}
47+
48+
public function slugExists(string $slug, string $type = null): bool
49+
{
50+
$collection = $this->collectionFactory->create()
51+
->addFieldToFilter('slug', $slug);
52+
53+
54+
if ($type) {
55+
$collection->addFieldToFilter('type', $type);
56+
}
57+
58+
return $collection->count() >= 1;
59+
}
60+
61+
public function pathExists(string $path): bool
62+
{
63+
try {
64+
$this->getByPath($path);
65+
} catch (NoSuchEntityException $e) {
66+
return false;
67+
}
68+
69+
return true;
70+
}
71+
72+
public function create(PathInterface $path): PathInterface
73+
{
74+
$collection = $this->collectionFactory->create();
75+
76+
if ($collection->getItemByColumnValue('path', $path->getPath())) {
77+
$model = $this->getByPath($path->getPath());
78+
$path->setId($model->getId());
79+
}
80+
81+
$this->resource->save($path);
82+
83+
return $path;
84+
}
85+
86+
87+
public function save(PathInterface $path): PathInterface
88+
{
89+
$this->resource->save($path);
90+
91+
return $path;
92+
}
93+
}

src/Model/Index/Spider.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
namespace Skywire\WordpressApi\Model\Index;
4+
5+
use Magento\Framework\App\Config\ScopeConfigInterface;
6+
use Skywire\WordpressApi\Model\Api\Type;
7+
8+
class Spider
9+
{
10+
/**
11+
* @var ScopeConfigInterface
12+
*/
13+
protected $scopeConfig;
14+
15+
/**
16+
* @var array
17+
*/
18+
protected $types;
19+
20+
/**
21+
* @var ApiClient
22+
*/
23+
protected $apiClient;
24+
25+
/**
26+
* @var PathFactory
27+
*/
28+
protected $pathFactory;
29+
30+
public function __construct(
31+
ScopeConfigInterface $scopeConfig,
32+
ApiClient $apiClient,
33+
PathFactory $pathFactory,
34+
array $types = []
35+
) {
36+
$this->scopeConfig = $scopeConfig;
37+
$this->types = $types;
38+
$this->apiClient = $apiClient;
39+
$this->pathFactory = $pathFactory;
40+
}
41+
42+
/**
43+
* Get an array of paths containing type and path slug
44+
*
45+
* @return Path[]
46+
*/
47+
public function getPaths()
48+
{
49+
$paths = [];
50+
51+
$client = $this->apiClient->getRestClient();
52+
foreach ($this->types as $type) {
53+
$apiPath = $this->scopeConfig->getValue('skywire_wordpress_api/api/path');
54+
$response = $client->get($apiPath . '/' . $type);
55+
56+
$body = (string)$response->getBody();
57+
58+
if (!$body) {
59+
continue;
60+
}
61+
62+
$items = \Zend_Json::decode($body);
63+
64+
foreach ($items as $item) {
65+
/** @var Path $path */
66+
$paths[] = $this->pathFactory->create()->setData(['type' => $type, 'slug' => $item['slug'], 'path' => "$type/{$item['slug']}"]);
67+
}
68+
}
69+
70+
return $paths;
71+
}
72+
}

0 commit comments

Comments
 (0)