Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough
Mar 28 2018
Mar 28

UPDATE: 1:27pm PT After analyzing the vulnerability and the most obvious remote exploitation path, we have deployed a platform wide mitigation and are logging potential exploits. At this time we do not see any systematic attacks. Patching your site is the only way to be sure you are safe, so please do that as soon as possible.

— — —

The Drupal Security Team has published Drupal SA-2018-002 to address a critical vulnerability. This the first update of this magnitude since SA-2014-005 (aka “Drupageddon”) back in 2014. In that case, the time from release to automated exploitation was around seven hours.

As soon as 8.5.1 (and related releases) came out, we immediately pushed the update to all site dashboards, where it can be deployed with a few clicks or via scripted mass-updates. Please update your Drupal sites now before continuing to read this post.

We’ve been planning for this since the Security Team issued a PSA last week, and have engineers standing by if additional response is needed.

As with SA-2014-005, we will update our status page as well as this blog post with any additional information, and will follow up with any interesting findings we can observe at a platform level.

However, I cannot emphasize enough that the only way to be sure you sites are safe is to deploy the core update. Please do not delay in rolling that out today.

Topics Drupal, Drupal Planet, Security
Apr 18 2017
Apr 18

Fairfax County Public Schools (FCPS) is the largest school system in Virginia and the 10th largest in the United States, with more than 200 schools and centers serving 186,000 students. To keep this large community of students, parents, teachers, employees, and the general public informed, FCPS is building out a network of 195 school websites.

Over time and without a unified and modern content management system, FCPS faced numerous obstacles to managing its content and effectively communicating with its audiences. The school system engaged Forum One to help realize its vision of a modern enterprise web platform that connected their sites centrally. Harnessing the content creation and syndication powers of Drupal with Pantheon Custom Upstreams, Forum One developed a platform that enables FCPS to deploy, manage, and update this network of school websites from a common codebase and to easily share news, events, and alerts from a central source.

I’m Brooke Heaton, a senior developer at Forum One, and I helped lead the development of our solution for the FCPS system. In this post, I’ll discuss how we worked with Pantheon to devise a powerful solution that met a number of critical needs for FCPS. I’ll outline the modules we used to scaffold each school site starting from a Pantheon Upstream, and I’ll also dig into the tools and practices we used to quickly deploy multiple sites.

One Codebase Upstream, Dozens of School Sites Downstream

Getting the solution right for FCPS required a long-term vision that would meet a range of needs in a sustainable and scalable way. Our solution needed to:

  • Provide a common CMS that is user friendly, highly efficient, and cost effective

  • Modernize the FCPS brand with an updated visual identity

  • Syndicate central communications for multiple, diverse audiences

  • Quickly scaffold and deploy numerous new sites with common menu items, homepage and landing pages, content importers, and a unified user interface

  • Centrally add or remove users from a central source

While a Drupal “multisite” approach could have met many such needs, experienced Drupalists can attest that the multisite approach has been fraught with issues. We opted instead to harness Pantheon’s Custom Upstream workflow, which allowed us to unify all sites with a common codebase while also customizing each site with each school’s own configuration—allowing them to display their individual school name, logo, custom menus items, unique landing pages, and their own users.

Utilizing Upstreams, we are also able to continually develop core functionality and new features and to then propagate these updates to downstream school sites.

school repo Upstream graphic

Code Propagation: Upstream code changes are merged to downstream school repositories.

Our solution was also able to create a content strategy and governance model that allows FCPS administrators to syndicate content from a central point—the central FCPS site—to individual schools by harnessing Drupal 8’s core Views, Feeds, and Migrate modules.  

FCPS.edu upstream graphic

Content Propagation: Up-to-the minute News, Events, and Blog updates are syndicated by the central FCPS website to all school sites and imported by Feeds or Migrate.

mobile view of FCPS site

Creating Turn-Key Sites with Drupal 8

To get where we wanted to go, the Forum One dev team utilized a suite of powerful Drupal 8 core and contributed modules that generate default-content, menus, taxonomy terms, and blocks—even images!—immediately after spinning up a new site from the Pantheon Upstream.

Key modules we used include:

  • Configuration Installer: A common installation profile that would import Drupal 8 configuration from a directory so that all of the core configuration of a standard FCPS school site would be there from the start.

  • Default Content: The ability to create generic and school system-wide content that cannot be saved in configuration and to export this in json format. Upon site deployment, the Default Content module scans the modules directory for any exported default content and adds it to the database. Brilliant!

  • Migrate: Now integrated into the Drupal core, the Migrate module allows us to import complex content from a central source, whether csv or xml. While the Drupal 8 Feeds module continues to mature, the Migrate module combined with Migrate Plus and Migrate Source CSV provides powerful tools to import content.

  • Views: Also part of Drupal core, the Views module provides powerful content. syndication tools, including the ability to produce content “feeds” in json, csv, or xml format. This allows content from the central FCPS site to be broadcast in a lightweight data format, then imported by the Feeds module on each individual school site. Triggered regularly by a cron job, Feeds instances import the latest system-wide News, Events, and Blog posts.

The FCPS Install Profile

With a solid foundation in a central FCPS site (hat tip to F1 Tech Lead Chaz Chumley), we were able to clone the central site then ‘genericize’ the initial site so that it could be customized by each school. We removed site.settings from config to prevent Upstream code from overwriting downstream site settings, such as the site name, url, email, etc. We also developed a special solution in the theme settings to allow schools adjust their site colors with a custom theme color selector. Bring on the team spirit!

With this genericized starting site in code and all pages, menus, taxonomy terms, image files, and blocks exported via Default Content, we were ready to deploy our code to the Upstream. To set up the Upstream, we placed a request to Pantheon with some basic information about our Upstream and within minutes, we were ready to deploy our first FCPS school site. Huzzah!

Spinning up a New FCPS School Site from Pantheon’s Upstream

With the installation profile complete and our codebase hosted on Pantheon’s Upstream, we could now create our first school site and install Drupal from the profile. While sites can be created via Pantheon’s UI, we sped up the process using Pantheon’s Terminus CLI tool and Drush to quickly spin up multiple sites while meticulously tracking site metadata and settings. Pantheon’s helpful documentation illustrates just how easy this is:

