Skip to content

Commit 84572f4

Browse files
committed
Made package open for extension
1 parent 59ef5df commit 84572f4

File tree

3 files changed

+154
-7
lines changed

3 files changed

+154
-7
lines changed

README.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ $meta = [
9393
$urlSeeds = GoogleProvider::create($config)->fetch($query, $meta);
9494
```
9595

96-
##### Add new providers
96+
##### Add new providers to package
9797

9898
1. Git clone the project
9999
2. Create your new class in the ``Snippetify\SnippetSniffer\Providers` folder
@@ -104,6 +104,22 @@ $urlSeeds = GoogleProvider::create($config)->fetch($query, $meta);
104104
7. Write tests. Take a look at `Snippetify\SnippetSniffer\Tests\Providers\GoogleProviderTest` to get you helped
105105
8. Send a pull request to us
106106

107+
##### Use your own providers
108+
109+
1. Your provider must implement `Snippetify\SnippetSniffer\Providers\ProviderInterface`
110+
2. Take a look at `Snippetify\SnippetSniffer\Providers\GoogleProvider` to get you helped
111+
3. Your fetch method must return an array of `GuzzleHttp\Psr7\Uri`
112+
4. Pass your new provider in the configuration parameter as follow
113+
114+
```php
115+
// Configurations
116+
$config = [
117+
"providers" => [
118+
"provider_name" => "ProviderClass::class"
119+
]
120+
];
121+
```
122+
107123
#### Scrapers
108124

109125
Scrappers allow you to scrape html page and extract the snippets.
@@ -136,7 +152,7 @@ $urlSeed = "website url to scrape";
136152
$snippets = (new DefaultScraper($config))->fetch(new Uri($urlSeed));
137153
```
138154

139-
##### Add new scrapers
155+
##### Add new scrapers to package
140156

141157
1. Git clone the project
142158
2. Create your new class in the ``Snippetify\SnippetSniffer\Scrapers` folder
@@ -147,6 +163,23 @@ $snippets = (new DefaultScraper($config))->fetch(new Uri($urlSeed));
147163
7. Write tests. Take a look at `Snippetify\SnippetSniffer\Tests\Scrapers\StackoverflowScraperTest` to get you helped
148164
8. Send a pull request to us
149165

166+
##### Use your own scrapers
167+
168+
1. Your scraper must implement `Snippetify\SnippetSniffer\Scrapers\ScraperInterface`
169+
2. Take a look at `Snippetify\SnippetSniffer\Scrapers\StackoverflowScraper` to get you helped
170+
3. Your fetch method must return an array of `Snippetify\SnippetSniffer\Common\Snippet`
171+
4. Pass your new scraper in the configuration parameter as follow
172+
173+
```php
174+
// Configurations
175+
// Important: Scrapper's name must be the website uri without the scheme. i.e. vuejs.org
176+
$config = [
177+
"scrapers" => [
178+
"scraper_name" => "ScraperClass::class"
179+
]
180+
];
181+
```
182+
150183
## Changelog
151184

152185
Please see [CHANGELOG](https://github.com/snippetify/snippet-sniffer/blob/master/CHANGELOG.md) for more information what has changed recently.

src/SnippetSniffer.php

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public function fetch(string $query, array $meta = []): array
6464
foreach ($urls as $url) {
6565
$snippets = array_merge($snippets, $this->scraper($url->getHost())->fetch($url));
6666
}
67-
67+
6868
return $snippets;
6969
}
7070

@@ -75,11 +75,28 @@ public function fetch(string $query, array $meta = []): array
7575
*/
7676
protected function provider(): ProviderInterface
7777
{
78-
if (!array_key_exists($this->config['provider']['name'], Core::$providers)) {
78+
$providers = Core::$providers;
79+
80+
if (!empty($this->config['providers'])) {
81+
foreach ($this->config['providers'] as $key => $value) {
82+
if (!class_exists($value)) {
83+
throw new \RuntimeException("Provider class not exists");
84+
}
85+
$providers[$key] = $value;
86+
}
87+
}
88+
89+
if (!array_key_exists($this->config['provider']['name'], $providers)) {
7990
throw new \RuntimeException("Provider not exists");
8091
}
8192

82-
return Core::$providers[$this->config['provider']['name']]::create($this->config['provider']);
93+
$provider = $providers[$this->config['provider']['name']]::create($this->config['provider']);
94+
95+
if (!$provider instanceof ProviderInterface) {
96+
throw new \RuntimeException("Provider class must implement the ProviderInterface");
97+
}
98+
99+
return $provider;
83100
}
84101

85102
/**
@@ -89,8 +106,25 @@ protected function provider(): ProviderInterface
89106
*/
90107
protected function scraper(string $name): ScraperInterface
91108
{
92-
$name = array_key_exists($name, Core::$scrapers) ? $name : 'default';
109+
$scrapers = Core::$scrapers;
110+
111+
if (!empty($this->config['scrapers'])) {
112+
foreach ($this->config['scrapers'] as $key => $value) {
113+
if (!class_exists($value)) {
114+
throw new \RuntimeException("Scraper class not exists");
115+
}
116+
$scrapers[$key] = $value;
117+
}
118+
}
119+
120+
$name = array_key_exists($name, $scrapers) ? $name : 'default';
121+
122+
$scraper = new $scrapers[$name]($this->config);
123+
124+
if (!$scraper instanceof ScraperInterface) {
125+
throw new \RuntimeException("Scraper class must implement the ScraperInterface");
126+
}
93127

94-
return new Core::$scrapers[$name]($this->config);
128+
return $scraper;
95129
}
96130
}

tests/SnippetSnifferTest.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,86 @@ public function testInvalidProvider()
6969
}
7070
}
7171

