Planet Drupal

Syndicate content
Drupal.org - aggregated feeds in category Planet Drupal
Updated: 4 min 14 sec ago

Tag1 Consulting: How to Maintain Contrib Modules for Drupal and Backdrop at the Same Time - Part 2

Tue, 02/17/2015 - 17:00
pThis is the second in a series of blog posts about the relationship between Drupal and a href=https://backdropcms.org/Backdrop CMS/a, a recently-released fork of Drupal. The goal of the series is to explain how a module (or theme) developer can take a Drupal project they currently maintain and support it for Backdrop as well, while keeping duplicate work to a minimum./p ul /ulpa href=http://tag1consulting.com/blog/how-maintain-contrib-modules-drupal-and-backdrop-same-time-part-2 target=_blankread more/a/p

Clemens Tolboom: Delete and edit comments on closed node

Tue, 02/17/2015 - 16:29
div class=field field-name-field-images field-type-image field-label-hiddendiv class=field-itemsdiv class=field-item evena href=/content/delete-and-edit-comments-closed-nodeimg src=http://build2be.com/sites/build2be.com/files/styles/medium/public/node-closed-comment-delete.png?itok=6fRZV3_y width=220 height=69 alt=Node closed comment delete title=Node closed comment delete //a/div/div/divdiv class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item evenpHaving a forum you needs quick deletions of improper comments./p pIn Drupal 7 and Drupal 8 you have to visit admin/content/comments to do so. But then you loose the thread./p pYou could review and use this a href=https://www.drupal.org/node/2427995patch/a or add this to your custom module. The first needs review and testing. The later needs a Drupal coder./p/div/div/div

Drupal Commerce: Using OpenID Connect for Single Sign-On with Drupal

Tue, 02/17/2015 - 16:03
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedpAt Commerce Guys we provide a varied range of a href=https://commerceguys.com/what-we-do/professional-servicesservices/a, including our cloud PaaS a href=https://platform.shPlatform.sh/a, this a href=/Drupal Commerce/a community website, support, and the a href=https://marketplace.commerceguys.comCommerce Marketplace/a./p pOur users may need to log in to any of these services, and sometimes several at the same time. So we needed to have a shared authentication system, a way of synchronizing user accounts, and single sign-on (SSO) functionality./p pAfter a lot of research on the existing methods, such as CAS, we found that there was no generic open-source solution which would cover all of our current needs and would also allow us to grow and scale in the future when adding new features or applications./p pWe decided to implement the OAuth 2.0 and OpenID Connect protocols, which were designed to be flexible, yet simple and standardized - exactly what we wanted./p/div/div/div

Drupal @ Penn State: Autopost to Facebook

Tue, 02/17/2015 - 15:15
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedpI ran into an issue with the Drupal for Facebook module, both for D6 and D7, where I wanted articles to auomatically be posted to Facebook when they are submitted.  There appeared to be no way to do this via the module and I had played around with Rules to see if that would work, but no luck./p/div/div/div

Colan Schwartz: Integrating remote data into Drupal 7 and exposing it to Views