$ terminus site:create --org=1a2b3c4d5e6f7g8h9i10j11k12l13m14n15o our_new_site 'Our New Site Label' o15n14m13l12k11j10i9h8g7f6e5d4c3b2a1 

The above command uses the format site: create [--org [ORG]] [--]

[notice] Creating a new site...

With a site created from the Upstream codebase, the next step was to update our local Drush aliases via Terminus so that we could install Drupal from our configuration_installer:

$ terminus sites aliases
[2017-04-05 00:00:00] [info] Pantheon aliases updated 

Then we run drush sa to identify the new DEV site alias: 

$ drush sa

@pantheon.our-new-site.test
@pantheon.our-new-site.dev
 ← we will use this alias to install the site on DEV

@pantheon.our-new-site.live

With the alias for our newly created site we install Drupal from the Upstream using Drush:

drush @pantheon.our-new-site.dev  si  config_installer -y --notify --account-name=administrator --account-pass=password \
 config_installer_site_configure_form.account.name=admin \
 config_installer_site_configure_form.account.pass.pass1=admin \
 config_installer_site_configure_form.account.pass.pass2=admin \
 config_installer_site_configure_form.account.mail=[email protected]

The above command will fully install Drupal using our configuration and will automatically add the default content provided by the default content exported to our custom module. 

Once Drupal was installed on Pantheon, we added site editor accounts for FCPS and trained school staff in customizing their site(s).

school sites dashboard

The initial batch of FCPS schools sites after deployment

What about updates?

After we deployed the first fifteen FCPS school sites and made them live to the world, it was inevitable that changes would soon be needed. Beyond the normal module and core updates, we also faced new functional needs and requests for enhancements (and yes, maybe even a few bugs that crept in), so we needed to updated our ‘downstream’ sites from the Pantheon Upstream. To do so, we merged our changes into our Upstream ‘master’ branch and within a few minutes each site displayed an update message showing that Upstream Updates are available’. This meant that we could merge Upstream changes into each school repository.

Upstream updates screenshot

To merge these changes into each site, we once again opted for the faster approach of using Pantheon’s Terminus CLI tool to quickly accept the Upstream changes and then run update.php on each of the school sites.

$ terminus site:list --format=list | terminus site:mass-update:apply --accept-upstream --updatedb --dry-run

$ terminus site:list --format=list | terminus site:mass-update:apply --accept-upstream --updatedb

To import the modified Drupal configuration, we also had to run a drush cim --partial on each site—a step that can be further automated in deployments by harnessing yet another brilliant Pantheon tool: Quicksilver Platform Hooks. With a Quicksilver hook to automatically run a Drupal partial configuration import after code deployments, we are able to remove another manual step from the process, further speeding up the efficiency of the platform.

Is this for you?

Combining Pantheon’s Custom Upstreams with Drupal 8 and its contributed modules can unleash a very powerful solution for nearly any organization that includes sub-organizations, branches, departments or other entities. Universities, public schools, government agencies, and even private enterprises can leverage this powerful tool to maintain strict control over “core” functionality while allowing for flexibility with individual sites.

You may also like: 

Aug 21 2016
Aug 21
TL;DR The Google Summer of Code period ends, and am glad that I am able to meet all the goals and develop something productive for the Drupal community. In this blog post, I will be sharing the details of the project, the functionality of the module and its current status.

I am glad that I was one of the lucky students who were selected to be a part of the Google Summer of Code 2016 program for the project “Integrate Google Cloud Vision API to Drupal 8”. The project was under the mentorship of Naveen Valecha, Christian López Espínola and Eugene Ilyin. Under their mentoring and guidance, I am able meet all the goals and develop something productive for the Drupal community.



Google Cloud Vision API bring to picture the automated content analysis of the images. The API can not only detect objects ranging from animals to famous monuments, but also detects faces on emotions. In addition, the API can also help censor images, extract text from images, detect logos and landmarks, and even the attributes of the image itself, for instance the dominant color in the image. Thus, it can serve as a powerful content analysis tool for images.

Now let us see how can we put the module to use, i.e. what are its use cases. To start with, the Google Vision API module allows Taxonomy tagging of image files using Label Detection. Label Detection classifies the images into a number of general purpose categories. For example, classifying a war scenario to war, troop, soldiers, transport, etc. based on the surroundings in the images. This feature of the module is especially important to filter the images based on some tags.

Second feature listing our use case is the Safe Search Detection. It quickly identifies and detects the presence of any explicit or violent contents in an image which are not fit for display. When this feature is enabled in the module, the Safe Search technique validates any image for explicit/violent contents. If found, these images are asked for moderation, and are not allowed to be uploaded on the site, thus keeping the site clean.

Please click here for video demonstration of the two above-mentioned use cases.

Continuing with the other use cases, the third one is Filling the Alternate Text field of an image file. Label, Logo, Landmark and Optical Character Detection feature of the Google Cloud Vision API have been used to implement this use case. Based on the choice entered by the end user, he/she can have the Alternate Text for any image auto filled by one of the four above-mentioned options. The choice “Label Detection” would fill the field with the first value returned in the API response. “Logo Detection” identifies the logos of famous brands, and can be used to fill the field accordingly. Likewise, “Landmark Detection” identifies the monuments and structures, ranging from natural to man-made; and “Optical Character Detection” detects and identifies the texts within an image, and fills the Alternate Text field accordingly.

Next comes the User Emotion Detection feature. This feature is especially important in cases of new account creation. On enabling this feature, it would detect the emotion of the user in the profile picture and notify the new user if he/she seems to be unhappy in the image, prompting them to upload a happy one.

Lastly, the module also allows Displaying the similar image files. Based on the dominant color component (Red, Green or Blue), the module quickly groups all the images which share the same color component, and display them under the “Similar Content” tab in the form of a list. Each item links itself to the image file itself, and is named as per the filename saved by the user. Users should note here that by “similar contents”, we do not mean that the images would resemble each other always. Instead we mean here the same dominant color components.

All the details of my work, the interesting facts and features have been shared on the Drupal Planet.

Please watch this video to know more on how to use the above-mentioned use cases in proper way.

[embedded content]


This is the complete picture of the Google Vision API module developed during the Google Summer of Code phase (May 23, 2016- August 23, 2016).


