You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+55-1Lines changed: 55 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -164,7 +164,61 @@ TODO
164
164
165
165
## How to contribute
166
166
167
-
TODO
167
+
This project need a lot of work and Github is the perfect place to share the burden. So everyone is welcome to help and
168
+
submit a pull request.
169
+
170
+
Keep in mind that the submitted code should be conform to [PSR-2 standard](http://www.php-fig.org/psr/psr-2/) and be
171
+
tested with [PHPUnit](http://phpunit.de/).
172
+
173
+
Probably you want to contribute by submitting a new Extractor. So let shed some light on some concepts involved in writing a new one.
174
+
175
+
### Writing an Extractor
176
+
177
+
Extractors defines the logic to request information to a given service API and to normalize the received data according
178
+
to a common [interface](src/OAuth/UserData/Extractor/ExtractorInterface.php).
179
+
The most basic way to define an extractor is to write a class that implements the [ExtractorInterface](src/OAuth/UserData/Extractor/ExtractorInterface.php)
180
+
(that is pretty self-explanatory). You could extend the class [Extractor](src/OAuth/UserData/Extractor/Extractor.php) that implements most of the needed code to get you started.
181
+
Anyway, extractors should **really** extend the class [LazyExtractor](src/OAuth/UserData/Extractor/LazyExtractor.php) where possible
182
+
because it acts as a boilerplate to define highly optimized extractors. This class easily allows you to implement extractors
183
+
that **lazy loads** data (perform requests only when needed to) and **caches** data (does not make the same request more than once and avoids
184
+
normalizing the same data more than once). Everything is done behind the scenes, so you'll need to focus only on methods that define how to make
185
+
requests and how to normalize data.
186
+
187
+
To understand how to write a new extractor by adopting the [LazyExtractor](src/OAuth/UserData/Extractor/LazyExtractor.php) we need to clarify
188
+
some concepts:
189
+
190
+
-**Supported fields**: an array of the fields (you should use field constants from the [ExtractorInterface](src/OAuth/UserData/Extractor/ExtractorInterface.php)) that can be extracted.
191
+
-**Loaders**: methods whose responsibility is to trigger the proper request to the OAuth provider endpoint to load a specific set of raw data. Generally
192
+
you need to define a loader for each block of information that could be retrieved from the endpoint. this methods must have the suffix `Loader` in their name.
193
+
Most of the service will allow you to retrieve all the user data with a single request, so, in this cases, you would have only a single loader method (eg: `profileLoader`).
194
+
-**Normalizers**: methods that accept raw data (the one previously fetched by some loader method) and uses it to extract the value for a given field.
195
+
Usually you have a normalizer for each supported field. Normalizers methods must have the suffix `Normalizer` (eg. `uniqueIdNormalizer` or `descriptionNormalizer`).
196
+
-**LoadersMap**: an array that associates supported fields (keys) to loaders methods (values). Loaders methods must be referenced without the `Loader` suffix.
197
+
Most of the time, if you have only the `profileLoader` loader you will have an array with all fields mapping to the string `profile`.
198
+
-**NormalizersMap**: an array that associates supported fields (keys) to the related normalizer methods (values). Normalizers methods must be
199
+
referenced without the `Normalizer` suffix. It's highly suggested to use the same name of the field for its related normalizer, so, most of the time,
200
+
you will end up by having an array that maps field constants to the same field constant (eg. `array(self::FIELD_UNIQUE_ID => self::FIELD_UNIQUE_ID)`) for
201
+
every supported field.
202
+
203
+
Once you defined *Supported Fields*, *Loaders*, *Normalizers*, *Loaders Map* and *Normalizers Map* from within your new extractor class you must
204
+
wire them to the underlying logic by passing them to the parent constructor. So if you defined methods such as `getSupportedField`, `getLoadersMap` and `getNormalizersMap`
205
+
you will end up with a constructor like this:
206
+
207
+
```php
208
+
public function __construct()
209
+
{
210
+
parent::__construct(
211
+
self::getLoadersMap(),
212
+
self::getNormalizersMap(),
213
+
self::getSupportedFields()
214
+
);
215
+
}
216
+
```
217
+
218
+
### A small example
219
+
220
+
I hope to have time to write a dedicated blog post to present a small example that explains, step by step, how to write a new extractor.
221
+
In the meanwhile you can have a look at the [currently existing extractors](src/OAuth/UserData/Extractor/).
0 commit comments