Mon, 02/16/2015 - 20:45
section class=field field-name-field-blog-topics field-type-taxonomy-term-reference field-label-inline clearfix view-mode-rss clearfix h2 class=field-labelTopics:nbsp;/h2 ul class=field-items li class=field-item even rel=schema:keywords a href=/blog-topics/drupal-planet typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=Drupal Planet/a /li li class=field-item odd rel=schema:keywords a href=/blog-topics/drupal-7 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=Drupal 7/a /li li class=field-item even rel=schema:keywords a href=/blog-topics/web-services typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=Web Services/a /li li class=field-item odd rel=schema:keywords a href=/blog-topics/structured-content typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=Structured Content/a /li /ul /section div class=field field-name-field-body field-type-text-long field-label-hidden view-mode-rssdiv class=field-itemsdiv class=field-item even property=schema:articleBodypDrupal's strength as a content management framework is in its ability to effectively manage and display structured content through its Web user interface. However, the out-of-the-box system assumes all data is local (stored in the database). This can present challenges when attempting to integrate remote data stored in other systems. You cannot, by default, display non-local records as pages. While setting this up is in itself a challenge, it is an even bigger challenge to manipulate, aggregate and display this data through a href=https://www.drupal.org/project/viewsViews/a./p pI've split this article into the following sections and subsections. Click on any of these to jump directly to the one of them./p ollia href=#introIntroduction/a/li lia href=#recent-changesWhat's Changed/a/li li a href=#architectureArchitecture/a ol type=ali a href=#remote-entity-definitionRemote entity definition/a ullia href=#remote-entity-definition-notesNotes/a/li /ul/li lia href=#access-to-remote-propertiesAccess to remote properties/a/li li a href=#remote-property-definitionRemote property definition/a ullia href=#remote-property-definition-notesNotes/a/li /ul/li lia href=#entity-instances-as-web-pagesEntity instances as Web pages/a/li lia href=#web-services-integrationWeb services integration/a/li lia href=#temporary-local-storageTemporary local storage/a/li li a href=#implementing-the-remote-connection-classImplementing the remote connection class/a ullia href=#clients-remote-entity-interface-implementationsClientsRemoteEntityInterface implementations/a/li lia href=#clients-connection-base-overridesParent overrides/a/li lia href=#local-methodsLocal methods/a/li /ul/li li a href=#implementing-the-remote-query-classImplementing the remote query class/a ullia href=#class-variables-and-constructorClass variables and constructor/a/li lia href=#setting-conditionsSetting conditions/a/li lia href=#executing-the-remote-queryExecuting the remote query/a/li lia href=#unmarshalling-the-response-data-and-returning-itUnmarshalling the response data and returning it/a/li lia href=#error-handlingError handling/a/li /ul/li /ol/li li a href=#views-supportViews support/a ol type=alia href=#views-basic-set-upBasic set-up/a/li lia href=#converting-from-an-efqConverting from an EntityFieldQuery/a/li /ol/li lia href=#alternativesAlternatives/a/li lia href=#referencesReferences/a/li /olhr /h2a name=intro id=introIntroduction/a/h2 pThis exposition is effectively a follow-up to some excellent articles from years past:/p ulliLarry Garfield's a href=http://www.palantir.net/blog/remote-data-drupal-museums-and-web-2009Remote Data in Drupal: Museums and the Web (2009)/a/li liFlorian Loretan's a href=http://www.wunderkraut.com/blog/remote-entities-in-drupal-7/2012-10-25Remote entities in Drupal 7 (2012)/a/li /ulpI'd recommend reading them for background information./p pThe first article (written in the Drupal 6 days) describes a Wipe/rebuild import method (Method 3) to bring remote data into Drupal. That's basically what we'll be discussing here, but there is now a standard method for doing so. What's interesting is that future plans mentioned there included a href=https://www.drupal.org/node/443422per-field storage engines/a (with some being remote). The idea never made it very far. This is most likely because grabbing field data from multiple locations is far too inefficient (multiple Web-service calls) compared to fetching an entire record from a single location./p pTaking a look at the second article, you can now see that Drupal 7 is dominant, and we have more tools at our disposal, but at the time this one was written, we still didn't have all of them in place. We did, however, have the following APIs for dealing with a href=https://www.drupal.org/node/1261744entities/a./p ollia href=https://api.drupal.org/api/drupal/includes%21entity.inc/7The entity API in Drupal Core/a/li lia href=https://www.drupal.org/project/entityThe Entity API contributed module/a/li /olh2a name=recent-changes id=recent-changesWhat's Changed/a/h2 pWe now have another API, the a href=https://www.drupal.org/project/remote_entityRemote Entity API/a, which was inspired by Florian's article. As you can imagine, this API is dependent on the Entity API which is in turn dependent on the Drupal Core's entity functionality./p pI recently added a href=https://www.drupal.org/node/2283083support for this new API/a to a href=https://www.drupal.org/project/efq_viewsEntityFieldQuery Views Backend/a, the module allowing Views to work with data stored outside of the local SQL database. Previously, it supported non-SQL data, but still assumed that this data was local. Tying these two components together gives us what we need to achieve our goal./p h2a name=architecture id=architectureArchitecture/a/h2 pSo we really need to take advantage of the three (3) entity APIs to load and display individual remote records./p ollia href=https://api.drupal.org/api/drupal/includes%21entity.inc/7The entity API in Drupal Core/a/li lia href=https://www.drupal.org/project/entityThe Entity API contributed module/a/li lia href=https://www.drupal.org/project/remote_entityThe Remote Entity API contributed module/a/li /olpThe first provides basic entity functionality in Drupal. The second adds enhanced functionality for custom entities. The third and final API adds additional handling mechanisms for working with any remote data. /ppWe'll need the following contributed modules to make all of this work./p ullia href=https://www.drupal.org/project/ctoolsChaos tool suite (ctools)/a/li lia href=https://www.drupal.org/project/entityEntity API/a/li lia href=https://www.drupal.org/project/clientsWeb Service Clients/a/li lia href=https://www.drupal.org/project/remote_entityRemote Entity API/a/li lia href=https://www.drupal.org/project/viewsViews/a/li lia href=https://www.drupal.org/project/efq_viewsEntityFieldQuery Views Backend/a/li /ulpIn addition to the above, a new custom module is necessary. I recommend something like emsiteshortname_entities_remote/em for the machine name. You can have another one, emsiteshortname_entities_local/em, for local entities without all of the remote code if necessary. In the em.info/em file, add emremote_entity/em (the Remote Entity API) as a dependency./p pYou'll want to divide your module file into at least three (3) parts:/p ollistrongEntity APIs:/strong Code for defining remote entities through any of the above entity APIs. (Part I)/li listrongDrupal Core:/strong Code for implementing Drupal Core hooks. This is basically a a href=https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_menu/7hook_menu()/a implementation with some helper functions to get your entity instances to show up at specific paths based on the remote entity IDs. (Part II)/li listrongWeb Service Clients:/strong Code for implementing what's necessary for the a href=https://www.drupal.org/project/clientsWeb Service Clients/a module, a prerequisite for the Remote Entity API. It's essentially the external communications component for accessing your remote data. (Part III)/li /olpMost of the code will be in PHP class files you'll want in a emclasses/em subdirectory (autoloaded by defining these in your em.info/em file), but you'll still need some code in your main module file./p pWe'll be adding only one new entity in this exercise, but the code is extensible enough to allow for more. Once one of these is set up, adding more is (in most cases) trivial./p h3a name=remote-entity-definition id=remote-entity-definitionRemote entity definition/a/h3 pYour basic remote entity definitions will exist in the Entity APIs section of your module file, Part I. Within the a href=https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_entity_info/7hook_entity_info()/a implementation, you'll see that different properties within the definition will be used by different layers, the three APIs./p pFor the following examples, let's assume we have a remote emevent/em data type./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr //spanspan style=color: #FF8000/****************************************************************************br / ** Entity APIsbr / ****************************************************************************/br /br //**br / * Implements hook_entity_info().br / *br / * @todo Add 'bundles' for different types of remote content.br / * @todo Add 'entity keys' =gt; 'needs remote save' if remote saving required.br / * @todo Remove 'static cache' and 'field cache' settings after development.br / */br //spanspan style=color: #007700function /spanspan style=color: #0000BBsiteshortname_entities_remote_entity_info/spanspan style=color: #007700() {br /  /spanspan style=color: #0000BB$entities/spanspan style=color: #007700[/spanspan style=color: #DD0000'siteshortname_entities_remote_event'/spanspan style=color: #007700] = array(br /br /    /spanspan style=color: #FF8000// Core properties.br /    /spanspan style=color: #DD0000'label' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BBt/spanspan style=color: #007700(/spanspan style=color: #DD0000'Event'/spanspan style=color: #007700),br /    /spanspan style=color: #DD0000'controller class' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'RemoteEntityAPIDefaultController'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'base table' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'siteshortname_entities_remote_events'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'uri callback' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'entity_class_uri'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'label callback' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'remote_entity_entity_label'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'fieldable' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BBFALSE/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'entity keys' /spanspan style=color: #007700=gt; array(br /      /spanspan style=color: #DD0000'id' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'eid'/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'label' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'event_name'/spanspan style=color: #007700,br /    ),br /    /spanspan style=color: #DD0000'view modes' /spanspan style=color: #007700=gt; array(br /      /spanspan style=color: #DD0000'full' /spanspan style=color: #007700=gt; array(br /        /spanspan style=color: #DD0000'label' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BBt/spanspan style=color: #007700(/spanspan style=color: #DD0000'Full content'/spanspan style=color: #007700),br /        /spanspan style=color: #DD0000'custom settings' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BBFALSE/spanspan style=color: #007700,br /      ),br /    ),br /    /spanspan style=color: #DD0000'static cache' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BBFALSE/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'field cache' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BBFALSE/spanspan style=color: #007700,br /br /    /spanspan style=color: #FF8000// Entity API properties.br /    /spanspan style=color: #DD0000'entity class' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'SiteshortnameEvent'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'module' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'siteshortname_entities_remote'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'metadata controller class' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'RemoteEntityAPIDefaultMetadataController'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'views controller class' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'EntityDefaultViewsController'/spanspan style=color: #007700,br /br /    /spanspan style=color: #FF8000// Remote Entity API properties.br /    /spanspan style=color: #DD0000'remote base table' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'siteshortname_entities_remote_events'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'remote entity keys' /spanspan style=color: #007700=gt; array(br /      /spanspan style=color: #DD0000'remote id' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'event_id'/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'label' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'event_name'/spanspan style=color: #007700,br /    ),br /    /spanspan style=color: #DD0000'expiry' /spanspan style=color: #007700=gt; array(br /      /spanspan style=color: #FF8000// Number of seconds before a locally cached instance must be refreshedbr /      // from the remote source.br /      /spanspan style=color: #DD0000'expiry time' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB600/spanspan style=color: #007700,br /      /spanspan style=color: #FF8000// A boolean indicating whether or not to delete expired local entitiesbr /      // on cron.br /      /spanspan style=color: #DD0000'purge' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BBFALSE/spanspan style=color: #007700,br /    ),br /  );br /br /  /spanspan style=color: #FF8000// Get the property map data.br /  /spanspan style=color: #0000BB$remote_properties /spanspan style=color: #007700= /spanspan style=color: #0000BBsiteshortname_entities_remote_get_remote_properties/spanspan style=color: #007700();br /br /  /spanspan style=color: #FF8000// Assign each map to its corresponding entity.br /  /spanspan style=color: #007700foreach (/spanspan style=color: #0000BB$entities /spanspan style=color: #007700as /spanspan style=color: #0000BB$key /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$einfo/spanspan style=color: #007700) {br /    /spanspan style=color: #0000BB$entities/spanspan style=color: #007700[/spanspan style=color: #0000BB$key/spanspan style=color: #007700][/spanspan style=color: #DD0000'property map'/spanspan style=color: #007700] =br /      /spanspan style=color: #0000BBdrupal_map_assoc/spanspan style=color: #007700(/spanspan style=color: #0000BBarray_keys/spanspan style=color: #007700(/spanspan style=color: #0000BB$remote_properties/spanspan style=color: #007700[/spanspan style=color: #0000BB$key/spanspan style=color: #007700]));br /  }br /br /  /spanspan style=color: #FF8000// Return all of the entity information.br /  /spanspan style=color: #007700return /spanspan style=color: #0000BB$entities/spanspan style=color: #007700;br /}br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /h4a name=remote-entity-definition-notes id=remote-entity-definition-notesNotes/a/h4 olliJust like the entity type emnode/em, which is subdivided into emcontent types/em (generically referred to as embundles/em in Drupal-speak), we can subdivide remote entities into their own bundles. In this case, we could have a High-school event bundle and a College event bundle that vary slightly, but instances of both would still be members of the entity type Event. We won't be setting this up here though./li liIn this article, we won't be covering remote saving (only remote loading), but it is possible through the remote API./li liMake sure to adjust the cache settings properly once development is complete./li liDetailed documentation on the APIs is available for a href=https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_entity_info/7the Core entity API/a, a href=http://cgit.drupalcode.org/entity/tree/entity.api.phpthe Entity API/a, and the a href=http://cgit.drupalcode.org/remote_entity/tree/remote_entity.api.phpthe Remote Entity API/a./li /olh3a name=access-to-remote-properties id=access-to-remote-propertiesAccess to remote properties/a/h3 pAs we're not using the a href=https://api.drupal.org/api/drupal/modules!field!field.module/group/field/7Field API/a to attach information to our entities, we need to do it with properties. The code below exposes the data we'll define shortly./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr //spanspan style=color: #FF8000/**br / * Implements hook_entity_property_info_alter().br / *br / * This is needed to use wrappers to access the remote entitybr / * data in the entity_data property of remote entities.br / *br / * @see: Page 107 of the Programming Drupal 7 Entities book.  The code below isbr / *   a variation on it.br / * @todo: Remove whenever this gets added to the remote_entity module.br / */br //spanspan style=color: #007700function /spanspan style=color: #0000BBsiteshortname_entities_remote_entity_property_info_alter/spanspan style=color: #007700(amp;/spanspan style=color: #0000BB$info/spanspan style=color: #007700) {br /br /  /spanspan style=color: #FF8000// Set the entity types and get their properties.br /  /spanspan style=color: #0000BB$entity_types /spanspan style=color: #007700= array(br /    /spanspan style=color: #DD0000'siteshortname_entities_remote_event'/spanspan style=color: #007700,br /  );br /br /  /spanspan style=color: #0000BB$remote_properties /spanspan style=color: #007700= /spanspan style=color: #0000BBsiteshortname_entities_remote_get_remote_properties/spanspan style=color: #007700();br /br /  /spanspan style=color: #FF8000// Assign the property data to each entity.br /  /spanspan style=color: #007700foreach (/spanspan style=color: #0000BB$entity_types /spanspan style=color: #007700as /spanspan style=color: #0000BB$entity_type/spanspan style=color: #007700) {br /    /spanspan style=color: #0000BB$properties /spanspan style=color: #007700= amp;/spanspan style=color: #0000BB$info/spanspan style=color: #007700[/spanspan style=color: #0000BB$entity_type/spanspan style=color: #007700][/spanspan style=color: #DD0000'properties'/spanspan style=color: #007700];br /    /spanspan style=color: #0000BB$entity_data /spanspan style=color: #007700= amp;/spanspan style=color: #0000BB$properties/spanspan style=color: #007700[/spanspan style=color: #DD0000'entity_data'/spanspan style=color: #007700];br /    /spanspan style=color: #0000BB$pp /spanspan style=color: #007700= amp;/spanspan style=color: #0000BB$remote_properties/spanspan style=color: #007700[/spanspan style=color: #0000BB$entity_type/spanspan style=color: #007700];br /    /spanspan style=color: #0000BB$entity_data/spanspan style=color: #007700[/spanspan style=color: #DD0000'type'/spanspan style=color: #007700] = /spanspan style=color: #DD0000'remote_entity_' /spanspan style=color: #007700. /spanspan style=color: #0000BB$entity_type/spanspan style=color: #007700;br /br /    /spanspan style=color: #FF8000// Set the default getter callback for each property.br /    /spanspan style=color: #007700foreach (/spanspan style=color: #0000BB$pp /spanspan style=color: #007700as /spanspan style=color: #0000BB$key /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$pinfo/spanspan style=color: #007700) {br /      /spanspan style=color: #0000BB$pp/spanspan style=color: #007700[/spanspan style=color: #0000BB$key/spanspan style=color: #007700][/spanspan style=color: #DD0000'getter callback'/spanspan style=color: #007700] = /spanspan style=color: #DD0000'entity_property_verbatim_get'/spanspan style=color: #007700;br /    }br /br /    /spanspan style=color: #FF8000// Assign the updated property info to the entity info.br /    /spanspan style=color: #0000BB$entity_data/spanspan style=color: #007700[/spanspan style=color: #DD0000'property info'/spanspan style=color: #007700] = /spanspan style=color: #0000BB$pp/spanspan style=color: #007700;br /  }br /}br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /h3a name=remote-property-definition id=remote-property-definitionRemote property definition/a/h3 pThis is where we define the field (or in this case property) information, the data attached to each entity, that we exposed above./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr //spanspan style=color: #FF8000/**br / * Get remote property information for remote entities.br / *br / * @returnbr / *   An array of property information keyed by entity type.br / */br //spanspan style=color: #007700function /spanspan style=color: #0000BBsiteshortname_entities_remote_get_remote_properties/spanspan style=color: #007700() {br /br /  /spanspan style=color: #FF8000// Initialize a list of entity properties.br /  /spanspan style=color: #0000BB$properties /spanspan style=color: #007700= array();br /br /  /spanspan style=color: #FF8000// Define properties for the entity type.br /  /spanspan style=color: #0000BB$properties/spanspan style=color: #007700[/spanspan style=color: #DD0000'siteshortname_entities_remote_event'/spanspan style=color: #007700] = array(br /br /    /spanspan style=color: #FF8000// Event information.br /    /spanspan style=color: #DD0000'event_id' /spanspan style=color: #007700=gt; array(br /      /spanspan style=color: #DD0000'label' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'Remote Event ID'/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'type' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'integer'/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'description' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'The remote attribute id.'/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'views' /spanspan style=color: #007700=gt; array(br /        /spanspan style=color: #DD0000'filter' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'siteshortname_entities_remote_views_handler_filter_event_id'/spanspan style=color: #007700,br /      ),br /    ),br /    /spanspan style=color: #DD0000'event_date' /spanspan style=color: #007700=gt; array(br /      /spanspan style=color: #DD0000'label' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'Date'/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'type' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'date'/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'description' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'The remote attribute date.'/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'views' /spanspan style=color: #007700=gt; array(br /        /spanspan style=color: #DD0000'filter' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'siteshortname_entities_remote_views_handler_filter_event_date'/spanspan style=color: #007700,br /      ),br /    ),br /    /spanspan style=color: #DD0000'event_details' /spanspan style=color: #007700=gt; array(br /      /spanspan style=color: #DD0000'label' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'Details'/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'type' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'text'/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'description' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'The remote attribute details.'/spanspan style=color: #007700,br /    ),br /  );br /br /  /spanspan style=color: #FF8000// Return all of the defined property info.br /  /spanspan style=color: #007700return /spanspan style=color: #0000BB$properties/spanspan style=color: #007700;br /}br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /h4a name=remote-property-definition-notes id=remote-property-definition-notesNotes/a/h4 olliTry to remember the distinction between local and remote entity IDs. At the moment, we're only interested in emremote/em properties so we don't don't need to worry about local IDs just yet./li liDon't worry too much about the Views filters. These are Views filter handler classes. They're only necessary if you'd like custom filters for the respective properties./li /olh3a name=entity-instances-as-web-pages id=entity-instances-as-web-pagesEntity instances as Web pages/a/h3 pThis starts the Core Hooks section of the module file, Part II. In this section, we're providing each remote data instance as a Web page just like standard local content within Drupal via emnodes/em./pp /ppThe a href=https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_menu/7hook_menu()/a implementation responds to hits to the emevent/EVENT_ID/em path, loads the object, themes all of the data, and then returns it for display as a page. We're assuming all of your HTML output will be in a template in the emincludes/siteshortname_entities_remote.theme.inc/em file in your module's directory./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr //spanspan style=color: #FF8000/****************************************************************************br / ** Drupal Corebr / ****************************************************************************/br /br //**br / * Implements hook_menu().br / */br //spanspan style=color: #007700function /spanspan style=color: #0000BBsiteshortname_entities_remote_menu/spanspan style=color: #007700() {br /  /spanspan style=color: #0000BB$items /spanspan style=color: #007700= array();br /br /  /spanspan style=color: #0000BB$items/spanspan style=color: #007700[/spanspan style=color: #DD0000'event/%siteshortname_entities_remote_event'/spanspan style=color: #007700] = array(br /    /spanspan style=color: #DD0000'title' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'Remote Event'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'page callback' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'siteshortname_entities_remote_event_view'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'page arguments' /spanspan style=color: #007700=gt; array(/spanspan style=color: #0000BB1/spanspan style=color: #007700),br /    /spanspan style=color: #DD0000'access arguments' /spanspan style=color: #007700=gt; array(/spanspan style=color: #DD0000'access content'/spanspan style=color: #007700),br /  );br /br /  return /spanspan style=color: #0000BB$items/spanspan style=color: #007700;br /}br /br //spanspan style=color: #FF8000/**br / * Menu autoloader wildcard for path 'event/REMOTE_ID'.br / *br / * @see hook_menu() documentation.br / * @param $remote_idbr / *   The remote ID of the record to load.br / * @returnbr / *   The loaded object, or FALSE on failure.br / */br //spanspan style=color: #007700function /spanspan style=color: #0000BBsiteshortname_entities_remote_event_load/spanspan style=color: #007700(/spanspan style=color: #0000BB$remote_id/spanspan style=color: #007700) {br /  return /spanspan style=color: #0000BBremote_entity_load_by_remote_id/spanspan style=color: #007700(/spanspan style=color: #DD0000'siteshortname_entities_remote_event'/spanspan style=color: #007700, /spanspan style=color: #0000BB$remote_id/spanspan style=color: #007700);br /}br /br //spanspan style=color: #FF8000/**br / * Page callback for path 'event/%remote_id'.br / *br / * @param $eventbr / *   The auto-loaded object.br / * @returnbr / *   The themed output for the event page.br / */br //spanspan style=color: #007700function /spanspan style=color: #0000BBsiteshortname_entities_remote_event_view/spanspan style=color: #007700(/spanspan style=color: #0000BB$event/spanspan style=color: #007700) {br /  /spanspan style=color: #0000BB$fullname /spanspan style=color: #007700= /spanspan style=color: #0000BB$event/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBname/spanspan style=color: #007700;br /  /spanspan style=color: #0000BBdrupal_set_title/spanspan style=color: #007700(/spanspan style=color: #0000BB$fullname/spanspan style=color: #007700);br /  /spanspan style=color: #0000BB$event_output /spanspan style=color: #007700= /spanspan style=color: #0000BBtheme/spanspan style=color: #007700(/spanspan style=color: #DD0000'siteshortname_entities_remote_event'/spanspan style=color: #007700, array(br /    /spanspan style=color: #DD0000'event' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$event/spanspan style=color: #007700,br /  ));br /  return /spanspan style=color: #0000BB$event_output/spanspan style=color: #007700;br /}br /br //spanspan style=color: #FF8000/**br / * Implements hook_theme().br / */br //spanspan style=color: #007700function /spanspan style=color: #0000BBsiteshortname_entities_remote_theme/spanspan style=color: #007700() {br /  return array(br /    /spanspan style=color: #DD0000'siteshortname_entities_remote_event' /spanspan style=color: #007700=gt; array(br /      /spanspan style=color: #DD0000'variables' /spanspan style=color: #007700=gt; array(/spanspan style=color: #DD0000'event' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BBNULL/spanspan style=color: #007700),br /      /spanspan style=color: #DD0000'file' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'includes/siteshortname_entities_remote.theme.inc'/spanspan style=color: #007700,br /    ),br /  );br /}br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /pThere's one more thing to do here. In our emhook_entity_info()/em implementation, we stated the following:/p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr /    /spanspan style=color: #DD0000'entity class' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'SiteshortnameEvent'/spanspan style=color: #007700,br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /pWe could have used emEntity/em here instead of emSiteshortnameEvent/em, but we want a custom class here so that we can override the URL path for these entities. So add the following class:/p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr //spanspan style=color: #007700class /spanspan style=color: #0000BBSiteshortnameEvent /spanspan style=color: #007700extends /spanspan style=color: #0000BBEntity /spanspan style=color: #007700{br /  /spanspan style=color: #FF8000/**br /   * Override defaultUri().br /   */br /  /spanspan style=color: #007700protected function /spanspan style=color: #0000BBdefaultUri/spanspan style=color: #007700() {br /    return array(/spanspan style=color: #DD0000'path' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'event/' /spanspan style=color: #007700. /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBremote_id/spanspan style=color: #007700);br /  }br /} br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /h3a name=web-services-integration id=web-services-integrationWeb services integration/a/h3 We're now onto Part III, setting up Web-service endpoints and associating remote resources with entities. This is done through the implementation of a few a href=https://www.drupal.org/project/clientsWeb Service Clients/a hooks. div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr //spanspan style=color: #FF8000/****************************************************************************br / ** Web Service Clientsbr / ****************************************************************************/br /br //**br / * Implements hook_clients_connection_type_info().br / */br //spanspan style=color: #007700function /spanspan style=color: #0000BBsiteshortname_entities_remote_clients_connection_type_info/spanspan style=color: #007700() {br /  return array(br /    /spanspan style=color: #DD0000'our_rest' /spanspan style=color: #007700=gt; array(br /      /spanspan style=color: #DD0000'label'  /spanspan style=color: #007700=gt; /spanspan style=color: #0000BBt/spanspan style=color: #007700(/spanspan style=color: #DD0000'REST Data Services'/spanspan style=color: #007700),br /      /spanspan style=color: #DD0000'description' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BBt/spanspan style=color: #007700(/spanspan style=color: #DD0000'Connects to our data service using REST endpoints.'/spanspan style=color: #007700),br /      /spanspan style=color: #DD0000'tests' /spanspan style=color: #007700=gt; array(br /        /spanspan style=color: #DD0000'event_retrieve_raw' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'SiteshortnameEntitiesRemoteConnectionTestEventRetrieveRaw'/spanspan style=color: #007700,br /      ),br /      /spanspan style=color: #DD0000'interfaces' /spanspan style=color: #007700=gt; array(br /        /spanspan style=color: #DD0000'ClientsRemoteEntityInterface'/spanspan style=color: #007700,br /      ),br /    ),br /  );br /}br /br //spanspan style=color: #FF8000/**br / * Implements hook_clients_default_connections().br / */br //spanspan style=color: #007700function /spanspan style=color: #0000BBsiteshortname_entities_remote_clients_default_connections/spanspan style=color: #007700() {br /br /  /spanspan style=color: #0000BB$connections/spanspan style=color: #007700[/spanspan style=color: #DD0000'my_rest_connection'/spanspan style=color: #007700] = new /spanspan style=color: #0000BBclients_connection_our_rest/spanspan style=color: #007700(array(br /    /spanspan style=color: #DD0000'endpoint' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'https://data.example.com'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'configuration' /spanspan style=color: #007700=gt; array(br /      /spanspan style=color: #DD0000'username' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000''/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'password' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000''/spanspan style=color: #007700,br /    ),br /    /spanspan style=color: #DD0000'label' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'Our REST Service'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'type' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'our_rest'/spanspan style=color: #007700,br /  ), /spanspan style=color: #DD0000'clients_connection'/spanspan style=color: #007700);br /br /  return /spanspan style=color: #0000BB$connections/spanspan style=color: #007700;br /}br /br //spanspan style=color: #FF8000/**br / * Implements hook_clients_default_resources().br / */br //spanspan style=color: #007700function /spanspan style=color: #0000BBsiteshortname_entities_remote_clients_default_resources/spanspan style=color: #007700() {br /  /spanspan style=color: #0000BB$resources/spanspan style=color: #007700[/spanspan style=color: #DD0000'siteshortname_entities_remote_event'/spanspan style=color: #007700] = new /spanspan style=color: #0000BBclients_resource_remote_entity/spanspan style=color: #007700(array(br /    /spanspan style=color: #DD0000'component' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'siteshortname_entities_remote_event'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'connection' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'my_rest_connection'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'label' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'Resource for remote events'/spanspan style=color: #007700,br /    /spanspan style=color: #DD0000'type' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'remote_entity'/spanspan style=color: #007700,br /  ), /spanspan style=color: #DD0000'clients_resource'/spanspan style=color: #007700);br /br /  return /spanspan style=color: #0000BB$resources/spanspan style=color: #007700;br /}br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /pIn the first function, we're adding metadata for the connection. In the second one, we're setting the endpoint and its credentials. The third function is what ties our remote entity, defined earlier, with the remote resource. There's some information on this a href=https://www.drupal.org/node/1228830documentation page/a, but there's more in the a href=http://cgit.drupalcode.org/clients/tree/README.txtREADME file/a./p h3a name=temporary-local-storage id=temporary-local-storageTemporary local storage/a/h3 pWe'll need to store the remote data in a local table as a non-authoritative cache. The frequency with which it gets refreshed is up to you, as described earlier in this article. We'll need one table per entity. The good news is that we don't need to worry about the details; this is handled by the Remote Entity API. It provides a function returning the default schema. If you want to do anything different here, you are welcome to define your own./p pThe argument provided in the call is used for the table description as The base table for em[whatever you provide]/em. This will go in your emsiteshortname_entities_remote.install/em file./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr //spanspan style=color: #FF8000/**br / * Implementation of hook_schema().br / */br //spanspan style=color: #007700function /spanspan style=color: #0000BBsiteshortname_entities_remote_schema/spanspan style=color: #007700() {br /  /spanspan style=color: #0000BB$schema /spanspan style=color: #007700= array(br /    /spanspan style=color: #DD0000'siteshortname_entities_remote_events' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BBremote_entity_schema_table/spanspan style=color: #007700(/spanspan style=color: #DD0000'our remote event entity type'/spanspan style=color: #007700),br /  );br /br /  return /spanspan style=color: #0000BB$schema/spanspan style=color: #007700;br /}br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /pIf you don't actually want to save one or more of your remote entities locally (say because you have private data you'd rather not have stored on your publicly-accessible Web servers), you can alter this default behaviour by defining your own controller which overrides the emsave()/em method./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr //spanspan style=color: #FF8000/**br / * Entity controller extending RemoteEntityAPIDefaultControllerbr / *br / * For most of our cases the default controller is fine, but we can usebr / * this one for entities we don't want stored locally.  Override the savebr / * behaviour and do not keep a local cached copy.br / */br //spanspan style=color: #007700class /spanspan style=color: #0000BBSiteshortnameEntitiesRemoteNoLocalAPIController /spanspan style=color: #007700extends /spanspan style=color: #0000BBRemoteEntityAPIDefaultController /spanspan style=color: #007700{br /br /  /spanspan style=color: #FF8000/**br /   * Don't actually save anything.br /   */br /  /spanspan style=color: #007700public function /spanspan style=color: #0000BBsave/spanspan style=color: #007700(/spanspan style=color: #0000BB$entity/spanspan style=color: #007700, /spanspan style=color: #0000BBDatabaseTransaction $transaction /spanspan style=color: #007700= /spanspan style=color: #0000BBNULL/spanspan style=color: #007700) {br /    /spanspan style=color: #0000BB$entity/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBeid /spanspan style=color: #007700= /spanspan style=color: #0000BBuniqid/spanspan style=color: #007700();br /  }br /}br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /h3a name=implementing-the-remote-connection-class id=implementing-the-remote-connection-classImplementing the remote connection class/a/h3 pCreate a file for the connection class./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr //spanspan style=color: #FF8000/**br / * @filebr / * Contains the clients_connection_our_rest class.br / */br /br //**br / * Set up a client connection to our REST services.br / *br / *  @todo Make private functions private once development is done.br / */br //spanspan style=color: #007700class /spanspan style=color: #0000BBclients_connection_our_rest /spanspan style=color: #007700extends /spanspan style=color: #0000BBclients_connection_basebr /  /spanspan style=color: #007700implements /spanspan style=color: #0000BBClientsConnectionAdminUIInterface/spanspan style=color: #007700, /spanspan style=color: #0000BBClientsRemoteEntityInterface /spanspan style=color: #007700{br /br /}br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /pWe'll now divide the contents of said file into three (3) sections, emClientsRemoteEntityInterface/em implementations, emclients_connection_base/em overrides and local methods./p h4a name=clients-remote-entity-interface-implementations id=clients-remote-entity-interface-implementationsClientsRemoteEntityInterface implementations/a/h4 pAs you can see below, we've got three (3) methods here./p ulliemremote_entity_load()/em will load a remote entity with the provided remote ID./li liementity_property_type_map()/em is supposedly required to map remote properties to local ones, but it wasn't clear to me how this gets used./li liemgetRemoteEntityQuery()/em returns a query object, either a select, insert or update based on whichever one was requested./li /uldiv class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr /  /spanspan style=color: #FF8000/**************************************************************************br /   * ClientsRemoteEntityInterface implementations.br /   **************************************************************************/br /br /  /**br /   * Load a remote entity.br /   *br /   * @param $entity_typebr /   *   The entity type to load.br /   * @param $idbr /   *   The (remote) ID of the entity.br /   *br /   * @returnbr /   *  An entity object.br /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BBremote_entity_load/spanspan style=color: #007700(/spanspan style=color: #0000BB$entity_type/spanspan style=color: #007700, /spanspan style=color: #0000BB$id/spanspan style=color: #007700) {br /    /spanspan style=color: #0000BB$query /spanspan style=color: #007700= /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBgetRemoteEntityQuery/spanspan style=color: #007700(/spanspan style=color: #DD0000'select'/spanspan style=color: #007700);br /    /spanspan style=color: #0000BB$query/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBbase/spanspan style=color: #007700(/spanspan style=color: #0000BB$entity_type/spanspan style=color: #007700);br /    /spanspan style=color: #0000BB$query/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBentityCondition/spanspan style=color: #007700(/spanspan style=color: #DD0000'entity_id'/spanspan style=color: #007700, /spanspan style=color: #0000BB$id/spanspan style=color: #007700);br /    /spanspan style=color: #0000BB$result /spanspan style=color: #007700= /spanspan style=color: #0000BB$query/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBexecute/spanspan style=color: #007700();br /br /    /spanspan style=color: #FF8000// There's only one. Same pattern as entity_load_single().br /    /spanspan style=color: #007700return /spanspan style=color: #0000BBreset/spanspan style=color: #007700(/spanspan style=color: #0000BB$result/spanspan style=color: #007700);br /  }br /br /  /spanspan style=color: #FF8000/**br /   * Provide a map of remote property types to Drupal types.br /   *br /   * Roughly analogous to _entity_metadata_convert_schema_type().br /   *br /   * @returnbr /   *   An array whose keys are remote property types as used as types for fieldsbr /   *   in hook_remote_entity_query_table_info(), and whose values are typesbr /   *   recognized by the Entity Metadata API (as listed in the documentation forbr /   *   hook_entity_property_info()).br /   *   If a remote property type is not listed here, it will be mapped to 'text'br /   *   by default.br /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BBentity_property_type_map/spanspan style=color: #007700() {br /    return array(br /      /spanspan style=color: #DD0000'EntityCollection' /spanspan style=color: #007700=gt; /spanspan style=color: #DD0000'listlt;stringgt;'/spanspan style=color: #007700,br /    );br /  }br /br /  /spanspan style=color: #FF8000/**br /   * Get a new RemoteEntityQuery object appropriate for the connection.br /   *br /   * @param $query_typebr /   *  (optional) The type of the query. Defaults to 'select'.br /   *br /   * @returnbr /   *  A remote query object of the type appropriate to the query type.br /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BBgetRemoteEntityQuery/spanspan style=color: #007700(/spanspan style=color: #0000BB$query_type /spanspan style=color: #007700= /spanspan style=color: #DD0000'select'/spanspan style=color: #007700) {br /    switch (/spanspan style=color: #0000BB$query_type/spanspan style=color: #007700) {br /      case /spanspan style=color: #DD0000'select'/spanspan style=color: #007700:br /        return new /spanspan style=color: #0000BBOurRestRemoteSelectQuery/spanspan style=color: #007700(/spanspan style=color: #0000BB$this/spanspan style=color: #007700);br /      case /spanspan style=color: #DD0000'insert'/spanspan style=color: #007700:br /        return new /spanspan style=color: #0000BBOurRestRemoteInsertQuery/spanspan style=color: #007700(/spanspan style=color: #0000BB$this/spanspan style=color: #007700);br /      case /spanspan style=color: #DD0000'update'/spanspan style=color: #007700:br /        return new /spanspan style=color: #0000BBOurRestRemoteUpdateQuery/spanspan style=color: #007700(/spanspan style=color: #0000BB$this/spanspan style=color: #007700);br /    }br /  }br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /h4a name=clients-connection-base-overrides id=clients-connection-base-overridesParent overrides/a/h4 pThe only method we need to worry about here is emcallMethodArray()/em. Basically, it sets up the remote call./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr /  /spanspan style=color: #FF8000/**************************************************************************br /   * clients_connection_base overridesbr /   **************************************************************************/br /br /  /**br /   * Call a remote method with an array of parameters.br /   *br /   * This is intended for internal use from callMethod() andbr /   * clients_connection_call().br /   * If you need to call a method on given connection object, use callMethodbr /   * which has a nicer form.br /   *br /   * Subclasses do not necessarily have to override this method if theirbr /   * connection type does not make sense with this.br /   *br /   * @param $methodbr /   *  The name of the remote method to call.br /   * @param $method_paramsbr /   *  An array of parameters to passed to the remote method.br /   *br /   * @returnbr /   *  Whatever is returned from the remote site.br /   *br /   * @throws Exception on error from the remote site.br /   *  It's up to subclasses to implement this, as the test for an error andbr /   *  the way to get information about it varies according to service type.br /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BBcallMethodArray/spanspan style=color: #007700(/spanspan style=color: #0000BB$method/spanspan style=color: #007700, /spanspan style=color: #0000BB$method_params /spanspan style=color: #007700= array()) {br /br /    switch (/spanspan style=color: #0000BB$method/spanspan style=color: #007700) {br /      case /spanspan style=color: #DD0000'makeRequest'/spanspan style=color: #007700:br /br /        /spanspan style=color: #FF8000// Set the parameters.br /        /spanspan style=color: #0000BB$resource_path /spanspan style=color: #007700= /spanspan style=color: #0000BB$method_params/spanspan style=color: #007700[/spanspan style=color: #0000BB0/spanspan style=color: #007700];br /        /spanspan style=color: #0000BB$http_method /spanspan style=color: #007700= /spanspan style=color: #0000BB$method_params/spanspan style=color: #007700[/spanspan style=color: #0000BB1/spanspan style=color: #007700];br /        /spanspan style=color: #0000BB$data /spanspan style=color: #007700= isset(/spanspan style=color: #0000BB$method_params/spanspan style=color: #007700[/spanspan style=color: #0000BB2/spanspan style=color: #007700]) ? /spanspan style=color: #0000BB$method_params/spanspan style=color: #007700[/spanspan style=color: #0000BB2/spanspan style=color: #007700] : array();br /br /        /spanspan style=color: #FF8000// Make the request.br /        /spanspan style=color: #0000BB$results /spanspan style=color: #007700= /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBmakeRequest/spanspan style=color: #007700(/spanspan style=color: #0000BB$resource_path/spanspan style=color: #007700, /spanspan style=color: #0000BB$http_method/spanspan style=color: #007700, /spanspan style=color: #0000BB$data/spanspan style=color: #007700);br /        break;br /    }br /br /    return /spanspan style=color: #0000BB$results/spanspan style=color: #007700;br /  }br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /h4a name=local-methods id=local-methodsLocal methods/a/h4 We're assuming REST here, but you can use any protocol. pWe have a emmakeRequest()/em method, which actually performs the remote call, and emhandleRestError()/em which deals with any errors which are returned./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr /  /spanspan style=color: #FF8000/**************************************************************************br /   * Local methodsbr /   **************************************************************************/br /br /  /**br /   * Make a REST request.br /   *br /   * Originally from clients_connection_drupal_services_rest_7-gt;makeRequest().br /   * Examples:br /   * Retrieve an event:br /   *  makeRequest('event?eventId=ID', 'GET');br /   * Update a node:br /   *  makeRequest('node/NID', 'POST', $data);br /   *br /   * @param $resource_pathbr /   *  The path of the resource. Eg, 'node', 'node/1', etc.br /   * @param $http_methodbr /   *  The HTTP method. One of 'GET', 'POST', 'PUT', 'DELETE'. For an explanationbr /   *  of how the HTTP method affects the resource request, see the Servicesbr /   *  documentation at http://drupal.org/node/783254.br /   * @param $data = array()br /   *  (Optional) An array of data to pass to the request.br /   * @param boolean $data_as_headersbr /   *   Data will be sent in the headers if this is set to TRUE.br /   *br /   * @returnbr /   *  The data from the request response.br /   *br /   *  @todo Update the first two test classes to not assume a SimpleXMLElement.br /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BBmakeRequest/spanspan style=color: #007700(/spanspan style=color: #0000BB$resource_path/spanspan style=color: #007700, /spanspan style=color: #0000BB$http_method/spanspan style=color: #007700, /spanspan style=color: #0000BB$data /spanspan style=color: #007700= array(), /spanspan style=color: #0000BB$data_as_headers /spanspan style=color: #007700= /spanspan style=color: #0000BBFALSE/spanspan style=color: #007700) {br /br /    /spanspan style=color: #FF8000// Tap into this function's cache if there is one.br /    /spanspan style=color: #0000BB$request_cache_map /spanspan style=color: #007700= amp;/spanspan style=color: #0000BBdrupal_static/spanspan style=color: #007700(/spanspan style=color: #0000BB__FUNCTION__/spanspan style=color: #007700);br /br /    /spanspan style=color: #FF8000// Set the options.br /    /spanspan style=color: #0000BB$options /spanspan style=color: #007700= array(br /      /spanspan style=color: #DD0000'headers' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBgetHeaders/spanspan style=color: #007700(),  /spanspan style=color: #FF8000// Define if you need it.br /      /spanspan style=color: #DD0000'method'  /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$http_method/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'data'    /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$data/spanspan style=color: #007700,br /    );br /br /    /spanspan style=color: #FF8000// If cached, we have already issued this request during this page request sobr /    // just use the cached value.br /    /spanspan style=color: #0000BB$request_path /spanspan style=color: #007700= /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBendpoint /spanspan style=color: #007700. /spanspan style=color: #0000BB$context_path /spanspan style=color: #007700. /spanspan style=color: #DD0000'/' /spanspan style=color: #007700. /spanspan style=color: #0000BB$resource_path/spanspan style=color: #007700;br /br /    /spanspan style=color: #FF8000// Either get the data from the cache or send a request for it.br /    /spanspan style=color: #007700if (isset(/spanspan style=color: #0000BB$request_cache_map/spanspan style=color: #007700[/spanspan style=color: #0000BB$request_path/spanspan style=color: #007700])) {br /      /spanspan style=color: #FF8000// Use the cached copy.br /      /spanspan style=color: #0000BB$response /spanspan style=color: #007700= /spanspan style=color: #0000BB$request_cache_map/spanspan style=color: #007700[/spanspan style=color: #0000BB$request_path/spanspan style=color: #007700];br /    } else {br /      /spanspan style=color: #FF8000// Not cached yet so fire off the request.br /      /spanspan style=color: #0000BB$response /spanspan style=color: #007700= /spanspan style=color: #0000BBdrupal_http_request/spanspan style=color: #007700(/spanspan style=color: #0000BB$request_path/spanspan style=color: #007700, /spanspan style=color: #0000BB$options/spanspan style=color: #007700);br /br /      /spanspan style=color: #FF8000// And then cache to avoid duplicate calls within the page request.br /      /spanspan style=color: #0000BB$request_cache_map/spanspan style=color: #007700[/spanspan style=color: #0000BB$request_path/spanspan style=color: #007700] = /spanspan style=color: #0000BB$response/spanspan style=color: #007700;br /    }br /br /    /spanspan style=color: #FF8000// Handle any errors and then return the response.br /    /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBhandleRestError/spanspan style=color: #007700(/spanspan style=color: #0000BB$request_path/spanspan style=color: #007700, /spanspan style=color: #0000BB$response/spanspan style=color: #007700);br /    return /spanspan style=color: #0000BB$response/spanspan style=color: #007700;br /  }br /br /  /spanspan style=color: #FF8000/**br /   * Common helper for reacting to an error from a REST call.br /   *br /   * Originally from clients_connection_drupal_services_rest_7-gt;handleRestError().br /   * Gets the error from the response, logs the error message,br /   * and throws an exception, which should be caught by the module making usebr /   * of the Clients connection API.br /   *br /   * @param $responsebr /   *  The REST response data, decoded.br /   *br /   * @throws Exceptionbr /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BBhandleRestError/spanspan style=color: #007700(/spanspan style=color: #0000BB$request/spanspan style=color: #007700, /spanspan style=color: #0000BB$response/spanspan style=color: #007700) {br /br /    /spanspan style=color: #FF8000// Report and throw an error if we get anything unexpected.br /    /spanspan style=color: #007700if (!/spanspan style=color: #0000BBin_array/spanspan style=color: #007700(/spanspan style=color: #0000BB$response/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBcode/spanspan style=color: #007700, array(/spanspan style=color: #0000BB200/spanspan style=color: #007700, /spanspan style=color: #0000BB201/spanspan style=color: #007700, /spanspan style=color: #0000BB202/spanspan style=color: #007700, /spanspan style=color: #0000BB204/spanspan style=color: #007700, /spanspan style=color: #0000BB404/spanspan style=color: #007700))) {br /br /      /spanspan style=color: #FF8000// Report error to the logs.br /      /spanspan style=color: #0000BBwatchdog/spanspan style=color: #007700(/spanspan style=color: #DD0000'clients'/spanspan style=color: #007700, /spanspan style=color: #DD0000'Error with REST request (@req). Error was code @code with error @error and message @message.'/spanspan style=color: #007700, array(br /        /spanspan style=color: #DD0000'@req'      /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$request/spanspan style=color: #007700,br /        /spanspan style=color: #DD0000'@code'     /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$response/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBcode/spanspan style=color: #007700,br /        /spanspan style=color: #DD0000'@error'    /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$response/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBerror/spanspan style=color: #007700,br /        /spanspan style=color: #DD0000'@message'  /spanspan style=color: #007700=gt; isset(/spanspan style=color: #0000BB$response/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBstatus_message/spanspan style=color: #007700) ? /spanspan style=color: #0000BB$response/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBstatus_message /spanspan style=color: #007700: /spanspan style=color: #DD0000'(no message)'/spanspan style=color: #007700,br /      ), /spanspan style=color: #0000BBWATCHDOG_ERROR/spanspan style=color: #007700);br /br /      /spanspan style=color: #FF8000// Throw an error with which callers must deal.br /      /spanspan style=color: #007700throw new /spanspan style=color: #0000BBException/spanspan style=color: #007700(/spanspan style=color: #0000BBt/spanspan style=color: #007700(/spanspan style=color: #DD0000Clients connection error, got message '@message'./spanspan style=color: #007700, array(br /        /spanspan style=color: #DD0000'@message' /spanspan style=color: #007700=gt; isset(/spanspan style=color: #0000BB$response/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBstatus_message/spanspan style=color: #007700) ? /spanspan style=color: #0000BB$response/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBstatus_message /spanspan style=color: #007700: /spanspan style=color: #0000BB$response/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBerror/spanspan style=color: #007700,br /      )), /spanspan style=color: #0000BB$response/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBcode/spanspan style=color: #007700);br /    }br /  }br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /h3a name=implementing-the-remote-query-class id=implementing-the-remote-query-classImplementing the remote query class/a/h3 pThis is where the magic happens. We need a new class file, emOurRestRemoteSelectQuery.class.php/em, that will assemble the select query and execute it based on any set conditions./p h4a name=class-variables-and-constructor id=class-variables-and-constructorClass variables and constructor/a/h4 pFirst, let's define the class, its variables and its constructor. It's a subclass of the emRemoteEntityQuery/em class. Most of the standard conditions would be added to the em$conditions/em array, but conditions handled in a special way (say those dealing with metadata) can be set up as variables themselves. In the example below, the constructor sets the active user as it can affect which data is returned. You can, however, set whatever you need to initialize your subclass, or leave it out entirely./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr //spanspan style=color: #FF8000/**br / * @filebr / * Contains the OurRestRemoteSelectQuery class.br / */br /br //**br / * Select query for our remote data.br / *br / * @todo Make vars protected once no longer developing.br / */br //spanspan style=color: #007700class /spanspan style=color: #0000BBOurRestRemoteSelectQuery /spanspan style=color: #007700extends /spanspan style=color: #0000BBRemoteEntityQuery /spanspan style=color: #007700{br /br /  /spanspan style=color: #FF8000/**br /   * Determines whether the query is RetrieveMultiple or Retrieve.br /   *br /   * The query is Multiple by default, until an ID condition causes it to bebr /   * single.br /   */br /  /spanspan style=color: #007700public /spanspan style=color: #0000BB$retrieve_multiple /spanspan style=color: #007700= /spanspan style=color: #0000BBTRUE/spanspan style=color: #007700;br /br /  /spanspan style=color: #FF8000/**br /   * An array of conditions on the query. These are grouped by the table theybr /   * are on.br /   */br /  /spanspan style=color: #007700public /spanspan style=color: #0000BB$conditions /spanspan style=color: #007700= array();br /br /  /spanspan style=color: #FF8000/**br /   * The from date filter for event searchesbr /   */br /  /spanspan style=color: #007700public /spanspan style=color: #0000BB$from_date /spanspan style=color: #007700= /spanspan style=color: #0000BBNULL/spanspan style=color: #007700;br /br /  /spanspan style=color: #FF8000/**br /   * The to date filter for event searchesbr /   */br /  /spanspan style=color: #007700public /spanspan style=color: #0000BB$to_date /spanspan style=color: #007700= /spanspan style=color: #0000BBNULL/spanspan style=color: #007700;br /br /  /spanspan style=color: #FF8000/**br /   * The user id.br /   */br /  /spanspan style=color: #007700public /spanspan style=color: #0000BB$user_id /spanspan style=color: #007700= /spanspan style=color: #0000BBNULL/spanspan style=color: #007700;br /br /  /spanspan style=color: #FF8000/**br /   * Constructor to generically set up the user id condition ifbr /   * there is a current user.br /   *br /   * @param $connectionbr /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BB__construct/spanspan style=color: #007700(/spanspan style=color: #0000BB$connection/spanspan style=color: #007700) {br /    /spanspan style=color: #0000BBparent/spanspan style=color: #007700::/spanspan style=color: #0000BB__construct/spanspan style=color: #007700(/spanspan style=color: #0000BB$connection/spanspan style=color: #007700);br /    if (/spanspan style=color: #0000BBuser_is_logged_in/spanspan style=color: #007700()) {br /      global /spanspan style=color: #0000BB$user/spanspan style=color: #007700;br /      /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBuseridCondition/spanspan style=color: #007700(/spanspan style=color: #0000BB$user/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBname/spanspan style=color: #007700);br /    }br /  }br /}br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /h4a name=setting-conditions id=setting-conditionsSetting conditions/a/h4 pWe have three (3) methods which set conditions within the query. ementityCondition()/em sets conditions affecting entities in general. (The only entity condition supported here is the entity ID.) empropertyCondition()/em sets conditions related to properties specific to the type of data. For example, this could be a location filter for one or more events. Finally, we have emuseridCondition()/em which sets the query to act on behalf of a specific user. Here we simply record the current Drupal user./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr /  /spanspan style=color: #FF8000/**br /   * Add a condition to the query.br /   *br /   * Originally based on the entityCondition() method in EntityFieldQuery, butbr /   * largely from USDARemoteSelectQuery (Programming Drupal 7 Entities) andbr /   * MSDynamicsSoapSelectQuery.br /   *br /   * @param $namebr /   *  The name of the entity property.br /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BBentityCondition/spanspan style=color: #007700(/spanspan style=color: #0000BB$name/spanspan style=color: #007700, /spanspan style=color: #0000BB$value/spanspan style=color: #007700, /spanspan style=color: #0000BB$operator /spanspan style=color: #007700= /spanspan style=color: #0000BBNULL/spanspan style=color: #007700) {br /br /    /spanspan style=color: #FF8000// We only support the entity ID for now.br /    /spanspan style=color: #007700if (/spanspan style=color: #0000BB$name /spanspan style=color: #007700== /spanspan style=color: #DD0000'entity_id'/spanspan style=color: #007700) {br /br /      /spanspan style=color: #FF8000// Get the remote field name of the entity ID.br /      /spanspan style=color: #0000BB$field /spanspan style=color: #007700= /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBentity_info/spanspan style=color: #007700[/spanspan style=color: #DD0000'remote entity keys'/spanspan style=color: #007700][/spanspan style=color: #DD0000'remote id'/spanspan style=color: #007700];br /br /      /spanspan style=color: #FF8000// Set the remote ID field to the passed value.br /      /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBconditions/spanspan style=color: #007700[/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBremote_base/spanspan style=color: #007700][] = array(br /        /spanspan style=color: #DD0000'field' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$field/spanspan style=color: #007700,br /        /spanspan style=color: #DD0000'value' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$value/spanspan style=color: #007700,br /        /spanspan style=color: #DD0000'operator' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$operator/spanspan style=color: #007700,br /      );br /br /      /spanspan style=color: #FF8000// Record that we'll only be retrieving a single item.br /      /spanspan style=color: #007700if (/spanspan style=color: #0000BBis_null/spanspan style=color: #007700(/spanspan style=color: #0000BB$operator/spanspan style=color: #007700) || (/spanspan style=color: #0000BB$operator /spanspan style=color: #007700== /spanspan style=color: #DD0000'='/spanspan style=color: #007700)) {br /        /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBretrieve_multiple /spanspan style=color: #007700= /spanspan style=color: #0000BBFALSE/spanspan style=color: #007700;br /      }br /    }br /    else {br /br /      /spanspan style=color: #FF8000// Report an invalid entity condition.br /      /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBthrowException/spanspan style=color: #007700(br /        /spanspan style=color: #DD0000'OURRESTREMOTESELECTQUERY_INVALID_ENTITY_CONDITION'/spanspan style=color: #007700,br /        /spanspan style=color: #DD0000'The query object can only accept the \'entity_id\' condition.'br /      /spanspan style=color: #007700);br /    }br /  }br /br /  /spanspan style=color: #FF8000/**br /   * Add a condition to the query, using local property keys.br /   *br /   * Based on MSDynamicsSoapSelectQuery::propertyCondition().br /   *br /   * @param $property_namebr /   *  A local property. Ie, a key in the $entity_info 'property map' array.br /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BBpropertyCondition/spanspan style=color: #007700(/spanspan style=color: #0000BB$property_name/spanspan style=color: #007700, /spanspan style=color: #0000BB$value/spanspan style=color: #007700, /spanspan style=color: #0000BB$operator /spanspan style=color: #007700= /spanspan style=color: #0000BBNULL/spanspan style=color: #007700) {br /br /    /spanspan style=color: #FF8000// Make sure the entity base has been set up.br /    /spanspan style=color: #007700if (!isset(/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBentity_info/spanspan style=color: #007700)) {br /      /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBthrowException/spanspan style=color: #007700(br /        /spanspan style=color: #DD0000'OURRESTREMOTESELECTQUERY_ENTITY_BASE_NOT_SET'/spanspan style=color: #007700,br /        /spanspan style=color: #DD0000'The query object was not set with an entity type.'br /      /spanspan style=color: #007700);br /    }br /br /    /spanspan style=color: #FF8000// Make sure that the provided property is valid.br /    /spanspan style=color: #007700if (!isset(/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBentity_info/spanspan style=color: #007700[/spanspan style=color: #DD0000'property map'/spanspan style=color: #007700][/spanspan style=color: #0000BB$property_name/spanspan style=color: #007700])) {br /      /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBthrowException/spanspan style=color: #007700(br /        /spanspan style=color: #DD0000'OURRESTREMOTESELECTQUERY_INVALID_PROPERY'/spanspan style=color: #007700,br /        /spanspan style=color: #DD0000'The query object cannot set a non-existent property.'br /      /spanspan style=color: #007700);br /    }br /br /    /spanspan style=color: #FF8000// Adding a field condition (probably) automatically makes this a multiple.br /    // TODO: figure this out for sure!br /    /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBretrieve_multiple /spanspan style=color: #007700= /spanspan style=color: #0000BBTRUE/spanspan style=color: #007700;br /br /    /spanspan style=color: #FF8000// Use the property map to determine the remote field name.br /    /spanspan style=color: #0000BB$remote_field_name /spanspan style=color: #007700= /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBentity_info/spanspan style=color: #007700[/spanspan style=color: #DD0000'property map'/spanspan style=color: #007700][/spanspan style=color: #0000BB$property_name/spanspan style=color: #007700];br /br /    /spanspan style=color: #FF8000// Set the condition for use during execution.br /    /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBconditions/spanspan style=color: #007700[/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBremote_base/spanspan style=color: #007700][] = array(br /      /spanspan style=color: #DD0000'field' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$remote_field_name/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'value' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$value/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'operator' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$operator/spanspan style=color: #007700,br /    );br /  }br /br /  /spanspan style=color: #FF8000/**br /   * Add a user id condition to the query.br /   *br /   * @param $user_idbr /   *   The user to search for appointments.br /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BBuseridCondition/spanspan style=color: #007700(/spanspan style=color: #0000BB$user_id/spanspan style=color: #007700) {br /    /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBuser_id /spanspan style=color: #007700= /spanspan style=color: #0000BB$user_id/spanspan style=color: #007700;br /  }br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /h4a name=executing-the-remote-query id=executing-the-remote-queryExecuting the remote query/a/h4 pThe emexecute()/em method marshals all of the conditions, passes the built request to the connection's emmakeRequest()/em that we saw earlier, calls emparseEventResponse()/em (which we'll investigate below) and then returns the list of remote entities that can now be used by Drupal./p pFeel free to ignore the authentication code if it's not required for your implementation. I left it in as an extended example of how this could be done./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr /  /spanspan style=color: #FF8000/**br /   * Run the query and return a result.br /   *br /   * @returnbr /   *  Remote entity objects as retrieved from the remote connection.br /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BBexecute/spanspan style=color: #007700() {br /br /    /spanspan style=color: #FF8000// If there are any validation errors, don't perform a search.br /    /spanspan style=color: #007700if (/spanspan style=color: #0000BBform_set_error/spanspan style=color: #007700()) {br /      return array();br /    }br /br /    /spanspan style=color: #0000BB$querystring /spanspan style=color: #007700= array();br /br /    /spanspan style=color: #0000BB$path /spanspan style=color: #007700= /spanspan style=color: #0000BBvariable_get/spanspan style=color: #007700(/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBbase_entity_type /spanspan style=color: #007700. /spanspan style=color: #DD0000'_resource_name'/spanspan style=color: #007700, /spanspan style=color: #DD0000''/spanspan style=color: #007700);br /br /    /spanspan style=color: #FF8000// Iterate through all of the conditions and add them to the query.br /    /spanspan style=color: #007700if (isset(/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBconditions/spanspan style=color: #007700[/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBremote_base/spanspan style=color: #007700])) {br /      foreach (/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBconditions/spanspan style=color: #007700[/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBremote_base/spanspan style=color: #007700] as /spanspan style=color: #0000BB$condition/spanspan style=color: #007700) {br /        switch (/spanspan style=color: #0000BB$condition/spanspan style=color: #007700[/spanspan style=color: #DD0000'field'/spanspan style=color: #007700]) {br /          case /spanspan style=color: #DD0000'event_id'/spanspan style=color: #007700:br /            /spanspan style=color: #0000BB$querystring/spanspan style=color: #007700[/spanspan style=color: #DD0000'eventId'/spanspan style=color: #007700] = /spanspan style=color: #0000BB$condition/spanspan style=color: #007700[/spanspan style=color: #DD0000'value'/spanspan style=color: #007700];br /            break;br /          case /spanspan style=color: #DD0000'login_id'/spanspan style=color: #007700:br /            /spanspan style=color: #0000BB$querystring/spanspan style=color: #007700[/spanspan style=color: #DD0000'userId'/spanspan style=color: #007700] = /spanspan style=color: #0000BB$condition/spanspan style=color: #007700[/spanspan style=color: #DD0000'value'/spanspan style=color: #007700];br /            break;br /        }br /      }br /    }br /br /    /spanspan style=color: #FF8000// From date parameter.br /    /spanspan style=color: #007700if (isset(/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBfrom_date/spanspan style=color: #007700)) {br /      /spanspan style=color: #0000BB$querystring/spanspan style=color: #007700[/spanspan style=color: #DD0000'startDate'/spanspan style=color: #007700] = /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBfrom_date/spanspan style=color: #007700;br /    }br /br /    /spanspan style=color: #FF8000// To date parameter.br /    /spanspan style=color: #007700if (isset(/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBto_date/spanspan style=color: #007700)) {br /      /spanspan style=color: #0000BB$querystring/spanspan style=color: #007700[/spanspan style=color: #DD0000'endDate'/spanspan style=color: #007700] = /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBto_date/spanspan style=color: #007700;br /    }br /br /    /spanspan style=color: #FF8000// Add user id based filter if present.br /    /spanspan style=color: #007700if (isset(/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBuser_id/spanspan style=color: #007700)) {br /      /spanspan style=color: #0000BB$querystring/spanspan style=color: #007700[/spanspan style=color: #DD0000'userId'/spanspan style=color: #007700] = /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBuser_id/spanspan style=color: #007700;br /    }br /br /    /spanspan style=color: #FF8000// Assemble all of the query parameters.br /    /spanspan style=color: #007700if (/spanspan style=color: #0000BBcount/spanspan style=color: #007700(/spanspan style=color: #0000BB$querystring/spanspan style=color: #007700)) {br /      /spanspan style=color: #0000BB$path /spanspan style=color: #007700.= /spanspan style=color: #DD0000'?' /spanspan style=color: #007700. /spanspan style=color: #0000BBdrupal_http_build_query/spanspan style=color: #007700(/spanspan style=color: #0000BB$querystring/spanspan style=color: #007700);br /    }br /br /    /spanspan style=color: #FF8000// Make the request.br /    /spanspan style=color: #007700try {br /      /spanspan style=color: #0000BB$response /spanspan style=color: #007700= /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBconnection/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBmakeRequest/spanspan style=color: #007700(/spanspan style=color: #0000BB$path/spanspan style=color: #007700, /spanspan style=color: #DD0000'GET'/spanspan style=color: #007700);br /    } catch (/spanspan style=color: #0000BBException $e/spanspan style=color: #007700) {br /      if (/spanspan style=color: #0000BB$e/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBgetCode/spanspan style=color: #007700() == /spanspan style=color: #0000BBOUR_REST_LOGIN_REQUIRED_NO_SESSION/spanspan style=color: #007700) {br /        /spanspan style=color: #0000BBdrupal_set_message/spanspan style=color: #007700(/spanspan style=color: #0000BB$e/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBgetMessage/spanspan style=color: #007700());br /        /spanspan style=color: #0000BBdrupal_goto/spanspan style=color: #007700(/spanspan style=color: #DD0000'user/login'/spanspan style=color: #007700, array(/spanspan style=color: #DD0000'query' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BBdrupal_get_destination/spanspan style=color: #007700()));br /      }br /      elseif (/spanspan style=color: #0000BB$e/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBgetCode/spanspan style=color: #007700() == /spanspan style=color: #0000BBOUR_REST_LOGIN_REQUIRED_TOKEN_EXPIRED/spanspan style=color: #007700) {br /br /        /spanspan style=color: #FF8000// Logoutbr /        /spanspan style=color: #007700global /spanspan style=color: #0000BB$user/spanspan style=color: #007700;br /        /spanspan style=color: #0000BBmodule_invoke_all/spanspan style=color: #007700(/spanspan style=color: #DD0000'user_logout'/spanspan style=color: #007700, /spanspan style=color: #0000BB$user/spanspan style=color: #007700);br /        /spanspan style=color: #0000BBsession_destroy/spanspan style=color: #007700();br /br /        /spanspan style=color: #FF8000// Redirectbr /        /spanspan style=color: #0000BBdrupal_set_message/spanspan style=color: #007700(/spanspan style=color: #0000BB$e/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBgetMessage/spanspan style=color: #007700());br /        /spanspan style=color: #0000BBdrupal_goto/spanspan style=color: #007700(/spanspan style=color: #DD0000'user/login'/spanspan style=color: #007700, array(/spanspan style=color: #DD0000'query' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BBdrupal_get_destination/spanspan style=color: #007700()));br /      }br /    }br /br /    switch(/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBbase_entity_type/spanspan style=color: #007700) {br /      case /spanspan style=color: #DD0000'siteshortname_entities_remote_event' /spanspan style=color: #007700:br /        /spanspan style=color: #0000BB$entities /spanspan style=color: #007700= /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBparseEventResponse/spanspan style=color: #007700(/spanspan style=color: #0000BB$response/spanspan style=color: #007700);br /        break;br /    }br /br /    /spanspan style=color: #FF8000// Return the list of results.br /    /spanspan style=color: #007700return /spanspan style=color: #0000BB$entities/spanspan style=color: #007700;br /  }br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /h4a name=unmarshalling-the-response-data-and-returning-it id=unmarshalling-the-response-data-and-returning-itUnmarshalling the response data and returning it/a/h4 pHere, in the emparseEventResponse/em method, we decode the response data (if there is any), and do any additional work required to get each entity's data into an object. They're all returned as a single list (array) of entity objects. If the response provides information on the format (XML, JSON, etc.), you can unmarshal the data differently based on what the server returned./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr /  /spanspan style=color: #FF8000/**br /   * Helper for execute() which parses the JSON response for event entities.br /   *br /   * May also set the $total_record_count property on the query, if applicable.br /   *br /   * @param $responsebr /   *  The JSON/XML/whatever response from the REST server.br /   *br /   * @returnbr /   *  An list of entity objects, keyed numerically.br /   *  An empty array is returned if the response contains no entities.br /   *br /   * @throwsbr /   *  Exception if a fault is received when the REST call was made.br /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BBparseEventResponse/spanspan style=color: #007700(/spanspan style=color: #0000BB$response/spanspan style=color: #007700) {br /br /    /spanspan style=color: #FF8000// Fetch the list of events.br /    /spanspan style=color: #007700if (/spanspan style=color: #0000BB$response/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBcode /spanspan style=color: #007700== /spanspan style=color: #0000BB404/spanspan style=color: #007700) {br /      /spanspan style=color: #FF8000// No data was returned so let's provide an empty list.br /      /spanspan style=color: #0000BB$events /spanspan style=color: #007700= array();br /    }br /    else /spanspan style=color: #FF8000/* we have response data */ /spanspan style=color: #007700{br /br /      /spanspan style=color: #FF8000// Convert the JSON (assuming that's what we're getting) into a PHP array.br /      // Do any unmarshalling to convert the response data into a PHP array.br /      /spanspan style=color: #0000BB$events /spanspan style=color: #007700= /spanspan style=color: #0000BBjson_decode/spanspan style=color: #007700(/spanspan style=color: #0000BB$response/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBdata/spanspan style=color: #007700, /spanspan style=color: #0000BBTRUE/spanspan style=color: #007700);br /    }br /br /    /spanspan style=color: #FF8000// Initialize an empty list of entities for returning.br /    /spanspan style=color: #0000BB$entities /spanspan style=color: #007700= array();br /br /    /spanspan style=color: #FF8000// Iterate through each event.br /    /spanspan style=color: #007700foreach (/spanspan style=color: #0000BB$events /spanspan style=color: #007700as /spanspan style=color: #0000BB$event/spanspan style=color: #007700) {br /      /spanspan style=color: #0000BB$entities/spanspan style=color: #007700[] = (object) array(br /br /        /spanspan style=color: #FF8000// Set event information.br /        /spanspan style=color: #DD0000'event_id' /spanspan style=color: #007700=gt; isset(/spanspan style=color: #0000BB$event/spanspan style=color: #007700[/spanspan style=color: #DD0000'id'/spanspan style=color: #007700]) ? /spanspan style=color: #0000BB$event/spanspan style=color: #007700[/spanspan style=color: #DD0000'id'/spanspan style=color: #007700] : /spanspan style=color: #0000BBNULL/spanspan style=color: #007700,br /        /spanspan style=color: #DD0000'event_name' /spanspan style=color: #007700=gt; isset(/spanspan style=color: #0000BB$event/spanspan style=color: #007700[/spanspan style=color: #DD0000'name'/spanspan style=color: #007700]) ? /spanspan style=color: #0000BB$event/spanspan style=color: #007700[/spanspan style=color: #DD0000'name'/spanspan style=color: #007700] : /spanspan style=color: #0000BBNULL/spanspan style=color: #007700,br /        /spanspan style=color: #DD0000'event_date' /spanspan style=color: #007700=gt; isset(/spanspan style=color: #0000BB$event/spanspan style=color: #007700[/spanspan style=color: #DD0000'date'/spanspan style=color: #007700]) ? /spanspan style=color: #0000BB$event/spanspan style=color: #007700[/spanspan style=color: #DD0000'date'/spanspan style=color: #007700] : /spanspan style=color: #0000BBNULL/spanspan style=color: #007700,br /      );br /    }br /br /    /spanspan style=color: #FF8000// Return the newly-created list of entities.br /    /spanspan style=color: #007700return /spanspan style=color: #0000BB$entities/spanspan style=color: #007700;br /  }br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /h4a name=error-handling id=error-handlingError handling/a/h4 pWe provide a helper method dealing with errors raised in other methods. It records the specific error message in the log and throws an exception based on the message and the code./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr /  /spanspan style=color: #FF8000/**br /   * Throw an exception when there's a problem.br /   *br /   * @param string $codebr /   *   The error code.br /   *br /   * @param string $messagebr /   *   A user-friendly message describing the problem.br /   *br /   * @throws Exceptionbr /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BBthrowException/spanspan style=color: #007700(/spanspan style=color: #0000BB$code/spanspan style=color: #007700, /spanspan style=color: #0000BB$message/spanspan style=color: #007700) {br /br /    /spanspan style=color: #FF8000// Report error to the logs.br /    /spanspan style=color: #0000BBwatchdog/spanspan style=color: #007700(/spanspan style=color: #DD0000'siteshortname_entities_remote'/spanspan style=color: #007700, /spanspan style=color: #DD0000'ERROR: OurRestRemoteSelectQuery: @code, @message.'/spanspan style=color: #007700, array(br /      /spanspan style=color: #DD0000'@code' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$code/spanspan style=color: #007700,br /      /spanspan style=color: #DD0000'@message' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$message/spanspan style=color: #007700,br /    ));br /br /    /spanspan style=color: #FF8000// Throw an error with which callers must deal.br /   /spanspan style=color: #007700throw new /spanspan style=color: #0000BBException/spanspan style=color: #007700(/spanspan style=color: #0000BBt/spanspan style=color: #007700(/spanspan style=color: #DD0000OurRestRemoteSelectQuery error, got message '@message'./spanspan style=color: #007700, array(br /      /spanspan style=color: #DD0000'@message' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$message/spanspan style=color: #007700,br /    )), /spanspan style=color: #0000BB$code/spanspan style=color: #007700);br /  }br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /pEverything we've covered so far gets our remote data into Drupal. Below, we'll expose it to Views./p h2a name=views-support id=views-supportViews support/a/h2 h3a name=views-basic-set-up id=views-basic-set-upBasic set-up/a/h3 pAt the beginning of this article, I stated that we required the EntityFieldQuery Views Backend module. This allows us to replace the default Views query back-end, a local SQL database, with one that supports querying entities fetchable through the Remote Entity API. Make sure to add it, emefq_views/em, to your custom remote entity module as a dependency./p pFor the curious, the changes I made to EFQ Views Backend to add this support can be found in the issue a href=https://www.drupal.org/node/2283083Add support for remote entities/a./p pI added official documentation for all of this to the a href=http://cgit.drupalcode.org/remote_entity/tree/README.txtRemote Entity API README/a (via a href=https://www.drupal.org/node/2283135Explain how to integrate remote querying through Views/a). As it may not be obvious, when creating a new view of your remote entities, make sure that the base entity is the EntityFieldQuery version, not simply the entity itself. When selecting the entity type on which to base the view, you should see each entity twice: the standard one (via the default query back-end) and the EFQ version./p pAs stated in the documentation, you need to a add a embuildFromEFQ()/em method to your emRemoteEntityQuery/em subclass (which we went over in the previous section). We'll review why this is necessary and give an example next./p h3a name=converting-from-an-efq id=converting-from-an-efqConverting from an EntityFieldQuery/a/h3 pAs EFQ Views only builds EntityFieldQuery objects, we need to convert that type of query to an instance of our RemoteEntityQuery subclass. If EFQ Views stumbles upon a remote query instead of a local one, it will run the emexecute()/em method on one of these objects instead./p pSo we need to tell our subclass how to generate an instance of itself when provided with an EntityFieldQuery object. The method below handles the conversion, which EFQ Views calls when necessary./p div class=codeblockcodespan style=color: #000000span style=color: #0000BBlt;?phpbr /  /spanspan style=color: #FF8000/**br /   * Build the query from an EntityFieldQuery object.br /   *br /   * To have our query work with Views using the EntityFieldQuery Views module,br /   * which assumes EntityFieldQuery query objects, it's necessary to convertbr /   * from the EFQ so that we may execute this one instead.br /   *br /   * @param $efqbr /   *   The built-up EntityFieldQuery object.br /   *br /   * @returnbr /   *   The current object.  Helpful for chaining methods.br /   */br /  /spanspan style=color: #007700function /spanspan style=color: #0000BBbuildFromEFQ/spanspan style=color: #007700(/spanspan style=color: #0000BB$efq/spanspan style=color: #007700) {br /br /    /spanspan style=color: #FF8000// Copy all of the conditions.br /    /spanspan style=color: #007700foreach (/spanspan style=color: #0000BB$efq/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBpropertyConditions /spanspan style=color: #007700as /spanspan style=color: #0000BB$condition/spanspan style=color: #007700) {br /br /      /spanspan style=color: #FF8000// Handle various conditions in different ways.br /      /spanspan style=color: #007700switch (/spanspan style=color: #0000BB$condition/spanspan style=color: #007700[/spanspan style=color: #DD0000'column'/spanspan style=color: #007700]) {br /br /        /spanspan style=color: #FF8000// Get the from date.br /        /spanspan style=color: #007700case /spanspan style=color: #DD0000'from_date' /spanspan style=color: #007700:br /          /spanspan style=color: #0000BB$from_date /spanspan style=color: #007700= /spanspan style=color: #0000BB$condition/spanspan style=color: #007700[/spanspan style=color: #DD0000'value'/spanspan style=color: #007700];br /          /spanspan style=color: #FF8000// Convert the date to the correct format for the REST servicebr /          /spanspan style=color: #0000BB$result /spanspan style=color: #007700= /spanspan style=color: #0000BB$from_date/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBformat/spanspan style=color: #007700(/spanspan style=color: #DD0000'Y/m/d'/spanspan style=color: #007700);br /          /spanspan style=color: #FF8000// The above format() can return FALSE in some cases, so add a checkbr /          /spanspan style=color: #007700if ( /spanspan style=color: #0000BB$result /spanspan style=color: #007700) {br /            /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBfrom_date /spanspan style=color: #007700= /spanspan style=color: #0000BB$result/spanspan style=color: #007700;br /          }br /          break;br /br /        /spanspan style=color: #FF8000// Get the to date.br /        /spanspan style=color: #007700case /spanspan style=color: #DD0000'to_date'/spanspan style=color: #007700:br /          /spanspan style=color: #0000BB$to_date /spanspan style=color: #007700= /spanspan style=color: #0000BB$condition/spanspan style=color: #007700[/spanspan style=color: #DD0000'value'/spanspan style=color: #007700];br /          /spanspan style=color: #FF8000// Convert the date to the correct format for the REST servicebr /          /spanspan style=color: #0000BB$result /spanspan style=color: #007700= /spanspan style=color: #0000BB$to_date/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBformat/spanspan style=color: #007700(/spanspan style=color: #DD0000'Y/m/d'/spanspan style=color: #007700);br /          /spanspan style=color: #FF8000// The above format() can return FALSE in some cases, so add a checkbr /          /spanspan style=color: #007700if ( /spanspan style=color: #0000BB$result /spanspan style=color: #007700) {br /            /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBto_date /spanspan style=color: #007700= /spanspan style=color: #0000BB$result/spanspan style=color: #007700;br /          }br /          break;br /br /        /spanspan style=color: #FF8000// Get the user ID.br /        /spanspan style=color: #007700case /spanspan style=color: #DD0000'user_id'/spanspan style=color: #007700:br /          /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBuser_id /spanspan style=color: #007700= /spanspan style=color: #0000BB$condition/spanspan style=color: #007700[/spanspan style=color: #DD0000'value'/spanspan style=color: #007700];br /          break;br /br /        default:br /          /spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBconditions/spanspan style=color: #007700[/spanspan style=color: #0000BB$this/spanspan style=color: #007700-gt;/spanspan style=color: #0000BBremote_base/spanspan style=color: #007700][] = array(br /            /spanspan style=color: #DD0000'field' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$condition/spanspan style=color: #007700[/spanspan style=color: #DD0000'column'/spanspan style=color: #007700],br /            /spanspan style=color: #DD0000'value' /spanspan style=color: #007700=gt; /spanspan style=color: #0000BB$condition/spanspan style=color: #007700[/spanspan style=color: #DD0000'value'/spanspan style=color: #007700],br /            /spanspan style=color: #DD0000'operator' /spanspan style=color: #007700=gt; isset(/spanspan style=color: #0000BB$condition/spanspan style=color: #007700[/spanspan style=color: #DD0000'operator'/spanspan style=color: #007700]) ? /spanspan style=color: #0000BB$condition/spanspan style=color: #007700[/spanspan style=color: #DD0000'operator'/spanspan style=color: #007700] : /spanspan style=color: #0000BBNULL/spanspan style=color: #007700,br /          );br /          break;br /      }br /    }br /br /    return /spanspan style=color: #0000BB$this/spanspan style=color: #007700;br /  }br //spanspan style=color: #0000BB?gt;/span/span/code/divbr /pThat should be it! You'll now need to spend some time (if you haven't already) getting everything connected as above to fit your specific situation. If you can get these details sorted, you'll then be ready to go./p h2a name=alternatives id=alternativesAlternatives/a/h2 pAt the time of this writing, there appears to be only one alternative to the Remote Entity API (not including custom architectures). It's the a href=https://www.drupal.org/project/wsdataWeb Service Data/a suite. The main difference between the modules is that Web Service Data doesn't store a local cache of remote data; the data is always passed through directly./p pIf this more closely matches what you'd like to do, be aware that there is currently no EntityFieldQuery support:/p blockquoteSupport for EntityFieldQuery (coming soon) will allow developers to make entity field queries with web service data./blockquote pThis is very clearly stated on the main project page, but I wasn't able to find an issue in the queue tracking progress. So if you choose this method, you may have to add EFQ support yourself, or you may not be able to use Views with your remote entities./p h2a name=references id=referencesReferences/a/h2 ulliThe a href=https://www.drupal.org/project/clients_ms_dynamics_soapMS Dynamics Client Connection/a reference implementation/li liThe a href=https://www.drupal.org/node/2034119Programming Drupal 7 Entities/a book/li /ulpemThis article, a href=http://colans.net/blog/integrating-remote-data-drupal-7-and-exposing-it-viewsIntegrating remote data into Drupal 7 and exposing it to Views/a, appeared first on the a href=http://colans.net/Colan Schwartz Consulting Services blog/a./em/p/div/div/divspan rel=schema:url resource=/blog/integrating-remote-data-drupal-7-and-exposing-it-views class=rdf-meta element-hidden/spanspan property=schema:name content=Integrating remote data into Drupal 7 and exposing it to Views class=rdf-meta element-hidden/span