I would put to use these concepts in best possible way, and try to contribute to the Drupal community with my best efforts.
Aug 16 2016
Aug 16
TL;DR Last week I had worked moving the helper functions for filling Alt Text of image file to a new service; and moving the reused/supporting functions of the tests to an abstract parent class, GoogleVisionTestBase. This week I have worked on improving the documentation of the module and making the label detection results configurable.

With all major issues and features committed to the module, this week I worked on few minor issues, including the documentation and cleanup in the project..

It is an immense pleasure for me that I am getting the feedbacks from the community on the Google Vision API module. An issue Improve documentation for helper functions was created to develop more on documentation and provide the minute details on the code. I have worked on it, and added more documentation to the helper functions so that they can be understood better.

In addition, a need was felt to let the number of results obtained from the Vision API for each of the feature as configurable, and allow the end user to take the control on that. The corresponding issue is Make max results for Label Detection configurable. In my humble opinion, most of the feature implementations and requests to the Google Cloud Vision API have nothing to do with allowing the end user to configure the number of results. For instance, the Safe Search Detection feature detects and avoids the explicit contents to be uploaded, and does not need the number of results to be configurable. However, the taxonomy tagging using Label Detection should be user dependent, and hence, I worked on the issue to make the value configurable only for Label Detection purpose. This value can be configured from the Google Vision settings page, where we set the API key. I have also developed simple web tests to verify that the value is configurable. Presently, the issue is under review.

I have also worked on standard coding fixes and pa-reviews and assisted my mentor, Naveen Valecha to develop interfaces for the services. I assisted him on access rights of the functions, and fixing the documentation issues which clashed with the present one.

Lastly, I worked on improving the README and the module page to include all the new information and instructions implemented during the Google Summer of Code phase.

With all these works done, and all the minor issues resolved, I believe that the module is ready for usage with all the features and end user cases implemented.
Next Week, I’ll work on creating a video demonstration on how to use Google Vision API to fill the Alt Text attribute of an image file, detect the emotion in the user profile pictures and to group the similar images which share the same dominant color.
Aug 09 2016
Aug 09
TL;DR Last week I had worked on modifying the tests for “Fill Alt Text”, “Emotion Detection” and “Image Properties” features of the Google Vision API module. The only tasks left are moving the supporting functions to a separate service, in addition to, creating an abstract parent class for tests and moving the functions there.



There are few supporting functions, namely, google_vision_set_alt_text() and google_vision_edit_alt_text() to fill the Alt Text in accordance to the feature requested from the Vision API, and also to manipulate the value, if needed. I moved these functions to a separate service, namely, FillAltText, and have altered the code to use the functions from there instead of directly accessing them.

In addition, there are a number of supporting functions used in the simple web tests of the module, to create users, contents and fields, which were placed in the test file itself, which in one way, is a kind of redundancy. Hence, I moved all these supporting functions to abstract parent class named GoogleVisionTestBase, and altered the test classes to extend the parent class instead and in place of WebTestBase. This removed the redundant code, as well as, gave a proper structure and orientation to the web tests.
These minor changes would be committed to the module directly, once the major issues are reviewed by my mentors and committed to the module.
Aug 03 2016
Aug 03
TL;DR Last week, I had worked on and developed tests to ensure that the Alt Text field of an image file gets filled in accordance to the various detection features of the Vision API, namely Label Detection, Landmark Detection, Logo Detection and Optical Character Detection. This week I have worked to modify and add tests to various features of the Google Vision module, namely filling of Alt Text field, emotion detection of user pictures and grouping the image files on the basis of their dominant color component.

My mentors reviewed the code and the tests which I had put for review to get them committed to the Google Vision API module. However, the code needs some amendment pointed out by my mentors, which was to be corrected before commit. Hence, I spent this week working on the issues and resolving the flaws, rather than starting with a new feature. Let me start discussing my work in detail.

I had submitted the code and the tests which ensure that the Alt Text field gets properly filled using various detection features according to the end user choice. However, as was pointed out by my mentor, it had one drawback- the user would not be able to manipulate or change the value of the field if he wishes to. Amidst the different options available to the end user to fill the alt text field of the image file, there was a small bug- once an option is selected, it was possible to switch between the options, however, disabling it was not working. After, been pointed out, I worked on modifying the feature and introducing the end user ability to manipulate the value of the field as and when required. Also, I worked on the second bug, and resolved the issues of disabling the feature.

Regarding the Emotion Detection(Face Detection) feature of the Vision API, I was guided to use injections instead of using the static methods directly, and to modify variables. For example, the use of get(‘entity_type.manager’) over the static call \Drupal::entityTypeManager(). Apart from these minor changes, a major issue was the feature was being called whenever an image file is associated with. However, I need to direct it to focus only when the user uploads an image, and not on its removal (as both the actions involves an image file, hence the bug).

In the issue, Implementation of Image Properties feature in the Vision API, I had queried multiple times to the database in the cycle to fetch results and build the routed page using the controllers. However, my mentor instructed me that its really a bad way of implementing the database queries to fetch the results. Hence, I modified the code and changed them to single queries to fetch the result and use them to build the page. In addition, I was asked to build the list using ‘item_list’ instead of using the conventional ‘#prefix’ and ‘#suffix’ to generate the list. Another important change in my approach towards my code was the use of db_query(), the use of which is deprecated. Hence, I switched to use addExpressions() instead of db_query().
Presently, the code is under review by the mentors. I will work further on them, once they get reviewed and I get further instructions on it.
Jul 27 2016
Jul 27
TL;DR Last week, I had worked on and developed tests to ensure that the similar images are grouped in accordance to the Image Properties feature of the Vision API. The code is under review by the mentors, and I would continue on it once the review is done. Meanwhile, they also reviewed the “Fill Alt Text” feature issue, and approved it is good to go. This week, I have worked on developing tests for this issue.

An important feature that I have implemented in the Google Vision API module is the filling of Alt Text field of an image file entity by any of the four choices- Label Detection, Landmark Detection, Logo Detection and Optical Character Detection. My mentor suggested me to check the availability of the response and then fill the field, as we can not fully rely on the third party responses. With this minor suggestion being implemented, now its time to develop tests to ensure the functionality of this feature.

I started developing simple web tests for this feature, to ensure that the Alt Text field is properly filled in accordance to the choice of the user. It requires the selection of the four choices one by one and verify that the field is filled correctly. Thus we require four tests to test the entire functionality. I have added an extra test to ensure that if none of the options are selected then the field remains empty.