72+
public function testCustomProviderClassNotExists()
73+
{
74+
try {
75+
$config = [
76+
'provider' => [
77+
'cx' => $_SERVER['PROVIDER_CX'],
78+
'key' => $_SERVER['PROVIDER_KEY'],
79+
'name' => $_SERVER['PROVIDER_NAME'],
80+
],
81+
'providers' => [
82+
'gigbyte' => 'lormemdm'
83+
]
84+
];
85+
$sniffer = new SnippetSniffer($config);
86+
$sniffer->fetch('js array contains', [ 'page' => 1, 'limit' => 10 ]);
87+
} catch (\Exception $e) {
88+
$this->assertInstanceOf(\RuntimeException::class, $e);
89+
}
90+
}
91+
92+
public function testCustomProviderClassNotImpementsProviderInterface()
93+
{
94+
try {
95+
$config = [
96+
'provider' => [
97+
'cx' => $_SERVER['PROVIDER_CX'],
98+
'key' => $_SERVER['PROVIDER_KEY'],
99+
'name' => 'gigbyte',
100+
],
101+
'providers' => [
102+
'gigbyte' => SnippetSniffer::class
103+
]
104+
];
105+
$sniffer = new SnippetSniffer($config);
106+
$sniffer->fetch('js array contains', [ 'page' => 1, 'limit' => 10 ]);
107+
} catch (\Exception $e) {
108+
$this->assertInstanceOf(\RuntimeException::class, $e);
109+
}
110+
}
111+
112+
public function testCustomScraperClassNotExists()
113+
{
114+
try {
115+
$config = [
116+
'provider' => [
117+
'cx' => $_SERVER['PROVIDER_CX'],
118+
'key' => $_SERVER['PROVIDER_KEY'],
119+
'name' => $_SERVER['PROVIDER_NAME'],
120+
],
121+
'scrapers' => [
122+
'gigbyte' => 'lormemdm'
123+
]
124+
];
125+
$sniffer = new SnippetSniffer($config);
126+
$sniffer->fetch('js array contains', [ 'page' => 1, 'limit' => 10 ]);
127+
} catch (\Exception $e) {
128+
$this->assertInstanceOf(\RuntimeException::class, $e);
129+
}
130+
}
131+
132+
public function testCustomScraperClassNotImpementsScraperInterface()
133+
{
134+
try {
135+
$config = [
136+
'provider' => [
137+
'cx' => $_SERVER['PROVIDER_CX'],
138+
'key' => $_SERVER['PROVIDER_KEY'],
139+
'name' => $_SERVER['PROVIDER_NAME'],
140+
],
141+
'scrapers' => [
142+
'default' => SnippetSniffer::class
143+
]
144+
];
145+
$sniffer = new SnippetSniffer($config);
146+
$sniffer->fetch('js array contains', [ 'page' => 1, 'limit' => 10 ]);
147+
} catch (\Exception $e) {
148+
$this->assertInstanceOf(\RuntimeException::class, $e);
149+
}
150+
}
151+
72152
public function testContainsResults()
73153
{
74154
$data = $this->sniffer->fetch('js array contains', [ 'page' => 1, 'limit' => 10 ]);

0 commit comments

Comments
 (0)