DrupalCon News: Making website magic with the DrupalCon site building track

Mon, 02/16/2015 - 19:45
div class=field field--name-body field--type-text-with-summary field--label-hiddendiv class=field__itemsdiv class=field__item evenpIn honor of this year’s DrupalCon in a href=http://en.wikipedia.org/wiki/HollywoodTinseltown/a, we invite you to indulge in a bit of Drupal movie magic./p pImagine the scene…/p pNARRATORbr / You are about to enter another dimension, a dimension not only of configuration and security but of UI. A journey into a wondrous land of complex sites without custom development. Next stop, the emDrupal Zone!/em/p pTHE SCENEbr / Intl. Acme, Inc. Meeting Room - it is day/p pFADE IN/p/div/div/div

Chromatic: Atomic Drupal Development: Building Pieces Before Pages

Mon, 02/16/2015 - 18:12
div class=field field-name-body field-type-text-with-summary field-label-hidden pimg src=http://blog-media.chromaticsites.com.s3.amazonaws.com/drupal/uploads/2015/02/13/atomic-drupal-development-graphic.svg alt= //p pMany designers are praising the benefits of a href=http://bradfrost.com/blog/post/atomic-web-design/Atomic Design/a. Rather than designing pages, Atomic Design focuses on designing systems of individual, reusable components. Designers aren’t – or at least shouldn’t be – the only ones thinking this way. From content strategy to QA, the entire team must be on the same atomic page./p pDevelopment is one area of a project that stands to benefit the most from this change in thought. Organizing a codebase by individual components keeps developers out of each other’s hair, reducing the code and effort overlap that often occurs when building by page or section. It also makes the codebase much easier to understand and maintain. Developers will know where to find code and how to fix, alter, or extend it, regardless of the original author. After enforcing coding standards, only git’s history will know who wrote what. This all saves time and money./p pBecause there are many ways to do anything in Drupal, building every component with the same approach is crucial. In the Drupal world, this approach is known as “the Drupal way”./p h2Building a component the Drupal way/h2 pIndividual a href=https://www.drupal.org/documentation/blocksblocks/a, a href=https://www.drupal.org/project/panelspanel panes/a, or other a href=http://en.wikipedia.org/wiki/User_interfaceUI/a elements would be examples of a component in Drupal. They are placed into a href=https://www.drupal.org/node/171224regions/a within layouts to build pages. Other pages may use the same component in the same or different regions. A given component may vary across pages, but the design and intended functionality are similar. A simple search form is a good example, but they can be much more complex./p pa href=http://blog-media.chromaticsites.com.s3.amazonaws.com/drupal/uploads/2015/02/13/drupal-components-in-regions.jpgimg src=http://blog-media.chromaticsites.com.s3.amazonaws.com/drupal/uploads/2015/02/13/drupal-components-in-regions.jpg style=width:40%;float:right;margin:5px 0 10px 10px; alt=A screenshot of a CHROMATIC blog article with regions outlined and components highlighted title=A screenshot of a CHROMATIC blog article with regions outlined and components highlighted //a/p pDesign deliverables often arrive as complete pages. If the designers haven’t already, identify the components that each page consists of. Break up the page’s layout into regions and those regions into components. Determine which components live on more than one page and if they vary between them. It also helps to identify different components that share design or functionality with others. It’s important to recognize early if they will be sharing code./p pBefore writing a line of code, determine where in the codebase the component will live. a href=http://chromaticsites.com/blog/how-organize-drupal-features-reduce-merge-conflicts-and-stay-saneOrganize custom modules by content types or sections and add relevant components to the same modules/a. A module exported with a href=https://www.drupal.org/project/featuresFeatures/a should be treated no differently than one created by hand; don’t be afraid to add custom code to them (please do). The end goal is to have all back-end and (most) front-end code for a given component living in the same module./p pemWarning: This article is about to move fast and cover more ground than it should. It will move from back-end to front-end. There are many wonderful resources about each topic covered below, so they will be linked to rather than recreated. This will instead provide a high level overview of how they fit together and will highlight the most important pieces./em/p h3Component containers and placement/h3 pThe most common container for a custom component is a a href=https://www.drupal.org/documentation/blocksblock/a, a href=http://fourword.fourkitchens.com/article/building-custom-blocks-drupal-7created with a series of hooks/a. Contributed modules like a href=https://www.drupal.org/project/contextContext/a can help place them on the page. More complex projects may choose to build pages with the a href=https://www.drupal.org/project/panelsPanels module/a. For pages built with Panels, a href=https://ohthehugemanatee.org/blog/2014/01/03/how-to-create-a-custom-panels-pane/custom panel page plugins/a are a component’s container of choice./p pThe a href=https://www.lullabot.com/blog/article/assembling-pages-drupaldecision between blocks and Context, Panels, or another approach/a is important to make early in the project. It is also important to stick with the same approach for every component. This article will focus less on this decision and more on how to construct the markup within the container of choice./p h3View modes and entity_view()/h3 pIf the component displays information from a a href=https://www.drupal.org/node/717120node/a or a href=https://www.drupal.org/node/1261744another type of entity/a, render it with a a href=https://www.drupal.org/node/1577752view mode/a. View modes can render different information from the same entity in different ways. Among other benefits, this helps display content in similar ways among different components./p pCreate a view mode with a href=https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_entity_info_alter/7code class=prettyprinthook_entity_info_alter()/code/a or with the a href=https://www.drupal.org/project/entity_view_modeEntity view modes/a contributed module. This module also provide template suggestions for each entity type in each view mode. Render an individual piece of information with a view mode inside of a component using a href=http://drupalcontrib.org/api/drupal/contributions!entity!entity.module/function/entity_view/7code class=prettyprintentity_view()/code/a (you’ll need the a href=https://www.drupal.org/project/entityEntity span class=capsAPI/span module/a) or a href=https://api.drupal.org/api/drupal/modules%21node%21node.module/function/node_view/7code class=prettyprintnode_view()/code/a. Alter the entity’s information as needed using a preprocess function and adjust the markup in a template. Those pieces will be discussed later./p pIf a component lists more than one entity or node, build a view with the a href=https://www.drupal.org/project/viewsViews contributed module/a. It is best if the view renders content with view modes using the Format options. Create Views components with the Block (or Content pane for Panels) display(s). Views also provides a href=https://api.drupal.org/api/views/theme%21theme.inc/group/views_templates/7template suggestions/a to further customize the markup of the component. The exported view should live in the same module as the code that customizes it. a href=https://www.drupal.org/node/1343708EntityFieldQuery/a might be worth considering as an alternative to using Views./p h3hook_theme() and render arrays/h3 pIf the component does not display information from an entity, such as a UI element, build it with a href=https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_theme/7code class=prettyprinthook_theme()/code/a. Drupal core and contributed modules use a href=https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_theme/7code class=prettyprinthook_theme()/code/a to build elements like a href=https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_link/7links/a and a href=https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_item_list/7item lists/a. This allows other modules to override and alter the information used to render the element. a href=https://www.drupal.org/node/173880Default theme functions and templates can also be overridden to alter their markup/a./p pChoose a name for the element that will identify it throughout the codebase. Outline what information the element will need to build the desired output. Use these decisions to define it using a href=https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_theme/7code class=prettyprinthook_theme()/code/a. Again, keep this hook in the same custom module as the rest of the code for the component./p pTo render a a href=https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_theme/7code class=prettyprinthook_theme()/code/a implementation, construct a a href=https://www.drupal.org/node/930760render array/a. This array should contain the name of the implementation to render and any data it needs as input. Build and return this array to render the element as markup. The a href=https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme/7code class=prettyprinttheme()/code/a function is a common alternative to render arrays, but it has been deprecated in Drupal 8. There are advantages to using render arrays instead, as explained in a href=https://www.drupal.org/node/930760Render Arrays in Drupal 7/a./p h3Custom templates/h3 pDrupal renders all markup through a href=https://www.drupal.org/node/190815templates/a and a href=https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme/7theme functions/a. Use templates to construct markup instead of theme functions. Doing so makes it easier for front-end developers to build and alter the markup they need./p pTemplates place variables provided by a href=http://drupalcontrib.org/api/drupal/contributions!entity!entity.module/function/entity_view/7code class=prettyprintentity_view()/code/a, render arrays, and preprocess functions into the markup. They should live in the “templates” directory of the same module as the rest of the component’s code. The a href=https://www.drupal.org/node/1089656name of a template will come from theme hook suggestions/a. Underscores get replaced with dashes. Tell a href=https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_theme/7code class=prettyprinthook_theme()/code/a about the template for each element it defines./p pa href=https://www.lullabot.com/blog/article/theming-best-practices-garland-gets-cleanupThere should be no logic in the template/a and they should not have to dig deep into Drupal’s objects or arrays. They should only use an code class=prettyprintif/code statement to determine if a variable has a value before printing its markup and value. They can also use a code class=prettyprintforeach/code to loop through an array of data. Further manipulation or function calls should happen in a preprocess function./p h3Preprocess functions/h3 pUse a href=https://www.drupal.org/node/223430preprocess functions/a to extract and manipulate data such as field values and prepare them for the template. They are the middleman between the input and the output./p pPreprocess functions a href=http://themery.com/dgd7/advanced-theming/preprocess-process/implementfollow the naming convention/a of a href=https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_theme/7code class=prettyprinthook_theme()/code/a implementations. Common base themes often use Drupal core’s preprocess functions, such as a href=https://api.drupal.org/api/drupal/modules!node!node.module/function/template_preprocess_node/7code class=prettyprinthook_preprocess_node()/code/a, in their template.php file. Keeping all preprocess functions in one file will create a mess in no time. Instead, place preprocess functions in the modules that define the parts their working with. This might be the custom feature that contains the exported content type./p h3jQuery/JavaScript files/h3 pCreate a separate JavaScript file for each component that needs custom JavaScript. Place it in a “js” directory within the module and name the file after the component. Be sure to use the a href=https://www.lullabot.com/blog/article/understanding-javascript-behaviors-drupalDrupal behavior system/a and name the behavior after the module and component./p pa href=http://wearepropeople.com/blog/7-ways-to-add-custom-js-and-css-to-a-page-in-drupalAdd the JavaScript file to each page the component will appear on/a. If the component appears on most pages, it might be best to just add it to every page. This will cause less span class=capsHTTP/span requests with JavaScript aggregation enabled. The a href=https://twitter.com/davereid/status/294554866649542657best way to do so/a is with a href=https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_page_build/7code class=prettyprinthook_page_build()/code/a. JavaScript files can also be attached to entities rendered through view modes within a href=https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_entity_view/7code class=prettyprinthook_entity_view()/code/a. The best way to add JavaScript to a a href=https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_theme/7code class=prettyprinthook_theme()/code/a implementation is by attaching it to the render array./p h3Sass components/h3 pWhen using a a href=https://drupalize.me/videos/what-css-preprocessorspan class=capsCSS/span preprocessor/a like a href=http://sass-lang.com/Sass/a, there isn’t much of a penalty to dividing the span class=capsCSS/span into many files. Create a new a href=http://sass-lang.com/guideSass partial/a for each component and give the file the same name as the component. Keep them in a “components” directory within the Sass folder structure. Unlike all other code mentioned in this article, it is often best to keep all span class=capsCSS/span for these components within the theme. Only keep span class=capsCSS/span that supports the core behavior of the component in the module. Consider what styles should persist if it were a contributed module used with other themes./p pIn the component’s template, base the class names off of the component’s name as well. This makes it easy to find the component’s Sass after inspecting the element in the source. Follow the popular a href=https://bem.info/method/span class=capsBEM/span/a / a href=https://smacss.com/span class=capsSMACSS/span/a / a href=http://www.smashingmagazine.com/2011/12/12/an-introduction-to-object-oriented-css-oocss/span class=capsOOCSS/span/a methodologies from there./p h2Coming up for air/h2 pAs mentioned, there are often endless ways to complete the same task in Drupal. This makes learning best practices difficult and “the Drupal way” will vary in the minds of different experts. The best way to grasp what works best is to start building something with other people and learn from mistakes. The approach outlined in this article aligns with common practice, but mileage will vary per project./p pRegardless of approach, focusing on components before pages will only become more important. Drupal content is already displayed on everything from watches to car dashboards. The web is not made of pages anymore. Designers have begun to embrace this and Drupal developers should too; everyone will benefit!/p /div