I created the image files using the images available in the simpletests. The images can be accessed through drupalGetTestFiles(). The filling, however, requires call to the Google Cloud Vision API, thus inducing dependency on the API key. To remove the dependency, I mocked the function in the test module, returning the custom data to implement the feature.

The first test ensures that the Label Detection feature returns correct response and the Alt Text field is filled correctly. The simpletest provides a list of assertions to verify it, however, I found assertFieldByName() to be most suitable for the purpose. It asserts the value of a field based on the field name. The second test ensures that the Landmark Detection feature works correctly. Similarly, the third and fourth test ensures the correct functionality of the Logo and the Optical Character Detection feature.

The fifth test which I have included perform tests when none of the options are selected. It ensures that under this case, the Alt Text field remains empty, and does not contain any unwanted values.
I have posted the patch covering the suggestions and tests on the issue queue Fill the Alt Text of the Image File using Google Vision API to be reviewed by my mentors. Once they review it, I would work on it further, if required.
Jul 26 2016
Jul 26
TL;DR In the past two weeks I had worked on using the Image Properties feature offered by the Google Cloud Vision API to group the image files together on the basis of the dominant color components filling them. In addition, I had also worked on detecting the image files and filling the Alternate Text field based on the results of Label/Landmark/Logo/Optical Character Detection, based on the demand of the end user. This week, I have worked on and developed tests to ensure that the similar images are grouped in accordance to the Image Properties feature of the Vision API.

At present, the Google Vision API module supports the Label Detection feature to be used as taxonomy terms, the Safe Search Detection feature to avoid displaying any explicit contents or violence and the User Emotion detection to detect the emotions of the users in their profile pictures and notify them about it.

I had worked on grouping the images on the basis of the dominant color component(Red, Green or Blue) which they are comprised of. I got the code reviewed by my mentors, and they approved it with minor suggestions on injecting the constructors wherever possible. Following their suggestions, I injected the Connection object instead of accessing the database via \Drupal::database().

After making changes as per the suggestions, I started developing simple web tests for this feature, to ensure that the similar images gets displayed under the SImilarContents tab. It requires the creation of new taxonomy vocabulary and adding an entity reference field to the image file entity. After the creation of the new Vocabulary and addition of the new field to the image file, I created the image files using the images available in the simpletests. The images can be accessed through drupalGetTestFiles(). The first test ensures that if the Vocabulary named ‘Dominant Color’ is selected, the similar images gets displayed under the file/{file_id}/similarcontent link.

The grouping, however, requires call to the Google Cloud Vision API, thus inducing dependency on the API key. To remove the dependency, I mocked the function in the test module, returning the custom data to implement the grouping.

To cover the negative aspect, i.e. the case when the Dominant Color option is not selected, I have developed another test which creates a demo vocabulary to simply store the labels, instead of the dominant color component. In this case, the file/{file_id}/similarcontent link displays the message “No items found”.
I have posted the patch covering the suggestions and tests on the issue queue to be reviewed by my mentors. Once they review it, I would work on it further, if required.
Jul 14 2016
Jul 14
TL;DR Previous week I had worked on detecting the emotion in the profile pictures of the users, and notifying them to change the image if they do not look happy. The work is under review by the mentors. Once it gets reviewed, I would resume it if it needs any changes. This week I have worked on filling the ‘Alt Text’ field of an image file based on any one of the method selected by the end user- Label Detection, Landmark Detection, Logo Detection and Optical Character Detection.

Last week, I had worked on implementing the Face Detection feature in the Google Vision API module. The code is currently under the review by the mentors. Once, they review it, I would develop further on it if it requires any changes.

The Google Cloud Vision API provides the features to detect popular landmarks in an image(Landmark Detection), logos of popular brands(Logo Detection), texts within an image(Optical Character Detection), in addition to Label Detection. These features, though of less significance, are helpful in identifying an image. Hence, I have started working on implementing a new helpful case for the users- Filling of the Alternate Text field of an image file using these features.

The Alt Text field of the image file entity is modified to incorporate the options to fill the field using the features. The user may select any one of the four options to fill the Alt Text field of the image.

Coming to the technical aspect, I have made use of hook_form_BASE_FORM_ID_alter() to alter the Alternate Text field of the image file entity. I have modified the edit form of the Alt Text field to add four radio options, namely- Label Detection, Landmark Detection, Logo Detection and Optical Character Detection. The user may select any of the options and save the configuration. The Alternate Text field would be filled up accordingly.
Presently, the code is under the review by the mentors. Once it gets reviewed, I would make suggested changes, if required.
Jul 07 2016
Jul 07
TL;DR Previous week I had worked on grouping the contents based on the dominant color component in their images, if present. The work is under review of the mentors. And once, it gets reviewed, I would work further on that issue. Meanwhile, I have started developing and implementing the Emotion Detection feature of the Google Cloud Vision API. It would detect the emotion of the person in the profile picture uploaded, and if the person looks angry or unhappy, he would be notified thereof. This feature is especially important when building sites for professional purposes, as the facial looks matters a lot in such cases.

Last week, I had worked on implementing the Dominant Color Detection feature in the Google Vision API module. The code is currently under the review by the mentors. Once, they review it, I would develop further on it if it requires any changes.

Hence, meanwhile, I have started working on implementing a new feature Face Detection in an image. This feature gives us the location of the face in an image, and in addition, the emotions and expressions on the face.

I have used this feature to detect the emotion of the person in the profile picture uploaded by him/her. If the person does not seem happy in the image, he/she is notified thereof of their expressions. This is especially useful when the end users are developing a site for professional purposes, as in professional matters, expressions matters a lot.

Coming to the technical aspect, I have made use of hook_entity_bundle_field_info_alter() to alter the image fields, and check the emotions in the uploaded images. This function has been used, as we only want to implement this feature on the image fields. If the image is not a happy one, then appropriate message is displayed using drupal_set_message(). This feature also makes use of Constraints and Validators just like the Safe Search detection feature. Presently, the code is under the review by the mentors.

