Safety concerns in an E-Commerce site and how Drupal is addressing it
The advances in technology has brought in an unprecedented growth in E-Commerce industry, which has become a major target for cyber crimes. It becomes necessary to address the security measures for websites as any data breach leads to the loss of sensitive information along with monetary losses. This not only threatens reputation of the organization but also leads to mistrust among customers. When compared to leading organizations, smaller firms are affected more as they have to suffer substantial losses.
Full security over the web can’t be attained as the hackers are devising new plans everyday to access consumer data. But, threats can be minimised by following certain security measures.
Based on our experience of working on several E-Commerce websites built using Drupal framework, in this article, we will talk about various safety parameters and how these risks can be addressed.
Sensitive Data Exposure
The PCI DSS recommends that an E-Commerce application shouldn’t store unnecessary consumer information as it may be prone to cyber attacks. Such information should be stored in a confidential manner, using strong encryptions.
In Drupal, the stored account passwords are protected and hashed based on Portable PHP Password Hashing Framework. The Drupal community-contributed codes offer solutions to encrypt sensitive data, whether stationary or in circulation.
XSS (Cross-site Scripting)
The XSS attacks are a type of injection, where infected scripts are injected into trusted websites. When these scripts are received by browsers, it leads to data breach.
By default, any untrusted user's content is filtered to remove dangerous elements in Drupal Core. In case any anonymous content is identified, the errors which can lead to XSS vulnerabilities can be mitigated by building safer defaults.
Weak Access Control
The end users can’t be given the kind of access that administrators have over their site. This is concealed using certain Java Scripts. If these Java Scripts become accessible to all, data can be easily breached. Additional security measures like two factor authentication through OTPs and e-mails should also be implemented to limit such kind of access.
Access controls in Drupal are protected by a powerful permission-based system which checks for proper authorization before any action is taken. With a number of modules, access checking can be tightly integrated into the entire menu-rendering and routing system. This enables the protection of visibility of navigation links and pages by the same system that handles incoming requests.
Security Misconfiguration
Although the contemporary E-Commerce applications come with an extra layer of security, but any loophole in the configuration can make them vulnerable.
Inefficiencies that lead to misconfiguration are corrected through usability testing and fixes that are recommended for inclusion to Drupal core. There are several contributed projects that conduct automated security review or implement further secure configurations.
Broken Authentication and Session Management
Almost every webpage users use, caches their data and links a unique session ID with them while displaying the result they seek. If they copy and share the URL of the website with another individual, they also accidentally end up giving their session ID. If it is replicated, hackers can easily get into users’ session and access their information.
User accounts and authentication are managed by Drupal core on the server to prevent a user from escalating authorisation. The passwords are hashed using PHP framework and existing sessions are destroyed upon login and logout.
Unvalidated Redirects and Forwards
It is advisable for users to go for only authenticated redirects and certified links present in the comments section of a web page. This is because unauthenticated redirects and links can lead you to a malicious page, created by an attacker to get the access to important administrative functions of the webpage.
Internal page redirects cannot be used to circumvent Drupal's integrated menu and access control system. Drupal protects a site against automatic redirection via anonymous links to off-site URLs which could be used in a phishing attack.
Security is an essential part of E-Commerce development and should be one of the fundamental objectives that needs to be kept in mind. It should be a part of development practice from project planning stage itself. If you are using Drupal to build your E-Commerce platform, it is as secured as any other pure E-Commerce enterprise framework available in market. And in new age of commerce where content and community are part of your marketing effort, Drupal scores over most of different options available. Just to substantiate, one of the leading enterprise commerce framework, Magento Commerce site itself runs on Drupal.
If you are building an E-Commerce site using Drupal and need assistance, please do contact us.
Using SteemSQL to query Steem database in your SteemJS Application
SteemJS is still rudimentary and if you start developing some applications you will know that they will fall short. For a bot that I was working on I wanted to know if the user has already posted earlier with the same tag. The case in questions was I wanted to check if the user is misusing the #introduceyourself tag. So before posting a welcome message to the users I wanted to check if he has created more than two posts with the#introduceyourself tag.
What will you learn?
In this tutorial you will learn
- How to use SteemSQL in SteemJS code
- How to use
steem.api.streamTransaction
function to do something when a user has created a post. - Using SteemSQL to identify if the user has already create posts with a similar tag.
Requirements
These are good to have requirements. Even if you don't know these you can still read the tutorial and make sense out of it.
- Basics of Javascript
- Basics of SteemJS
Difficulty
- Advanced. You can take a look at the code even if you are not at an advanced level. It might seem a little complicated but it will start making sense to once you cover your basics. I will be happy to answer any queries you have in the comments section.
Add relevant node packages and settings.
In the below script we are adding relevant node packages and their related settings.
We are adding steem package so that we can use steemJS APIs. We are setting that url to wss://steemd-int.steemit.com which is functioning without any issues for me for last two months. We are settings up variables that will be used across the file.
We are adding mssql package as SteemSQL is a MS-SQL database. You can get your SteemSQL credentials by purchasing the subscription as mentioned in the post
var steem = require('steem');
steem.api.setOptions({ url: 'wss://steemd-int.steemit.com' });
const BASEURL = 'https://steemit.com/'
const ACCOUNT_NAME = 'steemladder'
console.log('SteemLadder app has started');
const sql = require('mssql');
const config = {
user: 'Steemit-gokulnk',
password: 'you-will-get-this-once-you-subscribe',
server: 'vip.steemsql.com',
database: 'DBSteem',
}
Listem to streamTransaction to identify when a comment is posted.
In the below script we are listening streamOperations. Once the streamOperation is emmitted we are getting the txType and txData from the operation. We are then checking if the txType is comment and it has no parent(comments without parents or posts) and has metadata. If it passes all these conditions they we get the tags of the posts from metadata and see if the tags text contains the tags we are looking for.
steem.api.streamOperations(function (err, operations) {
var txType = operations[0];
var txData = operations[1];
var steemDbquery = '';
if (txType == 'comment' && txData.parent_author == '' && txData.json_metadata){
var metadata = JSON.parse(txData.json_metadata);
if (metadata) {
var tags = metadata.tags || [];
var parentAuthor = txData.author;
var parentPermlink = txData.permlink;
var commentPermlink = steem.formatter.commentPermlink(parentAuthor, parentPermlink);
if (tags.indexOf("introduceyourself") > -1) {
Once it matches all these we now need to check if the user has already posted earlier with the same tag.
Use SteemSQL before running doSomething function
This is the core of the tutorial and we will see how to use the SteemSQL query in steemJS.
In the code below we are checking that the json_metadata contains the work introduce and depth is 0 to make sure that we are querying only the posts and not the comments. Since node.js is asynchronous we will get the response from the DB and we need to use then to process that output. Within the the then function we are checking if we have got more than 2 rows which satisfies our conditions. Including the current post if the user has posted less than or equal to two posts with #introduce tags then we can perform some action like say up-voting their posts.
steemDbquery = `SELECT * FROM [dbo].[Comments] where author = '${parentAuthor}' AND json_metadata like '%introduce%' AND DEPTH = 0`;
sql.connect(config).then(pool => {
console.log('Connected to SteemSQL');
return pool.request()
.query(steemDbquery)
}).then(result => {
console.log(result); // Print SQL results to console for debugging
if (result.rowsAffected[0] <=2) {
doSomething();
}
sql.close();
})
sql.on('error', err => {
console.log('Unable to connect to DB');
})
Helper Functions
Following Helper functions are used to generate links to the authors and blogs.
function steemBlogFullurl(author, permlink) {
return BASEURL + '@' + author + '/' + permlink;
}
function steemBlogFullurl(author, permlink) {
return BASEURL + '@' + author + '/' + permlink;
}
function steemAuthorFullurl(author) {
return BASEURL + '@' + author;
}
function steemAuthorLink(author) {
return getLink('@' + author, steemAuthorFullurl(author));
}
function getLink(linkText, targetLink) {
if (typeof linkText == "undefined" || linkText == ''){
linkText = targetLink;
}else if (typeof targetLink === "undefined") {
targetLink = linkText;
}
return `<a href = ${targetLink} target="_blank">${linkText}</a>`;
}
Final notes.
You can checkout the final code from Github.
Curriculum
If you are a developer and would like to kickcstart your learning you can check the following link to set up your dev environments and tools. As I write further tutorials I will add them to the list.
- Steem Development Tools and Details
- Steem JS Hellow World - Build matrix like Steem Stream
- For easier access I will keep updating the code and demo links on github pages
Originally published on https://steemit.com/utopian-io/@gokulnk/using-steemsql-to-query-steem-d…
Build matrix like Steem Stream with SteemJs
This is going to be the first tutorial in the tutorial series I will be starting. I am working on a couple of Steem projects and I will share my learnings from the project as Tutorial Series. This tutorial intends to be the "Hello World" program of coding on Steem Blockchain. In this tutorial we will create a simple activity stream which shows the latest activity on the blockchain. To make things a little interesting I will format it in the Matrix style. You will know what I mean once you look at the demo. If you just want to take sneak peak at what we will be achieving before starting the tutorial take a look at https://nkgokul.github.io/steem-tutorials/SteemStream.html
What will you learn?
In this tutorial you will learn
- How to use SteemJS
- How to use
steem.api.streamTransaction
function to check for transactions from the latest blocks. - Create a basic HTML that will display the steem stream in a matrix like fashion.
Requirements
These are good to have requirements. Even if you don't know these you can still read the tutorial and make sense out of it.
- Basics of HTML
- Basics of Javascript
Difficulty
- Basic. You can take a look at the code even if you are not from a development background. I will be happy to answer any queries you have in the comments section.
Create a HTML skeleton
<body>
<div id="gokul-details">
<h3>This example was created by <a href="https://www.steemit.com/@gokulnk" target="_blank">@gokulnk</a></h3>
</div>
<div id="steem-data-wrapper">
<h2>Please wait while fetching the data from Steem Blockchian.</h2>
</div>
</body>
Within the body tag create a div which we will use to populate the contents of our data stream from Steem blockchain.
Add relevant javascript files
In your head tag add the following scripts
<script src="https://cdn.steemjs.com/lib/latest/steem.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
The first script is the minified version of SteemJS library which will help us interact with the steem blockchain direction from the javascript/browser.
The second script is the jQuery library file which simplifies DOM manipulations and saves time in performing the frequently used actions in javascript. We will use these two files in all the browser based tutorials going forward.
Understanding steem.api.streamTransactions
function
The takeaway from this tutorial will be how to use steem.api.streamTransactions
function
console.log('hello, is this working')
var counter = 1;
const BASEURL = 'https://steemit.com/'
const ACCOUNT_NAME = 'gokulnk'
steem.api.setOptions({ url: 'https://api.steemit.com' });
steem.api.streamTransactions('head', function(err, result) {
let txType = result.operations[0][0]
let txData = result.operations[0][1]
jQuery('#steem-data-wrapper').prepend('<div class="stream-activity' + counter + '">' + counter++ + ' ' + getMessagefromTransaction(txType, txData) + '</div>');
});
In this code we are doing a couple of things.
- setup some variables like counter and BASEURL variables which we will be using erstwhile.
steem.api.setOptions({ url: 'https://api.steemit.com' });
sets the url of the endpoint to https://api.steemit.com. Recently there were some changes made to the endpoints and a couple of witness servers were not working. In case you are getting any errors google for other endpoints and update them accordingly.- Minitor the blockchain with
steem.api.streamTransactions
function, decorate/process them using the functiongetMessagefromTransaction(txType, txData)
- Using jQuery prepend the output to the div we created earlier in HTML with id "steem-data-wrapper". We will be using jQuery for prepending this value.
The processing function
The processing function uses a switch case to identify the different types of transactions and returns a relevant activity message.
function getMessagefromTransaction(txType, txData) {
//console.log(txType, txData) ;
//console.log(txType, JSON.stringify(txData)) ;
var custom_json;
switch (txType) {
case 'vote':
return steemAuthorLink(txData.voter) + ' upvoted ' + steemAuthorLink(txData.author) + "'s post " + getLink(txData.title, steemBlogFullurl(txData.author, txData.permlink));
// statements_1
break;
case 'comment':
if (txData.parent_author == ''){
return steemAuthorLink(txData.author) + ' created a post ' + getLink(txData.title, steemBlogFullurl(txData.author, txData.permlink));
}else {
return steemAuthorLink(txData.author) + ' posted a comment' + ' on '+ getLink(txData.permlink, steemBlogFullurl(txData.author, txData.permlink));
}
break;
case 'transfer':
return steemAuthorLink(txData.from) + ' transferred ' + txData.amount + ' to '+ steemAuthorLink(txData.to) + ' with the memo "' + txData.memo + '"';
break;
case 'claim_reward_balance':
return steemAuthorLink(txData.account) + ' claimed his remaining rewards balance of ' + txData.reward_steem + ", "+ txData.reward_sbd + " and " + txData.reward_vests;
console.log(txType, txData) ;
break;
case 'custom_json':
if (txData.id == 'follow') {
custom_json = JSON.parse(txData.json);
return steemAuthorLink(custom_json[1].follower) + ' followed ' + steemAuthorLink(custom_json[1].following);
}
default:
return txType + ' ' + JSON.stringify(txData).substring(0,300) + ((txData.length > 300) ? "....." : "");
break;
}
}
Following Helper functions are used to generate links to the authors and blogs.
function steemBlogFullurl(author, permlink) {
return BASEURL + '@' + author + '/' + permlink;
}
function steemBlogFullurl(author, permlink) {
return BASEURL + '@' + author + '/' + permlink;
}
function steemAuthorFullurl(author) {
return BASEURL + '@' + author;
}
function steemAuthorLink(author) {
return getLink('@' + author, steemAuthorFullurl(author));
}
function getLink(linkText, targetLink) {
if (typeof linkText == "undefined" || linkText == ''){
linkText = targetLink;
}else if (typeof targetLink === "undefined") {
targetLink = linkText;
}
return `<a href = ${targetLink} target="_blank">${linkText}</a>`;
}
Final notes.
You can checkout the final code and the demo to see what you have created with the help of this tutorial.
Originally published on https://steemit.com/utopian-io/@gokulnk/build-matrix-like-steem-stream-…
AngularJS Series: An introduction to Scope
This is the Sixth post in my series on the AngularJS; have a look on my initial posts covering ‘An intro to AngularJS’, ‘Data-binding methods’, ‘Modules & controllers', 'Filters' and ‘Custom services’.
Before jumping to another component of AngularJS - Scope - let’s make sure you all have seen the term $scope under controller function(). Scope is used to access variable and methods in Angular.
As the name suggests, $scope means ‘within the range’. In Angular, $scope is a reserved word. As per the name $scope does the same by availing variable/functions () within the range. So the same variable could be rendered in the view.
Technically: $scope is service for AngularJS. It is an object that refers to a model. It acts as a mediator between the View & the Controller. It allows accessing properties and variable Within the scope. Scope looks to expression in your view and performs the event.
Sample code:
The below source code allows you to print the data directly from the Scope. As you can see our custom app has myCtrl controller and data is bind to the scope using $scope.name & $scope.job. The same variable can be pulled up in view while rendering the data. We have used {{name}} & {{job}} in our view.
Response Result:
Another way to create a controller
You might have come across a situation where you need to develop a huge application of not just 50-100 lines of code but 10X larger than that. In this scenario, it's very difficult to manage each and every controller and get a minified version of JS script. When we talk about the minified version that means it will remove unnecessary blank space, comment and try to look for parameter and transform it to very simple name.
While compiling new variable ‘b’ will be replaced with $scope.
Sample code :
Every App has a local & global scope (root scope), where $rootScope never bound with any controller. In other words, $rootScope is a parent controller where are $scope_1 ,$scope_2…..$scope_n are the child of parent controller(--------- ) and can be accessible from anywhere in the application. Here variable has the same name and calls out within the scope and outside of the scope. In this scenario, variable within the local scope gets executed before root scope.
Let me share one small example:
Code Simplification:
In above codebase, a module has two controllers including run().
run() is one of the phases of code execution order. Only constant and an instance can be taken up and called right after config(). In other words, you can use run() to boost the application.
Back to code: we have two controller myCtrl & yourCtrl. These controllers are called within local scope whereas $rootScope have an object in global scope and rendered the same in the view.
To access the $rootScope property or methods within the controller, you need to mention $root. Method_name or $root.property_name
In case you need $rootScope inside the local scope of your controller then you need to pass $rootScope as Dependency injection in your local scope of the controller.
In below source code $rootScope.job will take up the value from the global controller and assign back to myCtrl. Using this technique, global data can be passed through multiple controller and local data within the same controller.
app.controller('myCtrl', function($scope, $rootScope) { $scope.name = "Jaywant Topno"; $scope.job = $rootScope.job; });
Sample response:
This is what Scope in AngularJS all about. The goal of our series of tutorial on AngularJS is to bring you valuable information to help you gro tow enhance your technical knowledge. We hope you enjoy this post!
Git Source code: https://github.com/xaiwant/AngularJS-Scope
How to integrate Salesforce with Drupal 8 website
Integration of CRM tool with web applications has turned out to be an undaunted task especially when you monitor/manage your contacts, existing clients and leads generated for marketing campaigns. In this post, I would like to walk you through Salesforce integration with Drupal web application. Let’s dive in to the basics of Salesforce.
Salesforce is a cloud-based CRM solution that helps business effectively manage sales, service, marketing, collaboration, analytics, and building custom mobile apps. In order to manage the business effectively, companies need to integrate their Drupal website with Salesforce CRM solution, which is quite configurable. Not to mention Drupal offers various modules that help in synchronizing your application with CRM. Check out how.
Prerequisites
- A salesforce developer account
- A Drupal website
- Drupal Salesforce module
Server requirement:
SSL is mandatory for using Salesforce on the website.
Creating connected app in Salesforce
Step 1 Login your Salesforce account.
Step 2 Follow the steps:
Setup->Apps->App manager->New connected App
Follow the steps as shown in the screenshot:
Step 3 Now you can see connected app form, select required fields.
3.1 Basic information: Provide basic information about your app.
3.2 API (Enable OAuth setting): OAuth (Open Authorization) gives access to resources without revealing user credentials to apps and end user's account information can be used by third-party services. Select setting checkbox.
Step 4 Check whether the setting is selected or not as it toggles a form with some other required fields.
Step 5 Enter the callback URL “yourdomain.com/salesforce/oauth_callback”.
Step 6 Select other fields as per your requirement and process it. Wait for 2-10 minutes before using your app. Now continue the process.
Here you will get the consumer key and secret key (these keys are required to connect Drupal to Salesforce). Now you can use the connected app on your Drupal website.
Salesforce module:
Download Salesforce module and install it on your Drupal website. Also, download and install dependent modules like key & encrypt.
Let’s check out the submodules in Salesforce and what they do:
- Salesforce: OAUTH2 authorization, wrapper around REST API.
- Salesforce Mapping: Maps Drupal entities to Salesforce fields, including field level mapping.
- Salesforce Push: Pushes Drupal entity updates in to Salesforce.
- Salesforce Pull: Pulls Salesforce object updates into Drupal on cron run.
- Salesforce Encrypt: This module is dependent on two other module Encrypt & Key so make sure these are installed. Module required for access and refresh token with security.
Setting up Salesforce on Drupal website:
Step 1 Go to Configuration->Salesforce->Salesforce Authorization
Step 2 Add the oAuth configuration setting here
Create Salesforce mapping:
Before Salesforce mapping, make sure what exactly are you looking for.
Scenario:
Let’s map out basic information, like first name, last name, email of Drupal users to Salesforce and push them to CRM tool.
Follow this path (admin/structure/salesforce/mappings) to get a form similar to the shown below.
Now fill the list of values:
- Label: Label of the mapping.
- Drupal Entity: Select users in both of the fields “Drupal Entity Type” and “User Bundle” in order to map out Drupal users.
- Salesforce object: Here the selected value should be contacted only.
- Action Trigger: Ones you create a user on Drupal site, use that as a contact in Salesforce tool. For this, select all the data push actions, like insert, update, delete.
Now select Upsert key and Mapped fields.
Upsert key: By setting Upsert key on Salesforce, you can prevent data duplicacy.
Mapped fields: Fill the following columns.
- Property: Listed Drupal fields
- Salesforce field: Listed Salesforce fields
- Direction: There are three directions on the radio button. Here you can see the mapped data that will be updated on Salesforce or on your Drupal site or will synchronize on both. Your mapped field data depends on this setting.
- Operations: If you don’t want to map this field then delete it by selecting the ‘delete field option’.
I have added Email as an Upsert key and for direction field, select “Drupal to Salesforce”.
How to test:
Steps 1 Create a user from admin.
Note: Salesforce module will automatically push the data on CRM with contacts.
Step 2 Run cron directly to update data with Salesforce contact by using the following path:
/admin/config/system/cron
The integration of Salesforce with your Drupal has endless benefits as it helps your sales and marketing to work efficiently and meet the process they perform on a regular basis in a more streamlined way. Further, it also enables you to custom-tailor industry-specific tasks, such as contact status in the Sales pipeline and contact reminders.
Below given is a presentation on "Salesforce integration with Drupal".
AngularJS: Developing custom Services
This is the fifth post in my series on the AngularJS; have a look at my initial posts covering ‘An intro to AngularJS’, ‘data-binding methods’, ‘Modules & controllers' and 'Filters'.
Considering the series is getting a bit longer, but it has immense importance as these tutorials are written in such a way to help you develop the understanding of Angular and its various components. Let’s move towards another important component of AngularJS - Services.
In a layman language, AngularJS Services is a piece of code (either business logic or objects) that can be used by an Angular application.
Key Points:
- It keeps your controller lightweight & makes logic that would be independent of the controller.
- Services only instantiated once. (the same instance is used during application cycle).
- Services are not instantiated by default but when a controller refers to services it gets instantiated if it is not instantiated earlier.
- A Controller can use multiple services and one service can also use another service.
Types of Services in AngularJS
1. Built-in Services: AngularJS by default provide core services, such as $http, $log, $location angularjs etc.
2. Custom-services: These services are developed by developers to achieve certain business logic in the form of service.
In this blog cum tutorial, we will build custom services and in the next, I will walk you through built-in services of AngularJS.
Long story short, there are three different ways to develop custom services.
Factory: While creating services, a developer is responsible to create a service name and register the service factory function for the Angular module. Check out how to create your own custom service and call them directly to your controller.
Sample code
Using the above source code, we can create a service name and register it to the service factory function.
The above source code has factory service that is created under the module. Where call service object with null value gets initiated and assign that service object for all the service members and return the same object. The returned object can be used directly by the controller. It passes the return object directly to the controller as a parameter.
Once the value is available in the controller parameter then we can easily access the member function of that service as below code sample.
Service: Service is similar to the factory service. But let me tell you How does it make a difference over a selection of the right service. There is a major difference between AngularJs service vs factory service. In the service factory, we don’t need to create an additional service object and a new member function can be added directly to service definition similar to our controller, where we define member function. Also, member function gets instantiated automatically and sends the response to the controller parameter.
The only difference between service and factory is that service object declaration. Here you don’t need to create an object and Angular takes care of - how member function gets instantiate and send to the controller as a parameter as well as minor syntax changes.
We can go with any of the service/factory.
Provider: At this moment you must be thinking of What is a Provider in AngularJS. Let me clear you, In Angular Provider is another way to develop custom services. It is one of the core services in Angular in which services and factory are depended on. The provider has a lot of customization options compared to services and factory. Remember whenever we create custom services using factory/service, it automatically gets called to the provider in the background.
A provider is really helpful whenever there is a service call. It helps you in initializing the configuration before any service call. In this scenario, Provider is the best option. Use Provider only when you need to instantiate some sort of configuration information or use factory/service.
Myapp.config provides configuration for service "TaxServiceProvider". Suffix for a service provider with 'Provider'. App configuration gets registered before the controller and services. So next time when the app controller gets instantiated it looks for service. Service is built with the Provider. While in the Bootstrap process, Provider (service) looks for configuration and executes the service.
Let’s start building a sum of two numbers using Services:
In the below source, we are implementing a simple addition of two numbers and business login using services in AngularJS.
Below we have two sources:
1. an_page.html: Is a view
2. an.js: implemented factory service
Code Explanation: In the View, we are providing two input boxes with one addition button. By default, the value of a and b will be taken up from hardcoded value, which is written directly on the controller.
$scope.a =20;
$scope.b =30;
When someone tries to change the value of any of the input fields the view also gets changed.
You could also initialize the same in View using ng-init. Instead of writing business logic or the addition of two numbers function inside the controller, create factory service and implement logic in the same.
As mentioned earlier, the basic rule of creating Factory service is to:
1. Create a blank object.
2. Assign method to that object
3. Return object so that the same could be passed over the controller as an argument.
an_page.htmlan.js
Let’s implement the same services using the service method.
As mentioned earlier, we don’t need to create any new object. We can directly add the member to the service. Note that an instance of service is auto-created by AngularJS.
& same could be passed to the controller as an argument.
Below is the source code for an.js
Moving to the next methodology of a service creation - Provider. It’s similar to factory service but allows you to add some additional configuration. Here sumServiceProvider is the provider name followed by service name + postfix(Provider keyword) else Angular will never instantiate your service configuration. As soon as Angular find service as a provider, it starts searching for configuration and instantiate some additional configuration.
MyApp.config(['sumServiceProvider', function (sumServiceProvider) {
………
}]);
Let’s build our provider service. This is similar to factory service.
this.$get = function () {
}
The above function gets executed automatically by AngularJS that allows you to implement a service object as well as methods.
Source Code:
So far we have learned about different variants of services as well as ways to create a service and when to use them. This installment will give you an in-depth knowledge of AngularJS Services and will help you build a strong foundation. This post is a follow-up to our previous post Filters in AngularJS. Hope you enjoyed reading.
GitHub source code: https://github.com/xaiwant/AngularJS-Services
How to integrate Bynder DAM System with Drupal 8
In order to have a strong online presence, it's significant to offer an amazing digital experience to customers. And for this, offering a seamless experience to content managers is extremely important. To achieve this one of very important aspect is making digital assets available at different web properties to editors while they are creating content. These assets should be searchable with meta information as well as other related information. Bynder is one such digital asset management system that allows easy access to your digital file.
Let’s have a look what Bynder is and how to integrate it with Drupal 8 web application to import digital files into content pieces.
First thing first, Bynder is a cloud-based platform that helps marketers to create, find, and use digital content. Every brand that leverages media, graphics, and documents for marketing or sales efforts is a great fit to use Bynder. It is a digital content library that understands the ways in which marketers need to use the content.
Further, the integration of Bynder with Drupal eliminates the hassle of logging into a different platform to access digital files to content. With this, content managers can use any assets available in their repository system.
Integrating Bynder into a Drupal 8 Site
First, create a Bynder account on www.bynder.com and create API tokens to access the portal using the Drupal module
Module Dependencies:
- Media Entity: Media entity provides a 'base' entity for media.
- Entity Browser: This module provides a generic entity browser/selector.
- DropzoneJS: An open source library that provides drag-drop file uploads feature with image previews.
Library Dependencies:
- DropjoneJS: Download this library and add it inside the libraries folder.
- ImagesLoaded: This library detects when images are loaded. Download from https://github.com/desandro/imagesloaded and add it inside the libraries folder.
- Masonry: It is a grid layout library. Download from https://github.com/desandro/masonry/releases and add it inside the libraries folder.
Installation:
Step 1 Enable the Bynder module via drush - drush en bynder
Step 2 At this point you should be prompted to update the Composer dependencies.
Step 3 Make sure all the packages are installed correctly in your vendor folder - default path is /vendor
Step 4 Bynder needs the "bynder/bynder-php-sdk": "^1.0" . The directory /vendor/bynder/bynder-php-sdk should be present after the composer update.
Configuration:
Step 1 Go to admin/config/services/bynder
Step 2 Fill the configuration form with your Bynder API token details. The details will include Consumer Key, Consumer Secret, Token, Token Secret and Account domain.
Step 3 Save the form to fetch the derivatives and brand information from the Bynder portal
Step 4 The jQuery version should be set to 1.7 or higher for content add/edit pages.
Step 5 Test the Bynder connection from the configuration page and Reload Derivatives. Every time a new Derivative is created in Bynder side, derivatives reloads on the Drupal site.
Step 6 Bynder provides a default media entity that can be referred to a Drupal content-type. Select Bynder and image media type as shown in the below
screenshot.
Step 7 Create an entity browser to upload and select Bynder media:
Create an entity browser from “/admin/config/content/entity_browser” and then select the entity browser from Manage Form Display (/admin/structure/types/manage/article/form-display) for the content-type in which you want to select images from Bynder.
Step 8 Attach Bynder media in a content.
A Bynder media can be added to a content from the node add/edit form. The entity reference field stores the references to Bynder assets. A popup opens by clicking the upload asset button. Go to the Bynder Search Tab and select an image.
Note: Log in to the Bynder repository to upload an image from node creation form.
Step 9 Uploading an image to Bynder
Through Bynder’s uploader widget, you can also upload images from Drupal to the Bynder Repository.
That’s it. This is how Bynder, a data asset management system, is one such tool that eases content management work of any publishing house. I believe after completing this tutorial, you will have a better understanding of how Bynder works? How to install and configure it? Once the setup is completed upload images to your Account Domain and starts using those on the Drupal site.
Componentizing Drupal Front End using Pattern Lab
Componentization has become a growing consideration in most of the web application development firms. The reasons are obvious, instead of reinventing the wheels again and again, why don’t we re-use them. This article will help you to understand the importance of componentizing your Drupal front end and how you can achieve that using Pattern Lab.
So what is Componentization?
In front-end perspective, components are a collection of HTML, CSS, and JS that combines together to form a display element and Component-Driven Development (CDD), a development methodology by which the web pages are built from the bottom up. 'Componentization' is the process of breaking things down into small and easily identifiable pieces, a practice used by developers and designers alike to solve complex problems.
Why should you follow component driven front-end development approach?
Allows for re-use of Components
A component-based UI approach accelerates the development
You can completely decouple the front-end development
Testing becomes easier
Parallelize development
Flexible project workflow
How to use component driven front-end development approach In Drupal?
One of the most popular tools for component driven front-end development is Pattern Lab. What makes Pattern Lab so famous is its flexibility in pairing up with the Atomic Design methodology. Addition of twig templating system in Drupal makes it easier for us to integrate Pattern Lab with Drupal. Although many starter kits for Pattern Lab with Drupal 8 are available, I personally find Emulsify the most useful one. Emulsify is a starter kit for Pattern Lab based theming created by Fourkitchens.
Integrating Emulsify with Drupal
Let me explain how you can use Emulsify for componentizing your Drupal front-end development. Emulsify is a Drupal 8 starter kit theme, which means we install Emulsify and tweak it to meet our needs rather than creating a subtheme out of it.
Before installing Emulsify, there are certain prerequisites which need to be met:
Node
Gulp
Composer
Components Module
Installing Emulsify:
Step 1: Emulsify can either be installed using composer or you can directly download Emulsify and place it in your themes directory.
For installation using composer: composer require Fourkitchens/Emulsify.
Step 2: You can rename the downloaded Emulsify theme to suit your project if needed.
Step 3: Move the Unified Twig Extension module from the Emulsify to modules/unified-twig-extensions.
Step 4: Enable the Emulsify theme, unified-twig-extensions and components module.
Step 5: Run ‘npm install’ from the Emulsify theme directory.
Step 6: Run ‘composer install’ from the Emulsify theme directory.
You will now have a working theme based on Pattern Lab.
Now, Let’s create a simple component in Emulsify
Step 1: Run npm start from terminal
Your terminal screen would look like this
A Pattern Lab instance will be created. Access URL’s are displayed on the screen. This process would take care all of the tasks like compiling the sass to CSS and updating the living style guide. Your Pattern Lab instance would look as below.
Step 2: Create Component
Certain components are built within Emulsify by default. Let's create a view that will display article teasers. We will be using the card component which is in the Emulsify theme.
Step 2.1 Create a view which displays the article teasers
Step 2.2 Override node template for article teaser view mode.
Here we are including the molecule 01-card.twig.
Step 2.3 Override the view template for our articles-list view
Here we are extending the card-grid organism for the necessary wrapper div.
Now clear the cache and view the article list view page. You will be able to see a nice gird card with the contents you added for the article.
So now you know how to isolate front-end workflow in Drupal using Pattern Lab. If you have any suggestions or queries please comment down let me try to answer.
Below is the presentation on "Contentization of front-end workflow in Drupal 8 using Pattern Lab".
Everything about Filters in AngularJS
This is the fourth post in my series on the AngularJS; check out my initial piece covering ‘An intro to AngularJS’, ‘Data-binding methods’ and ‘Modules & controllers’.
In Angular, Filters are used to format/search functionality in AngualrJS/transform the data. Angular provides default formatter that allows you to display the data in a formatted way to your view or pass the same for the input of another variable. By default, Angular has a list of Filter component in AngularJS and they can be added to your data by including a pipe (|) with expression.
- Uppercase
- Lowercase
- OrderBy
- Number
- Date
- Currency
- Filter
- JSON
- LimitTo
Let’s explore each of them.
Uppercase: Format the data in Uppercase. Sample code:Logged in User Details
- {{n.name | uppercase}}
Uppercase passed in Controller:
We can pass the Filter to Controller by adding $filter argument in controller function. We already have a javascript function to handle uppercase and the same can be achieved in AngularJS as well. Below source code will let you pass the filter in the Controller.
Output:
Hello World
HELLO WORLD
HELLO WORLD
Response: The above source code format the username in uppercase.

Lowercase: Run the following code to format the data in lowercase.
Sample code:
Logged in User Details
- {{n.name | lowercase}}
Response: The above source code format the username in lowercase. See the screenshot below.

Lowercase passed in Controller:
You can also pass the filter in a controller by adding $filter argument in controller function. Javascript function handles lowercase. Similar to Uppercase, the same can be achieved in AngularJS.
Output:
SAY HELLO TO NEW WORLD ANGULAR!
say hello to new world angular!
say hello to new world angular!
Orderby: Suppose you have a long list of user data: first name, location, job, salary. But when it comes to rendering, how would you like to filter the data in your view? Based on salary/firstname/location. Using orderby, you can achieve this. Have a look at the below code and the result.
Sample code:
- {{ns.name + ', ' + ns.city}}
Response: In the above source code, I have filtered the user data based on the city so the response would look similar to this.

number: It formats data by returning number value in a string.
syntax:
{{ expression | number : fractionSize}}
Here we have expressions that we are formatting the data into a string. With numbers, we have additional parameter fractionize that tells how many digits you can display decimal numbers.
Sample code:
Result:
What if we add price as 707.6758956 and fractionsize: 2
By default, it prints first three digits after decimal point. By adding fractionsize, you can display the number of values of your choice after the decimal.
Will print till next two digits after decimal places.
Input: 77757.677876543
Output: 77757.67
It also prints infinite value when we have something like.
input: 77754323467876432456787654356898765432456787654356787654307.677876543
Output: 7.775e+58
Date: This filter transforms a string date into a human-readable format as listed below:
- yyyy: 4 digit numeric year representation. e.g: 1989, 2017
- MMMM: month name in string format e.g: January, November
- MMM: first three letter of month e.g: JAN, MAR, FEB, DEC
- HH: 24 hours time format e.g: 24, 01,17
- mm: minutes in double-digit format. e.g: 34, 59
Similar to that there are various formatters in AngularJS official documentation. https://docs.angularjs.org/api/ng/filter/date
Syntax:
{{ DateExpression | date : format : timezone}}
Here DateExpression is a timestamp.
The format of an optional parameter. String either would be medium, short, full date, long date etc. by default it takes medium Date.
timezone is also an optional parameter that is used for formatting. e.g: +0530, +0430.
Sample: {{1288323623006 | date:'medium'}}Result: The above codebase is printing medium date format includes MMM d, y h:mm:ss a

Currency: Add Currency prefix. By default, it takes location currency symbol.
Syntax: {{ expression | symbol : fractionSize}}
Expression is the amount that needs to be manipulated.
Symbol: It is an optional parameter. Placeholder for currency symbol e.g: USD, $, ₹
Fractionsize: It shows a number of digits after the decimal. Add 0 if you do not want to display any value after the decimal.
Sample code: {{20000000000 | currency: "₹" }}
result: ₹20,000,000,000.00
Filter: Technically, Filter is used to return a new array when an item is found. It is also used to get the matching element from the array.
Syntax: {{ filter_expression | filter : expression : comparator : anyPropertyKey}}
filter_expression: source array
expression: element that you are looking for whether string, object, function.
anyPropertyKey: Is an optional parameter. Element needs to be searched.
In the below codebase, we have filtered the output data based on name having ‘i’ and gender ‘m’. Passing multiple filter value treat as & operator. Change the filter value to get the desired result.
Sample code:
Output:
Jani,m
Birgit,m
Demo Dynamic User Filter Codebase:
Json: Converts javascript objects to JSON. Primarily, it is used to debug the applications.
Syntax: {{ expression | json : spacing}}
expression : data to be filtered.
spacing: indentation . default is 2.
Sample code:
The below source code formats the data in JSON format with indentation is set to 8.
Output:
{ "name": "Alfreds Futterkiste", "city": "Berlin", "country": "Germany" }
LimitTo: This filer returns a string or array having a specific number of elements. The counting number of character in the string, array or digits can be taken from either from the beginning or the end.
Syntax: {{ expression | limitTo : limit : begin}}
expression: containing array,string, number etc.
Limit: It returns string length. If it’s in –(negative) then it will start from the end or else from the beginning.
Begin: It is an optional parameter and used to offset from the end of input. The default is 0.
Sample code:
Output:
Try to change the beginning and limit value and see the response.
eraser
sharpener
tape
So far we have gone through almost all the filters provided by AngularJS. Hope you must have used them in real time scenario. In case you have any question or suggestion then please comment below.