Makak Media: Taking BackDrop For A Test Drive

Mon, 02/16/2015 - 17:41
div class=field field-type-filefield field-field-blog-image div class=field-items div class=field-item odd img class=imagefield imagefield-field_blog_image width=470 height=470 title=Backdrop Drupal fork alt=Backdrop src=http://www.makakmedia.co.uk/files/backdrop-logo.png?1424100055 / /div /div /div pSo the first a href=https://backdropcms.org/ target=_blankBackDrop/a release is out there in the wild ready for a quick test drive! We're excited to see where this fork of Drupal 7 leads as we believe it to be a good complementary system to Drupal with a long term future./p pFirst off we checked under the hood to get things configured and found the settings.php file in the root folder, which makes for easier access. Also all those txt files have been removed including the CHANGELOG.txt file, which we remove by default, as it supplies useful info to any hacker out there!/p pNaturally the a href=https://backdropcms.org/installation target=_blankinstallation process/a is very similar to Drupal but with a few less settings giving it a simpler feel./p pUpon installation you're presented with a responsive admin menu with a slightly different structure to the standard Drupal menu. Responsiveness out of the box is great and the new menu again has a simpler look./p pa href=http://www.makakmedia.co.uk/blog/taking-backdrop-test-drive target=_blankread more/a/p