In addition to the implementation of Face Detection, I also worked on expanding the tests of the Safe Search Detection feature of the Google Vision API module to test other entities as well, in addition to the nodes. I have expanded the tests to test the safe search constraint on the comment entity as well. This requires the creation of a dummy comment type, adding an image field to the comment type, and attaching the comment to the content type. The image field contains the safe search as the constraint on it. This test is basically similar to the tests present in the module for the node entity. The code is under review by the mentors and would soon be committed to the module. For reference on how to create dummy comment types and attaching it to the content types, the CommentTestBase class is very helpful.
Jun 29 2016
Jun 29
TL;DR The safe search constraint feature is now committed to the module along with proper web tests. So, this week I started off with a new feature offered by the Google Cloud Vision API- “Image Properties Detection”. It detects various properties and attributes of an image, namely, the RGB components, pixel fraction and score. I have worked on to detect the dominant component in the image present in any content, and display all the contents sharing similar dominant color. It is pretty much like what we see on the e-commerce sites.

Previous week I had worked on writing web tests for the safe search constraint validation on the image fields. This feature is now committed in the module Google Vision API.

This week I have worked on implementing another feature provided by the Google Cloud Vision API, namely, Image Properties Detection. This feature detects the color components of red, green and blue colors in the images along with their pixel fractions and scores. I have used this feature to determine the dominant color component (i.e. red, blue or green) in the image, and to display all those contents which have the same dominant color in their images.

I have developed the code which creates a new route- /node/{nid}/relatedcontent to display the related contents in the form of a list. This concept makes use of Controllers and Routing System of Drupal 8. The Controller class is extended to render the output of our page in the format we require. The contents are displayed in the form of list with the links to their respective nodes, and are named by their titles.

In addition to the grouping of similar contents, the colors are also stored in the form of taxonomy terms under a taxonomy vocabulary programmatically generated under the name Dominant Colors.

This issue is still under progress, and requires little modification. I need to add the link to the new route in each of the nodes, so as to  get a better interface to access those contents. Henceforth, I will put this patch for review.
A very simple example of creating routes and controllers in your module can be found here.
Jun 29 2016
Jun 29
TL;DR It has been over a month since I started working on my Drupal project “Integrate Google Cloud Vision API to Drupal 8”, and gradually I have crossed the second stage towards the completion of the project, first being selection in the Google Summer of Code 2016 programme. Here, I would like to share my experiences and accomplishments during this one month journey, and also I would like to summarize my further plans with the project and the features which I would be implementing in the coming two months.

Let me first describe the significance of this post and what actually does “midterm submission” means? The GSOC coding phase has been divided into two halves, viz. Midterm submission and Final submission. In the first half, the students try to accomplish around 50% of the project, and submit their work to the mentors for evaluation. Those who passed the midterm evaluations are allowed to proceed further and complete the remaining portion of their project.

Now coming back to my experiences, after successfully passing through the Community Bonding period of the GSOC 2016 programme, now it was the time for start coding our project proposal to reality. As I had shared earlier that during the Community Bonding period, I came to know that the project has already been initiated by Eugene Ilyin,(who is now a part of my GSOC team). So, we discussed upon the project and set a roadmap of the project and the goals we need to achieve in the GSOC period. I had started coding the very first day of the coding phase, moving the new as well as existing functions to services. My mentors Naveen Valecha, Christian López Espínola and Eugene Ilyin really helped me a lot and guided me whenever and wherever I needed their guidance and support. They helped me to get through new concepts and guided me to implement them in the most effective way to make the module the best that we could.

During this period, I also came to learn about a lot of new techniques and concepts which I had not implemented earlier. Right from the very first day of the coding period, I have been coming across new things everyday, and it is really interesting and fun to learn all those techniques. I also learnt about the use of validators and constraints and how can they be implemented both on general basis or specifically on fields. I also learnt about how to create test modules and alter various classes and their functions in our tests so as to remove the dependency on web access or on valid informations for our testing purposes. I learnt new things every day and enjoyed implementing them to code our module plan into reality. At present, the module supports the Label Detection feature of the Vision API, along with the tests to verify whether the API key has been set by the end user or not. Currently, the feature of Safe Search Detection is available as a patch which can be found here, which would soon be committed to the module.
[embedded content] I have shared all the details of my work on the Drupal Planet. Please watch this video for detailed information on how to use the Google Vision API module on your Drupal site.
Jun 23 2016
Jun 23
TL;DR In my last post Avoid Explicit Contents in the images using Google Vision module, I had discussed about the services which “Safe Search” feature of the Vision API provides us, and how we have put this into use in the Google Vision module as a constraint to all the image fields which would be validated when the option is enabled. This week I have worked on developing simple web tests for testing this feature whether it gives us the results as expected.

Last week I had worked on developing the code to use the Safe Search detection feature as a constraint to the image fields which would validate the images for the presence of explicit contents, provided that the user enables the configuration for the concerned image field.

Besides the code, testing the functionality using simple web tests are equally essential to ensure that the feature executes perfectly when necessary steps are implemented. Hence, this week I have worked on developing simple web tests, which ensures that we have a fully functional feature.

I have tested both the conditions with safe search enabled and disabled to verify the results which should be obtained. When the safe search is enabled, any image containing any sort of  explicit content, is detected, and asked for moderation. If the image is not moderated, then the image is not saved. When the same image was passed through the second test, with safe search disabled, it was stored successfully, thus providing us the expected results.

To conduct the test successfully, I had to create a demo content type in my tests using drupalCreateContentType(), which would have an image field with the ‘Enable Safe Search’ option. This was something new to me to how to add an extra field to the default content type settings. The Drupal documentation on FieldConfig and FieldStorageConfig were of great help to understand the underlying concepts and functions which the field offers, and thus helping me to create custom fields programmatically. However, in order to perform the test, I had to call the API directly, which required a valid API key and an image which actually contains explicit content. Hence, my mentors asked me to override the functions of the class (mocking the services) in such a way that it removes the dependency from both the key and the image. Thus, I created a test module inside the Google Vision module, and override the function.

Summarizing the above, I can say that in addition to learning how to test the constraints and validators, I also came to learn about some really cool techniques, including the creation of custom fields in tests and mocking the services.
Jun 14 2016
Jun 14
TL;DR Safe Search detection of the Google Cloud Vision API allows the end users to avoid any explicit content or violence in images to be uploaded on the site. I worked on integrating this feature to the module as a constraint to those image fields which have the “Safe Search” feature enabled.

