📜 ⬆️ ⬇️

Drupal: we write the parser for Feeds

Feeds module is very popular among Drupal developers. But the question arises what to do if it is necessary to slightly expand its functionality. The system of plugins of the module Feeds will help us in this.
There are 3 types of plugins from which you must inherit new ones:

In this article I would like to dwell on the writing of the parser module, since quite often you have to deal with importing files with a specific structure.

Module creation

As usual, to create a module, we need to create an info file and a module file:

json_example_parser.info
name = Json example parser description = Simple json parser package = Feeds core = 7.x dependencies[] = feeds 


json_example_parser.module
 <?php /** * @file * Json example parser - simple parser plugin */ /** * Implementation of hook_feeds_plugins(). *    . */ function json_example_parser_feeds_plugins() { $info = array(); $info['JsonExampleParser'] = array( 'name' => 'JSON parser', 'description' => 'Parses custom JSON.', 'handler' => array( 'parent' => 'FeedsParser', //      ,   Feeds - FeedsFetcher, FeedsParser  FeedsProcessor 'class' => 'JsonExampleParser', //  ,       'file' => 'JsonExampleParser.inc', //    'path' => drupal_get_path('module', 'json_example_parser'), //     ), ); return $info; } //    Feeds    function json_example_parser_enable() { //clear the cache to display in Feeds as available plugin. cache_clear_all('plugins:feeds:plugins', 'cache'); } ?> 

The comments describe the main points of the hooks.
')
Initial data

For example, take the “Computer Game” node for the imported material with the following fields:

The data that we will parse will come in JSON format. It doesn’t matter whether it is a downloadable file or an HTTP collector, Fetcher is responsible for this and the methods for obtaining data depend on the set of plugins for the collector.

Input JSON:

 [ { "name":"Team Fortress 2", "year":2007, "price":0 }, { "name":"Warcraft III: The Frozen Throne", "year":2003, "price":13.9 }, { "name":"Diablo III", "year":2012, "price":33 } ] 


Creating a parser class

In order to create a parser class, you must inherit it from the standard abstract class FeedsParser and override the parse and getMappingSources methods. Redefinition of the remaining methods is optional.

JsonExampleParser.inc
 <?php /** * A JSON example parser */ class JsonExampleParser extends FeedsParser { /** * Implements FeedsParser::parse(). */ public function parse(FeedsSource $source, FeedsFetcherResult $fetcher_result) { $result = new FeedsParserResult(); //    $source_config = $source->getConfigFor($this); //  JSON  $fetch_items = json_decode($fetcher_result->getRaw()); foreach ($fetch_items as $value) { $item = array('name' => $value->name); if ($value->year) { $item['year'] = intval($value->year); } if ($value->price) { $item['price'] = floatval($value->price); } //     if ( $source_config['type'] == 'all' || ($source_config['type'] == 'free' && $item['price'] == 0) || ($source_config['type'] == 'paid' && $item['price'] > 0)) { //     $result->items[] = $item; } } return $result; } /** * Implements FeedsParser::getMappingSources(). */ public function getMappingSources() { return array( 'name' => array( 'name' => t('Game name'), 'description' => t('The name of the computer game.'), ), 'year' => array( 'name' => t('Release year'), 'description' => t('Release year of the computer game.'), ), 'price' => array( 'name' => t('Game price'), 'description' => t('The cost of the computer game.'), ), ) + parent::getMappingSources(); } /** * Configuration form. *  ,       . */ public function configForm(&$form_state) { $form = array(); $form['type'] = array( '#type' => 'select', '#title' => t('Game type'), '#description' => t('Game filter by type.'), '#options' => array( 'all' => t('All game'), 'paid' => t('Paid'), 'free' => t('Free'), ), '#default_value' => $this->config['type'], ); return $form; } /** * Define default configuration values. *    ,       . */ public function configDefaults() { return array( 'type' => 'all', ); } /** * Define defaults. *     . */ public function sourceDefaults() { return array( 'type' => $this->config['type'], ); } /** * Show configuration form for users. *         . */ public function sourceForm($source_config) { $form = array(); $form['#weight'] = -10; $form['help']['#markup'] = '<div class="help"><p>' . t('Select the type of game you want to import') . ':</p></div>'; $form['type'] = array( '#type' => 'select', '#title' => t('Game type'), '#description' => t('Game filter by type.'), '#options' => array( 'all' => t('All game'), 'paid' => t('Paid'), 'free' => t('Free'), ), '#default_value' => isset($source_config['type']) ? $source_config['type'] : 'all', ); return $form; } } 


A little about the methods.

parse is the parsing method; it gets the object of the source class FeedsSource and the object of the class FeedsFetcherResult from which the read data is extracted. This method forms a ready-made FeedsParserResult object with a set of items to be saved.

getMappingSources is a method that determines the fields that will be available from the source for writing to the fields of the object being created. For example, in this case, the mapping field name will be written to the node header, etc.

configForm - this method provides a form of customization that will be displayed on the admin page in the importer settings. Saving data occurs automatically.

configDefaults - default settings if the user did not use the form to configure the parser.

sourceDefaults is the overridden method for accessing the saved parameters from the configuration form.

sourceForm is a form that will be available to users when importing, complementing the Fetcher form.

Conclusion

As a result, we got a full-fledged plugin for the Feeds module with unlimited customization options and processing of any input data. For a more detailed view of the Feeds plug-ins, I advise you to look at the source codes of standard add-ons that come with the module.

Source: https://habr.com/ru/post/164707/


All Articles