DrupalDare: G-WAN as a static Drupal file server

Mon, 02/16/2015 - 17:26
So now that we have concluded that it's easy to setup distribution of files on a separate subdomain, what about using a completely other web server (or in this case an application server)? Will it blend?

Acquia: Development based on Drupal's Fundamental Particles - Brad Czerniak

Mon, 02/16/2015 - 13:34
div class=form-item form-type-item labelLanguage /label Undefined /div div class=field field-name-body field-type-text-with-summary field-label-hidden div class=field-items div property=content:encoded class=field-item evenp Presenter Brad Czerniak caught my eye with a blog post entitled a href=https://www.commercialprogression.com/post/10-things-i-learned-using-drupal-hackathon10 things I learned using Drupal at a hackathon/a, based on his experiences taking part in the #hackDPL (Detroit Public Library) competitive hackathon. In our podcast interview we talk about that – before moving on to Brad's session about the Drupal development best practices he and his team use at a href=https://www.commercialprogression.comCommercial Progression/a in Michigan./p /div /div /div figure class=field-item even rel= resource=https://www.acquia.com/sites/default/files/jdc_brad_image.png class=field-item even div id=styles-2 class=styles styles-field-image styles-style-scale_width_280 styles-container-image styles-preset-scale_width_280 img typeof=foaf:Image src=https://www.acquia.com/sites/default/files/styles/scale_width_280/public/jdc_brad_image.png?itok=_V2ovT59 alt= title= //div !-- render the title tag as caption -- /figure span property=dc:title content=Development based on Drupal#039;s Fundamental Particles - Brad Czerniak class=rdf-meta element-hidden/span

Annertech: Enlightening - The Dark Art of Solr Search with Drupal

Mon, 02/16/2015 - 12:41
span class=field field-node--title field-name-title field-type-string field-label-hiddenEnlightening - The Dark Art of Solr Search with Drupal/span div class=field field-node--body field-name-body field-type-text-with-summary field-label-hidden div class=field-items div class=field-itemh2Why this blog post?/h2 pOften when I add a search function to a Drupal website using Apache Solr, I'm amazed at how complex some people think this is. Many developers/site builders are of the belief that this is some kind of very-hard-to-master black art. They could not be more wrong./p pSo what I want to contribute back to the Drupal community is an understanding of how Solr works, why/how it differs from Drupal Core Search module, and the benefits Solr has over core search./p/div /div /div

lakshminp.com: The Drupal 8 plugin system - part 2

Mon, 02/16/2015 - 11:38
pWe saw in a href='http://www.lakshminp.com/the-drupal-8-plugin-system-part-1/' part 1/a how plugins help us in writing reusable functionality in Drupal 8. There are a lot of concepts which plugins share in common with services, like:/p ol lilimited scope. Do one thing and do it right. /li liPHP classes which are swappable./li /ol pWhich begs the question, how exactly are plugins different from services? br / If your interface expects implementations to yield the same behaviour, then go for services. Otherwise, you should write it as a plugin. This needs some explaining. br / For instance, if you are creating an interface to store data in a persistent system, like MySQL or MongoDB, then it would be implemented as a service. The codesave()/code function in your interface interface will be implemented differently for both the services, but the behaviour will be the same, i.e., it takes data as input parameters, stores them in the respective data store and returns a success message./p pOn the other hand, if you are creating an image effect, it needs to be a plugin. (It already is. Check a href='https://api.drupal.org/api/drupal/core' !modules!image!src!ImageEffectInterface.php/interface/ImageEffectInterface/8image effects as plugins/a). The core concept of image plugins is to take in an image, apply an effect on it and return the modified image. Different image effects yield different behaviours. An image scaling effect might not produce the same behaviour as that of an image rotating effect. Hence, each of these effects need to be implemented as a plugin. If any module wants to create a new image effect, it needs to write a new plugin by extending the codeImageEffectBase/code class./p h4 id=pluginsusedincorePlugins used in core/h4 pLet's take a look at the major plugin types provided by Drupal 8 core. An example plugin of each plugin types will be the subjects of future blog posts./p ol lipstrongBlocks/strong br / Drupal 8 finally got blocks right. Custom blocks can be created from the codeBlockBase/code class./p/li lipstrongField Types, Field Widgets and Field Formatters/strong br / Check a href='http://www.lakshminp.com/the-drupal-8-plugin-system-part-1/' part 1/a for how this is done in Drupal 8./p/li lipstrongActions/strong br / Drupal 8 allows module developers to perform custom actions by implementing the codeActionBase/code class. Blocking a user, unpublishing a comment, making a node sticky etc. are examples of actions./p/li lipstrongImage Effects/strong br / Image effects are plugins which manipulate an image. You can create new image effects by extending codeImageEffectBase/code. Examples of core image effects are codeCropImageEffect/code and codeScaleImageEffect/code./p/li lipstrongInput filters/strong br / User submitted input is passed through a series of filters before it is persisted in the database or output in HTML. These filters are implemented as plugins by implementing the codeFilterBase/code class./p/li lipstrongEntity Types/strong br / In Drupal parlance, entities are objects that persist content or configuration in the database. Each entity is an instance of an entity type. New entity types can be defined using the annotation discovery mechanism./p/li lipstrongViews related plugins/strong br / A large collection of different plugin types are employed by views during the querying, building and rendering stages. /p/li /ol h4 id=plugindiscoveryPlugin Discovery/h4 pPlugin discovery is the process by which Drupal finds plugins written in your module. Drupal 8 has the following plugin discovery mechanisms:/p ol lipstrongAnnotation based/strong. Plugin classes are a href='http://www.lakshminp.com/annotations-in-drupal-8/' annotated/a and have a directory structure which follows the PSR-4 notation. /p/li lipstrongHooks/strong. Plugin modules need to implement a hook to tell the manager about their plugins./p/li lipstrongYAML files/strong. Plugins are listed in YAML files. Drupal Core uses this method for discovering local tasks and local actions./p/li lipstrongStatic/strong. Plugin classes are registered within the plugin manager class itself. This is useful if other modules should not create new plugins of this type./p/li /ol pAnnotation based discovery is the most popular plugin discovery method in use. We will briefly look at how we create a new plugin type using this method in the next part./p

DrupalDare: CDN, Cookieless Requests and Subdomains

Mon, 02/16/2015 - 10:52
In this text I will go in to the topic of using a separate domain for serving your static files to avoid the client sending unnecessary cookies in the headers and why it may be or may not be a solution to speed up your website.

Drupal core announcements: Drupal core security release window on Wednesday, February 18

Mon, 02/16/2015 - 04:37
div class=field field-type-datestamp field-field-start7 div class=field-items div class=field-item odd div class=field-label-inline-first Start:nbsp;/div span class=date-display-single2015-02-18 (All day) America/New_York/span /div /div /div div class=field field-type-text field-field-event-type div class=field-items div class=field-item odd Online meeting (eg. IRC meeting) /div /div /div div class=field field-type-userreference field-field-organizers div class=field-labelOrganizers:nbsp;/div div class=field-items div class=field-item odd a href=/user/14705 title=View user profile.David_Rothstein/a /div /div /div pThe monthly security release window for Drupal 6 and Drupal 7 core will take place on Wednesday, February 18./p pThis does not mean that a Drupal core security release will necessarily take place on that date for either the Drupal 6 or Drupal 7 branches, only that you should prepare to look out for one (and be ready to update your Drupal sites in the event that the Drupal security team decides to make a release)./p pThere will be no bug fix release on this date; the next window for a Drupal core bug fix release is Wednesday, March 4./p pFor more information on Drupal core release windows, see the documentation on a href=http://drupal.org/documentation/version-info#whenrelease timing/a and a href=http://drupal.org/node/1173280security releases/a, and the a href=http://groups.drupal.org/node/260803discussion/a that led to this policy being implemented./p

Drupalpress, Drupal in the Health Sciences Library at UVA: two new drupal distros – one for voting, one for 3d printing e-commerce