Let me first give a brief summary about the current status of the module Google Vision. In the earlier weeks, I had implemented the services and wrote tests for the module, which are now committed to the module.

Now, coming to the progress of this week.

I had started with integrating the Safe Search detection feature in the module. Safe Search detection allows its users to detect any explicit contents within the image, and hence can be very useful for site administrators who do not want to display any explicit images on their sites.

This feature was initially integrated using a function call in the module. However, my mentors suggested that this feature should rather be a Constraint on the image fields, which would be validated if the feature is enabled for the field. It depends on the user whether to keep safe search on their site or not, and they can implement it any time they want by just enabling/disabling the checkbox on the image field. Hence, now it is a user choice, rather than the developer’s choice whether to implement this feature or not.

Presently, the code is under review by my mentors whether it needs changes or is ready for commit.

Constraints and Validators are wonderful features of Drupal 8. Constraints, as the name goes, are certain restrictions which we pose on the various fields. Validators are used to implement the logic to create the situation under which the constraints are to be applied. Some helpful examples of applying custom constraints and validators can also be found Sitepoint.
This week had a lot of new things stored for me. I had no idea about the constraints and validators when I was asked to implement them at the first place. I spent hours on them, learning about them and seeking guidance from my mentors on the issues I faced. I developed gradually on it, and by the end of the week, I was able to implement them for the safe search detection feature.
Jun 07 2016
Jun 07
TL;DR I have already created services for the functions which bridges the module to the API, implementing the features offered by the Google Cloud Vision API, thus completing my first step towards Integrating Google Cloud Vision API to Drupal 8. This week I worked on generating error reports if the API key is not set by the user, and developing tests to test the API key configuration and whether the key is stored successfully or not.

The first step towards the integration of Google Cloud Vision API to Drupal 8 was completed with the functions moved to services. I had posted the patch for the review by my mentors. They provided their suggestions on the patch, which I worked on, and every step resulting in a better and more beautiful code.

I would also like to share that this week, our team expanded from a team of three, to a team of four members. Yes! Eugene Ilyin, the original maintainer of the module Google Vision API has joined us to mentor me through the project.

Now coming to the progress of the project, the schedule says I need to configure the Google Cloud Vision API at taxonomy field level, so that the end users may use the taxonomy terms to get the desired response from the API. However, the module already used the configuration for Label Detection, and in a discussion with my mentors, it was figured out that the current configuration does not need any changes, as at present the behaviour is pretty clear and obvious to let the developers use it easily; rather we should work on implementing the runtime verification and storage of API key supplied by the end users. I was required to write and implement the code which would give error report if the API key was not saved prior to the use of the module, and also to write tests for verifying the configuration and ensuring the storage of the key.

I created patches and posted it in the issue to get it reviewed by my mentors. I brought the suggested changes in the code and finally have submitted the patch implementing the required functionalities. I also worked on this issue, solving and implementing minor suggestions before it gets ready to be accepted and committed! And finally, my first patch in this project has been accepted and the changes has been reflected in the module.
At the end of these two weeks, I learnt about services and dependency injection which prove to be very useful concepts implemented in Drupal 8. I also had experiences of writing tests to check the runtime functionality of the module.
May 31 2016
May 31
TL;DR I have started working on the project Integrate Google Cloud Vision API to Drupal 8. As of the task of this week, the common functions have been moved to services. The crucial concepts involved Dependency Injection and use of Guzzle over curl.

My mentors suggested me to create issues for my tasks in the issue queues of the module Google Vision API, where they would track my progress and also discuss and leave suggestions for the improvement of the module. Thus, starting with my task for the first week, I created the issue Moving the common functions to services in the issue queue of the module and started coding the functions into services and injecting them as and when needed. I started the week by learning the concepts of services and containers, and gradually learnt about Dependency Injections in Drupal 8. The post on Services and dependency injection in Drupal 8 and the videos of Drupalize.me were of great help to understand the concept of services and implement dependency injection.

After completing this part, I put the patch for review, and there followed the next part- Use of Guzzle over curl in the services and injecting the httpClient service. I spent significant time learning the concept of Guzzle which was quite new for me. My mentors Naveen Valecha and Christian López Espínola helped me a lot to understand Guzzle, and subsequently this task was completed with Guzzle replacing curl and injection of httpClient. In addition, the present code made use of concatenated strings for sending the data during API call. I changed the code to make use of arrays and Json utility class and its static functions to send the data instead of strings. When the code seemed perfect, my mentors suggested me to perform clean up along with proper documentation.
At the end of the week, I successfully uploaded the patch with all the suggestions implemented, clean up done and documentation added, thereby completing the task for my first week.
May 23 2016
May 23
TL;DR I’ll be working on Integrating Google Cloud Vision API to Drupal 8 this summer as part of Google Summer of Code programme. During my community bonding period I got the chance to work with lots of grey shavers in drupal community.

I have been selected as one of the eleven students for the Google Summer of Code, who would be coding their summer away for Drupal. This summer I will be working on project Integrate Google Cloud Vision API to Drupal 8. The API detects objects ranging from animals to famous monuments and landmarks. Not only that, it supports the recognition of a wide range of famous logos/brands. Face detection, text detection within an image and safe searches are among the other features which this API provides. It is really cool for a Content Management System to have such a powerful feature, so I would be working this summer to implement this feature in Drupal.

Before jumping directly into the coding phase, the students selected for the Google Summer of Code, were given a month to bond with the community, their mentors and other friends with whom they share the same platform. This phase is known as “Community Bonding Period”, which lasted from April 23, 2016 to May 22, 2016.

Everyday brings up new opportunities to do something new, meet like-minded people across the globe, and contribute to awesomeness!! This is the simplest way in which I can put the "Community Bonding" period.

This is the ideal time when the students get closer to the community, interact with their mentors, learn more about the organization codebase and have a more detailed discussion on the project and its timelines before actually start the coding.

To mentor me through the project, I have been blessed with two experienced mentors- Naveen Valecha and Christian López Espínola. I have been discussing with them on the project, its execution and the tough areas for last few weeks. I was also guided to learn some basic methodologies, including the services and configuration management which would be of great help in my project. Meanwhile, I also devoted my time to the community by contributing in the core issues, providing suggestions, developing patches and reviewing the project applications, including Field Group Table Component and AddressField Copy of the newbies in the Drupal world, highlighting how can they develop it in a better way, and thus lightening the burden of the community as far as I could.

