Skip to content

Commit 6a180a4

Browse files
author
Luciano Mammino
committed
Improved README
1 parent ac68eb8 commit 6a180a4

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

README.md

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,61 @@ TODO
164164

165165
## How to contribute
166166

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/).
168222

169223
## Contributors
170224

0 commit comments

Comments
 (0)