Sun, 02/15/2015 - 21:29
pTwo new drupal distributions available on githubimg class=alignnone size-full wp-image-848 src=http://blog.hsl.virginia.edu/drupalpress/wp-content/uploads/sites/13/2015/02/frong.png alt=frong width=85 height=94 //p p** a href=https://github.com/alibama/cvillecouncilushttps://github.com/alibama/cvillecouncilus/a is the distribution behind a href=https://www.cvillecouncil.us%20https://www.cvillecouncil.us /a- it#8217;s an attempt to run a political campaign through a virtual proxy#8230;/p p** https://github.com/alibama/rapid-prototyping-ecommerce-drupal #8211; this is the code behind a href=http://rpl.mae.virginia.edu/http://rpl.mae.virginia.edu//a it#8217;s an e-commerce solution for 3d printing#8230; A lot of this is implemented in rules and other well-standardized code thanks to a href=https://www.acquia.com/about-us/team/joseph-pontaniJoe Pontani/a - a talented developer here in Virginia.  Joe integrated several third party tools, and set up the UVa payment gateway through Nelnet./p pBoth sites are getting updates over the next few months #8211; the Charlottesville Council website also has a a href=https://www.drupal.org/project/drupalgapdrupalgap/a implementation on it #8211; absolutely awesome toolset#8230;/p pa href=https://github.com/18F/api-standards18F API compliance/a is another feature I#8217;m pretty stoked about#8230; I got most of that done with the a href=https://www.drupal.org/project/oauth2_serveroauth2 server/a, a href=https://www.drupal.org/project/views_datasourceviews datasource/a, a href=https://www.drupal.org/project/servicesservices/a and a couple of great notification features done with a href=https://www.drupal.org/project/views_rulesrules + views /a i#8217;ll get that feature out asap = it#8217;s really convenient #8211; matching a a href=https://www.drupal.org/project/profile2profile2/a taxonomy field onto content taxonomy fields for notifications with new content./p pany questions #8211; please drop a line in the comments below/p

DrupalOnWindows: Bypassing Form Validations and Required Fields in Drupal: the BFV module.

Sun, 02/15/2015 - 07:00
div class=form-item form-type-item labelLanguage /label English /div div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedpRequired or not required? To validate or not to validate? That is the question. So you've setup (the site builder's way, no custom forms) your required fields and custom validations for Node types, just to get this feedback from the customer:/p blockquote pemstrongThat field we defined as mm..... as required (something trivial and not really critical such as an image file) is actually not always required. Users X and Y should be able to bypass that restriction./strong/em/p/blockquote/div/div/divdiv class=view view-read-more view-id-read_more view-display-id-entity_view_1 view-dom-id-58adb01753a9a66a7c98325e97564d18 div class=view-header hr/ h2More articles.../h2 /div div class=view-content div class=item-list ul li class=views-row views-row-1 views-row-odd views-row-first div class=views-field views-field-title span class=field-contenta href=/en/blog/drupal-iis-or-apacheDrupal on IIS or Apache/a/span /div/li li class=views-row views-row-2 views-row-even div class=views-field views-field-title span class=field-contenta href=/en/blog/bypassing-form-validations-and-required-fields-drupal-bfv-moduleBypassing Form Validations and Required Fields in Drupal: the BFV module./a/span /div/li li class=views-row views-row-3 views-row-odd div class=views-field views-field-title span class=field-contenta href=/en/blog/node-comment-and-forum-working-together-boost-user-participationNode Comment and Forum working together to boost user participation/a/span /div/li li class=views-row views-row-4 views-row-even div class=views-field views-field-title span class=field-contenta href=/en/blog/installing-drupal-windows-and-sql-serverInstalling Drupal on Windows and SQL Server/a/span /div/li li class=views-row views-row-5 views-row-odd div class=views-field views-field-title span class=field-contenta href=/en/blog/setting-code-syntax-higlighting-drupalSetting up Code Syntax Higlighting with Drupal/a/span /div/li li class=views-row views-row-6 views-row-even div class=views-field views-field-title span class=field-contenta href=/en/blog/getting-2000-requests-second-without-varnishGetting #2,000 requests per second without varnish/a/span /div/li li class=views-row views-row-7 views-row-odd views-row-last div class=views-field views-field-title span class=field-contenta href=/en/blog/distinct-options-views-exposed-filter-views-selective-filters-moduleDistinct options in a views exposed filter: The Views Selective Filters Module/a/span /div/li /ul/div /div /div

Drupal @ Penn State: A window into our Community

Sat, 02/14/2015 - 17:22
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedh3Intro/h3 pSomething that inspired me recently to write about DUG, are the efforts of MediaCurrent. Media Current has recently been pushing forward a series of postings talking about how they are giving back and being a lot more open about use of time to give back (which is awesome)./p/div/div/div

Angie Byron: Webchick's plain Drupal English Guide to the Remaining Drupal 8 Critical Issues: DrupalCon Bogotá Edition