In this one month, I met a lot of like-minded across the globe who have gathered together to take the community to greater heights, and I felt myself lucky enough to get an opportunity to work with them. I tried developing good bonding with my mentors, being in touch with them and bringing to their notice all my actions and tracks. 
This I suppose is the most essential purpose of this one month pre-coding phase.

Here, I would also like to share a strange experience of mine during the community bonding period. During this phase, I came to know that the project on which I am working on, was already initiated by Eugene Ilyin. Here lies the bond strength of the Drupal Community. On having the discussion on this with Eugene, he not only agreed to let me work on the project, but has also agreed to mentor me on my project. It once again proved the awesomeness of the community, and how all of us come together, collaborate and help each other to grow as well as take the community to greater heights. This was all about my month of Community Bonding.

The month ends, and now we jump into coding the summer away.
Apr 30 2016
Apr 30
TL;DR My first contribution to Drupal was a small contributed module named Image CircleSlider. It had gone through different stages of examination by different reviewers, and during this process, I came to know about the work flow of a sandbox project to a full project.

Since the release of my first module Image Circle Slider, I have been asked this question at several instances that what did I do to get my module to be accepted.

So here I am discussing my experience of the first module I contributed. I was an intern at Innoraft Solutions Pvt. Ltd., where I came across this jQuery plugin, and was asked to implement it in Drupal. Though it was a very simple plugin, yet was an innovative one, and brought the images in a very modern way, instead of traditional sliding system. After developing the code of the module, I created it as sandbox project, and queued it to get it reviewed by the community. P.S. A useful tip in order to go to the top of the priority list- Take part in the review process yourself, and help others to get their review done. It earns a special tag to your project: "PAReview Bonus".  Drupal is a friendly community, and we here believe in joining hands and working, instead of the stiff competition which exists in today's world, and hence this review process. Once the reviewers start reviewing your project, they would be providing their valuable suggestions, and each step would take your project to its completion and acceptance. And when sufficient reviews have been done, and there would be no application blockers, it would be marked as "Reviewed and Tested by the Community", which the pre-final step and ultimately the git administrator would give you the access to release your project as Full Project. This is a one-time process, and once you have been given git access, you can directly release your projects, and give your service to the community. Another important point: I have seen many a times that the contributors gets restless during the process, and want to get it done within a single day. However, things does not go this way. Please be patient during the review process. These things does not happen overnight, and you need to be patient and coordinate with the community.

Hope this helps to all the new comers. Happy contributing!!

Mar 15 2016
Mar 15
TL;DR I'll be working on the project Integrate Google Cloud Vision API to Drupal 8 this summer as part of the Google Summer of Code programme. This API offers automated content analysis of the images, including landmark detection, logo detection, face detection, text detection in images among others.

The Google Summer of Code results are out!! And I have been one of those few students who have successfully been able to get their names on the list of selected students, who would be working for the next three months on the Open Source Projects.

Now, let me describe here the project and its applications.

Well, Google Cloud Vision API bring to picture the automated content analysis of the images. The API can not only detect objects ranging from animals to famous monuments, but also detects faces on emotions. In addition, the API can also help censor images, extract text from images, detect logos and landmarks, and even the attributes of the image itself, for instance the dominant color in the image.

What is so special about this project idea? This is the first question which comes in every mind regarding any GSOC project. So here is the answer. This feature has not been implemented in the Content Management Systems(CMS), and its integration in Drupal can give the users, a powerful tool which carries out automated content analysis of the images. Integration of this API would not only add to Drupal characteristics, but also would open up a new horizon for Drupal. Won't it be great if a CMS can detect logo of famous brands? Or some explicit contents not fit to be displayed? Or the detection of natural as well as artificial structures in an image? So, to summarize the aspects of Vision API, it offers the following features:
  1. Label Detection- It detects broad set of categories in an image, ranging from living animals to non-living places.
  2. Explicit Content Detection- Detects and notifies about adult or violent content within an image.
  3. Logo Detection- Detects the logos of popular brands.
  4. Landmark Detection- Detects natural as well as artificial structures within an image.
  5. Image Attributes- Detects general attributes of an image, such as dominant color and background shades.
  6. Optical Character Recognition(OCR)- Detects and extracts texts within an image. Vision API supports a broad range of languages along with the support for automatic language identification.
  7. Face Detection- Detects multiple faces within an image, along with associated key facial attributes like emotional state. However, it still does not embed the support of facial recognition.
  8. Integrated REST API- Access via REST API to request one or more annotation types per image.

For more details on Google Cloud Vision API, please have a look at Vision API 
Mar 09 2016
Mar 09

We just finished covering how simple configuration is still easy in Drupal 8, but how is Drupal 8 making the hard things possible in a way to justify changing the old variables API? Well, in Drupal 7, when you needed to handle complex configuration, the first step was ditching variable_get(), system_settings_form(), and related APIs. Drupal 8 has improved this situation two ways. First, you don’t have to throw out basic configuration code to handle complex needs. Second, more things are possible.

[Related] Managing Configuration in Code in Drupal 8

The goal of the Configuration Management Initiative was to maintain the declarative nature of configuration even when side-effects or cross-referenced validation are necessary. (Contrast with the Drupal 7 trick of using hook_update_N() as an imperative method.) Specifically, Drupal 8’s configuration management system operates under the perturbation model of constraint programming. That is, modules and core ship with defaults that work with each other, and configuration changes by a site owner create perturbations that either can be satisfied trivially (like the site front page path) or through propagating changes (described below). Sometimes, the constraints can’t be all satisfied, like deleting a field but also using it in a view; Drupal 8 helps here by making dry-run configuration tests possible. At least you can know before deploying to production!

Let’s go on a tour of hard problems in Drupal configuration management by walking through the use cases.

Subscriptions and Side-Effects

Often, configuration takes effect by simply changing the value. One example is the front page path for a site; nothing else needs to respond to make that configuration effective. In Drupal 7, these basic cases typically (and happily) used variables. Things got messy when a module needed to alter the database schema or similar systems to activate the configuration. Drupal 7 didn’t have a answer for this in core, though you could build on top of the Features module.

Anyway, in Drupal 8, side effects happen two ways. You should use the first when possible.

Subscribing

