📜 ⬆️ ⬇️

Drupal 7. DIY subscription module

Instead of the preface


The functionality of subscriptions to any content is one of the most sought after in the web industry. Many sites can boast of such. And our project was no exception. Given: Drupal 7 site. What is required: find or write a module that implements all the necessary functions. Which option was chosen and what came of it, you can read further.




')

Search for suitable modules


The most obvious and guessable option is the Subscriptions module. This module allows users to subscribe to changes to nodes and taxonomies (including new comments to the content). The main reason for rejecting this option was the inability to subscribe without reloading the page and the focus of the module mainly on email links.

Another option is the Notifications module. In principle, its extensibility and scalability were suitable for us (to create our types of subscriptions), but the lack of a stable version under 7.x did not allow us to use it.

So, the solution was only one thing - to write the module itself.

Initial setup


Fully describing the entire module does not make sense (it will definitely go beyond the topic of the article), so I will describe the main functionality and start with the main points: admin settings. First, you need to create a content type (in my example, this is Item ) with a number of fields. Hereinafter, the focus will be on the fields Title , Body , Image .



Secondly, the next step is to create Views for outputting nodes of this type. For example, as in the following image:



In addition to the fields described earlier, Nid is also displayed in this Views . What is it for? Having tempered this field (to which the subscription event will be attached later), we can customize its output at our discretion.

Module files and their description


To start developing a module, create a custom_subscriptions folder in sites / all / modules . We need 4 files: custom_subscriptions.info (basic information about the module), custom_subscriptions.install (installation settings), custom_subscriptions.module (the module file itself) and custom_subscriptions.js (the script will implement the subscription mechanism without reloading the page). Now about each of them in more detail.

Info file

Contents of the custom_subscriptions.info file:

name = "Custom Subscriptions" description = "Allows users to follow content" core = 7.x version = 7.x-1.0 php = 5.1 scripts[] = custom_subscriptions.js 

As you can see, the script file was connected here.

Installation file

For the example placed here, one table in the database containing the fields uid (user ID) and nid (node ​​ID to which the user is subscribed) will suffice.

Contents of the custom_subscriptions.install file:

 <?php /** * Implements hook_schema() */ function custom_subscriptions_schema() { $schema['custom_subscriptions'] = array( 'description' => t('The base table for subscriptions'), 'fields' => array( 'sid' => array( 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, ), 'uid' => array( 'type' => 'int', 'length' => 10, 'not null' => TRUE, ), 'nid' => array( 'type' => 'int', 'length' => 10, 'not null' => TRUE, ), ), 'primary key' => array('sid'), ); return $schema; } 

After installation, the table will have the following structure:



Theme setting

First of all, you should create a template for displaying Nid in Views . In our case, it has the name views-view-field - items - page - nid.tpl.php (the name for the template can be obtained in the Advance d / Theme section in the View s settings). The template file is located in the theme (the Zen subtopic was used under the name STARTERKIT ), in the templates folder.

The contents of the file views-view-field - items - page - nid.tpl.php :

 <?php global $user; ?> <?php if ($user->uid != 0): ?> <?php $following = db_select('custom_subscriptions', 'cs') ->fields('cs') ->condition('uid', $user->uid) ->condition('nid', $output) ->execute() ->rowCount(); ?> <?php if ($following == 0):?> <?php print('<a href="follow/' . $output . '" class="follow">FOLLOW</a>'); ?> <?php else:?> <?php print('<a href="unfollow/' . $output . '" class="following">FOLLOWING</a>'); ?> <?php endif; ?> <?php endif; ?> 

As can be seen from the presented code, the subscription field is available only to authorized users. In addition, depending on the presence of a record in the custom_subscriptions table, the field header changes from FOLLOW (if the user is not already subscribed to the node) to FOLLOWING (if the subscription already exists). Information about the action being performed ( follow / unfollow ) and the identifier of the node ni d will be stored in the href attribute.

Subscription mechanism development

Since the functionality of the module file and the script are interrelated, they will be considered together.