Sat, 02/14/2015 - 10:09
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedpem(Apologies for the atrocious state of the HTML that follows; this content is originally from this a href=https://docs.google.com/a/acquia.com/document/d/1NPrRzDHinng_m7T5dkqYp1EFRz7YNiCf6zBpD35gqIs/edit#heading=h.s4qidulco3wzGoogle Doc/a.)/em/p phtmlheadtitleWebchick#39;s quot;plain Drupal Englishquot; Guide to the Remaining Drupal 8 Critical Issues: DrupalCon Bogotaacute; Edition/titlemeta content=text/html; charset=UTF-8 http-equiv=content-type/headbody class=c19br / p class=c6span class=c3/span/p p class=c6 c17span class=c2/span/p p class=c11span class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Flatinamerica2015.drupal.org%2Famp;sa=Damp;sntz=1amp;usg=AFQjCNGJrgwnj274TDCl2SC8jCcTR-MdIgDrupalCon Bogotaacute;/a/spanspannbsp;just finished up, and /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%2Fdrupal%3Fstatus%5B0%5D%3D1%26status%5B1%5D%3D13%26status%5B2%5D%3D8%26status%5B3%5D%3D14%26status%5B4%5D%3D4%26priorities%5B0%5D%3D400%26categories%5B0%5D%3D1%26categories%5B1%5D%3D2%26version%5B0%5D%3D8.xamp;sa=Damp;sntz=1amp;usg=AFQjCNF8nVOE_XYO8vT4zxqVhLbjBEDpXQcritical issue/a/spanspan-wise/spanspannbsp;we#39;ve managed to stay in the 50s for a few days (down from a high of 150 last summer!), so now seems like as good a time as any to write down what#39;s left to /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fdrupal-8.0%2Fget-involvedamp;sa=Damp;sntz=1amp;usg=AFQjCNGBWBAEHObfCfWKwarFwozMIh50rQship Drupal 8/a/spanspan!/span/p p class=c6span/span/p p class=c11spanThis post will attempt to document all of the remaining 55 criticals (as of this writing), and attempt to offer a somewhat quot;plain Englishquot; (or at least quot;Drupal Englishquot; ;)) description of each, loosely categorized into larger areas in which we could really use extra help. There are over /spanspan class=c2a class=c0 href=http://www.google.com/url?q=http%3A%2F%2Fdrupalcores.com%2Famp;sa=Damp;sntz=1amp;usg=AFQjCNHGpEysQ8In8V6ElYae14OKAKpjlg2,600 contributors to Drupal 8/a/spanspannbsp;at this time, please /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fdrupal-8.0%2Fget-involved%23helpamp;sa=Damp;sntz=1amp;usg=AFQjCNE8wZbctf2QLIuB8mY3GwARruilbQjoin us/a/spanspan!/span/p p class=c6span/span/p p class=c11span class=c16(Note: These descriptions might not be 100% accurate; this is my best approximation based on the issue summary and last few comments of each issue. If I got the description of your pet issue wrong, please update your issue summary. ;))/span/p !--break--p class=c6span class=c16/span/p h1 class=c7a name=h.inl72dbedobg/aspanTable of contents/span/h1 p class=c11 c17span class=c2a class=c0 href=#h.ypqccthuaoguQuick vocabulary lesson/a/span/p p class=c11 c17span class=c2a class=c0 href=#h.t6s6dg6hbxhnCurrent state of critical issues/a/span/p p class=c1span class=c2a class=c0 href=#h.p75y1r4tm9nvSecurity/a/span/p p class=c4span class=c2a class=c0 href=#h.c3q69feo7cmiSecurity Parity with Drupal 7/a/span/p p class=c4span class=c2a class=c0 href=#h.6deq2nteoql6Session and User Authentication API/a/span/p p class=c4span class=c2a class=c0 href=#h.6kuo2v4augbaREST/a/span/p p class=c4span class=c2a class=c0 href=#h.em182923ghiiNew security improvements/a/span/p p class=c1span class=c2a class=c0 href=#h.biagh7n8rgptPerformance/a/span/p p class=c4span class=c2a class=c0 href=#h.i2oyr5rqaj4xProfiling/a/span/p p class=c4span class=c2a class=c0 href=#h.z6xejabnynwFix regressions relative to Drupal 7/a/span/p p class=c1span class=c2a class=c0 href=#h.sumg6cigkyfoEntity Field API/a/span/p p class=c1span class=c2a class=c0 href=#h.pvyrwdfyvdc0Views/a/span/p p class=c1span class=c2a class=c0 href=#h.yssr9b6rl72aConfiguration system/a/span/p p class=c1span class=c2a class=c0 href=#h.744pljan9umiquot;Fix it, or elsequot;/a/span/p p class=c1span class=c2a class=c0 href=#h.h46w1jnuchnrGeneral house-keeping/a/span/p p class=c1span class=c2a class=c0 href=#h.rmvhprdt1fbkOther/a/span/p p class=c11 c17span class=c2a class=c0 href=#h.bf4k5phhkgn7Thrilling conclusion! (also known as quot;TL;DRquot;)/a/span/p p class=c6span/span/p h1 class=c7a name=h.ypqccthuaogu/aspanQuick vocabulary lesson/span/h1 p class=c11spanWithin this list, there are numerous quot;markersquot; used to signify that some of the issues in this list are more important to fix ASAP. These are:/span/p p class=c6span/span/p ul class=c8 lst-kix_9vpbdt1zxr8p-0 start li class=c1 c5span class=c15 c3D8 upgrade path/spanspan: An issue tagged /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%3Fissue_tags%3DD8%2520upgrade%2520pathamp;sa=Damp;sntz=1amp;usg=AFQjCNEXNqQsm8FbF5G9RG2BykCXaeQvDwD8 upgrade path/a/spanspannbsp;(currently, 13) means it blocks a beta-to-beta upgrade path for Drupal 8, generally because they materially impact the data schema or they impact security. Once we resolve all of these blockers, early adopters will no longer need to reinstall Drupal between beta releases, but can just run the update.php script as normal. This is currently our biggest priority./span/li li class=c1 c5span class=c3 c12Blocker/spanspan: An issue tagged /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%2Fdrupal%3Fproject_issue_followers%3D%26status%255B%255D%3D1%26status%255B%255D%3D13%26status%255B%255D%3D8%26status%255B%255D%3D14%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26issue_tags_op%3D%253D%26issue_tags%3Dblockeramp;sa=Damp;sntz=1amp;usg=AFQjCNFnReuY9Oi3etLjtLzttlaaRGhnHwblocker/a/spanspannbsp;(currently, 5) means it blocks other issues from being worked on. This is currently our second-biggest priority (or 0th priority in the case an issue blocks a D8 upgrade path issue :D). I#39;ve noted these as quot;sub-bulletsquot; of the issues that are blocking them./span/li li class=c1 c5span class=c3 c20Postponed/spanspan: Issues that are marked /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%2Fdrupal%3Fproject_issue_followers%3D%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26version%255B%255D%3D8.x%26issue_tags_op%3D%253Damp;sa=Damp;sntz=1amp;usg=AFQjCNEjNZ9RiYEbx9e3p6ABvoXyTCygpQpostponed/a/spanspannbsp;(currently, 9)/spanspannbsp;are either currently blocked by one of the quot;Blockerquot; issues, or we#39;ve deliberately chosen to leave off until later./span/li li class=c1 c5span class=c10 c3gt;30 days/spanspan: These patches have a patch more than 30 days old, and/or were last meaningfully commented on gt;30 days ago. If you#39;re looking for a place to start, re-rolling these is always helpful!/span/li li class=c1 c5span class=c3No patch/spanspan: This issue doesn#39;t have a patch yet. Oh the humanity! Want to give it a shot?/span/li /ul p class=c6span/span/p p class=c11spanOther weird core issue nomenclature:/span/p ul class=c8 lst-kix_d07eoiemqszj-0 start li class=c1 c5spanquot;metaquot; means a discussion/planning issue, with the actual patch action happening in related/child issues./span/li li class=c1 c5spanquot;PP-3quot; means quot;this issue is postponed on 3 other issuesquot; (PP-1 means 1 other issue; you get the drift)./span/li /ul h1 class=c7a name=h.t6s6dg6hbxhn/aspanCurrent state of critical issues/span/h1 p class=c11spanSections roughly organized from quot;scariestquot; to quot;least scaryquot; in terms of how likely they are to make Drupal 8 take a longer time to come out./span/p h2 class=c7 c21a name=h.p75y1r4tm9nv/aspanSecurity/span/h2 p class=c11spanBecause Drupal 8 hasn#39;t shipped yet, it#39;s not following Drupal#39;s standard /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fsecurityamp;sa=Damp;sntz=1amp;usg=AFQjCNE6hXR2nTFHqCu3OvDgPLfu_y0OswSecurity Advisory/a/spanspannbsp;policy, so there are still outstanding, public /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%2Fdrupal%3Fproject_issue_followers%3D%26status%255B%255D%3D1%26status%255B%255D%3D13%26status%255B%255D%3D8%26status%255B%255D%3D14%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26version%255B%255D%3D8.x%26issue_tags_op%3D%253D%26issue_tags%3Dsecurityamp;sa=Damp;sntz=1amp;usg=AFQjCNEE-dzgLOIyDKSjRNfsHuZCz5V5jQsecurity/a/spanspannbsp;issues (13 as of this writing). We need to resolve most of these prior to providing a Drupal 8 beta-to-beta upgrade path, as this is the time when we signal to early adopters that it#39;s an OK time to start /spanspan class=c16cautiously/spanspannbsp;building real sites on Drupal 8./span/p p class=c6span/span/p p class=c11span class=c3Skills needed:/spanspannbsp;Various/span/p h3 class=c7 c18a name=h.c3q69feo7cmi/aspanSecurity Parity with Drupal 7/span/h3 p class=c11spanThis class of security issue is to ensure that when Drupal 8 ships, it won#39;t have any regressions security-wise relative to Drupal 7./span/p p class=c6span/span/p ul class=c8 lst-kix_yganm4mrgvck-0 start li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2419941amp;sa=Damp;sntz=1amp;usg=AFQjCNGK1L8XgveCFCz6l1g6qPhNcOcUhwCheck every Drupal 7 contrib SA that may affect Drupal 8 core modules/a/spanspannbsp;(/spanspan class=c15 c3D8 upgrade path/spanspan)/spanspannbsp;/spanspanIn order to ship Drupal 8, we need to ensure that there are no outstanding security advisories for contributed modules that were pushed into Drupal 8 core. /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fu%2Fnickwaring89amp;sa=Damp;sntz=1amp;usg=AFQjCNHx40Z5ftf-hlxruq3c_PeaRk6mPAnickwaring89/a/spanspannbsp;has started a /spanspan class=c2a class=c0 href=https://docs.google.com/a/acquia.com/spreadsheets/d/1kULeE6-Kpd181d4-1eBOi1mInbV-nbfS4kyUzzkPSvM/editfantabulous spreadsheet/a/spanspannbsp;for tracking this./span/li /ul ul class=c8 lst-kix_yganm4mrgvck-1 start li class=c9 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2419923amp;sa=Damp;sntz=1amp;usg=AFQjCNHbxhTjkzh6PXzA6AKaWOZoZvpxHwPort SA-CONTRIB-2013-096 to D8/a/spanspannbsp;(/spanspan class=c15 c3D8 upgrade path/spanspan)/spanspannbsp;/spanspanHere#39;s one such issue for Entity Reference module. /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2140237amp;sa=Damp;sntz=1amp;usg=AFQjCNE_Q1z7h0E-5PgopAMTZ0GEjAZ_OQSA-CONTRIB-2013-096/a/spanspannbsp;addressed a relatively esoteric remote access bypass bug, and the patch needs to be forward-ported to Drupal 8./span/li li class=c9 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2426389amp;sa=Damp;sntz=1amp;usg=AFQjCNEBR15tqk_V6vSj-1k_ZSjhOtnfJgPort SA-CONTRIB-2015-039 to D8/a/spanspannbsp;(/spanspan class=c15 c3D8 upgrade path/spanspan) nbsp;/spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2424403amp;sa=Damp;sntz=1amp;usg=AFQjCNG77PvXsIeFn7NNNnsmB1TfaCcq4wSA-CONTRIB-2015-039/a/spanspannbsp;addressed two issues in Views module, a redirect and default permissions for disabled views. The first was fixed in D8, but access checks are still missing from a few views for the second./span/li /ul ul class=c8 lst-kix_yganm4mrgvck-0 li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2421503amp;sa=Damp;sntz=1amp;usg=AFQjCNEikiGzTxTjIYmAJVNiYwxdgkE1iASA-CORE-2014-002 forward port only checks internal cache/a/spanspannbsp;(/spanspan class=c15 c3D8 upgrade path/spanspan) Oopsie. Missed a spot. :P /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2FSA-CORE-2014-002amp;sa=Damp;sntz=1amp;usg=AFQjCNFeY1YGG7yO-Cp9bJ2eNUfTub1dvASA-CORE-2014-002/a/spanspannbsp;was a moderately critical Form API issue, where anonymous users#39; form entries on cached forms could potentially leak to other anonymous users. It was partially fixed, but not for reverse-proxies./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2099137amp;sa=Damp;sntz=1amp;usg=AFQjCNG7-dmCg0gmcbaJig_AG4X0LPt4NgEntity/field access and node grants not taken into account with core cache contexts/a/spanspan class=c3nbsp;/spanspanWe need to figure out and document what the API looks like for field/entity access modules that interact with the new render cache in Drupal 8./span/li /ul p class=c6span/span/p h3 class=c7a name=h.6deq2nteoql6/aspanSession and User Authentication API/span/h3 p class=c11spanBecause of various intricate dependencies, the /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%3Fprojects%3D%26project_issue_followers%3D%26status%255B%255D%3D1%26status%255B%255D%3D13%26status%255B%255D%3D8%26status%255B%255D%3D14%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26issue_tags_op%3D%253D%26issue_tags%3Dauthenticationamp;sa=Damp;sntz=1amp;usg=AFQjCNHUVxi3Nzd7xh8WMJ5yV2ZyWr4e7gauthentication/a/spanspannbsp;part of Drupal 8 isn#39;t yet converted to object-oriented code, and prevents us from further optimizing bootstrap. This set of issues fixes various problems with this part of the code, and ensures these important security APIs are complete and ready to ship./span/p p class=c6span/span/p ul class=c8 lst-kix_yganm4mrgvck-0 li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2371629amp;sa=Damp;sntz=1amp;usg=AFQjCNEPNBsa6yiO9TJTXxrrFHPZuf5R0Q[meta] Finalize Session and User Authentication API/a/spanspannbsp;(/spanspan class=c12 c3Blocker/spanspan)/spanspannbsp;The main tracking issue for work in this area. /span/li /ul ul class=c8 lst-kix_yganm4mrgvck-1 start li class=c9 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2286971amp;sa=Damp;sntz=1amp;usg=AFQjCNE3qHai1PTtt4NZof7Ov5HTm3cwlgRemove dependency of current_user on request and authentication manager/a/spanspannbsp;Aims to solve a circular dependency when implementing alternative authentication schemes, and move authentication to only happening once per request, closing a potential security hole./span/li li class=c9 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2283637amp;sa=Damp;sntz=1amp;usg=AFQjCNHotmL3gf7a_UsK2mlM7DXxxHePLASession for an authenticated user can only be set by Cookie AuthenticationProvider/a/spanspannbsp;(/spanspan class=c10 c3gt;30 days/spanspan, /spanspan class=c3No patch/spanspan) Currently, alternative authentication providers, such as /spanspan class=c2a class=c0 href=http://www.google.com/url?q=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FBasic_access_authenticationamp;sa=Damp;sntz=1amp;usg=AFQjCNE1YdRxSeAnkCI6OWfgrKUjQ2HtGQHTTP basic authentication/a/spanspan, do not play nicely with the default login form, because Cookie trumps all./span/li li class=c9 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2286591amp;sa=Damp;sntz=1amp;usg=AFQjCNFq3Rn3xjTMFFxUtBkIpi4gMAXP8Q[meta] Security audit the Authentication component/a/spanspannbsp;(/spanspan class=c20 c3Postponed/spanspan) Since the Authentication component is new to Drupal 8, this issue proposes performing a security audit on it once it#39;s complete, and prior to a release candidate./span/li /ul h3 class=c7a name=h.6kuo2v4augba/aspanREST/span/h3 ul class=c8 lst-kix_yganm4mrgvck-0 li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2418119amp;sa=Damp;sntz=1amp;usg=AFQjCNE5DhudRAsbbsLBpOwYBUDMWh2mygREST user updates bypass tightened user account change validation/a/spanspannbsp;(/spanspan class=c15 c3D8 upgrade path/spanspan) Since Drupal 7, when you edit your user account, you have to provide the existing password when you want to change the password or e-mail. This security feature is currently by-passed by REST user updates as you can change the password or e-mail without providing the password./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2364011amp;sa=Damp;sntz=1amp;usg=AFQjCNHiSSvwiGTekNKdi9DIloIaXDKdGAExternal caches mix up response formats on URLs where content negotiation is in use/a/spanspannbsp;(/spanspan class=c10 c3gt;30 days/spanspan) Drupal 8#39;s request processing system is currently based on /spanspan class=c2a class=c0 href=http://www.google.com/url?q=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FContent_negotiationamp;sa=Damp;sntz=1amp;usg=AFQjCNHcBrGVQONVoIMLN5YSMYElSdT8BAcontent negotiation/a/spanspannbsp;(which allows you to serve multiple versions of a document at the same URI based on what headers are sent e.g. /spanspan class=c14Accept: text/html/spanspannbsp;or /spanspan class=c14Accept: application/json/spanspan). This is generally considered the quot;right wayquot; to do REST. However, various external caches and CDNs have trouble with this mechanism, and can mix them up and can send random formats back. The issue proposes changing from content negotiation to separate, distinct paths such as /spanspan class=c14/node/1.json/spanspan./span/li /ul p class=c6span/span/p h3 class=c7a name=h.em182923ghii/aspanNew security improvements/span/h3 p class=c11spanThese issues affect new security improvements we want to make over and above what Drupal 7 does./span/p p class=c6span/span/p ul class=c8 lst-kix_yganm4mrgvck-0 li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2280965amp;sa=Damp;sntz=1amp;usg=AFQjCNE6yDK--MVpSZgZP0ksjjcY_pFPyw[meta] Document or remove every SafeMarkup::set() call/a/spanspannbsp;One of the big security improvements in Drupal 8 is the introduction of /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2296163amp;sa=Damp;sntz=1amp;usg=AFQjCNHzHdi5mifH6_l5xc_Ydw1MBTrjqwTwig#39;s autoescape feature/a/spanspan, which ensures that all output to the browser is escaped by default. However, this is quite a big change that requires all of the code that was previously escaping content to stop doing that, else it gets double-escaped (so you start seeing amp;lt; and amp;quot; and whatnot in the UI). We originally introduced the ability to manually mark markup safe with SafeMarkup::set(), but the recommended approach is actually to use Twig everywhere, so this issue is to ensure that all remaining instances of the manual way are fixed, or at least documented to explain why they#39;re using the non-recommended method./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2273925amp;sa=Damp;sntz=1amp;usg=AFQjCNHPAbdYg2eVFILdxr4wSf9Wv4Y2XAPassing in #markup to drupal_render is problematic/a/spanspannbsp;(/spanspan class=c3 c10gt;30 days/spanspan) Another issue in the Twig autoescape space, we need to ensure that markup set by the quot;#markupquot; in e.g. form definitions is properly escaped./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2388255amp;sa=Damp;sntz=1amp;usg=AFQjCNG_pyMR6BJLQviWq_GJ2zG4nRUAlQLimit PDO MySQL to executing single statements if PHP supports it/a/spanspannbsp;Remember /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2FSA-CORE-2014-005amp;sa=Damp;sntz=1amp;usg=AFQjCNEQRTkLmxQjO-2mhrfqYZjegbotJQSA-CORE-2014-005/a/spanspan? Yeah, so do we. ;) This issue is to make sure that if another SQL injection vulnerability is ever found again, the damage it can do is more limited by eliminating the ability for MySQL to execute multiple queries per PDO statement./span/li /ul p class=c6span/span/p h2 class=c7a name=h.biagh7n8rgpt/aspanPerformance/span/h2 p class=c11spanTied with security, 13 of the remaining issues are tagged /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%2Fdrupal%3Fproject_issue_followers%3D%26status%255B%255D%3D1%26status%255B%255D%3D13%26status%255B%255D%3D8%26status%255B%255D%3D14%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26version%255B%255D%3D8.x%26issue_tags_op%3D%253D%26issue_tags%3DPerformanceamp;sa=Damp;sntz=1amp;usg=AFQjCNG98Y_gFvVEV5XHo5qZ8GarKoAm_wPerformance/a/spanspan. While it may seem odd/scary to have this be a big chunk of the work left, it#39;s a common practice to avoid /spanspan class=c2a class=c0 href=http://www.google.com/url?q=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FProgram_optimizationamp;sa=Damp;sntz=1amp;usg=AFQjCNEmMdOMhBEUKJH-GUvIFKxDC8Yngwpremature optimization/a/spanspan, and instead focus on optimization once all of the foundations are in place./span/p p class=c6span/span/p p class=c11span class=c3Skills needed:/spanspannbsp;Profiling, caching, optimization, render API/span/p h3 class=c7 c18a name=h.i2oyr5rqaj4x/aspanProfiling/span/h3 p class=c11spanHere are a sub-set of issues where we need /spanspan class=c2a class=c0 href=http://www.google.com/url?q=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FProfiling_%2528computer_programming%2529amp;sa=Damp;sntz=1amp;usg=AFQjCNHX9Ju8VdZb8SednN4ujo8eHdEANQperformance profiling/a/spanspannbsp;to determine what gives us the biggest bang for our effort./span/p p class=c6span/span/p ul class=c8 lst-kix_rfxe804vasvo-0 start li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2289201amp;sa=Damp;sntz=1amp;usg=AFQjCNE6oVI4QL1UrYjSq5Q8K40EBFdZAw[Meta] Make drupal install and run within reasonable php memory limits so we can reset the memory requirements to lower levels/a/spanspannbsp;Due to a variety of issues, including the YAML parsing slowness mentioned above, Drupal 8 currently requires 64M of memory to install, which will only go up as contrib modules are added. The goal is to reduce that significantly, more towards Drupal 7#39;s numbers. The issue contains a number of profiling results and sub-issues that help./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2407177amp;sa=Damp;sntz=1amp;usg=AFQjCNEAR3vsrB_mQMMCTimAuF7SYnAo3QProfile to determine which services should be lazy/a/spanspannbsp;Drupal 8 exposes a number of /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2133171amp;sa=Damp;sntz=1amp;usg=AFQjCNH8McLuguuXUNZGAfuw9HdNfSj4jQServices/a/spanspannbsp;(which contain re-usable functionality and allow for pluggability/replacement). Normally, all services that are dependencies of other services are loaded on page load. However, we recently introduced the /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F1973618amp;sa=Damp;sntz=1amp;usg=AFQjCNEULKE_uS7GX-6HWjuW1-FGs5P8NAability to mark individual services as quot;lazyquot;/a/spanspanmdash;meaning, to only load them on-demand. This issue is to determine which services are currently loading on every request, yet unneeded for most, so we can mark them as such./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2241377amp;sa=Damp;sntz=1amp;usg=AFQjCNGvBaynn0ugVU6K_QVHT2n1T_Ke0gProfile/rationalise cache tags/a/spanspannbsp;Drupal 8#39;s caching API introduces the notion of /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F1884800amp;sa=Damp;sntz=1amp;usg=AFQjCNFZMLi5pOcaHkbac-4UTkZiJrsZ3Qcache tags/a/spanspan, allowing for much more focused and targeted cache clears for much better performance. This issue involves investigating our usage of cache tags in D8 and seeing how they could be optimized/improved./span/li /ul h3 class=c7a name=h.z6xejabnynw/aspanFix regressions relative to Drupal 7/span/h3 ul class=c8 lst-kix_5xn4xca12dzt-0 start li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F1744302amp;sa=Damp;sntz=1amp;usg=AFQjCNGumXl7Vciwe3NdIB9dXRKVsaU2jA[meta] Resolve known performance regressions in Drupal 8/a/spanspannbsp;This is the main tracking issue in this space. During the 8.x cycle we#39;ve introduced several known performance regressions compared to Drupal 7 (sometimes to make progress on features/functionality, other times because we introduced changes that we hoped would buy us better scalability down the line), which we need to resolve before release so that Drupal 8 isn#39;t slower than Drupal 7. The performance team meets weekly and tracks their progress in a /spanspan class=c2a class=c0 href=https://docs.google.com/a/acquia.com/spreadsheet/ccc?key=0AgIiMuY_XxscdFZobFRaVjFnNkZmRUYyd2tqbmRvSGcamp;usp=drive_web#gid=0detailed spreadsheet/a/spanspan. /span/li /ul ul class=c8 lst-kix_5xn4xca12dzt-1 start li class=c9 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2395143amp;sa=Damp;sntz=1amp;usg=AFQjCNFteJLZwA3olK2UJ_HrZySQ3dJkGQYAML parsing is very slow, cache it with APCu in Drupal\Core\Config\FileStorage::read/a/spanspannbsp;(/spanspan class=c12 c3Blocker/spanspan) Installation in Drupal 8 is not as quick as it otherwise would be due to the slowness of parsing YAML files, sometimes more than once. This issue proposes to add a caching layer to speed things up, and also help eliminate noise found in profiling./span/li li class=c9 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2351015amp;sa=Damp;sntz=1amp;usg=AFQjCNGSS8ymNv0hzyoGkkCorrHKOeCrvQConvert menu CSRF tokens to use #post_render_cache/a/spanspannbsp;(/spanspan class=c12 c3Blocker/spanspan, /spanspan class=c10 c3gt;30 days/spanspan) nbsp;Drupal employs robust /spanspan class=c2a class=c0 href=http://www.google.com/url?q=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FCross-site_request_forgeryamp;sa=Damp;sntz=1amp;usg=AFQjCNGNxgWLDXkph21PuNF3gXAzYceNYgCross-Site Request Forgery/a/spanspannbsp;protection which involves appending a user-specific token on forms and links. However, this is both a bit overkill (in most systems there is just a single CSRF token per request) and also prevents caching of CSRF-protected forms/links./span/li /ul ul class=c8 lst-kix_5xn4xca12dzt-2 start li class=c11 c5 c13span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F1805054amp;sa=Damp;sntz=1amp;usg=AFQjCNHcoAuK7nmE8y_UEa_gkEcp9-F5Kg[PP-1] Cache localized, access filtered, URL resolved, (and rendered?) menu trees/a/spanspannbsp;(/spanspan class=c20 c3Postponed/spanspan, /spanspan class=c10 c3gt;30 days/spanspan) nbsp;An /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F1805054%23comment-8806959amp;sa=Damp;sntz=1amp;usg=AFQjCNELAJoATN0Vbf36CyXoDmysllW81Qimpressive performance improvement/a/spanspannbsp;for the new D8 toolbar, as well as menu blocks./span/li li class=c11 c5 c13span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F1965074amp;sa=Damp;sntz=1amp;usg=AFQjCNHX7OevQ7GNN5MS13aHU3y_N4EsvAAdd cache wrapper to the UrlGenerator/a/spanspannbsp;In Drupal 8, the url() function has been replaced by the /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2046643amp;sa=Damp;sntz=1amp;usg=AFQjCNGbzAYyB329l3-xqRgIPMBy00PkUgUrlGenerator/a/spanspannbsp;class instead. This issue is proposing to add caching to make it able to not re-do work once it#39;s already generated a given URL on the page./span/li /ul ul class=c8 lst-kix_5xn4xca12dzt-0 li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F356399amp;sa=Damp;sntz=1amp;usg=AFQjCNHJEkurZMY_J_lseygRmlU6bJA4rwOptimize the route rebuilding process to rebuild on write/a/spanspannbsp;Rebuilding the list of routes is expensive, and can result in race conditions (this also /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2425259amp;sa=Damp;sntz=1amp;usg=AFQjCNF_ZTbyYnjr1lCGReNjTPrEuUJIIwaffects Drupal 7/a/spanspan). This issue proposes to move menu rebuilding to write-only requests, which are expected to be expensive anyway./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2263569amp;sa=Damp;sntz=1amp;usg=AFQjCNGcgPe5UQGwbp0nUt5w4tu4WYMT6ACache-enabled forms generate cached form data for every user on every request/a/spanspannbsp;(/spanspan class=c3No patch/spanspan) There#39;s currently a bug exposed by Viewsmdash;/spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2252763amp;sa=Damp;sntz=1amp;usg=AFQjCNGYKD-eZUSuloKkdIKw-I4bFH6-8AViews exposed filter form causes enormous form state cache entries/a/spanspanmdash;but also visible in other forms that employ caching, which results in the form cache ballooning out of control. Needs to be fixed./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2396333amp;sa=Damp;sntz=1amp;usg=AFQjCNHmOWAPpp3HItML1p8-7Egm5Y8ogQBlockContentBlock ignores cache contexts required by the block_content entity/a/spanspannbsp;This is a bug fix (critical because there could be access control implications if a custom block has access-controlled fields on it) that ensures that a block and its associated block content both share the same list of cache contexts (e.g. language, roles, etc.)./span/li /ul h2 class=c7a name=h.sumg6cigkyfo/aspanEntity Field API/span/h2 p class=c11spanTracked under the /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%2Fdrupal%3Fproject_issue_followers%3D%26status%255B%255D%3D1%26status%255B%255D%3D13%26status%255B%255D%3D8%26status%255B%255D%3D14%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26version%255B%255D%3D8.x%26issue_tags_op%3D%253D%26issue_tags%3DEntity%2BField%2BAPIamp;sa=Damp;sntz=1amp;usg=AFQjCNH5xucBYr72OGkC1CJGy5b6Z9qr7AEntity Field API/a/spanspannbsp;tag (currently 6 issues)./span/p p class=c6span/span/p p class=c11span class=c3Skills needed:/spanspannbsp;Entity/Field API, Form API, Schema API/span/p p class=c6span/span/p ul class=c8 lst-kix_gkrhy9ftmdx5-0 start li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2423213amp;sa=Damp;sntz=1amp;usg=AFQjCNEm8zigRoETiM0xpgzyoHiJ7PEWNwSchema for newly defined entity types is never created/a/spanspannbsp;(/spanspan class=c3 c15D8 upgrade path/spanspan) When you first install a module that defines an entity type (for example, Comment), its database tables are correctly generated. However, if an entity definition is later added by a developer to an already-installed module, the related database schema won#39;t get created, nor will it be detected in update.php as an out-of-date update to run./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2405469amp;sa=Damp;sntz=1amp;usg=AFQjCNF6wft03zVHvuEyt9diRWr3opMtsAFileFormatterBase should extend EntityReferenceFormatterBase/a/spanspannbsp;(/spanspan class=c15 c3D8 upgrade path/spanspan) Entity Reference fields define a EntityReferenceFormatterBase class, which contains logic about which entities to display in the lookup, including non-existing entities and autocreated entities. File field#39;s FileFormatterBase class currently duplicates that logic, except it misses some parts, including access checking, which makes this a security issue. The issue proposes to simply make File field#39;s base class a sub-class of Entity Reference#39;s, removing the need of quot;sort of but not quite the samequot; code around key infrastructure./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2227227amp;sa=Damp;sntz=1amp;usg=AFQjCNFvSPNVJUSYpsaaC3je8mUVmSrEVgFieldTypePluginManager cannot instantiate FieldType plugins, good thing TypedDataManager can instantiate just about anything/a/spanspannbsp;Currently, you get a fatal error if you attempt to use Drupal 8#39;s /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fdeveloping%2Fapi%2F8%2Fpluginsamp;sa=Damp;sntz=1amp;usg=AFQjCNGHDJTI-JgUDgHDVY3h2LK4-As6MgPlugin API/a/spanspannbsp;to create a new instance of a field type. The current code in core is avoiding this problem by going roundabout via the /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F1794140amp;sa=Damp;sntz=1amp;usg=AFQjCNE7bW8j1L2jjLD1_nS4nCvjsW14owTyped Data API/a/spanspannbsp;instead. This issue#39;s critical because these are two of the most central APIs in Drupal 8, and they should work as expected./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F1696648amp;sa=Damp;sntz=1amp;usg=AFQjCNEEchonPMehGXhlW8w9B6bEaTtMBg[META] Untie content entity validation from form validation/a/spanspannbsp;Despite all the work to modernize Drupal 8 into a first-class REST server, there still remain places where validation is within form validation functions, rather as part of the proper entity validation API, which means REST requests (or other types of workflows that bypass form submissions) are missing validation routines. This meta issue tracks progress of moving the logic to its proper place./span/li /ul ul class=c8 lst-kix_gkrhy9ftmdx5-1 start li class=c5 c9span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2002180amp;sa=Damp;sntz=1amp;usg=AFQjCNF9xvqIvcl67YwKnFshYuhlejx2GwEntity forms skip validation of fields that are edited without widgets/a/spanspannbsp;(/spanspan class=c10 c3gt;30 days/spanspan) If a field can be edited with a form element that is not a Field API widget, we do not validate its value at the field-level (i.e., check it against the field#39;s constraints). Fixing this issue requires ensuring that all entity forms only use widgets for editing field values./span/li /ul ul class=c8 lst-kix_gkrhy9ftmdx5-2 start li class=c11 c5 c13span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2395831amp;sa=Damp;sntz=1amp;usg=AFQjCNH-RDl70ORNNulODzZ6hS4JX5UCEgEntity forms skip validation of fields that are not in the EntityFormDisplay/a/spanspannbsp;(/spanspan class=c3No patch, /spanspan class=c10 c3gt;30 days/spanspan) Drupal 8 has a new feature called quot;form modesquot; (basically analogous to quot;/spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F1577752amp;sa=Damp;sntz=1amp;usg=AFQjCNEjeFtdJbjqlLQkga6WGx_XxRZhoAview modes/a/spanspanquot; in Drupal 7, except allowing you to set up multiple forms for a given entity instead). Currently, we#39;re only validating fields that are displayed on a given form mode, even though those fields might have validation constraints on other fields that are not displayed. Critical because it could present a security issue./span/li /ul h2 class=c7 c21a name=h.pvyrwdfyvdc0/aspanViews/span/h2 p class=c11spanViews issues are generally tracked with the /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%2Fdrupal%3Fproject_issue_followers%3D%26status%255B%255D%3D1%26status%255B%255D%3D13%26status%255B%255D%3D8%26status%255B%255D%3D14%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26issue_tags_op%3D%253D%26issue_tags%3DVDCamp;sa=Damp;sntz=1amp;usg=AFQjCNGdFWFDDaUn7RV5xlUPP96K0BfhcQVDC/a/spanspannbsp;tag. There are currently 6 criticals at this point which touch on Views (some already covered in earlier sections)./span/p p class=c6span/span/p ul class=c8 lst-kix_9lopuf4j9p0n-0 start li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2342045amp;sa=Damp;sntz=1amp;usg=AFQjCNFYkCUijOMV0LTQJWAEiqXdwIsKZwViews base fields need to use same rendering as Field UI fields, for formatting, access checking, and translation consistency/a/spanspannbsp;(/spanspan class=c15 c3D8 upgrade path, /spanspan class=c12 c3Blocker/spanspan) This is a critical blocker to multilingual functionality; right now, Views mixes up languages when a node title (base field) and body (field UI field) are in the same view. However, it#39;s also the cause of various other inconsistencies, like the inability to select formatters and formatter options on base fields. This issue proposes treating base entity fields the same as Field UI fields in Views./span/li /ul ul class=c8 lst-kix_9lopuf4j9p0n-1 start li class=c9 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2385443amp;sa=Damp;sntz=1amp;usg=AFQjCNEyACbu7oe819jdX0twm-CxjsxRxA[PP-1] Base entity fields using #39;standard#39; plugin added via EntityViewsData to not respect field level access/a/spanspannbsp;(/spanspan class=c15 c3D8 upgrade path, /spanspan class=c20 c3Postponed/spanspan) Basically, a subset of the same problem. It#39;s postponed because the above issue may end up solving it./span/li /ul ul class=c8 lst-kix_9lopuf4j9p0n-0 li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2381217amp;sa=Damp;sntz=1amp;usg=AFQjCNFmL59VCm0NjAb1b-T29tkrR94qQQViews should set cache tags on its render arrays, and bubble the output#39;s cache tags to the cache items written to the Views output cache/a/spanspannbsp;This one is critical because it could result in Views showing stale content due to not correctly associating the cache tags of content displayed inside a view with the view itself./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2252763amp;sa=Damp;sntz=1amp;usg=AFQjCNGYKD-eZUSuloKkdIKw-I4bFH6-8AViews exposed filter form causes enormous form state cache entries/a/spanspannbsp;Because serialized views are ginormous, the size of the form cache grows exponentially on repeated load of a view with an exposed filter. This issue aims to reduce what is cached by views to stop this from happening./span/li /ul h2 class=c7 c21a name=h.yssr9b6rl72a/aspanConfiguration system/span/h2 p class=c11spanThe /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%3Fprojects%3D%26project_issue_followers%3D%26status%255B%255D%3D1%26status%255B%255D%3D13%26status%255B%255D%3D8%26status%255B%255D%3D14%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26issue_tags_op%3D%253D%26issue_tags%3DConfiguration%2Bsystemamp;sa=Damp;sntz=1amp;usg=AFQjCNFeeu8qmScm4vhXlSzmkbs5O7D-EQconfiguration system/a/spanspannbsp;is remarkably close to being shippable! Only 4 critical issues left. We#39;re now working on finalizing the niggly bits around edge cases that involve configuration that depends on other configuration./span/p p class=c6span/span/p p class=c11span class=c3Skills needed:/spanspannbsp;Configuration system, Entity Field API, Views/span/p p class=c6span/span/p ul class=c8 lst-kix_gdjmrlbf1bc0-0 start li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2345225amp;sa=Damp;sntz=1amp;usg=AFQjCNGrRIuplFmdAu3if6E4EPcVjezoMQ[meta-3] CMI path to release/a/spanspan: The main tracking issue for CMI-related issues./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2090115amp;sa=Damp;sntz=1amp;usg=AFQjCNFOWVft_KgKgMIWO4d3EjnoyfTncwDon#39;t install a module when its default configuration has unmet dependencies/a/spanspannbsp;(/spanspan class=c15 c3D8 upgrade path/spanspan) Seems like a good idea. :P Basically handles the situation where a module provides some default configuration (say, a default View), which references a dependency on some other module (say, an Entity Reference field). You want to ensure that the module#39;s default configuration can#39;t be installed unless all the various dependencies it needs are there./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2420107amp;sa=Damp;sntz=1amp;usg=AFQjCNH8NyvaOIPZhA1l_kWXwnn0nDSXZwDetermine which config entities can be fixed and which will be deleted when a dependency is removed/a/spanspannbsp;(/spanspan class=c12 c3Blocker/spanspan) When we uninstall a module we list which other configuration will be quot;affectedquot; by the uninstallation. This issue proposes to add new functionality to the configuration system to work out what is going to happen when a specified dependency (or set of dependencies in the case of multiple modules) is going to be removed./span/li /ul ul class=c8 lst-kix_gdjmrlbf1bc0-1 start li class=c9 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2416409amp;sa=Damp;sntz=1amp;usg=AFQjCNHtcw1ZuRdAtOsplntKct5pHLI_mw[PP-1] Delete dependent config entities that don#39;t implement onDependencyRemoval() when a config entity is deleted/a/spanspannbsp;(/spanspan class=c15 c3D8 upgrade path/spanspan) In the case where dependent configuration is part of the main configuration (for example, fields on a node type) we want to ensure clean-up is done when the main configuration is deleted./span/li /ul h2 class=c7a name=h.744pljan9umi/aspanquot;Fix it, or elsequot;/span/h2 p class=c11spanThis subset of issues are things that are part of core currently, and we would /spanspan class=c16really/spanspannbsp;like to keep, but are willing to make some hard choices in the event they are among the last remaining criticals blocking release. The quot;postponedquot; among this list means quot;postponed until we#39;re down to only a handful of criticals left.quot; If these issues end up remaining in the list, we will move their functionality to contrib, and hope to add it back to core in a later point release if it gets fixed up./span/p p class=c6span/span/p p class=c11span class=c3Skills required:/spanspannbsp;Various, but mainly low-level infrastructure and non-MySQL database skills./span/p p class=c6span/span/p ul class=c8 lst-kix_hhgio4gd2kqu-0 start li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2267715amp;sa=Damp;sntz=1amp;usg=AFQjCNGoAdO3NRztXRE9gIlciA5vz63pBQ[meta] Drupal.org (websites/infra) blockers to a Drupal 8 release/a/spanspannbsp;(/spanspan class=c12 c3Blocker/spanspan) This issue contains a quot;grab bagquot; of Drupal.org blockers that prevent an optimal Drupal 8 release, including things like semantic versioning support, testing support for multiple PHP/database versions, and support for Composer-based installations. If this issue is one of the last remaining criticals, we might choose to ship Drupal 8 anyway, and jettison one or more features in the process, such ashellip;/span/li /ul ul class=c8 lst-kix_hhgio4gd2kqu-1 start li class=c9 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2157455amp;sa=Damp;sntz=1amp;usg=AFQjCNEgTsGRSmLI-OiIWf5A7QYErFfAKA[Meta] Make Drupal 8 work with PostgreSQL/a/spanspannbsp;The meta/planning issue for fixing PostgreSQL (both in terms of functionality and in terms of failing tests)./spanspannbsp;/spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fu%2Fbzrudi71amp;sa=Damp;sntz=1amp;usg=AFQjCNFUCvi3AYakspUgohzh2ZplWqKK9Qbzrudi71/a/spanspannbsp;is predominantly leading the charge here and making steady progress, but more hands would be greatly appreciated./span/li /ul ul class=c8 lst-kix_hhgio4gd2kqu-2 start li class=c11 c5 c13span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F1013034amp;sa=Damp;sntz=1amp;usg=AFQjCNHk2hD-OQrWA37h_ROJJoNXzydlngPostgreSQL constraints do not get renamed by db_rename_table()/a/spanspannbsp;One of the sub-issues of the above, critical because it causes failing tests./span/li li class=c11 c5 c13span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2160433amp;sa=Damp;sntz=1amp;usg=AFQjCNFzZCC_NtbjKPeItf7ZZUzJdbPREQ[policy, no patch] Move PostgreSQL driver support into contrib/a/spanspannbsp;(/spanspan class=c20 c3Postponed/spanspan) If efforts to fix PostgreSQL fails or we don#39;t get testbot support for PostgreSQL in time, it#39;s off to contrib-land (where, sadly, it is even /spanspan class=c16less/spanspannbsp;likely to survive regressions)./span/li /ul ul class=c8 lst-kix_hhgio4gd2kqu-1 li class=c9 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2318191amp;sa=Damp;sntz=1amp;usg=AFQjCNHtt1ORniAF6M1YVYgRXILWF56vJA[meta] Database tests fail on SQLite/a/spanspannbsp;(/spanspan class=c10 c3gt;30 days/spanspan) Same deal as PostgreSQL but for SQLite. /spanspan class=c16Unlike/spanspannbsp;PostgreSQL/spanspannbsp;though, this one doesn#39;t have anyone leading the charge at this time, and it#39;s also a lot harder to punt this to contrib, since we use it for various things such as testbot. /spanspan class=c3Help wanted!/span/li /ul ul class=c8 lst-kix_hhgio4gd2kqu-0 li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2352637amp;sa=Damp;sntz=1amp;usg=AFQjCNEIKMTpX4Cqss6MWuSotfn1WZIijQRemove the UI for installing/updating modules from update module if it is not fixed in time for release/a/spanspannbsp;(/spanspan class=c20 c3Postponed/spanspan) One major security improvement of Drupal 7 was providing the ability to install/update modules and themes directly from the browser. However, the feature has atrophied in Drupal 8 due to lack of test coverage and lack of active use/maintenance, and now the functionality is broken. And while the feature#39;s very useful, it#39;s not useful enough to further delay Drupal 8#39;s release if it#39;s one of the last critical issues left. /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fu%2Fjoelpittetamp;sa=Damp;sntz=1amp;usg=AFQjCNFfBXaLfc0AvUBAlJYUWbX-abqotwjoelpittet/a/spanspannbsp;is making a valiant effort to try and save this feature in /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2042447amp;sa=Damp;sntz=1amp;usg=AFQjCNFHXswMfBDsyPh_0-7fw3CzSYNpZQInstall a module user interface does not install modules (or themes)/a/spanspan, but the issue would definitely benefit from other helping hands, particularly for extra testing/patch reviews./span/li /ul p class=c6span/span/p h2 class=c7 c21a name=h.h46w1jnuchnr/aspanGeneral house-keeping/span/h2 p class=c11spanThese are all basic things we need to keep on top of between now and release, to ensure that when we#39;re down to only a handful of criticals, we#39;re ready to ship a release candidate. The good news is, these are also all generally really easy patches to make, and often also to test./span/p p class=c6span/span/p p class=c11span class=c3Skills needed:/spanspannbsp;Basic patch rolling / reviewing / testing skills. (/spanspan class=c3good for newbies!/spanspan)/span/p p class=c6span/span/p ul class=c8 lst-kix_2mieegahdh2w-0 start li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2400407amp;sa=Damp;sntz=1amp;usg=AFQjCNFRZ0NVFJ9hzUREQoci8LdyxYiI2g[meta] Ensure vendor (PHP) libraries are on latest stable release/a/spanspannbsp;Basically, exactly what it says. :) Making sure that all of the external libraries referenced in core#39;s /spanspan class=c2a class=c0 href=http://www.google.com/url?q=http%3A%2F%2Fcgit.drupalcode.org%2Fdrupal%2Ftree%2Fcore%2Fcomposer.jsonamp;sa=Damp;sntz=1amp;usg=AFQjCNGO-TwEbV5aj3Iownn5YY8Mo1HDSwcomposer.json/a/spanspannbsp;file are up to the latest stable releases./span/li /ul ul class=c8 lst-kix_2mieegahdh2w-1 start li class=c9 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2343035amp;sa=Damp;sntz=1amp;usg=AFQjCNEW3ZFmLx2OmjxyKCFTJOepPkAYmgUpgrade validator integration for Symfony versions 2.5+/a/spanspannbsp;This one is called out specially because doing this brings us inline with Symfony 3, which is important for future-proofing Drupal 8./span/li /ul ul class=c8 lst-kix_2mieegahdh2w-0 li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2203431amp;sa=Damp;sntz=1amp;usg=AFQjCNHOSbRNiJ3zQjyCwhQEJ9plR1dtxQ[meta] Various asset (JavaScript) libraries have to be updated to a stable release prior to 8.0.0/a/spanspannbsp;(/spanspan class=c12 c3Blocker/spanspan) Same deal, but for JavaScript libraries, which are generally located in the/spanspana class=c0 href=http://www.google.com/url?q=http%3A%2F%2Fcgit.drupalcode.org%2Fdrupal%2Ftree%2Fcore%2Fassets%2Fvendoramp;sa=Damp;sntz=1amp;usg=AFQjCNFG_0GAO6J-92wsByJe5bRkPNpTsgnbsp;/a/spanspan class=c2a class=c0 href=http://www.google.com/url?q=http%3A%2F%2Fcgit.drupalcode.org%2Fdrupal%2Ftree%2Fcore%2Fassets%2Fvendoramp;sa=Damp;sntz=1amp;usg=AFQjCNFG_0GAO6J-92wsByJe5bRkPNpTsghttp://cgit.drupalcode.org/drupal/tree/core/assets/vendor/a/spanspannbsp;folder./span/li /ul ul class=c8 lst-kix_2mieegahdh2w-1 start li class=c9 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F1341792amp;sa=Damp;sntz=1amp;usg=AFQjCNEQTZKeukQyAohsQq7NyOBJH_lMCA[meta] Ship minified versions of external JavaScript libraries/a/spanspannbsp;(/spanspan class=c20 c3Postponed/spanspan) Basically, in the Gilded Mobile Agetrade; we want to ensure that we#39;re sending as little over the wire as possible, so scrunching various JS libraries down to the smallest possible file size needs to be the default. Separate issue from above because it needs to happen for both updated and existing JS libraries. Postponed because there#39;ll be less work to do once all of the out-of-date JS libraries are updated and minified at the same time./span/li /ul ul class=c8 lst-kix_2mieegahdh2w-0 li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F1393358amp;sa=Damp;sntz=1amp;usg=AFQjCNGOIY3qJRsir5uzh2g1aAQUiNtDZw[META-12] Review #39;revisit before release candidate#39; tag/a/spanspannbsp;There are a number of issues that for one reason or another (for example, because we made a decision in order to unblock progress but weren#39;t completely sure if it#39;d be the right one N months/years later when D8 shipped) we#39;ve tagged /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%2Fdrupal%3Ftext%3D%26assigned%3D%26submitted%3D%26project_issue_followers%3D%26version%255B%255D%3D8.x%26issue_tags_op%3D%253D%26issue_tags%3Drevisit%2Bbefore%2Brelease%2Bcandidateamp;sa=Damp;sntz=1amp;usg=AFQjCNEJatKhMZfWls7LEr7Eh-hZLy4P0wrevisit before release candidate/a/spanspan. We need to make sure this list is down to zero in order to ship Drupal 8./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2341575amp;sa=Damp;sntz=1amp;usg=AFQjCNHF8XConzj3-XAM793BbCFUYi7hTw[meta] Provide a beta to beta upgrade path/a/spanspannbsp;(/spanspan class=c15 c3D8 upgrade path, /spanspan class=c20 c3Postponed/spanspan) A policy issue that documents what holds up a beta-to-beta upgrade path, and what happens after we ship an quot;upgrade path beta.quot; Postponed until all other critical D8 upgrade path issues are fixed./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2362647amp;sa=Damp;sntz=1amp;usg=AFQjCNE_-a_R6YC72WmazGwZ4RIsnm2T6Q[policy, no patch] 8.0.0 release candidates, release, patch versions, 8.1.x/a/spanspannbsp;A policy discussion about what happens once we reach zero critical issues. Needs to be figured out before that happens. :)/span/li /ul h2 class=c7a name=h.rmvhprdt1fbk/aspanOther/span/h2 p class=c11spanI couldn#39;t figure out a nice heading for these, so here#39;s the rest./span/p p class=c6span/span/p ul class=c8 lst-kix_91g62kqwec1n-0 start li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2372507amp;sa=Damp;sntz=1amp;usg=AFQjCNGys0U30HBIgCI6WvtvKxBPNqI0qwRemove _system_path from $request-gt;attributes/a/spanspannbsp;Symfony provides a $request object, which has an quot;attributesquot; property for the purpose of storing various contextual bits. But the problem with $request-gt;attributes-gt;get(#39;_MAGIC_KEY#39;) is that the values are undocumented, there#39;s no IDE autocompletion, and it#39;s not clear which are internal vs. public properties, so we have an issue at /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2124749amp;sa=Damp;sntz=1amp;usg=AFQjCNHi1yhUwzJ6piRLwPao-x5CH0MNqg[meta] Stop using $request-gt;attributes-gt;get(MAGIC_KEY) as a public API/a/spanspan. to try and stop doing that. brbrHowever, _system_path in particular is used a ton, since it#39;s very common to want to know the path of the current request. The patch exposes a quot;CurrentPathquot; service instead, which eliminates all of those issues./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2421263amp;sa=Damp;sntz=1amp;usg=AFQjCNFVGxFRDovFv321NlON0HBDCOenUgPotential data loss: concurrent node edits leak through preview/a/spanspannbsp;Because the temp store that Drupal 8#39;s new node preview system employs uses an entity#39;s ID as the key, rather than something uniquely identifiable to a user, if two users are editing the same node and hit preview at the same time, one of them is going to lose data due to a race condition./span/li li class=c1 c5span class=c2 c3a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fnode%2F2339491amp;sa=Damp;sntz=1amp;usg=AFQjCNHIErRFTx4OrpIE4iyKqvg4Pu7GYQAjax file uploads fail on IE 9/a/spanspannbsp;Pretty much exactly what it says on the tin. :P/span/li /ul h1 class=c7a name=h.bf4k5phhkgn7/aspanThrilling conclusion! (also known as quot;TL;DRquot;)/span/h1 p class=c11spanWell, not so thrilling, but at least a conclusion. :)/span/p p class=c6span/span/p ul class=c8 lst-kix_f44wt6l5fd2z-0 start li class=c1 c5spanAnywhere you see a /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%2Fdrupal%3Fproject_issue_followers%3D%26status%255B%255D%3D1%26status%255B%255D%3D13%26status%255B%255D%3D8%26status%255B%255D%3D14%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26issue_tags_op%3D%253D%26issue_tags%3Dblockeramp;sa=Damp;sntz=1amp;usg=AFQjCNFnReuY9Oi3etLjtLzttlaaRGhnHwblocker/a/spanspannbsp;issue, attack it with fire. Those are holding other criticals up./span/li li class=c1 c5spanThe biggest area of focus right now is /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%3Fissue_tags%3DD8%2520upgrade%2520pathamp;sa=Damp;sntz=1amp;usg=AFQjCNEXNqQsm8FbF5G9RG2BykCXaeQvDwD8 upgrade path/a/spanspannbsp;blockers. Many of them are /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%2Fdrupal%3Fproject_issue_followers%3D%26status%255B%255D%3D1%26status%255B%255D%3D13%26status%255B%255D%3D8%26status%255B%255D%3D14%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26version%255B%255D%3D8.x%26issue_tags_op%3D%253D%26issue_tags%3Dsecurityamp;sa=Damp;sntz=1amp;usg=AFQjCNEE-dzgLOIyDKSjRNfsHuZCz5V5jQsecurity/a/spanspannbsp;issues./span/li li class=c1 c5spanAnother big area is /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%2Fdrupal%3Fproject_issue_followers%3D%26status%255B%255D%3D1%26status%255B%255D%3D13%26status%255B%255D%3D8%26status%255B%255D%3D14%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26version%255B%255D%3D8.x%26issue_tags_op%3D%253D%26issue_tags%3DPerformanceamp;sa=Damp;sntz=1amp;usg=AFQjCNG98Y_gFvVEV5XHo5qZ8GarKoAm_wPerformance/a/spanspan, both fixing existing regressions, and profiling to determine where our biggest wins are./span/li li class=c1 c5span class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%2Fdrupal%3Fproject_issue_followers%3D%26status%255B%255D%3D1%26status%255B%255D%3D13%26status%255B%255D%3D8%26status%255B%255D%3D14%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26issue_tags_op%3D%253D%26issue_tags%3DVDCamp;sa=Damp;sntz=1amp;usg=AFQjCNGdFWFDDaUn7RV5xlUPP96K0BfhcQViews/a/spanspannbsp;and /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%2Fdrupal%3Fproject_issue_followers%3D%26status%255B%255D%3D1%26status%255B%255D%3D13%26status%255B%255D%3D8%26status%255B%255D%3D14%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26version%255B%255D%3D8.x%26issue_tags_op%3D%253D%26issue_tags%3DEntity%2BField%2BAPIamp;sa=Damp;sntz=1amp;usg=AFQjCNH5xucBYr72OGkC1CJGy5b6Z9qr7AEntity Field API/a/spanspannbsp;are tied in third place for number of remaining criticals. Let#39;s have a race, shall we? ;)/span/li li class=c1 c5spanThe /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fproject%2Fissues%2Fsearch%3Fprojects%3D%26project_issue_followers%3D%26status%255B%255D%3D1%26status%255B%255D%3D13%26status%255B%255D%3D8%26status%255B%255D%3D14%26status%255B%255D%3D4%26priorities%255B%255D%3D400%26categories%255B%255D%3D1%26categories%255B%255D%3D2%26issue_tags_op%3D%253D%26issue_tags%3DConfiguration%2Bsystemamp;sa=Damp;sntz=1amp;usg=AFQjCNFeeu8qmScm4vhXlSzmkbs5O7D-EQconfiguration system/a/spanspannbsp;is looking pretty good, but still has a handful of sticky issues left./span/li li class=c1 c5spanThere are a series of /spanspan class=c2a class=c0 href=#h.744pljan9umiimportant features we#39;ll lose/a/spanspannbsp;if they#39;re not fixed up in time./span/li li class=c1 c5spanIf you#39;re looking for something somewhat easy/mundane, help yourself to one of the /spanspan class=c2a class=c0 href=#h.h46w1jnuchnrgeneral house-keeping/a/spanspannbsp;issues./span/li li class=c1 c5spanDon#39;t forget about the /spanspan class=c2a class=c0 href=#h.rmvhprdt1fbkother miscellaneous issues/a/spanspannbsp;I was too tired to categorize./span/li /ul p class=c6span/span/p p class=c11spanSorry this post was so long (and probably has its share of inaccuracies) but I hope it will be helpful to some. It#39;s basically what I needed to get back up to speed after taking a few months off of Drupal 8, so figured I#39;d /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.lullabot.com%2Fblog%2Farticle%2Fdrupal-best-practice-document-your-way-understandingamp;sa=Damp;sntz=1amp;usg=AFQjCNFB0FT6TPrt2Xb8M1Uj53Urc9PVRAdocument my way to understanding/a/spanspan./span/p p class=c6span/span/p p class=c11spanNow, let#39;s /spanspan class=c2a class=c0 href=https://www.google.com/url?q=https%3A%2F%2Fwww.drupal.org%2Fdrupal-8.0%2Fget-involvedamp;sa=Damp;sntz=1amp;usg=AFQjCNGBWBAEHObfCfWKwarFwozMIh50rQget #39;er done/a/spanspan! :D/span/p p/body/html/p /div/div/divdiv class=field field-name-taxonomy-vocabulary-1 field-type-taxonomy-term-reference field-label-abovediv class=field-labelTags:nbsp;/divdiv class=field-itemsdiv class=field-item evena href=/taxonomy/term/63 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=drupal 8/a/divdiv class=field-item odda href=/taxonomy/term/1 typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=drupal/a/divdiv class=field-item evena href=/drupal-core-diaries typeof=skos:Concept property=rdfs:label skos:prefLabel datatype=drupal core diaries/a/div/div/div

3C Web Services: Introduction to the Super Login Module for Drupal 7

Sat, 02/14/2015 - 00:13
Drupal’s default login page form is functional but does leave a lot to be desired. It’s pretty bland and, if left as-is, is always a telltale sign that your site is a Drupal website. The Super Login Module for Drupal 7 is a simple way to improve the look and functionality of Drupal's login page.

Stanford Web Services Blog: Behat Custom Step Definition: Wait for Batch API to Finish

Fri, 02/13/2015 - 23:00
div class=field field-name-body field-type-text-with-summary field-label-hiddendiv class=field-itemsdiv class=field-item even property=content:encodedp class=summaryIf you're using a href=http://behat.readthedocs.org/en/v2.5/quick_intro.htmlBehat/a and the a href=https://www.drupal.org/project/drupalextensionDrupal Extension/a, you might find the following code snippet helpful if you want to add a step to wait for batch jobs to finish./p pIf one of your Behat scenarios kicks off a batch job (e.g., a Feeds import), and you want to wait for that batch job to finish before moving on to the next step, add this step definition in your FeatureContext.php file:/p/div/div/div