This is the modern and clean method of responding to configuration changes, regardless of whether the changes are to your module’s configuration or not. There are a number of configuration events you can receive. The most basic is ConfigEvents::SAVE, which fires on any change, whether created using the admin GUI, Drush, or a configuration import.

A good example of this approach in core is the system module’s cache tag system. It invalidates rendered cache items when the site theme changes; it does more than that, but we’ll be pulling the examples from there. The foundation for Drupal 8-style event listening is Symfony’s EventSubscriberInterface, which provides an object-oriented way to list the events of interest and set a callback. Drupal 7 developers should think of it like a non-alter hook.

The first step is getting the right files in the right places for the autoloader. You will need ConfigExample.php (assuming you name the class ConfigExample) and a example.services.yml (assuming your module name is “example”). You should end up with something like this, starting from the module root:

  • example/

    • example.info.yml (required for any module)

    • example.services.yml (example based on system.services.yml)

    • src/

      • EventSubscriber/

The second step is to register interest in the appropriate events from your class, which happens by implementing getSubscribedEvents() (which is the only member function required by the EventSubscriberInterface). The following code causes the member function onSave() to run whenever configuration gets saved:

 public static function getSubscribedEvents() {
    $events[ConfigEvents::SAVE][] = ['onSave'];
    return $events;
}
?>

Third, we need to implement the onSave() callback to invalidate the cache when the appropriate configuration keys change. If system.theme or system.theme.global changes, the code will call the appropriate function to invalidate the cache:

public function onSave(ConfigCrudEvent $event) {
    if (in_array($event->getConfig()->getName(), ['system.theme', 'system.theme.global'], TRUE)) {
         // Invalidate the cache here.
    }
 }
?>

The example above covers the intermediate “respond to a configuration change” use case. If you’d also like to validate configuration on import, you can see an example in SystemConfigSubscriber. It shows both subscribing to import events and stopping propagation on invalid input.

Using Hooks

This is where things get dirty; we’re now in hook_something_alter() territory. It’s hard to reason about things in this territory, but here we are anyway because it’s necessary for a handful of use cases. To be clear, you’re basically killing kittens when you re-jigger data the way an alter hook can. If you’re doing cleanup, I’d recommend queueing something into the batch system instead using the subscription method, even if your batch job has to attempt things and re-enqueue itself if other batch processing needs to finish first. Anyway, warning over. Here’s your example, shamelessly pulled from the API site. This gets the list of deleted configurations matching the key “field.storage.node.body.” If any exist, it adds a new function call to the end of the steps for propagating the configuration.

function example_config_import_steps_alter(&$sync_steps, \Drupal\Core\Config\ConfigImporter $config_importer) {
 $deletes = $config_importer->getUnprocessedConfiguration('delete');
 if (isset($deletes['field.storage.node.body'])) {
    $sync_steps[] = '_additional_configuration_step';
 }
}
?>

Settings Forms

In Drupal 7, have you ever saved a settings form and then gotten a page back with the old setting still in place (usually because something messed with $conf in settings.php)? Never again in Drupal 8! Configuration forms save to the pre-alteration values, and modules can read those “raw” values themselves through Config::getRawData() or ConfigFormBaseTrait::config() to provide custom forms.

However, if you just need a basic form, you can use pre-alteration values automatically with Drupal 8’s ConfigFormBase, which replaces system_settings_form() and seamlessly integrates with everything in Drupal 8’s configuration world from events to imports to version control.

A great example of ConfigFormBase use is in the system module’s LoggingForm.php.

Discovery and Multiple Objects for a Module

Need more than a (possibly nested), single configuration file for your module? If you provide something like views where there are multiple, independent configurations still owned by your module, you need Configuration Entities. These entities allow enforcing a schema, listing the individual configurations (which correspond one-to-one with YAML files). These entities are cleaner than the Drupal 7 approaches of spamming the variable namespace, creating a configuration table, or using some combination of ctools and Features.

Three-Way Merging

I don’t want to go into deep detail because there’s a great blog post on configuration merging already, but I will underscore the importance of three-way merging for configuration. Unless you have a completely linear flow with one development environment and no changes happening in test or live, there will be cases where configuration diverges both on the development branch and in production versus the last common revision. A three-way merge allows safely determining what changed on each side without the hazards of simply comparing development’s configuration to production’s (which can make additions on one side appear to be deletions on the other). You could kind of do this with Features, but the use of PHP arrays and other serialization made the committed configuration unfriendly to diff utilities. Drupal 8 uses canonicalized YAML output, which is both human- and diff-friendly.

Setting Dynamic Options with PHP

In the Style of settings.php

The biggest difference you’ll notice isn’t in settings.php but in the GUI. Values you coerce here will not appear in the GUI in Drupal 8 (for reasons mentioned in the Settings Forms section above). The following example is shamelessly pulled from the Amazee Labs post.

Drupal 7:

$conf['mail_system']['default-system'] = 'DevelMailLog';
?>

Drupal 8:

$config['system.mail']['interface']['default'] = 'devel_mail_log';
?>

In a Module

This is back into dirty territory because modules ought to provide higher-level ways of altering their behavior other than expecting other modules to hurriedly erase and change configuration values before the module reads them. If you must go down this path, you need to register the class performing the changes as a service under “config.factory.override” and implement ConfigFactoryOverrideInterface. This happens much as the service entry and class for subscribing happen above.

Configuration Lockdown

The most you could do in Drupal 7 was hard-code many variables in settings.php and periodically audit the site’s configuration with Features. With the transparently named Configuration Read-Only Mode module, you can actually prevent ad hoc changes in, say, your test or live environment. On Pantheon, for example, you could do the following to prevent configuration changes in the production environment:

if (defined('PANTHEON_ENVIRONMENT') && PANTHEON_ENVIRONMENT == 'live') {
    $settings['config_readonly'] = TRUE;
}

Bundling Related Configuration

This is still Features territory, actually more than ever. Contrary to rumors, Features is alive and well for Drupal 8. Relieved of the burden of extracting and applying configuration, Features is back to its original role of bundling functionality, most often in the form of configuration YAML to be imported by Drupal 8. So, in short, Features is now just for features.

Other Resources

The latest stack + the latest Drupal: See how Drupal 8 reaches its full potential on Pantheon

Topics Development, Drupal, Drupal Hosting, Drupal Planet

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web