Let's start with visual effects: in the script file, add the appearance of a field of hovering subscriptions, as well as changing the text of the inscription from FOLLOWING to UNFOLLOW when hovering over this field (just as implemented on Twitter ).

Contents of the custom_subscriptions.j s file:

 (function ($) { Drupal.behaviors.collectiveMove = { attach: function(context, settings) { // show buttons on hover $('.view-items .views-row').hover(function() { $(this).find('.views-field-nid a').css('display', 'block'); }); // hide buttons on mouseleave $('.view-items .views-row').mouseleave(function() { $(this).find('.views-field-nid a.follow, .views-field-nid a.unfollow').css('display', 'none'); }); // show 'unfollow' when user has already had a subscription $('.view-items .views-row .views-field-nid .following').live('mouseover', function() { $(this).text('UNFOLLOW'); $(this).addClass('unfollow'); }); // hide 'unfollow' when user has already had a subscription $('.view-items .views-row .views-field-nid .following').live('mouseout', function() { $(this).text('FOLLOWING'); $(this).removeClass('unfollow'); }); } }; })(jQuery); 

Now the most interesting thing begins - the transfer of data between the module file and the script. The basic idea is as follows: when you click on the FOLLOW post- request, the data about the action ( 'follow' ) and the node's identifier are transmitted to the module, where the received data is written to the database. For UNFOLLOW, the mechanism is similar, but the action will be different ( 'unfollow '), and the resulting data will be deleted from the database table.
To begin, create a page to which the request will be sent using hook_men u.

Contents of the custom_subscriptions.module file:

 <?php /* Implements hook_menu() */ function custom_subscriptions_menu() { $items = array(); $items['custom_subscriptions_ajax'] = array( 'title' => 'Ajax callback', 'page callback' => 'custom_subscriptions_ajax', 'access callback' => TRUE, 'type' => MENU_CALLBACK, ); return $items; } 

I remind you that according to the code design rules for modules for Drupal, only the opening php tag is put.

The page is ready - add functionality.

Contents of the custom_subscriptions.module file:

 <?php /* Implements hook_menu() */ function custom_subscriptions_menu() { ... } /** * Implements ajax callback function */ function custom_subscriptions_ajax() { global $user; if($_POST['type'] == 'follow') { if ($_POST['nid']) { db_insert('custom_subscriptions') ->fields(array( 'uid' => $user->uid, 'nid' => $_POST['nid'], )) ->execute(); print(1); } } else if($_POST['type'] == 'unfollow') { if ($_POST['nid']) { db_delete('custom_subscriptions') ->condition('uid', $user->uid) ->condition('nid', $_POST['nid']) ->execute(); print(1); } } else { print(0); } } 

Depending on the follow / unfollow action received from the post- request, we add or delete the record from the table. Each entry is identified by uid (take the global user ID) and nid . If successful, type '1'.

Now the most important thing is to transmit data by clicking on the nid field on the page formed using Views .

Contents of the custom_subscriptions.js file:

 (function ($) { Drupal.behaviors.collectiveMove = { attach: function(context, settings) { ... // click on follow/unfollow buttons $('.view-items .views-row .views-field-nid a').bind('click', function(e) { e.preventDefault(); var href = $(this).attr('href'); var strs = href.split('/'); var item = $(this); $.post( Drupal.settings.basePath + 'custom_subscriptions_ajax', { type: strs[0], nid: strs[1], }, function (data) { if (data == 1) { if (strs[0] == 'follow') { item.text('UNFOLLOW'); item.removeClass('follow'); item.addClass('following unfollow'); item.attr('href', 'unfollow/' + strs[1]); } if (strs[0] == 'unfollow') { item.text('FOLLOW'); item.removeClass('following'); item.removeClass('unfollow'); item.addClass('follow'); item.attr('href', 'follow/' + strs[1]); } } } ); }); } }; })(jQuery); 

When clicking on the link in the nid field, we go through the following steps:

Instead of an afterword


This article described the process of creating the simplest module of subscriptions to nodes in Drupal 7 . The main point is the implementation of subscriptions without reloading the page using the post- request.
You can take a look at the finished module here: github.com/Sacret/custom_subscriptions

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


All Articles