Community Praise for the Salesforce Handbook "The developer.force.com community is the best resource for anyone wishing to learn more about the Force.com platform. Jeff Douglas and Wes Nolte, are two of the communities most active and respected members. The Salesforce Handbook is as close as you can get to bottling the combined experience of Jeff and Wes into a book designed to get new developers building apps in no time. They just made my job so much easier!"
Quinton Wall Developer Evangelist, salesforce.com "This book is great! I've been a Salesforce Admin for over 4 years and I thought I knew a lot. But I started to expand my knowledge the minute I began reading this book. It's well written and really is the perfect fit between the Dummies series and Visualforce guides. In my opinion it's a must have for any admin!."
Mike Gerholdt Popular Salesforce.com blogger /Certified Advanced Administrator "This is a pragmatic and clear guide to using Force.com and building applications in the cloud. Jeff and Wes spend their days building awesome applications on the platform, and this experience and skill is very apparent throughout the book. A must read!."
Jon Mountjoy Community Manager & Editor-In-Chief, salesforce.com "The Handbook provides a broad, high-level view of the Force.com platform with all of the information you need to get started. It's a definite asset to any new administrator or developer."
Ron Hess Developer Evangelist, salesforce.com "Online searches for Salesforce related topics will inevitably lead you to Wes or Jeff's blog. To have their knowledge captured in a single, thorough reference is simply awesome."
Mike Leach Business Applications Development, Facebook "The Salesforce Handbook is an essential reference tool for any Force.com developer, whether you're a seasoned pro or a beginner. Jeff and Wes describe routines and strategies most needed in Enterprise Force.com development."
Kyle Roche President & CEO, Isidorey Cloud Solutions "The Salesforce Handbook is priceless. For new and experienced force.com developers alike, this book is a 'must have'."
Scott Hemmeter Owner, Arrowpointe Corp. "Indispensable resource that skillfully explains the advantages of cloud computing, provides best practice for coding in the cloud, not to mention provides many great tips and recipes that will keep even seasoned Force.com developers continually coming back for more. A book you can't afford not to have!"
Joel Dietz CEO, Titania, Inc. "The handbook is an excellent resource for the administrator seeking to improve skills and for the beginning developer, whether a trained programmer or an administrator. The handbook provides a bridge from administration to development for Salesforce CRM power users, and introduces the platform to novices. It should be a part of any discussion on Force.com 101."
David Schach President, X-Squared On Demand "An essential guide to Salesforce.com; from honing the skills you already have to stretching you to try things with Salesforce you thought .'only developers.' could do. Jeff and Wes provide information and instruction that's not only easy to grasp but the kind of things that will make you a Salesforce.com hero in your organization. It's the .'I've got Salesforce, so now what.' guide to applying the power of the cloud to real business situations and making the most of your Salesforce investment."
Jeff Grosse Founder, crmfyi.com & The Salesforce Channel
Salesforce Handbook
Salesforce Handbook A newcomer.'s guide to building applications on salesforce.com and the Force.com platform
Jeff Douglas & Wes Nolte
Salesforce Handbook Copyright © 2010 by Jeff Douglas and Wes Nolte All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or by any information storage or retrieval system, without the prior written permission of the copyright owner and the publisher. ISBN 978-1-4461-0853-6 Printed and bound in the United States of America Trademarked names may appear in this book. Rather than use a trademark symbol with every occurrence of a trademarked name, we use the names only in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark. The information in this book is distributed on an ."as is." basis, without warranty. Although every precaution has been taken in the preparation of this work, neither of the authors shall have any liability to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the information contained in this work. Please visit http://salesforcehandbook.wordpress.com for more information or to interact with Jeff and Wes.
For Cathy, the one person that I simply can’t live without. I love you. —JD
For Mum, Dad and Woni - who will have neither interest nor understanding of the contents of this book, but who I know will read it anyway. —WN
Contents Contents Foreword About the Authors Acknowledgements Introduction Target Audience Salesforce.com is the Final Word Next Steps Conventions Used in this Book Terminology Conventions Typographic Conventions Iconic Conventions
Introduction to Salesforce.com Salesforce.com Overview Salesforce.com IS Cloud Computing Save Money and Time Innovate Quicker
What is Salesforce.com? Sales Cloud Service Cloud Collaboration Cloud Force.com Custom Cloud Custom Application Development VMforce
Security User Security and Authentication Session Security Network-based Security Security Tokens Data Security
Infrastructure Scheduled releases Metadata-driven Architecture
Force.com Database Standard Field Types Relationship Fields System Fields Apex Triggers
Platform Limits Salesforce.com Editions Sales and Service Cloud Editions Custom Cloud Editions
Salesforce.com License Types Standard Salesforce.com Applications Salesforce CRM Content Chatter Salesforce Knowledge Entitlements & Service Contracts Salesforce Ideas Salesforce Answers Salesforce Mobile Customer Portal Partner Portal Salesforce to Salesforce Force.com Sites
Standard Objects Account Person Account Contact
Lead Campaign Opportunity Quote Product and Price Book Case
Custom Objects Types of Orgs Production Org Sandbox Org Developer Org Partner Developer Org Pre-release Org Where Should You Develop?
Getting Started with Salesforce.com Managing Users Profiles Roles Groups
Securing and Sharing Data Object-Level Security Field-Level Security Record-Level Security Field Accessibility Record Types
Automate Business Processes with Workflow Developing Approval Processes Formulas Syntax Cross Object Formulas Where Do I Use Them? Workflows & Business Rules Visualforce Limitations Best Practices Examples
Validating User Input Building Public Websites Going Global Divisions Locale Currencies Advanced Currency Management Translating the User Interface
Using Analytics Running Dynamic Reports Custom Report Types Dashboards Analytic Snapshots
Overriding Link, Tabs and Labels Sending Mass Email Importing Data Deploying Code to Production Force.com IDE Force.com Migration Tool Unmanaged Packages Change Sets
Storing Application Metadata List Custom Settings Hierarchy Custom Settings
Monitoring your Org Debug Logs Email Logs Login History View Setup Audit Trail Time-Based Workflow Queue
Scheduled Jobs Outbound Messages Apex Job Queue Import Queue Mass Email Queue Case Escalation Rule Queue Entitlement Process Queue Bulk Data Load Jobs
Google Integration Add Google Docs to Salesforce.com Google Docs Tab Gmail to Salesforce.com Gmail Buttons and Links Google Talk Sidebar Component Google AdWords
Working Remotely Force.com Connect for Microsoft Office Salesforce for Outlook Force.com Connect for Lotus Notes Force.com Connect Offline
Programmatic Development Tools & Strategies A New but Familiar Development Infrastructure That.'s Old School Developing in the Clouds The Importance of Metadata
The Right Tool for the Right Job Developing Applications on the Force.com Platform Deploying Applications on the Force.com Platform Developing Applications that Scale Testing Applications on the Force.com Platform Analysis and Maintenance on the Force.com Platform Tools to Assist Productivity & More Application Support on the Force.com Platform
Programmatic Development Languagesn MVC in the Cloud The Model Data Creation, Manipulation, Update and Deletion Data Retrieval using SOQL and SOSL
The Controller The Apex Programming Language CRUD Operations Apex Triggers Scheduling Apex Batch Apex Governor Limits Debugging Apex
The View The System Architecture MVC: Bringing it all Together When would you use Visualforce? Advantages of Using Visualforce Visualforce Controllers Visualforce Page Syntax Output Components Static Resource in Visualforce Pages
Visualforce & the Web Visualforce Email Templates Mobile Visualforce Pages Security Order of Execution Visualforce View State
Development Best Practices Apex Triggers Visualforce
Unit Testing
Miscellanea Global Variables Functions & Operators
Integration with the Cloud Path 1: AppExchange Publishing to the AppExchange The AppExchange from a Consumers Perspective
Path 2: Build Your Own SOAP Based Web Services RESTful Web Services Deployment and Modifying the Model with the Metadata API File-Based Metadata API Calls Force.com Web Service Connector (WSC) Tolerado OAuth
Path 3: Native ERP & Desktop Connectors Path 4: Middleware Connectors Path 5: Toolkits PHP Toolkit Self-Service Portal Toolkit for PHP 5 Standalone PHP Bulk API Client AJAX Toolkit Adobe Flash Builder for Force.com Salesforce Python Toolkit Force.com Toolkit for Google Data APIs Force.com Office Toolkit Force.com for Google App Engine iOS Toolkit for Force.com Force.com for Amazon web services Force.com for Facebook ActiveSalesforce Perl Toolkit Force.com for PayPal X Payments Platform SalesforceCFC - A ColdFusion Toolkit for Force.com
Advanced Development Examples Using External ID Fields Visualforce Component Ids & JavaScript Passing JavaScript Values to Apex ActionSupport with Facets and JavaScript Passing Parameters with a CommandLink Passing Parameters with a CommandButton Using Anonymous Code Blocks Use an Inline Visualforce Page with Standard Page Layouts Apex Search with Checkbox Results using a Wrapper Class Dependent Multi-level Pick Lists Uploading a Document using Visualforce Uploading an Attachment using Visualforce Visualforce and CSS Redirecting Users to Different Visualforce Pages RESTful Web Service Callouts using POST Force.com & Case-Sensitivity Calling a REST Web Service (XML) Calling a REST Web Service (JSON) Locking sObject Records Automating Approval Processes with Triggers Enhancing the Lead Conversion Process Using Email Templates with Apex Writing an Inbound Email Service Unit Tests & Code Coverage Programmatically Creating Sharing Rules Rolling Back Transactions with Database Savepoints Enforcing Security With Sharing Keywords
Working with Person Accounts Summary
Foreword
You’ve just picked up a book on Salesforce and the Force.com platform—welcome to the ground floor in our industry’s shift to cloud computing. Few would disagree that the development of consumer and enterprise applications has been completely transformed by the emergence of cloud computing over the past several years. First came a revolution in application delivery—the idea that applications could be delivered as a service over the internet, without any software to install or maintain. Then came a revolution in application infrastructure—the idea that developers could consume raw computing and storage capabilities as a service, without any physical infrastructure to deploy or maintain. Now we’re seeing a revolution in application platforms—giving developers the ability to build applications using higher-level building blocks, without any concept of the underlying physical machine or database. Force.com is the leading platform as a service, and represents a major contribution in our industry's shift to the cloud. Here’s why Force.com is so important to everyone in the technology ecosystem:
To the enterprise On-premise platforms are lousy for custom application development. You spend lots of time planning and then building your development and deployment stack-- all before you write a single line of code that your end users actually care about. And once you’ve actually deployed, you can't take advantage of future platform capabilities without expensive customizations and rewrites. This kind of wasted effort has fueled the growth an entire industry of service providers, with busloads of consultants to build and maintain custom applications. Building on Force.com is different. Across Appirio's 200+ enterprise customers, we see savings of over 50% on operating costs and up to 5x improvements in time-to-market when building custom apps on cloud platforms. For one publishing client, we built a custom application that automated their entire publishing process in less than 6 months. Their estimate for doing this using on-premise platforms was over 3 years. In terms of ongoing cost/productivity improvements, they have estimated a 50-75% reduction in the time and effort it takes to add new products. And since the application is built on the Force.com platform, upgrades are seamless and the platform gets better over time, all for no additional cost.
To application vendors Force.com is as disruptive to standalone SaaS vendors as Salesforce.com was to on-premise CRM vendors. Force.com changes the economics of building packaged applications-- we experienced this firsthand at Appirio building a packaged industry-specific application 100% on Force.com. Within 6 months, we were winning deals from established competitors... even those who were committed to the SaaS model. The fact is that its hard work to be a stand-alone SaaS vendor-- you spend up to 80% of your R&D dollars on infrastructure and operations... just “keeping the lights on.” We were able to focus 100% of our engineering on the business functionality our customers cared about. And when Salesforce released its “Chatter” social networking functionality, our application instantly became the only “social” application in the market.... a feature-set that will take our competitors dozens of developer years to replicate on their own platforms. One frequently heard sentiment is that nobody can build a “big” business using someone else’s platform. This is nonsense. Lots of big businesses have been built using the platform capabilities of others (e.g., on the Oracle database platform). There's no reason for this to change. Plenty of great businesses will be built throughout the cloud value chain, including platform providers, tools providers, and platform consumers that deliver business value directly to the customer.
To the rest of the ecosystem SaaS is just starting to penetrate the full business application market, a $50-100B market that includes ERP solutions. More great businesses will built in the market for SaaS applications, and some of these companies will build their offering using the capabilities of a platform delivered as a service. But cloud platforms like Force.com also impacts the much larger business “solutions” market, composed of the software and services that companies consume to develop customized solutions. This market is 3-4 times larger than the market for business applications — generally estimated by analysts at $200-300B. And that's just the beginning-- the market for hardware and infrastructure is also impacted by cloud platforms. These markets are seeing a dramatic concentration in their buying base, and some competition or substitution from companies they never would have expected, such as salesforce.com running its global customer base using only a few thousand servers. All told, platform as a service stands has the potential to disrupt $1 trillion of IT spending.
The implications? These are fundamental changes in application development that are just starting to be recognized by the broader development community. The fact that you're holding this book means that you have the opportunity to participate in this once-in-a-generation shift to a new IT architecture. Most developers out there don’t know that they don’t need to buy hardware and software anymore in order to develop and deploy world-class web applications. But you will. Enjoy this fantastic introduction to the world of developing on salesforce.com's Force.com platform—I look forward to seeing the applications that you develop!
Ryan Nichols VP Product Management & Marketing, Appirio Appirio (www.appirio.com) is a cloud solution provider offering products and professional services that help enterprises accelerate their adoption of cloud applications and platforms. Appirio's innovation and expertise has been recognized by Businessweek as one of America's Most Promising Startups and by AlwaysOn as On-Demand Company of the Year. Appirio has helped more than 180 leading enterprises implement, build and manage mission critical cloud solutions using salesforce.com, Google, Workday and Amazon. We are proud to serve a wide range of customers such as Avago, the City of Los Angeles, Diversey, Dunkin Brands, Flextronics, Japan Post Network, Ltd., IMS Health, Motorola, Qualcomm, RehabCare, Safety Kleen, Starbucks and VMware, as well as the 5,000 companies that use Appirio's products to connect and extend cloud platforms. Founded in 2006, Appirio has offices in the U.S. and Japan, and is backed by Sequoia Capital and GGV Capital.
Ryan Nichols runs product management and marketing for Appirio, and has driven the growth of Appirio's products that connect and extend cloud platforms, now used by over 5,000 companies. Ryan has nearly 15 years of experience bringing together business strategy and technology in the enterprise. He joined Appirio from SAP's corporate strategy group, in the office of the CEO, where he led projects to define and execute SAP's product, platform, and M&A strategy. Previously, Ryan's background spans consulting and business software. He was a management consultant for McKinsey & Company, serving over a dozen leading financial services and technology clients. He led professional services for an analytics software startup, delivering inventory and pricing analytics software and services to retail and CPG clients.
About the Authors
Jeff Douglas is a highly sought-after and award-winning technologist with more than 15 years of leadership experience crafting technology solutions for companies of all sizes. His technology skills were honed during the fast and furious “dot com era,” when he provided SAP development services for Fortune 500 companies including Coca-Cola, Anheuser-Busch, Disney Imagineering, Moen, and Ericsson. After years of being a lowly Java developer, in 2006 he ascended into cloud computing. He periodically writes for developer.force.com and actively tries to work the word “automagical” into functional documentation. He speaks at industry conferences, developer meetups and enthusiastically blogs about cloud computing (especially Force.com) at http://blog.jeffdouglas.com. Jeff works for Appirio, a cloud solution provider that offers both products and professional services to help enterprises accelerate their adoption of the cloud. With over 2,500 customers, Appirio has a proven track record of implementing mission-critical solutions and developing innovative products on cloud platforms such as salesforce.com, Google Apps, Workday and Amazon Web Services. From offices in the U.S. and Japan, Appirio serves a wide range of companies including Thompson Reuters, Japan Post Network, Ltd, Brady Corporation, BMC, RehabCare, Starbucks and Qualcomm. Appirio was founded in 2006, is the fastest growing partner of salesforce.com and Google, and is backed by Sequoia Capital and GGV Capital. Jeff resides in Sarasota, FL, with his wife Cathy and four children Scott, Tyler, Brittany, and Kira (adopted). He and his wife have been medical foster parents for over 12 years, caring for more than 75 children.
Wes Nolte has a long history of love for all things technology-based, with experience spanning the entire Information Technology spectrum across two continents. A relative newcomer to the cloud-computing scene he has nonetheless won several international accolades including the auspicious Force.com Developer Hero award; he also holds the much coveted title of Force.com Developer Challenge Winner. A prevalent member in a number of development communities, his highly acclaimed input on cloud computing matters is often sought across the US, Europe, Asia and Africa. Wes is seen as a champion of salesforce.com and the Force.com Platform, and his blog on the subject is regarded as one of the most influential in the world. From this soapbox he inspires the community by implementing and combining groundbreaking technologies in all manner of ingenious ways. His trail-blazing employment of the Force.com platform has been hugely advantageous to many of his peers in the Salesforce arena. As the head of Cloud Computing at Telegraph Media Group, one of the most renowned media companies in the world, Wes has access to cutting edge tools long before they’re accessible in the mainstream allowing him to dabble to his heart’s delight. Wes spent 27 years living in South Africa but now resides in North London where he feeds the ducks to relax and cycles in appropriately skinny jeans.
Acknowledgements
Writing this book was a great experience for both Wes and myself. As this was my second and Wes’ first printed publication, we had a lot to learn about the process. Even though we live on different continents and have never met in person, the magic of the Internet allowed us to work together smoothly and (semi) efficiently. What a great time we live in. We wanted to write a book that provides a high-level overview of salesforce.com and the Force.com platform that is both easy to understand and highly informative. Hopefully the information we present will provide you with a good starting point and allow you to drill down into portions of the platform that interests you. As with most endeavors, we couldn’t do it alone and would like to thank some of the key people that made this book possible. First and foremost, we’d like to thank our friends and family that spent countless weekend and evening hours helping us put this book together. Thanks to my wife, Cathy, for putting up with my crazy working hours and not killing me in the process. Even though she resists any type of new technology, she went so far as to proofread every chapter before we sent the book to print. She’s a keeper. And thanks to Wes’ fiancée Gerosha who (even as a developer in the hectic finance sector) played the role of muse, photographer and editor without even sighing a complaint. Next, we’d like to thank everyone in the salesforce.com community for reviewing our book, providing feedback and supporting us through our blogs, Twitter and various message boards. It’s a great community of passionate and supportive people and one of the things that makes salesforce.com so special. Also, thanks to Appirio and Telegraph Media Group for not only paying us a descent wage in return for our services, but for providing an environment where we have the opportunity to expand our boundaries and write this type of book. We’d especially like to thank Ryan Nichols, VP Product Management & Marketing for Appirio, who wrote the fantastic Foreword for our book. Ryan is a thought leader in the cloud computing space and we’re honored to have him take an interest in our book. And lastly, a big thanks goes to salesforce.com for making such a great product. Without their efforts we’d probably be doing something less sexy right now, like working for Oracle. We know many of the salesforce.com evangelists, engineers, product managers, professional service consultants, marketing and support reps personally and they are all a great bunch that are really passionate about their product and their customers’ success. Without their brilliance, dedication and countless hours of hard work, our jobs wouldn’t be possible. A very, special thanks goes out to all of the evangelists and especially Dave Carroll, Jon Mountjoy, Quinton Wall and Ron Hess for all their assistance and friendship over the years.
Jeff Douglas Wes Nolte
Introduction
This book is not intended to be a deep-dive on security, programming, reporting, configuration, etc. but more of a high-level overview on salesforce.com, Force.com development, tools, methodology and other resources. We will not cover all aspects of salesforce.com. This is not the “salesforce.com Bible”. We wrote this book to (hopefully) become an invaluable resource for anyone new or inexperienced with the Force.com platform. This book contains the information that we wish we had when we started developing applications on Force.com. For new administrators and developers coming on to the platform, we see a gaping hole in existing reference books. If you are an end user you can pick up a copy of Salesforce.com for Dummies. For advanced developers that need a deep-dive into the platform, there is Development with the Force.com Platform: Building Business Applications in the Cloud by Jason Ouellette of Appirio. Our book is for people somewhere in the middle; let’s say a business analyst or a new Java or .NET developer. We would like this to be the first book you pick up after your boss walks in and says, “Let’s take a look at salesforce.com and see if we can build some applications in the cloud”. Hopefully this book will get you up and running faster and make your transition into the cloud smoother.
Target Audience This book aims to strike a balance with information for both administrators (point-n-click development) and developers (Apex and Visualforce development). We tried to construct the later “programming” sections of the book in such a way that would be beneficial not only to developers but also provide administrators with an overview of the development process without making their eyes glaze over. Our goal was to make writing code “not so scary” for administrators. The programming sections of the book were relatively easy to write since this is our bailiwick. However, it was a struggle writing the declarative portions of the book. Declarative development on the Force.com platform is where the real power lies. However, it’s very hard to provide an overview of most declarative functionality without simply rewriting the salesforce.com Help sections. We trust that we provide some value without skipping around from topic to topic too often. The announcement of VMforce was also a major driver for this book. With the possibility of 6M+ Java developers moving to the Force.com platform we wanted to provide a way to transition them easily. We wrote the more advanced developer sections with these developers in mind.
Salesforce.com is the Final Word Throughout the book we’ll provide features explanations, code samples, tips from the trenches and links to resources for more information. One of the great things about salesforce.com is that they release new features and updates three times per year. The bad thing about salesforce.com is that they release new features and updates three times per year. This makes it hard to be right 100% of the time regarding how the platform “currently” works. If you find a contradiction in this book it’s probably due to a recent release or update. The best source of information is http://developer.force.com and salesforce.com Help and documentation, so always check there for the final word.
Next Steps After you are finished reading this book cover to cover, what are your next steps? Since we only provide a cursory overview of most topics we invite you to drill into aspects of the platform that interest you. The first website that you should bookmark is http://developer.force.com. This site contains the latest information regarding the Force.com platform. There are many hidden gems at developer.force.com so make sure you really explore the site.
For advanced developers that need a deep-dive into the platform, Apex, Visualforce and strategies for working with governors and limits, pick up a copy of Development with the Force.com Platform: Building Business Applications in the Cloud by Jason Ouellette. The book covers a surprisingly large number of development topics and is a great reference for both salesforce.com administrators and developers. It’s a logical extension to this book as it expands on topics that we cover at a high level.
Conventions Used in this Book Terminology Conventions Org
An instance in which the salesforce.com and Force.com applications are developed, tested and used.
Salesforce.com Not only the actual company, salesforce.com, but also collectively the software and its user interface.
Typographic Conventions
Italic URLs, email address Constant Width Used for program listings, as well as within paragraphs to refer to program elemetns such as variable or method names, data types, keywords and statements.
Constant Width Bold Shows commands or other directives such as clicking a button.
Iconic Conventions
An icon to indicate a "Tip from the trenches" or some other type of important note or sidebar.
An icon to indicate a "Common Pitfall" or issue that we have come across in the past.
An icon to indicate an important link to a website with a demo or more information.
There is so much great salesforce.com content on the web that we didn’t want to leave it out. Therefore we’ve set up a delicious.com account for quick access to all of the links that we’ve either referenced or have found useful with more information. We’ve categorized these links with delicious tags that you can find in the footnotes of each section. You can access the delicious bookmarks at: http://www.delicious.com/salesforcehandbook
Introduction to Salesforce.com Salesforce.com Overview
Salesforce.com is software as a service (SaaS), meaning that there is simply no software to install or servers to maintain. You simply sign up for an account and salesforce.com spins up an instance of their software that you can use to run your business right away. Salesforce.com offers a 30 trial and since there is no contract, you can cancel at any time and walk away if it’s not a fit for your business. Again there is not software to install; everything is accessible from your browser so it’s easy for users to get started. Even though salesforce.com is a pre-configured system you are not locked into their processes. You can tweak salesforce.com per your company’s specifications, develop custom functionality and even install free and low cost applications from the AppExchange. Founded in 1999 by Marc Benioff (Oracle), Parker Harris (Left Coast Software), Dave Moellenhoff, and Frank Dominguez (both from Clarify), salesforce.com started out as a Customer Relationship Management (CRM) product but over the years has evolved into much, much more. From a high level, salesforce.com consists of several products: Sales, Service & Support, Partner Relationship Management, Marketing, Content, Ideas, Analytics, and Chatter. Developers can extend the system by writing applications on the Force.com platform using salesforce.com’s proprietary languages Apex and Visualforce. Salesforce.com provides these services “in the cloud”. By now, you’ve probably heard about cloud computing. It’s gone from a forward-looking concept, initially adopted by smaller, nimble companies to a serious requirement for a growing number of larger businesses. Before we dive into salesforce.com let’s take a step back and talk about Cloud Computing, a concept that salesforce.com is championing.
Salesforce.com IS Cloud Computing A number of vendors are making claims to offer “cloud” solutions. However, simply moving your server to another company’s data center does not make it a cloud solution. In most development communities and the enterprise computing space in general, salesforce.com, Google and Amazon.com are leading the march towards enterprise adoption of cloud computing services1. The three commonly accepted levels of cloud computing offerings include Infrastructure as a Service (IaaS), Platform as a Service (PaaS), and Software as a Service (Saas). Each has its own unique, but sometimes overlapping place in the cloud computing space with their own unique features and benefits. However they do share some common attributes inherent to the space itself. The key characteristic of a cloud computing offering is that, above all, it should be multitenant. The opposite of multitenancy, single tenancy, is how most systems are currently designed today. Each customer gets their own server, database, application layer and user interface to do with what they please. With a multitenant application architecture there is a single instance of the server, database, application layer and user interface that is shared by all users but partitioned for each client’s data programmatically. All IaaS, PaaS and SaaS share this same core multitenant trait. At the lowest level, IaaS offers a physical or virtualized infrastructure to tenants on a subscription basis allowing them to pay for what they need in terms of computing power. Instead of purchasing servers, software, and physical location, a tenant of an IaaS offering can pay for these components as needed. Consider B2C companies whose do most of their business during Christmas. Gone are the days when they would have to purchase the servers and software to handle their peak Christmas demand and then let them stand idle when not needed. With leading IaaS vendors like Amazon.com offering “pay per CPU hour” pricing for Linux and Windows platforms these companies can simply spin up new server instances to handle anticipated demand. At the other end of the ladder, SaaS, much like IaaS, offers solutions to the customer on a per-usage model. The major difference is that SaaS offerings completely abstract the physical and application layers from the end user and/or developer. Salesforce.com, widely considered the leading SaaS application, provides its own customizable user interface and proprietary Apex programming language but doesn’t expose hardware or software layers to the end user. One of the major benefits of SaaS offerings is that when salesforce.com releases a new feature, fixes a bug or applies a patch, it’s immediately available to all customers. Customers may log into salesforce.com one morning and find out they have bright, shiny new features that dramatically impact their business with no effort or extra money spent to develop them. PaaS lies between IaaS and SaaS and abstracts a bit more of the low level architecture but still without providing an actual end user product. PaaS typically provides solutions stacks or building blocks that you can use to build your own solutions. Google App Engine is a prime example of a PaaS offering, currently supporting both a Java and a Python runtime allow you to build scalable web applications without the need for complex underlying hardware and software layers. Google abstracts those layers and lets you concentrate fully on business functionality. The Force.com platform is also considered a PaaS offering however it’s positioned a bit higher in the cloud quadrant than App Engine for a number of reasons. Like some other platform vendors, Force.com encapsulates the runtime environment using its own proprietary language. Apex, the language for Force.com development, looks and feels like Java in many ways but doesn’t support the full implementation of any JRE. Building solutions on a PaaS platform is quick and somewhat easy but does come with its own set of challenges. With PaaS offerings like Force.com and App Engine, a governor process, applications limits or application quotas restrict you. PaaS governors and limits protect the shared layers of the multitenant platform from being monopolized by one heavy application or runaway code. Application quotas define the dailyallotted amount of computing power, space, or bandwidth that any one application is allowed to utilize. This becomes a challenge as developers must develop solutions to operate both efficiently and with in application and/or platform restrictions.
Take a look at where the major players sit in relation to the types of cloud offerings we’ve discussed so far as well as in comparison to each other. You can quickly see that the major offerings seem to build on each other. Amazon Web Services, in the bottom-left section, offers the least customization. It simply removes your need to build out a physical infrastructure, leaving all the management and support to your IT staff. Shifting to the right, you see that App Engine offers just slightly more abstraction, now covering the platform and infrastructure while salesforce.com abstracts the application, platform and infrastructure layers. It’s important to note that the placement of the offerings on this diagram does not indicate preference or correlate with value in any way. Each of these offerings has its own unique value and place in the market and we’ve used a combination of them to build the best solution for our customers. Each offering does provide companies with the following benefits.
Save Money and Time Consider a basic Java application running on WebSphere and assume that it meets the requirements for an application that could be run in the cloud. With Amazon’s Elastic Computing Cloud (EC2) you can quickly build the Linux stack with a preconfigured Apache server and your choice of Java application server and database. You have to support the operating system, the database, the application server, the security, and all the same components you’d be supporting in an on-premise environment, except the physical machine. This, no doubt, saves time and money. But, IaaS offerings still need provisioning and long-term support at more layers than the application. Now, on the flip side, consider this same application running on Force.com. You don’t need hardware provisioned or software installed, and you don’t need an application server or a database. All these are wrapped into the core platform offering from salesforce.com.
Innovate Quicker Take a look at Figure 1-2, which shows two diagrams comparing the scope of activities and the budget and effort of a traditional IT department with those of another IT department that is leveraging a PaaS offering for its business applications. Take special notice of the amount of maintenance on the hardware, middleware, and application layers for the traditional IT department. It’s apparent that all that lost time is intruding on the time, budget, and effort left over for innovation. Now, in comparison, consider the IT department leveraging PaaS offerings for their hardware and middleware layers. Removing the maintenance required to keep those layers in house, the department is free to spend that extra time innovating on its core business applications. You might notice that vendor management is a new time-allotment category when you’re using PaaS solutions. However, that’s a small effort in comparison to managing these solutions internally. If you’re currently entrenched in a traditional software-development structure or a traditional IT department, one of these previous illustrations probably looks very familiar. The inefficiency of traditional IT is one of the main reasons so many companies are adopting Force.com for their development platform.
What is Salesforce.com? From its humble start as a sales force automation (SFA) tool, salesforce.com has grown into a platform for developing and running mission critical, enterprise applications. Most companies get started on salesforce.com as a way to track their customers and prospects more efficiently. Salesforce CRM is a set of business processes and integrated applications that help companies manage customer information, activities, and conversations in one centralized location. By combining business processes, people, and technology, companies can drive sales and keep customers satisfied after the sale. For sales managers, CRM allows them to forecast sales more accurately with real-time visibility into their team’s activities. For sales reps, CRM streamlines customer interactions allowing them to spend less time handling data and more time providing value to customers. Tracking sales from generated leads is the life-blood of any marketer. CRM provides marketing staff with the tools to track leads and sources, route leads to qualified sales personnel and provide analytics on what’s driving sales and what is not. After the sale, CRM helps you provide support and deliver answers fast. Whether questions come from Facebook, Twitter, email or phone, your reps can solve problems quicker and at lower costs using CRM. Salesforce.com separates its offerings into the four following “clouds”. The features and services that make up these clouds typically overlap but provide specific functionality.
Sales Cloud Sales force automation is the most popular of the sales tools, allowing companies to speed up the sales process and streamline lead to cash2. According to salesforce.com, more than 82,400 customers running more than 135,000 applications empowers over 2 million subscribers worldwide to manage resources and processes more effectively, pursue more business in less time, collaborate more closely and close more deals using SFA. The Sales Cloud consists of the following:
Accounts and Contacts Accounts and contacts are the lifeline of the sales process. Reps have one centralized location to get a complete customer picture at a glance —including account history, contacts, interactions, documents, and more. You can manage and track all of your information, communication, activities, and opportunities by contact, so you can close more business faster.
Marketing and Leads There’s no doubt that better quality leads means more sales. You can capture leads from websites, trade shows or direct mail that can be worked from the Sales Cloud. You can score leads more efficiently and automate their assignment to the right sales rep in record time and also track your marketing campaigns for leads and contacts across a wide spectrum for a consolidated view of campaign spending and performance.
Opportunities and Quotes Drive more revenue by working deals that are hot. With opportunities and quotes in one centralized location, your sales teams always have the latest opportunity related data including deal size, current stage, products involved, decision makers, milestones and customer communications.
Approvals and Workflow Design, streamline and automate virtually any process including shifting territorial boundaries, product configuration, telesales scripting and sales approvals. You can automate routine activities, eliminate redundant tasks and respond to changes in salesforce.com automatically.
Email and Productivity Sales reps spend a large part of their day in their email clients. Whether your company uses Google Apps, Microsoft Outlook or Lotus Notes, your sales team won’t lose a step. Reps can synchronize their address book, calendars and email with salesforce.com to dramatically improve sales productivity.
Content Library With Salesforce CRM Content you can provide your sales team with a centralized content library allowing them to subscribe to and find the latest version of relevant sales collateral needed to close deals.
Analytics and Forecasting Get the insight you need into your sales pipeline and revenue growth, analyze your customer data across multiple modules, and visualize results with customized reports and dashboards. With customizable forecasting, your company can effectively use its sales forecast to assist with resource planning and other supply chain management decisions.
Chatter Allow sales people to collaborate in real-time to close deals faster. Chatter automatically dispatches updates on people, data and documents that help shorten the sales cycle.
Partners Increase your visibility into what your direct and indirect sales channels are doing in one centralized location. Using the Partner Portal your
company empowers your indirect sales channels to sell more thus maximizing channel ROI.
Mobile Mobile access is becoming a necessity in today’s environment. Your sales reps need access to the latest data when they are on the road. With Salesforce Mobile reps can stay plugged in and on top of their accounts with their Blackberry, iPhone or Windows handsets.
Jigsaw Data Services Get instant access to millions of leads and contacts to eliminate dead, duplicate, incorrect, and incomplete records while automating data management and hygiene processes.
AppExchange Enhance your sales processes with hundreds of add-on apps and services from the AppExchange. The AppExchange is an on-demand application-sharing service that allows you to browse, test drive and seamlessly install applications that help you drive sales and increase revenue.
Service Cloud Service and support, the Service Cloud, is the premium customer service platform for providing faster, more personalized service delivered via virtually every conceivable channel whether its phone, email, instant messaging, Twitter, Facebook or other social platforms3. The Service Cloud consists of the following:
Case Management Support cases enable your company to track customer’s feedback, problem, or questions with a view of all relevant account data. Cases can be created manually or automatically via web, email or from social networks.
Call Center Salesforce CRM Call Center seamlessly integrates with third-party computer-telephony integration (CTI) systems to create industry leading call centers. You can provide agents with a complete customer view for every interaction enabling faster service and higher customer satisfaction.
Contracts and Entitlements With customer entitlements and service level agreements at their fingertips, service reps can ensure that customers receive the level of service that they are contracted for.
Customer Portal Give your customers on-demand answers and community involvement with a personalized self-service portal. The Customer Portal allows your company to deliver a personalized experience to your most important customers.
Knowledge Deliver answers to your customer’s questions when they want them. Salesforce Knowledge is a powerful, fully integrated knowledge base allowing your company to deliver relevant answers to customer inquiries and provide a better customer service experience.
Analytics Real-time analytics allows you to monitor customer service statistics via customizable reports and dashboards. You can dramatically improve your customer service efforts by identifying trends and identifying knowledge gaps. Analytics provide you with the metrics to keep your service and support operations running efficiently.
Chatter In support it’s all about what you know. With Chatter you enable collaboration for your support reps with automatic real-time updates on people, data and documents that help solve problems faster.
Email Provide your users with quick, convenient email tools for standardized messaging and branding as well as delivering content and solutions quickly and directly to customers.
Community Salesforce.com communities allow you to harness your customer community enabling them to help one another plus uncover new ideas to improve your company, products and processes.
Partners Empower your channel partners with the tools to provide better and more-effective service with the Partner Portal. Your company gains increased visibility into what your partners are doing thus maximizing channel ROI.
Approvals and Workflow Design, streamline and automate virtually any support process including quotes, returns, and case resolution. You can set up simple or sophisticated approval automation for virtually any process from discount requests to refunds.
AppExchange Extend your service and support capabilities with hundreds of add-on apps and services from the AppExchange. The AppExchange is an ondemand application-sharing service that allows you to browse, test drive and seamlessly install applications that help you deliver better support.
Collaboration Cloud Salesforce.com’s latest release is the Collaboration Cloud with Chatter4 . With Chatter, users can collaborate more effectively by following people, documents and data that is important to them with real-time update feeds. Users can set up groups and profiles to promote collaboration across multiple business applications while making sure people see only information that they have access to based on the Org-wide security and sharing model.
Force.com Custom Cloud The Force.com Custom Cloud is a radical shift for salesforce.com5. No longer can salesforce.com be marginalized as “just a CRM”. You can build virtually any application with this PaaS service. Why would you want to build your next application on the Force.com platform? Enterprise application development with traditional software has become too complex, too slow, and too expensive. Building applications on the Force.com platform is faster, less expensive, and produces higher quality applications than building on traditional on-premises platforms. Industry analysts state that building applications on the Force.com platform is 5X faster at ½ the cost because cloud computing: 1. Delivers faster time to value 2. Requires no up-front capital expenses 3. Minimizes operational costs 4. Requires fewer technical resources 5. Simplifies integration What makes application development on the Force.com fast and cost-effective?
Programmable user interface Force.com automatically generates a rich UI that can be customized by user profile with a simple, intuitive drag-and-drop page layout editor. If you want more control over the presentation layer, you can build your own UI with HTML, Flash, Flex, JavaScript and CSS.
Programmable cloud logic Using a point-n-click, declarative interface you can enforce rules, define processes and trigger events for your custom applications. For more granular control use the Force.com IDE to write Visualforce and Apex code that implements functionally to extend the platform.
Real-time database customizations Design and implement your data model with a simple point-n-click UI to define custom objects, fields, relationships, formulas and more. The database is tightly integrated with other parts of the platform providing reporting and search capabilities for all objects with no extra effort.
Granular security and sharing Easily control access to data at the object, field, or record level. Effortlessly create custom restriction and sharing rules across roles and profiles that are enforced by the UI, APIs, search results, reporting and analytics.
Integrated content library Finding content related to a business should be as easy as finding a video on YouTube. With great search results, user ratings, comments, and tagging, you can find the right content at the right time. And the integrated content library makes it easy to share presentations, video clips, documents, spreadsheets, or just about anything else.
Visual process manager A new visual process manager allows you to design wizards, multi-step processes and automate manual tasks including approvals, task assignments and notifications.
Customer-facing websites
Not only can you develop internal applications for your company but you can also design, build and host public-facing websites on the Force.com platform using standard Web technologies such as HTML, Flash, Flex and JavaScript.
Custom Application Development The majority of salesforce.com customizations are done with the declarative, point-n-click interface. However, in certain cases you may need to create entirely new processes or interfaces that are beyond the scope of the current declarative capabilities. In these cases, salesforce.com offers proprietary languages, Apex and Visualforce, which allow you to write custom code on the Force.com platform 6. Apex is a strongly-typed, object-oriented programming language that is compiled and executed on the Force.com multitenant infrastructure. If you have some development experience, Apex should be fairly easy to pick up. The language looks and feels like Java and has similar variable and expression syntax, block and conditional statement syntax, looping constructs, object and array notation, pass by reference and other features that you might expect in high level language. Where Apex shines is its built-in support for database operations. Apex supports DML statements for inserting, updating, upserting and deleting of records along with a powerful inline query (SOQL) and search (SOSL) syntax for locating records. To build applications or customize the salesforce.com UI, developers use Visualforce, a tag-based markup language similar to HTML, in conjunctions with Apex code. Visualforce tags provide developers with the ability to build AJAX-y applications with surprisingly few lines of code. Visualforce pages can consist of standard or custom components interspersed with snippets of HTML, CSS or JavaScript. We’ll be diving into Apex and Visualforce in-depth later on in the book.
VMforce Salesforce.com recently accounted a partnership with VMware to develop a new product called VMforce that allows Java developers to write native apps in the cloud that seamlessly hook into the Force.com platform7. Java developers can use the Spring Eclipse-based IDE to write standard POJOs, JSPs and Servlets that deploy effortlessly to VMforce servers in the salesforce.com datacenters. The native hooks into the Force.com platform (e.g., JPA, REST) allow developers to write applications that may normally exist outside the platform due to governor limits or other constraints. Companies can leverage existing development skills to move legacy Java apps to the cloud, develop new Java apps that run in a multi-tenant environment or reuse existing Java libraries that are not available on the Force.com platform.
Security Security is baked into all aspects of Force.com including user, session, network and platform restrictions 8. The platform features a robust and flexible security architecture, providing granular control over users, network access, and data not only from a programmatic aspect but from system configuration as well. These security protocols are intended to not only protect data and logic from unauthorized external access, but also from unauthorized internal access as well. When you access the application using a salesforce.com-supported browser, Secure Socket Layer (SSL) technology protects your information using both server authentication and data encryption, ensuring that your data is safe, secure, and available only to registered users in your company. We highly encourage you to visit the http://trust.salesforce.com/security site for the latest in security education. This is where salesforce.com customers can learn about security best practices, learn how to spot suspicious emails and attend security webinars.
User Security and Authentication When a new salesforce.com instance is provisioned, a unique “Org ID” is generated. You will need this Org ID anytime that you contact salesforce.com for support, billing or activation of features. This Org ID is used for both security and data access. To find your Org ID, click Setup -
> Administrative Setup -> Company Profile -> Company Information
Your production Org ID will always remain the same but a new Org ID will be generated each time your refresh a sandbox. This may affect any third-party tools that are licensed by Org ID. Salesforce.com requires that users login into the platform with a unique username and password. This determines the instance and Org ID for the user and ties these identifiers to their session. Each request to the platform utilizes this session and the associated Org ID to segment and compartmentalize data protecting your company’s data from users outside your Org.
Salesforce.com usernames must be unique across all production and sandbox environments. For instance, two production Orgs cannot have the same username
[email protected], but it can exist in both a production and a sandbox Org. Companies that utilize single sign-on to simplify and standardize their user authentication can implement either delegated or federated authentication with salesforce.com9. Using delegated authentication, Force.com does not validate passwords but instead uses an external Web service to validate user credentials. When a user attempts to login, the platform checks the user’s profile to see if they are enabled for SSO. If so, it makes a Web services call to the endpoint specified for the Org, asking it to validate the username and password. The Web service checks the credentials against an identity store (e.g., LDAP, OpenID) and either returns “true” or “false”. If true, the user is granted access to the application and proceeds normally. If false, the user is informed that their credentials are invalid. Federated authentication, the preferred and default of the two methods, uses Security Assertion Markup Language (SAML) to send authentication and authorization data between affiliated and unrelated Web services. Federated authentication does not validate the user’s actual password on the Force.com platform. Instead, the platform receives a SAML assertion in an HTTP POST request. The SAML assertion has a limited validity period, contains a unique identifier, and is digitally signed. If the assertion is still within its validity period, has an identifier that has not been used before, and has a valid signature from a trusted identity provider, the user is granted access to the application. If the assertion fails validation for any reason, the user is informed that their credentials are invalid. With the Winter ’11 release salesforce.com now supports OAuth2 for authorizing web applications. This not only allows you to extend the reach of your external applications but to do so in a more secure manner as you are no longer required to store user credentials in your client applications. A number of authentication flows for OAuth 2.0 are supported, including the web server flow, user-agent flow and SAML assertion flow.
Session Security When logging in, salesforce.com issues a session cookie to record encrypted authentication information for the duration of a the session. Session security is used to limit exposure to your network when a user leaves their computer unattended while still logged in. The session timeout is configurable for all users within the Org. When a user’s session times out (by default it’s two hours), they are prompted with a popup that asks them to continue working or log out. If they do not respond to the dialog at all, they are automatically logged out. You can edit these setting by clicking Setup -> Administration Setup -> Security Controls -> Session Settings.
Network-based Security To help prevent hackers and other unauthorized users from accessing your data, salesforce.com provides the ability to define the hours that users can login plus the range of IP addresses that logins can originate from. If a user attempts to login from an IP not defined in the network list, they will send a challenge email asking them to confirm their attempt to login. You can also whitelist IP addresses from which users can always login without a challenge by clicking Setup -> Administration Setup -> Security Controls -> Network Access.
Security Tokens Force.com has an addition layer of access for external and client applications. If you are running a development tool (e.g., Data Loader, Force.com IDE) or developing a web application that uses the Web services API, you will need to append a special security token to the end of your password if the IP address is outside of the trusted IP range. To receive or reset your security token click Setup -> Personal Setup -> My Personal Information -> Reset Security Token . This will create a new token and send an email to the email address contained in the user’s account.
Each time you reset your password a new security token will be automatically emailed to you. Be careful when resetting an administrator password as it may affect running applications and lock users out. For external applications you may want to create a new “API-only” user and set it’s password to never expire.
Data Security Securing access to data is one of the most challenging and complex processes in salesforce.com10. Locking down access is done by a combination of profile and role and involves configuring object level security, field level security and record level security. If you are implementing security and sharing rules for your Org you will want to research this topic in depth and test your design in a sandbox to insure that users don’t have access to unauthorized fields and records. Security is configured by both user profile and role. Profiles are typically defined by a user’s job function and are a collection of settings and permissions that determine what a user can do in the application. Currently, a user can only be assigned to one profile. A user’s role defines which actual records they have access to. Object level security is used to control CRUD access to objects by profile. For each profile you can determine whether or not a user can view, create, edit, or delete any instance of a particular type of object.
Once you have locked down access to objects by profile, you can limit access to individual fields with field-level security. Field-level security determines whether a user, based upon their profile, can see, edit, and delete the value for a particular field on an object. This allows you to protect sensitive fields (e.g., payroll information, social security numbers) without having to hide the entire object from specific profiles. These restrictions are also enforced through the various salesforce.com APIs.
Record-level security grants users access to the individual records in your Org and is configured with a combination of Org-wide defaults, the role hierarchy and sharing rules. Configuring record-level security begins by setting up the Org-wide defaults for each object. These settings specify the default level of access to records in the Org. For most objects, Org-wide sharing settings can be set to Private, Public Read Only, or Public Read/Write. With these setting in place you basically lock down access to the most restrictive level and then use the role hierarchy and sharing rules to open up access to users.
You can share access to records by a user’s position in the role hierarchy. You define a role by its position in the role hierarchy, which is similar to an org chart. A user has access to all records owned by roles beneath them in the role hierarchy. This ensures, for example, that sales managers have access to the same data as their sales reps. You can also use a territory hierarchy to share records based upon criteria such as zip code, industry or a custom field. You can also manually and programmatically share records with sharing rules. Sharing rules let you make automatic exceptions to Org-wide defaults for particular sets of (somewhat static) users to give them access to records they do not own or cannot normally see.
Profiles determine what a user can “see and do” with different types of objects while roles determine which records a user has “access” to.
Infrastructure Infrastructure is one of those things that you sometimes take for granted in a SaaS or PaaS environment11. Development in the cloud inherently removes the necessity to be concerned about infrastructure and allows us to focus more resources on business processes. However, infrastructure is one of the secret ingredients of salesforce.com. Over 77,000 companies and commercial vendors trust the platform to deliver robust, reliable, Internet-scale applications. Salesforce.com has five main data centers and is currently building out two new ones in the US. Equinix owns these facilities and salesforce.com co-locates their servers there. To ensure availability and redundancy, salesforce.com uses multiple network vendors at these locations.
Salesforce.com recently announced plans to build a new data center in London by 2012. Each user that logs into salesforce.com is mapped to what is called an “Org”, a complete “instance” of the salesforce.com software stack. Salesforce.com has roughly 3000 Dell servers (50% are idle, staged for disaster recovery) configured in a “pod” infrastructure. These pods are clustered pools of RedHat Linux boxes running open source Resin app servers, Oracle RAC database instances, Java app servers, Lucene full-text search servers, load balancing servers and a SAN disk array. Requests to these app servers are stateless providing for a high degree of scalability and allowing for long running transactions to utilize multiple boxes. The salesforce.com network architecture is designed for massive failover. Virtually every transaction from the primary data centers are replicated in real-time to the Reston, VA back-up data center. To ensure that users have a secure browser connection to the salesforce.com environment, all connections are via SSL 3.0/TLS 1.0, using global step-up certificates from Verisign. In response to phishing attacks, salesforce.com has significantly stepped up security and user education. For an extra layer of security, all data is transmitted across encrypted links, they have implemented an extra token-based external access protocol and you can configure network access by IP and time frame. When you sign up for an account, your Org is provisioned on an instance based upon your location:
You can determine what instance your Org is running on by looking at the URL in the address bar.
Sandbox Orgs run on their own instances as well (cs0-cs5 and tapp0 for older Orgs) and are on different maintenance and upgrade schedules. Knowing which instance your Org runs on is very important as salesforce.com schedules maintenance, updates and upgrades per instance. Additionally, when there are outages or disruption they typically do not affect all instances. You can visit http://trust.salesforce.com for real-time and historical information on system performance, planned maintenance and security threats and best practices.
Scheduled releases Salesforce.com schedules three major seasonal releases per year: Spring (February), Summer (June) and Winter (October). These releases typically contain changes to a wide range of salesforce.com products and services including the user interface, desktop integration products, development IDE, tools and APIs. These releases are rolled out to users at no additional charge and are available to everyone on the platform. Some features that greatly impact the user experience are required to be enabled by the Org’s administrator. For example, there is a new feature in Winter ’11 that allows a user to click on a record in table or chart in a report and be taken to the record detail page instead of another summary level. This feature must be enabled by the Org administrator. Salesforce.com works very hard to ensure compatibility of existing code and functionality and we’ve seen very few instances where upgrades break existing functionality. Salesforce.com actively strives to implement new functionality that users request. Users submit new ideas for functionality at the IdeaExchange allowing other users to vote the idea up or down. Salesforce.com takes these popular ideas into account with each release and decides whether they are rolled into the next release. Each release typically contains a number of ideas submitted by the salesforce.com community. A couple of months before the upcoming release, salesforce.com makes available a list of user submitted ideas that are under consideration by Product Managers for the next release. As the release date gets closer, salesforce.com starts communicating some of the new features on various blogs and webinars. They also make pre-release trial Orgs available so that administrators and developer can test out the impact of the new functionality. As the release data approaches, salesforce.com allows customers to optionally upgrade their sandboxes so that they can test out new customizations or features before rolling them out to users. Finally, salesforce.com schedules the updates of individual instances and notifies customers of the upgrade window and scheduled downtime. Following the upgrade, users simply log into their Org and are greeted with new and enhanced features and functionality.
Metadata-driven Architecture To meet the extreme demands of its large user population, Force.com’s foundation is a metadata-driven software architecture that enables multitenant applications. In Force.com, everything exposed to developers and application users is internally represented as metadata. Forms, reports, workflow, user access privileges, tenant-specific customizations and business logic, even the definitions of underlying data tables and indexes, are all abstract constructs that exist merely as metadata in Force.com’s Universal Data Dictionary (UDD). For example, when a developer is building a new custom application and defines a custom table, lays out a form or writes some procedural code, Force.com does not create an “actual” table in a database or compile any code. Instead, Force.com simply stores metadata that the platform’s engine can use to generate the “virtual” application components at runtime. When someone wants to modify or customize an aspect of the application, all that’s required is a simple non-blocking update to the corresponding metadata. Because metadata is a key ingredient of Force.com applications, the platform’s runtime engine must optimize access to metadata; otherwise, frequent metadata access would prevent the platform from scaling. With this potential bottleneck in mind, Force.com uses metadata caches to maintain the most recently used metadata in memory, avoid performance sapping disk I/O and code recompilations, and improve application response times. Force.com stores the application data for all virtual tables in a few large database tables that serve as heap storage. The platform’s engine then materializes virtual table data at runtime by considering corresponding metadata12. To optimize access to data in the system’s large tables, Force.com’s engine relies on a set of specialized pivot tables that maintain denormalized data for various purposes such as indexing, uniqueness, relationships, etc. Force.com’s data processing engine helps streamline the overhead of large data loads and online transaction processing by transparently performing data modification operations in bulk. The engine has built-in fault recovery mechanisms that automatically retry bulk save operations after factoring out records that cause errors. To further hone application response times, the platform employs an external search service that optimizes full-text indexing and searches. As
applications update data, the search service’s background processes asynchronously update tenant- and user-specific indexes in near real time. This separation of duties between the application engine and the search service lets platform applications efficiently process transactions without the overhead of text index.
Force.com Database One of the key features of the Force.com platform is the Force.com database, a powerful and intuitive data persistence layer baked into all aspects of platform 13. The Force.com database not only acts as a persistence layer for your data but also magically generates the user interface for creating, updating and displaying records. Non-technical users can create, configure and deploy persistent objects using the point-n-click, formbased interface in the Setup environment. Salesforce.com takes a slightly different approach with their database layer. Instead of coming from a pure database perspective, the Force.com database takes a more abstract approach and represents everything as objects. Whereas a traditional database has tables and columns, the Force.com database is composed of objects and fields. You can think of the two in roughly the same way.
Standard Field Types The Force.com database supports many of the field types that you would expect to find in a relational database plus some surprisingly useful additional ones:
Auto Number - A system-generated read-only sequence number with a format that you can define. The format is configurable (i.e., PR00001) and automatically increments for each new record inserted.
Formula - A read-only field that derives its value from a formula expression you define. Checkbox - Displays as a checkbox for Boolean data. Currency - A currency formatted number with optional multi-currency support. Date or Date/Time - For date or date and time combinations, allows the user to enter a date or pick a date from a popup calendar. Email - For entering email addresses that are also validated to ensure proper formatting. Number - For representing real numbers with optional decimal points. Percent - Allows users to enter a percentage number (e.g., 25) and automatically displays the percent sign with the number. Phone - Allows users to enter any phone number and automatically formats it as a phone number. Picklist and Multi-Select Picklists - Allows users to select one or more values from a list you define. However, the values in the object’s field are not restricted to these values.
Text and Text Areas - For representing text up to 255 characters in either a single line or multi-line text box. Text Area (Long) - For representing text up to 32,000 characters in a multi-line text box. Text Area (Rich) - For representing rich text (HTML) up to 32,000 characters with formatted text, images and links with an embedded WYSIWYG editor.
URL - Allows the user to enter a website address that open the URL in a separate browser window when clicked on. Relationship Fields The Force.com database simplifies that way that developers work with related records. Relational databases enforce data integrity with primary and foreign key relationships. The Force.com data abstracts and simplifies these requirements by creating simply relationships between objects. A relationship field stores the ID of the parent record in a pre-defined relationship, providing a user interface representations in both the parent and child records as well as structured way to query the chain of related objects.
For each relationship you can specify up to 5 levels in your queries. This allows you to build some powerful and useful queries that let you reach up or down the relationship chain to fetch data.
Lookup Relationship This relationship creates a simple (foreign key) relationship that links one object to another. These can be used to create one-to-one and oneto-many relationships. When displaying records in the salesforce.com UI, the platform generates a link to the related record allowing you to navigate from record to related record.
Master-Detail Relationship
A master-detail relationship creates a special type of relationship between two objects, the parent, or “master” object and its child, or “detail” object. Detail objects cannot live without a master object and once created, this relationship cannot be change. Detail objects also inherit the security from the master object and deletes cascade from the master to the detail objects. An example of a master-detail relationship would be a Sales Order (master object) and the individual Sales Order Line Items (detail objects) associated with it. The line items cannot exist without the order header and are deleted when the order header is deleted. A few caveats exist with this type of relationship. An object cannot be the master in one relationship and a detail in another. An object can be the master in multiple relationships, but these relationships cannot be used to implement multiple levels of detail.
This may seem backwards, but you create a master-detail relationship by adding a field to the child object instead of the parent. However, you cannot create a master-detail relationship for an object that currently contains data. A workaround is to create a lookup relationship to the master, add a value to all child records for the relationship, and then convert the lookup relationship to a master-detail relationship. The master object in a master-detail relationship can also contain a special field type called a rollup summary field. These fields store values aggregated from the child records in the relationship. For example, in our Sales Order example you could create an “Order Total” rollup summary field that automatically sums the amount of all line items. Rollup summary fields can either count records or sum, min and max specific fields based upon all records or records meeting certain criteria (e.g., matching record type, created date before today, Boolean value).
Many-to-Many Relationship There are development scenarios where you will need to implement a many-to-many relationship where a record on one side of a relationship can be associated with many records on the other side. In this case salesforce.com uses an intermediate object, which they refer to as a junction object (aka mapping table or pivot table). To implement a junction object, simply create a custom object and add two master-detail relationships to the objects on each side of the relationship.
An issue with junction objects involves usability. When you add the junction object as a related list on a page layout, the user may have to make an extra series of clicks to create new records or navigate back to the original record. This can be somewhat confusing from a UI perspective.
System Fields It’s no surprise that the Force.com database contains a number read-only system fields automatically associated with each object. For each record in the database, Force.com automatically assigns an identity field (called ID) and manages the identity data. The ID is a case sensitive 15 character string that is used to uniquely identify the record throughout the platform.
To view a record in the salesforce.com UI, simply append the record ID to your salesforce.com domain. For instance, when you enter https://na1.salesforce.com/0014000000Hg6pL, Force.com will fetch the record from the database, along with its associated metadata, and display the record using the automatically generated UI based upon your security settings. Each record is also required to have a special “name” field. This can either be an auto-number field or a human-readable identifier for the record to distinguish one record from one another. When Force.com generates a user interface, you’ll see that the value for the name field is always displayed as a link to the detail page of the record itself. Other read-only, system fields include:
CreatedDate – the date and time when the record was created CreatedById – the ID of the User that created the record LastModifiedById - the ID of the User that last modified the record LastModifiedDate – the date and time when the record was last modified by a User SystemModStamp – the date and time when the object was last modified by a User or system process (e.g., trigger, web service)
System fields are read-only. However, this can pose a problem when trying to import data. You may want to import created dates or created by for these new records. You can contact salesforce.com support and ask them to enable “Create Audit Fields”. This will allow you to import
some read-only fields for most standard and all custom objects using the Data Loader. In addition to traditional database functionality, the Force.com database has a number of services baked-in.
Apex Triggers Similar to other database triggers, Apex Triggers can be programmatically configured to fire before or after a record is created, updated, deleted or undeleted 14. Triggers have access to virtually all Apex functionality with a few exceptions (e.g., no callouts).
Validation Rules These rules help enforce data integrity from both the salesforce.com UI and API15. Validation rules fire each time a record is saved and performs the validation against a certain field based upon a formula expression. If the expression evaluates to true the save is aborted and an error message is displayed (or sent back through the API). For instance, you can create a validation rule stating that a field always contains a value or that a number entered into a field falls within a certain range.
Formulas These dynamically generated fields are the real workhorses of Force.com. A formula field behaves much like a spreadsheet formula in that it reflects some calculation based on other fields and operations based upon those fields16. For instance, for an opportunity you could create a formula that contains a discounted amounted field: {!Amount} – ({!Amount} * {!Pct_Discount}). This amount would display on any page layout, could be used for reporting and would look like a regular field to queries.
Field History You can configure each object to track changes to field values (up to 20 fields). Field history can be displayed on the page layout showing the before and after value, who changed the field and the date and time it was changed.
You can contact salesforce.com Support and have them increase the number of fields that can be tracked for your Org. We have seen them increased this number 40 for most requests.
Platform Limits Every programming environment imposes its own sets of constructs, features and constraints. The Force.com platform is no different. All programs, services and applications running on the platform run in a multi-tenant environment where their resources (e.g., memory, network, database connections) are being shared with every other program on the platform. Therefore it’s extremely important that the platform prevents rouge, runaway applications from saturating system resources and degrading the performance of other applications also running on the platform. Force.com implements a number of governors and limits to ensure that all applications “play nicely” with each other. One of the main tasks for new developers is learning how to write applications that run within these boundaries.
Governors are not evil. They often force us to take a step back and analyze our code to ensure that we are using best practices and system resources efficiently. Salesforce.com engineering is actively working to streamline and make governors and limits easier to work with. The Winter ‘11 release simplifies some of the limits surrounding test methods. Limits come in many flavors and may or not be in relation to the edition you are running17. For instance, there is a limit to the number of applications you can create, the number of tab for an Org and the number of custom fields an object may have. When developing custom applications, you have to actively take into consideration Apex governors and limits. The Apex runtime engine strictly enforces limits and issues a runtime exception if, for instance, a script exceeds a limit. Limits differ based upon the entry point of your code. For instance, when a Trigger is called from a Visualforce Controller the Apex runtime engine uses the limits for the Visualforce Controller, not the limits for the Trigger.
Governor exceptions cannot be caught and handled like most other exceptions. However, you can test for limits programmatically using the Limits class, which returns the amount of resources available in the current context.
Some limits can be tweaked by salesforce.com using their internal provisioning feature or “black tab”. For instance, the API limits are 5000 calls per user per 24 hours. However, salesforce.com Support can increase this limit on a case by case basis.
Salesforce.com Editions
Salesforce.com offers a number of bundles of its products and services, called “editions”, that provide the same look and feel but differ by price, features and functionality18. Within each edition companies can purchase different licenses, which allows them to access different features on the platform. These editions and licenses become very important when developing applications as you have to take your potential users’ edition and license types into consideration before offering functionality. You may develop a great managed package that fails when a customer installs it due to restriction (edition and/or licenses) in their Org.
We can’t stress how important it is to know the features and restrictions of each Edition. Applications that you develop on one Edition may not function on another Edition due to a feature not enabled or a set of governor limits.
Sales and Service Cloud Editions Contact Manager Edition Contact Manager (CME) is a starting point for many small business and provides access to key CRM features such as accounts, contacts, activities, calendars, notes, attachments and reports. CME is customizable to a point and is designed to whet a user’s appetite for more functionality. Contact management supports up to 5 users and is priced at $5/user/month. Store and manage unlimited contacts Track customer interactions via reporting Stay on top of your day with tasks and reminders Works with any email application Integrated with Google Apps Share documents using the content library Mobile access Restrictions include no access to Apex, Visualforce, API, sharing rules, scheduled reports, workflow, approval processes, assignments, custom labels, analytic snapshots, marketing user license (thus no campaigns), products or pricebooks, opportunities, leads, forecasting, account or sales teams, multiple currencies, custom profiles and development sandboxes.
Group Edition Group Edition (GE) is targeted towards small businesses and teams of up to five providing sales and support functionality and is priced at $25/user/month. In addition to what is offered by CME, GE offers access to accounts, contacts, opportunities, cases, and reports with a number of restrictions. Store and manage unlimited contacts Track customer interactions via reporting Stay on top of your day with tasks and reminders Works with any email application Integrated with Google Apps Share documents using the content library Capture leads from your web site Track sales opportunities Pre-built dashboards and reports Track Google AdWords performance Mobile access Phone support Storage limits, 1GB of data and 1GB of file storage shared by all users
Restrictions include no access to Apex, Visualforce, API, sharing rules, scheduled reports, workflow automation, approval processes, assignments, custom labels, analytic snapshots, marketing user license (no access to campaigns), products or pricebooks, leads, forecasting, account or sales teams, multiple currencies, custom profiles and development sandboxes.
Professional Edition Professional Edition (PE) is priced at $65/user/month and is designed for small- to midsized businesses that need more CRM functionality, security and personalization. PE is the first edition on the edition ladder where you can really start doings some development work. However some features are still missing and this will drive you crazy. Store and manage unlimited contacts Sales forecasting Marketing campaigns Track sales opportunities Service and support with cases, solutions & answers User personalization and security Mass email and templates Share documents using the content library Reports, dashboards and analytics Customizable dashboards Works with any email application Capture leads from your web site Integrated with Google Apps and AdWords Phone support Mobile access Storage limits, 20MB of data and 600MB of file storage/user Restrictions include no access to Apex, Visualforce, API (can be enabled for an additional charge), workflow automation, approval processes, products or pricebooks, account or sales teams, custom profiles, development sandboxes and can’t grant login access.
Enterprise Edition Enterprise Edition (EE) is designed for large, complex businesses and provides access to virtually all platform functionality for $125/user/month. EE is the edition that provides the most benefit for customers and the one that saleforce.com tries to sell the most. Most developers and administrators will want to work with EE as it allows them to provide the most functionality for end-users. EE includes all PE features plus: Apex and Visualforce API access Access to development sandboxes Products and pricebooks Workflow and approvals Sales territory management, account and sales teams Storage limits, 20MB of data and 600MB of file storage/user Offline access
Unlimited Edition Unlimited Edition (UE) is the flagship solution for salesforce.com and includes all EE functionality plus Premier Support, full mobile access, unlimited custom apps and increased storage limits for $250/user/month. It includes all Enterprise Edition features plus:
2000 database objects 24x7 Premier Support Fully customizable mobile capabilities Unlimited customizations and applications Access to multiple development sandboxes Increased storage limits, 120MB of data and 600MB of file storage/user
Custom Cloud Editions You can build virtually any application on salesforce.com’s infrastructure even if it’s not a CRM application. Most traditional on-premise database applications are great candidates for conversion to the Custom Cloud. Like the Sales and Service Clouds, the Custom Cloud includes a highly scalable database, security, workflow, customizable UI, analytics, granular security and sharing, development sandboxes and development tools that empower you to build powerful business applications, Web sites and mobile applications. The major difference between the Sales and Service Clouds and the Custom Cloud is that the latter does not provide access to CRM objects such as cases, solutions, campaigns, leads, opportunities, products, contracts, and forecasts. Access to accounts and contacts is available to specific licenses in certain editions so check the documentation before selecting an edition.
Force.com Free The Force.com Free Edition (FFE) allows you to build a single application for free for up to 100 users. Complete cloud platform Secure and reliable cloud infrastructure Up to 100 users Up to 10 custom objects per user Storage limits, 1GB of data and 1GB of file storage 1 Force.com Site with up to 250,000 page views per month 1 Developer sandbox API access for integration with third-party applications
Force.com Enterprise The Force.com Enterprise Edition (FEE) is salesforce.com’s most popular Cloud edition as it includes many of the key features that large enterprises require to run their mission critical applications in the cloud. All for only $50/user/month. Complete cloud platform Secure and reliable cloud infrastructure Unlimited number of users Up to 200 custom objects Access to accounts and contacts Up to 10 apps Storage limits, 20MB of data and 600MB of file storage/user Up to 25 Force.com Sites with up to 500,000 page views per month 1 Developer sandbox API access for integration with third-party applications Fully customizable mobile capabilities for an additional fee
Force.com Unlimited
The Force.com Unlimited Edition (FUE) offers virtually unlimited cloud computing for your entire company for $75/user/month. 24x7 Premier Support Complete cloud platform Secure and reliable cloud infrastructure Unlimited number of users Up to 2000 custom objects Access to accounts and contacts Unlimited apps per user Storage limits, 120MB of data and 600MB of file storage/user Up to 25 Force.com Sites with up to 1,000,000 page views per month Multiple sandboxes development, testing and training API access for integration with third-party applications Fully customizable mobile capabilities
Developer Edition The Developer Edition (DE) environment is where you develop your applications for free19. You can have as many DE Orgs as you need for any type of purpose. You can sign up for a new DE Org on the home page of http://developer.force.com and be up and running in a matter of minutes. If you are testing config change impact, developing new Apex code or developing a packaged application for distribution, most of your time will probably be spent in a DE Org. Additionally, all managed packages (applications) must be developed in a DE Org.
You cannot deploy code to production or sandbox environments from a DE Org using Change Sets. You will need to use the Force.com IDE, create an unmanaged package or move the code manually. DE Orgs provide full access to Force.com platform features, as well as licenses for other salesforce.com products that allow you to play around and discover new functionality. A number of salesforce.com licenses are provided including: 2 Salesforce licenses 3 Salesforce Platform licenses 2 Salesforce CRM licenses 2 Salesforce Mobile licenses 5 Salesforce Partner licenses 10 Customer Portal Manager licenses DE Orgs also have special limits based upon the nature of the edition:
20 MB of Data Storage 20 MB of File Storage 5000 API requests per rolling 24 hours A 500 MB bandwidth and 10 minute service request time limits (per rolling 24 hours) for Force.com Sites applications
Salesforce.com License Types Within each edition you also have a number of different licenses that provide access to specific features and functionality20. You can view the licenses available to your company and purchase additional licenses by clicking Setup -> Administration Setup -> Company Profile ->
Company Information.
Salesforce This is the most commonly purchased license and entitles users to full access to all standard CRM functionality, standard applications, custom applications and AppExchange apps.
Salesforce Platform This license is for users who need to access custom or AppExchange apps but not standard CRM functionality. These users have access to core platform functionality such as accounts, contacts, custom tabs, reports, dashboards and documents but are restricted in other ways. They do not have access to opportunities or forecasts and are not entitled to some user permissions and standard apps.
Salesforce Platform Light This license is for users who need to access custom or AppExchange apps but not standard CRM functionality. It essentially provides the same access rights as the Salesforce Platform license however the amount of times the user can log in is limited monthly. Salesforce Platform Light users cannot edit or create new dashboards and can only view them if the dashboard’s Running User also has a salesforce.com Platform Light license.
Force.com – One App This license is for users who need access to a single custom application but not standard CRM functionality. These users have the same rights as Salesforce Platform users (plus unlimited number of custom tabs) but are limited to a single custom application consisting of up to 10 custom objects and have only read-only access to accounts and contacts.
Force.com – Free This license is for users who need access to a single custom application but not standard CRM functionality. Essentially the same rights as Force.com – One App users but they do not have access to accounts and contacts.
Knowledge Only User This license is for users who only need access to Salesforce Knowledge and allows them to access the following tabs: Articles, Article Management, Home, Reports, and custom tabs. The license also includes a profile that grants access to the Articles tab via the “View Articles” user permission. A user’s profile must also include the “Manage Articles” permission to view and use the Article Management tab.
Content Only User This license is for users who only need access to Salesforce CRM Content and allows them to access the following tabs: Workspaces, Content, Subscriptions, Ideas and Home.
Ideas and Answers Internal User This license is for internal salesforce.com users who only require access to the Answers and Ideas features. The license allows users to access the Home tab, Answers tab, Ideas tab and up to three other custom tabs.
Guest User This is essentially a license for a Force.com Site which allows you to create one active Force.com Site for each Guest User license in your Org. Site visitors have access to any information made available in an active public site but can be restricted by object and read/write privileges. Your edition determines the number of Guest User licenses and you cannot purchase additional licenses.
Customer Portal Manager Standard This license is for Contacts that access your customer support information by logging into your Customer Portal. These users can view and edit data owned by them or users below them in the Customer Portal role hierarchy. They also have the ability to view and edit cases in which they are involved, access custom objects based upon their profile and receive the “Portal Super User” permission.
Customer Portal Manager Custom An extension of the Custom Portal Manager Standard license, this license also allows the user to run reports based their profile settings plus receive the “Delegated Portal User Administrator” permission. Partner portal users can also have the following two user licenses entitling them to additional features:
Silver Partner - This license entitles the user to access Salesforce CRM Content (based up feature license and profile), 2 MB of data storage and access to the documents tab, approvals and My Account Profile.
Gold Partner - This license entitles the user to access Salesforce CRM Content (based up feature license and profile), 5 MB of data storage and access to accounts, leads, opportunities, cases, custom objects, documents tab, approvals and My Account Profile.
High Volume Customer Portal User
This license is designed for contacts who need access to customer support information in your Org. These users don’t have roles, don’t appear in the role hierarchy and can only access specific records based upon specific criteria. These users can access accounts, assets, cases, contacts, custom objects, documents, ideas, and questions depending on their profile settings.
Chatter Only Salesforce.com recently announced a Chatter license for users who typically do not access Salesforce CRM but need to collaborate with other users via Chatter. The license is $15/user/month and allows the user to access profiles, status updates, people directories, real-time feeds, file sharing/content, groups, ideas, contacts, accounts, dashboards, reports, 1 custom app and up to 10 custom objects.
Be careful when purchasing salesforce.com licenses on a budget. You may be tempted to save money by choosing a “cheaper” license but down the road you may discover that your users do not have access to required features.
Standard Salesforce.com Applications In addition to core CRM functionality, salesforce.com has developed a large number of standard applications that you can utilize based upon your license.
Salesforce CRM Content Salesforce CRM Content allows you to organize, share, search, and manage content within your Org and make it accessible in various parts of salesforce.com21. Content can include virtually all file types including Microsoft Office, video, audio, web and Google docs. Content allows you to organize content by setting up searchable, virtual workspaces that are public or private. Documents can be previewed inline without needing to be downloaded to view. In addition to each user’s personal workspace, users can create multiple shared workspaces and define access to the workspaces and their content. Content authors can tag content documents for searching or additional classification. salesforce.com utilizes a powerful content search engine that scans the entire body of the document as well as content properties such as the title, description, tags, categorization data, and author name. Users can subscribe to a document ensuring that they receive notification when new versions are published or other changes are made. Salesforce CRM Content is also available in the Customer and Partner Portals as well as through Salesforce Mobile.
Chatter With Chatter users can collaborate with people inside your Org in real time in a completely secure manner with a familiar “Facebook-like” user interface 22. Users can follow people, documents and data to have access to real-time information that is important to them. Users can set up groups and profiles to promote collaboration across multiple business applications while making sure people only see information that they have access to based the Org-wide security and sharing model. You can even extend Chatter to external applications (e.g., Basecamp, Workday, SAP, Google Docs) to allow them to send updates about your employees, customers or projects.
Salesforce Knowledge A powerful, fully integrated knowledge base allowing companies to deliver relevant answers to customer inquiries enabling better customer service23. This application delivers knowledge across your call center, website, portals, Google search results and social communities. You can categories and organize information and quickly search for relevant articles that are filtered based upon what you know about the customer, attach the docs to cases or other records and even email the article.
Entitlements & Service Contracts This is a niche app that allows you to track and manage your service commitments to customers24. For support agents they can view the level of support that customers are entitled to and track the status with milestones and support cases to verify SLA commitment. You can use service contracts to up sell customers and generate support revenue.
Salesforce Ideas This community application allows users to post ideas and vote and comments on them25. Ideas can be organized into categories (e.g., New Product Development, Peripherals, Gloves) and sub-groups allowing users to filter and drill into what interests them. You can use Ideas internally within your Org or make it available externally via the customer portal.
Salesforce.com uses Ideas to develop new ideas for future releases. Users can vote ideas up or down to let Product Managers know which features are important to them. Salesforce.com actively uses these new ideas when determining new features to include in future releases.
Salesforce Answers Answers in another community application that allows members help one another26. Similar to a message board, users ask questions, community experts (other community users and customer service agents) provide answers, the community votes on the best answers and the best
knowledge in the community bubbles up to the top. Companies can sharply reduce support costs by tapping into the power of their communities resulting in faster answers, fewer inbound calls and happier customers.
Salesforce Mobile Salesforce Mobile is a feature that enables users to access their salesforce.com data from their iPhone, Blackberry, Palm Treo and Windows mobile devices. The Salesforce Mobile client application exchanges data with salesforce.com over wireless carrier networks, and stores a local copy of the user’s data in its own database on the mobile device. Users can edit local copies of their salesforce.com records when a wireless connection is unavailable, and transmit those changes when the connection becomes available. Administrators can create multiple mobile configurations determining the types of data that can be accessed. A separate Salesforce Mobile license is required for each users running the client. For Professional, Enterprise, Unlimited, or Developer Edition users without mobile licenses, salesforce.com offers Mobile Lite, a free, restricted version of Salesforce Mobile.
Customer Portal The Customer Portal allows you to deliver a personalized, service application to your most important customers27. The Customer Portal consists of functionality similar to salesforce.com and is one of their most used and customizable offerings. Many other applications use the customer portal in the background for authentication (e.g., Force.com Sites, Ideas) so don’t be surprised if you see it popping up from time to time. Functionality of the Customer Portal includes but is not limited to the following: Self-service functionality with case management, Salesforce Knowledge, Solutions and Answers Allow users to run customizable reports Provide access to documents and Salesforce CRM Content Access to a knowledge base for customers using Salesforce Knowledge Ability for customers to participate in Salesforce Ideas communities Expose access to custom objects to display and collect information for custom applications Ability to create profiles with customizable page layouts, list views and field-level security Manage users with profiles, roles, and sharing rules Enable access via single sign-on Tweak the look and feel by changing colors and logos and customizing tabs and their order Customize communication templates
Partner Portal The Partner Portal allows companies to empower their indirect sales channels to sell more thus maximize channel ROI28. With a secure, partner-only website, companies can provide their sales partners with personalized access to salesforce.com data. With partner relationship management (PRM), companies can create multiple portals to manage, track, and forecast their channel business alongside their direct sales business thus fostering closer relationships with partners that translate into higher profits. Channel managers utilize Partner accounts to manage partner companies, user and activities. Partner Portal users have limited access to salesforce.com based upon the particular license they are assigned - Silver (Standard) or Gold (Strategic). Depending on the type of license, users may have access to: Collaborate on sales opportunities with tasks and activities Provide self-service functionality with case management, Salesforce Knowledge (view and rate), Solutions and Answers Allow users to run customizable reports Provide access to documents and Salesforce CRM Content (read-only) Access to a knowledge base for customers using Salesforce Knowledge Allow customers to participate in Salesforce Ideas communities Expose access to custom objects to display and collect information for custom applications Ability to create profiles with customizable page layouts, list views, sharing rules, user roles, role hierarchy and field-level security Enable access via single sign-on Brand the look and feel by changing colors, fonts, logos and customizing tabs and their order
Customize communication templates Assign a salesforce.com user as the portal administrator
Salesforce to Salesforce Salesforce to Salesforce is a feature that allows you to share data with another salesforce.com Org29. So if a business partner is also using salesforce.com you can create connections that allow you to publish and subscribe to each other’s objects and fields for virtually any type of record (e.g., lead, accounts, opportunities, custom objects) in one another’s Org.
Force.com Sites Using Force.com Sites you can build and serve public websites and applications directly from the Force.com platform30. Force.com Sites are built using Apex and Visualforce but can also include simple HTML markup, JavaScript, CSS and Flash to create a visually compelling user experience. You can even run your Force.com Site from your own domain name if you’d like. You can create a corporate website or intranet, ecommerce applications or simple microsites for an existing website that dynamically exposes data from your salesforce.com Org. Force.com Sites is enabled for most editions but there are bandwidth and usage restrictions. Sites applications run as their own special public user with public access settings which controls which database objects and fields your visitors can see. You can even allow your visitors to authenticate with their customer or partner portal credentials.
Standard Objects Salesforce.com comes with a number of standard objects that you can use as soon as your Org is setup. They comprise the core functionality of the platform and most are customizable to some extent.
Account Since salesforce.com is by definition a CRM application, the account object is the heart and soul of virtually all processes in some way. Almost every object in salesforce.com is related to the account object in some way, by some relationship. Accounts represent your company’s customers, competitors and other business partners that you interact with. Each account record stores information such as name, address and phone numbers along with related information for contacts, opportunities, cases, activities, partners, contracts and notes. You can create accounts specific to companies, people and/or partners depending on enabled features. Accounts can be related to one another to create an “Account Hierarchy” to represent companies with different corporate structures (e.g., subsidiaries, divisions) and/or sales territories. Territory management is an account sharing system that allows users access to accounts based on some characteristics of the accounts (e.g., zip code, industry, revenue, or a custom field). It enables your company to structure and forecast your salesforce.com data and users the same way you structure your sales territories. Your company can also enable multiple users (e.g., executive sponsor, account executive, support representative) to work together on an account. You can build an account team of users by role and specify the level of access each account team member will have to the account and any contacts, opportunities, or cases associated with that account.
Person Account Out of the box (so to speak), salesforce.com is a B2B product. But what if your company provides home healthcare services or lawn care services or any other type of service for individual consumers? Salesforce.com can be tweaked for this scenario by using “Person Accounts”. By default, person accounts are not enabled. You’ll need to call support to have them enabled and they will repeatedly ask you if you really want to do this and if you understand the consequences. Once enabled, person accounts cannot be disabled. We recommend you setup a DE Org first and test out your solution there before enabling your production Org. So what actually happens when you enable person accounts and what are the consequences? In most situations, you can use person accounts as if they were contacts. You can include them in all contact list views (except the Recent Contacts list on the contacts home page), configure their own page layouts and field level security and use them in portals. When person accounts are enabled, a number of person-related info fields are created in the account object. So when you create a new person account record, salesforce.com creates not only an account record but also a contact record in the background. You cannot access the account record directly (it always relocates you back to the person account record) but it is needed for the functionality that requires a contact (emails, customer portal, etc.). Person accounts have some restrictions so you’ll want to see the documentation.
Contact Contacts represent the individuals associated with an account that you need to track in salesforce.com. You can store various information for a contact including title, phone numbers, email addresses, physical addresses, titles and custom information that’s important to your company. When contacts are added to an account, case, contract or opportunity they can be assigned a role that they play in that record. These roles are customizable for your Org.
Contacts that are not linked to an account are always private, regardless of your Org’s sharing model. Only the owner of the contact and administrators can view it. Sharing rules and workflow rules do not apply to private contacts.
Lead
Leads are simply prospective customers that you are trying to sell to. Leads can be entered manually, imported or captured from a Web-toLead form on your company’s website. Leads are very generic in nature and contain both company and contact information. When new leads are created you can automatically assign them to sales people with lead assignment rules or place them in a queue to manage distribution. Your sales team will work these leads and at some point in the sales process “convert” them by creating a new account, contact and, optionally, an opportunity. Administrators can configure field mappings which determines how the data from the lead is used to create the new account, contact and opportunity. All open and closed activities from the lead are attached to the account, contact, and opportunity.
Once leads are converted they can no longer be viewed directly but do appear in lead reports.
The lead object contains IsConverted, ConvertedDate, ConvertedAccountId, ConvertedContactId and ConvertedOpportunityId fields. You can query for converted records and determine what accounts, contacts and opportunities were created during the conversion process.
Campaign Campaigns are outbound marketing projects (e.g., direct mail program, seminar, print advertisement, email) that you want to plan, manage, and track within salesforce.com. Both leads and contacts can be added to campaigns. You can organize campaigns into hierarchies for easy analysis of related marketing tactics. All campaigns are executed outside of salesforce.com but you can track their response and analyze their influence on new business. Opportunities can be configured to either manually or automatically associate multiple influential campaigns to determine what marketing efforts impacted sales.
Opportunity Opportunities are past or pending sales for an account that you want to work and/or track. By using opportunities you are, in a sense, building your “pipeline” and enabling you to perform sales forecasting. Opportunities are one of the most widely used and heavily customized objects on the platform. Opportunities allow you to track the individual products (opportunity line items) that you are selling on the deal, multiple quotes, any partners involved and competitor and their products that you are competing against. For team selling, opportunity owners can set up sales teams of users assigned to specific roles (e.g., account executive, pre-sales consultant) with specific access privileges. You can also split opportunities to give credit to multiple members of the team. Forecasting is a way to estimate quarterly revenue from your opportunities. The forecast amount is based upon your pipeline and is the total amount of all “Commit” opportunities divided by the total amount of all “Best Case” opportunities. For a more granular view, you can setup customizable forecasting to reflect how your company forecasts its sales. With customizable forecasting, you can forecast on a monthly or quarterly basis, use different dates when applying amounts to forecasts, forecast based on revenue or quantity or both, and define additional quotas based on product families.
Quote A quote is a formal proposal for products and services that you are offering for a specific opportunity. Opportunities can contain multiple quotes and quotes are created from an opportunity and its products. When a quote and an opportunity are synced, any change to line items on the opportunity will sync with products on the quote, and vice versa. You can also create templates that allow you to email completed quotes as PDFs to prospects.
Product and Price Book Products are the actual items that you sell on your opportunities and quotes. Products are associated to one or more price books to create price book entries. Products can exist in multiple price books with many different prices. For example, you may have a “North American” price book with one set of prices for your products and a “South American” price book with a different set of prices. You can also create default revenue and/or quantity schedules for products or opportunity line items to determine how default unit prices are handled. You can use the standard price book that comes with salesforce.com or create custom price books. The standard price book is automatically generated to contain a master list of all products and standard prices regardless of the custom price books that also contain them. When you add products to your opportunities or quotes, you first have to select the price book.
When importing products you must also import price book entries. If you are using custom price books, you must also add the product to the standard price book in addition to the custom price book.
Case Cases are the foundation of the Service Cloud and are used to track customer issues and inquiries. Cases are typically used to track and manage customer feedback, issues or questions. Cases can be created by support representatives, from web forms on your website (web-to-
case), by customers themselves from the Customer Portal or directly from emails (email-to-case). New cases can be assigned directly to support agents, case teams or case queues using assignment rules. Cases allow you to interact with customer easily by sending and receiving email in one centralized location, replying with knowledge articles or solutions and managing entitlements more efficiently.
Custom Objects Custom objects allow you to store information that is unique and important to your company. Custom objects are often used as building blocks for custom applications. For instance, you could create a Shipment custom object that tracks your product shipments or a Part custom object to track individual repair parts. Administrators define the custom object and its properties, such as custom fields, relationships to other types of data, page layouts, and access rights to fields and records. Custom object look and function for the most part just like standard objects and have similar functionality (e.g., store records, searchable, reportable). Custom objects allow you to extend the Force.com platform with a simple, point-n-click interface.
Types of Orgs Salesforce.com offers different types of Orgs for different purposes. Not all types of Orgs are available to all companies and may require an additional fee.
Production Org Your production Org is where most users will perform their daily activities. Users can log into the production Org at https://login.salesforce.com. All usernames must be unique across all production Orgs.
Sandbox Org You can create multiple copies of your production Org for development, configuration, testing and/or training without affecting your production configuration and data. The edition that your company purchased may be entitled to sandboxes or you can purchase additional sandboxes. Users can log into sandbox Orgs at https://test.salesforce.com. Professional, Group, or Personal Orgs do not have access to sandboxes. Full copy sandboxes can be refreshed from your production Org every 29 days while developer and configuration-only sandboxes can be refresh from production daily.
Full Copy Sandbox Full sandboxes are essentially an exact replica of your production Org and all of its data, including standard and custom object records, documents, and attachments.
Configuration-Only Sandbox Configuration-only sandboxes copy all of your production Org’s reports, dashboards, price books, products, apps, and customizations under Setup, but exclude all of your Org’s standard and custom object records, documents, and attachments. It’s essentially a copy of your production environment without your data. Config sandboxes can only include up to 500 MB of data.
Developer Sandbox Developer sandboxes are special configuration-only sandboxes intended for coding and testing by a single developer. They provide an environment in which changes under active development can be isolated until they are ready to be shared. Just like configuration-only sandboxes, developer sandboxes copy all application and configuration information to the sandbox but not the data. Developer Sandboxes are limited to 10 MB of data.
Developer Org A developer Org is a free, non-expiring copy of an Enterprise Edition environment that you can use to instantly start developing, testing and deploying your applications. Developer Orgs are equipped with everything you need to get started including Apex, Visualforce, Web services API, Sites, pre-installed applications (Sales, Marketing, Ideas, Customer Portal, etc), licenses for numerous salesforce.com products (CRM, Mobile, Partner, etc.) and much, much more. Only Developer and Partner Developer Orgs can be used to create managed packages for distribution. You can sign up for as many Developer Orgs as you need by going to http://developer.force.com and clicking on the Get a Free Developer Edition link. Users can log into Developer Orgs at https://login.salesforce.com.
Partner Developer Org This is a free Developer Org with more storage, features and licenses for companies enrolled in the partner program.
Pre-release Org A pre-release Org is a limited time Org that allows you to test new features or functionality typically associated with a pilot program or an upcoming release. These are special cases and you will most likely need to signup for these Orgs or contact salesforce.com support. Users can log into pre-release Orgs at: https://prerellogin.pre.salesforce.com.
Where Should You Develop?
1 cloud-computing 2 sales-cloud 3 service-cloud 4 collaboration-cloud 5 custom-cloud 6 apex-intro 7 vmforce 8 security 9 sso 10 security-data 11 infrastructure 12 database 13 database 14 intro-triggers 15 validation-rule-examples 16 intro-to-formulas 17 governor-limits-intro 18 editions 19 developer-edition 20 licenses 21 crm-content 22 chatter 23 salesforce-knowledge 24 entitlements 25 ideas
26 answers 27 customer-portal 28 partner-portal 29 salesforce2salesforce 30 sites
Getting Started with Salesforce.com
Now that you have a good understanding of what salesforce.com is and what the platform consists of, let’s really dig into it. In this chapter we’ll discuss the major features and benefits of using the Force.com platform as well as some of the major design considerations that must take place in a multitenant environment.
Managing Users Every user that has access to the platform is identified by a username, password and a single profile. You can access the list of all users in your Org by clicking Setup -> Administration Setup -> Manage Users -> Users. The user record maintains not only personal information such as phone number and manager but platform settings such as time zone, email encoding, approval settings and mobile configurations 1. Users cannot be deleted once they are created but can be deactivated. You can change a user’s username once created as long as it remains unique.
Salesforce.com usernames must be unique across all production and sandboxes environments. For instance, two production Orgs cannot have the same username
[email protected], but it can exist in both a production and a sandbox Org.
Users can grant login permission for administrators so that they can impersonate users and troubleshoot application issues, security settings and record access easier. Users must go to Setup -> Personal Setup -> My Personal Information -> Grant Login Access and enter an expiration date to grant login access.
Profiles Profiles typically model a user’s job function (e.g., sales manager, marketing assistant) and users can only be assigned to a single profile2. A profile defines the objects that a user can access as well as the settings and permissions for various functions on the platform. You can access profiles by clicking Setup -> Administration Setup -> Manage Users -> Profiles. Each profile is assigned a specific license that provides access to specific features and functionality. Many of the more granular settings for the platform (e.g., Schedule Reports, Import Leads, View Setup and Configuration) and configured at the profile level. Profiles determine: CRUD permissions per object determining the user’s ability to create, read, edit, and delete records Which standard apps, custom apps and tabs the user can view The specific page layout the user sees per object The field-level security settings that determine the user’s ability to view and edit specific fields for each object Record types available per object to the user Login restrictions such as specific login hours and from which IP addresses a user can login from Admin and general user permissions for managing the Org and apps within it The Apex classes that a user is authorized to execute The Visualforce pages a user is allowed to access
Salesforce.com includes a number of standard profiles in every Org. As only certain settings can be changed on standard profiles, it is highly recommend that you clone standard profiles before using them.
Roles Used in combination with your sharing settings, roles control the actual records that can be viewed by users3. Users at any given role level can view, edit, and report on all data owned by or shared with users below them in the hierarchy, unless your Org’s sharing model for an object specifies otherwise. For example, if your role hierarchy contains a “VP Sales, North America” and a “VP Sales, Europe” role with additional roles underneath (e.g., Channel Sales, Direct Sales, Government) then all records owned by users under the VP Sales roles will be accessible to the users assigned to the VP Sales roles. However, users will not be able to access records owned by other users above them in the role hierarchy. This ensures that
bosses have access to all records owned by their subordinates and some that are private to them. All users that require visibility to the entire Org should belong to the highest level in the hierarchy. The role hierarchy is not necessarily your org chart but it may be similar. You can access your Org’s roles by clicking Setup -> Administration Setup -> Manage Users -> Roles. It is not necessary to create individual roles for each title at your company, rather each role in the hierarchy should represent a level of data access that a user or group of users needs.
A role is optional but it is a best practice to assign each user one. Every user should be assigned to a role, or their data will not display in opportunity reports, forecast roll-ups, and other displays based on roles.
Groups Groups are sets of users that can contain individual users, other groups, the users in a particular role or territory, or the users in a particular role or territory plus all of the users below that role or territory in the hierarchy4. Groups can be either public (created by administrators but accessible by everyone in your Org) or private (created by users for their own personal use). Groups are typically used for defining sharing rules, manual record sharing and configuring access to Salesforce CRM Content workspaces and actions in Salesforce Knowledge.
Securing and Sharing Data One of the first tasks when setting up a new Org is to define the sharing model 5. This is a balancing act between restricting data, thereby limiting risk of stolen or misused data, and providing access to data so that users can do their jobs effectively. The choices you make with the sharing model will drive a number of decisions for viewing data, access to specific fields, reporting and analytics down the road. With all of the permutations of Org-wide defaults, sharing rules, overrides and profile access, this is arguably the most complex topic in salesforce.com to wrap your head around.
Object-Level Security Profile-based or object-level security provides the broadest way to control access to data in salesforce.com. By configuring a user’s profile, you can prevent them from seeing, creating, editing, or deleting any instance of a particular type of object. Object-level security allows you to hide entire tabs and objects from particular users, so that they do not even know that type of data exists.
Field-Level Security Field-level security is configured again from a user’s profile and controls whether a user can see, edit, and delete the value for a particular field on an object. For instance, for an Administrative Assistant profile, you may want to remove access to payroll and social security information for obvious reasons. A common mistake when restricting access is to simply remove a field from a user’s page layout. This method only controls the visibility of the field on detail and edit pages for the object. To be absolutely certain that a user does not have access to a specific field, you must lock down the field with field-level security. This removes all access to the field for the API, related lists, list views, reports and other parts of platform.
Record-Level Security After setting profile access to objects and individual fields, you’ll need to determine your Org’s level of record-level security. For instance, you may want everyone in your Org to be able to view all Accounts but restrict Lead records so that Sales Reps can only see Leads they own. The first step is to lock down object access to the most restrictive level using Org-wide defaults. You can then use role hierarchies, sharing rules, and manual sharing to open up the records to other users who need to access. Org-wide defaults specify the default level of access to records and can be set separately for most standard and all custom objects. Organization-wide sharing settings can be set to the following:
Public Read/Write - All users can view, edit, and report on all records. Public Read Only - Only the owner and users above them in the role hierarchy can edit records. All other users can only view and report on records.
Private - Only the owner and users above them in the role hierarchy can view, edit and report on records. Controlled by Parent - A user can only view, edit and report on a detail records if they have access to the associated parent record. For example, a user can only view Activities for a Contact if they access to that Contact record.
Public Read/Write/Transfer - Applicable for Leads and Cases only. All users can view, edit, transfer ownership, and report on all records. Full Access - Applicable for campaigns only. Users can view, edit, delete, and transfer ownership of records. Users can share records with other users but cannot grant them Full Access.
Administrators and users with the View All Data or Modify All Data profile permissions checked have full access to all records of the selected object type, regardless of the sharing settings for the object.
After you have defined the Org-wide defaults, you can specify whether users have access to data owned by or shared with their subordinates in the hierarchy. Similar to, but not necessarily an Org chart, a role hierarchy represents the level of data access that a user or group of users have. The role hierarchy ensures that a supervisor always has access to their subordinate’s records regardless of the Org-wide default settings. In addition to role hierarchies, you can also implement territory hierarchies as an account sharing system that grants access to accounts based on the characteristics of the accounts. Sharing rules allow you to make automatic exceptions to your Org-wide defaults based upon some criteria to give access to specific groups of user for records that they do not own. For example, if you have a Private sharing model for Leads you could create a sharing rule that shares all Leads owned by the “North American” sales group with all users in the “North American” legal group. Sharing rules are the most effective when they are defined for a particular set of pre-defined users (e.g., public or personal group, a role, a territory, or a queue). Just like roles hierarchies, sharing rules are used to open up record access to users, and can never be more restrictive than your Org-wide defaults. For dynamic or frequently changing sets of users, programmatic Apex sharing rules may be a viable alternative. Apex managed sharing allows developers to write Apex code to programmatically share objects based upon some criteria. However, if sharing rules or Apex managed sharing does not fit the bill, record owners can use manual sharing to give read and edit permissions to users who would not have access to the record any other way. For records where sharing is an option, users will see a “Sharing” button on the record detail screen. They can then manually share the record with individual users or group of users. You can also provide record access to multiple users by using queues and teams. Queues are available for leads, cases, and custom objects. Once records are assigned to a queue (the queue is the actual record owner), they remain in the queue until they are assigned to a user or “accepted” by one of the members of the queue. Any queue member or users above them in the role hierarchy have access to the records in the queue and can take ownership of them. For accounts, opportunities, and cases, record owners can define teams of users to grant access to their records. A team is a configurable group of users that work on an account, opportunity or support case. When configuring a team, the record owner can define a role (e.g., Support Rep, Sales Engineer) and the level of access (e.g., read/write, read-only) to the record.
Field Accessibility Since access to fields can be a confusing combination of page layouts, field-level security and profile permissions, salesforce.com has a handy little section called Field Accessibility that allows you to view field access by profile or field for a particular object. You can find this section by clicking Setup -> Administration Setup -> Security Controls -> Field Accessibility . You can choose a field and view its accessibility by different profiles and record types. You can also choose profile and view field accessibility for different record types.
You can then click a field to modify the accessibility for that field based upon field level security and/or page layout.
Record Types Record types are an extremely powerful feature of salesforce.com that allow you to offer different business processes, segment data and personalize the UI based on user profiles6. By default, objects do not use record types. Once you add a record type for an object, the platform will add a new field called RecordTypeId to the object. You can determine which profiles have access to individual record types and display different page layouts to users based upon the record’s record type. You can also determine the picklist values that are available for the picklist fields on the object for a specific record type. When a user creates a new record they will be presented with a picklist of available record types for the object and will be required to choose the type of record they are creating. The platform will automatically display the page layout based upon their profile. For example, a use case for record types may be a company that repairs equipment. The company repairs two types of equipment, gasoline and diesel engines, so they create a record type for each one. When employees create a new record they select the type of engine (gasoline or diesel) and enter data about the engine based upon the record type. For gasoline engines there may be a field that allows the user to enter the date the engine was last serviced, while this field does not display for diesel engines. There may also be a field for the user to select the origin of the equipment. For gasoline engines the picklist values may be “North America” and “South America” while for diesel engines they may be “North America”, “South America” and “Europe” (they only sell diesel engines in Europe). When a user views a piece of equipment in the UI, the platform will automatically display the correct page layout for the user’s profile based upon the record type of the record. Record types are extremely useful in that you can create views, reports, workflow or Apex triggers that segment or operate only on specific record types. For users that typically use only a single record type you can set a default record type for each object thus allowing them to skip the record type select process when creating new records. Again, profiles can be assigned access to specific record types, which does not impact security in any way. Users can still view records irrespective of record types (based upon the sharing model of course) and even change the record type to any available record type. The record type limitation imposed by profiles is only enforced when a record is created.
Automate Business Processes with Workflow Workflow is one of the most widely used and loved features of salesforce.com 7. Workflow gives you the ability to automate and enforce key business processes without the need to write a single line of code.
You should always check to see if your business requirement can be met using workflow before writing Apex code. All workflow rules are accessible by clicking Setup -> App Setup -> Create -> Workflow & Approvals -> Workflow Rules . Workflow rules are configured per object, fire based upon changes to record values, filter records based upon some type of rule criteria and then performs some sort of action immediately or at a point in the future. Workflow rules can be configured to fire:
When a record is created, or when a record is edited and did not previously meet the rule criteria Only when a record is created Every time a record is created or edited Records processed by workflow rules must also meet a rule criterion. You can choose to run the rule if a certain criteria is met (i.e., Status equals “Rejected”) or a formula that you write evaluates to true (i.e., OwnerId <> LastModifiedById).
One of the most agonizing decisions you make when creating a new workflow rule is determining when the workflow rule should fire. If you want the workflow to fire only when the record is created then choose (obviously) the Only when a record is created option. If you want a rule to fire each time a record is created and updated (repeatedly) regardless of the rule criteria, then choose Every time a record is created or edited. The only caveat with this option is that you cannot add time-dependent actions. Perhaps the most widely used option is When a record is created, or when a record is edited and did not previously meet the rule criteria. Choose this option to include new records and updates to existing records, unless the rule just ran and still meets the rule criteria. The rule is not re-triggered on edits that do not affect rule criteria. For example, if setting a lead’s status to “In Progress” causes the rule to fire, with this option, the rule will only fire again if the lead’s status changes, then changes back to “In Progress” — no matter how many times you edit the record. When workflow rules fire, you want some sort of action to be performed. Workflow actions can be configured to happen immediately or at some point in the future. Immediate workflow actions are self-explanatory but with time-dependent workflow actions you could, for example, have salesforce.com automatically send an email reminder to a support case owner if the case has not been modified in the last two weeks or create a task for the VP of Sales to call a customer 5 days before an opportunity is scheduled to close. Time-dependent workflow is not analogous to a system scheduler where a process runs at some date in the future to find records that meet a specific criterion. When a record is saved, the platform checks to see if the record meets the workflow rule criteria. If so, it schedules the action(s) to take place at some point in the future. If the record is again updated and it no longer meets the workflow rule criteria, then all affected actions are cancelled. When workflow rules fire they can automate the following types of actions:
Field Updates - Update the value of a field on a record. For example, automatically change the lead’s owner to a queue or another user based upon the value of the lead status.
Email Alerts - Send an email to one or more recipients. For example, automatically send an account manager an email notification when a support case closes.
Tasks - Assign a new task to a user, role or record owner. For example, automatically assign a follow-up task for the account manager to call and thank a customer one week after the opportunity closes.
Outbound Messages - Send a secure, configurable API message (in XML format) to a designated listener. For example, automatically notify an external HR system when a user updates their home phone number.
Developing Approval Processes
Approval processes are an extension of workflow and are often talked about in the same context8. An approval process is an automated process your company can use to approve records in salesforce.com. Approval processes build upon workflow by allowing you to specify a sequence of steps that are required to approve a record. The process specifies the steps necessary for a record to be approved, who must approve it at each step and the actions to be taken when a record is submitted for approval, approved, rejected or recalled. You can build complex approval processes that dynamically evaluate and route approvals based upon specific criteria. For instance, you could build an approval process for purchase requests that routes the approval to an employee’s manager for requests under $1000 while requests over $1000 are sent to the purchasing manager.
You can also enable approval via email. This allows users to simply reply to an email by typing approve, approved, yes, reject, rejected, or no in the first line of the email body and adding comments in the second line.
Setting up an approval process involves many steps and quite a bit of planning to do it correctly. You may want to visually design your process with all stakeholders to ensure that it meets all requirements. This will help you translate the process using the Standard Setup Wizard or Jump Start Wizard. Some of the steps involved in setting up an approval process include:
Determine records that should be processed for approval - Your process can either include all records for a particular object or you can filter them by entry criteria. This criterion can either be a combination of field values (i.e., Lead Status = “Negotiation/Review”) or a formula that evaluates to true (i.e., Amount > 10,000).
Specify which users are allowed to submit records for approval - You can configure the process so that only the record owner or creator, members in a public group or users in a specific role can submit records for approval.
Specify the sender of approval requests - By default, approval request notifications are sent from the user submitting the request. You can specify a different “from” address if required by your business processes.
Who will be responsible for approving or rejecting requests? - Each independent step in the process can be configured to determine who can approve or reject the approval request. This can be the submitter’s manager, a user or queue that the submitter chooses, a queue specified by the administrator, a user listed in the submitter’s custom hierarchy or any combination of users or related users specified by the administrator.
Should delegates be allowed to approve requests? - An approval request can be approved by a designated delegate for the approver. For example, a VP of Sales may allow his assistant to approve requests when he is on the road. The Delegated Approver field must be configured on the user’s record with the delegate.
What actions should be taken when a record is first submitted for approval? - Records are automatically locked when a user submits them for approval. Using the Initial Submission Actions section, you can also configure workflow actions such as field updates, email alerts, tasks and outbound messages that are fired when first submitted.
Determine if users can edit records awaiting approval - Administrators and all users with the Modify All and Modify All Data permissions can always unlock and edit records. However, to possibly make the approval process flow smoothly you can also specify that the currently assigned approver can also edit the record.
Email templates to be used - By default salesforce.com uses a standard email template when notifying users that an approval request is assigned to them. If your business requires more details you can create your own email templates including standard merge fields.
Configure approval page layout - Part of the approval setup process is determining what information on the page layout that users will see. You can determine the individual fields, approval history related list and security settings.
Configure automatic conditional response - For each step on the process you can specify an entry criteria that automatically approves, rejects or skips the process based upon some criteria. For instance, you may configure the process so that purchase requests under $100 are automatically approved.
What actions should take place when a request is approved or rejected? - When a record has received all necessary approvals or is completely rejected, you can configure up to 10 actions each (40 total) of a new task, email alert, field update or outbound message. Items waiting to be approved can be easily configured to display on a user’s Home tab layout.
You can also write Apex triggers to automate approval processes based upon some value on the record. For instances, you may want to start an approval process when an opportunity reach 30% probability. See chapter 6 for a detailed example.
Formulas Formulas are a prevalent feature in the declarative development area of salesforce.com. The reason for their popularity is because they are a simple way for non-technical users to translate business requirements into application logic. Depending on their context, formulas can be used to present dynamically calculated field values, determine default field values, ensure data integrity or determine execution criteria9. Although it’s important to discuss the various contexts, it’s worthwhile introducing the commonalities such as syntax.
As you’ll see later, the declarative development areas that use formulas don’t require any Apex code or unit testing. This often makes them easier to maintain or change, and very quick to implement. It is for these reasons that it’s highly advised that you consider using these features as an alternative to programmatic development where possible.
Syntax Formulas are essentially equations that are executed at runtime e.g. when a page loads. Key to know at this point is that these equations aren’t just mathematical, but can also involve the evaluation of logic. Although it is beyond the scope of this book to detail the topics of mathematics and the languages of logic, consider the following simple example: Your business requirement is that you need a field that will display a discounted value for a purchased item if your customer spends more than X dollars. The first step required to translate this requirement into application logic is to word it using something called pseudo code. Essentially you need to break your problem into phrases separated by logical operators and (if required) mathematical expressions. The above requirement might be phrased as: IF customer A spends GREATER THAN X dollars THEN they will receive a Y% discount ELSE they don’t receive a discount. Here the words in capitals are the logical operators. The phrase between the IF and the THEN is the expression to evaluate, and the two logicbranches will deliver the appropriate results (a discount or no discount). Once your business requirement is phrased in this way then it’s simple to translate this pseudo code into formula code. The above example can be written as in Listing 2 - 1.
Listing 2 - 1. Simple Conditional Formula
The details of formula syntax is extensively documented in the reference documentation but it’s valuable to understand the categories that the groups that syntactic components fall into:
References to object fields - Used to include the value of other fields in your formula. Note that you can reference related object record fields very easily too! More on this later.
Operators - As mentioned before these can be either logical operators (used to determine the truth of a statement) or mathematical operators (used to calculate a value)
Literals - These are values that you hard-code, such as pieces of text or numbers Functions - The platform offers a number of built-in functions for common operations. Many of these are similar to those offered in Excel and fall into 4 categories: Date and Time, Text, Logical and Mathematical
Global Variables - Provide access to system or other convenient information. An example is the $Organization.Name
Cross Object Formulas Often you’ll find that you need to refer to fields in records that are related to the current record that the formula is being applied to e.g. the formula might apply to a Contact record, but in that formula you might want to refer to the related Account record. Luckily salesforce.com has made this very simple and the feature is aptly named Cross Object Formulas.
Note that it is only possible to access the fields in the direction of child to parent i.e. you will not be able to retrieve the data of child records from their parents. The syntax for these references is natural and precise. Consider the situation where you need to create a formula for a Contact record, but you need to refer to the related Account’s parent Account’s name. In this case the syntax would be Account.Parent.name i.e. you access the field value by using the related field names (separated by periods) until you arrive at the object field in question. For custom objects the syntax is slightly different e.g. if the formula applies to a custom object and needs to interrogate the parent object’s name field through the Parent__c relationship field, the syntax would be Parent__r.name. This is very powerful, especially when you consider that you can traverse up to 5 relationships deep10 (you can mix standard and custom objects relationship).
Where Do I Use Them? Formulas can be used in a number of areas within the platform as previously mentioned, and depending on their context can be used to achieve different types of results.
Formula Fields
These are read-only fields with values defined by the underlying formula. Data in these fields are not persisted but is calculated on the fly when the field is accessed. Creating formula fields can be done from the same area as the other field types. At creation time you’ll need to select the “type” that you wish the field to adopt e.g. currency, date, and text. The type you choose affects the field display, but also how the field is seen by any Apex or API interrogations.
Using formula functions you implicitly have access to some “sub” field- types including hyperlinks and images. You are free to use any combination of formula component in formula fields as long as the resultant value is of the pre-determined type. This way you have a powerful slate upon which you can use conditional logic to present a range of dynamic value types to your end users.
Never use a formula field as an indexing or filtering value. If you need a field value to be dynamically calculated but know that it will be used to filter data through API calls or in the WHERE clause of any SOQL statement, consider using static fields in combination with workflows instead. The reason here is that the calculation of formulas can be especially taxing “under the hood” to the platform in these conditions and will result in a performance loss.
Default values When declaring most field types you have the opportunity to declare a default value. This can either be as simple as a literal value or alternatively a formula of any complexity. If no value is specified for the field when a record is created then it will be assigned said default value.
Validation Rules Validation Rules do not result in dynamic values but instead determine whether the data in a specific field obeys your pre-defined data integrity rules. These can be either rules that force data in a certain field to conform to some standard, or they can enforce simple business or workflow rules. Validation rules are executed when records are edited and created, and if the error condition is calculated to be true the user will be prevented from committing the record. Consider the data integrity example where all account numbers must be numeric. Listing 2 - 2 shows the appropriate
validation rule.
Listing 2 - 2. Data Integrity Validation Formula
Listing 2 - 3 is an example of a business rule that prescribes that the number of worked weekly hours must be less than 40.
Listing 2 -3 . Business Validation Formula
Notice that formulas can only have logical operators as their outer most “action”. This way they will only result in a true or false value. You’ll have seen during the creation of validation rules that you must also provide an error message; if the outer most operation results in a value of true then that error message will be presented to the user. Be sure to run through the documented examples as they list a number of commonly used formulas in Validation Rules11.
Workflows & Business Rules Salesforce.com supports a number of common business processes such as workflows, approvals, escalations, assignments and autoresponse rules. Each of these requires the system to execute business logic to determine whether the rules should be applied, and that’s where formulas enter the picture again. In this way formulas within these rule-types are similar to validation rules but instead of preventing a user from changing data an appropriate rule-action will take place.
Visualforce Visualforce is the Force.com programming language for building user interfaces. The application of formulas in this context could thus be considered a programmatic one. Formulas in Visualforce are used to evaluate expressions, and in doing so be used as logical operators e.g. whether a certain page should be displayed, or they can deliver values such as literals, global variable values or even static resources 12.
Listing 2. 1 Formulas in Visualforce Pages - Conditional Display of OutputPanel
Although the syntax of formulas here is slightly different (you’ll have access to number of other functions, operators and global variables) the overlap is so large that you’ll have no trouble implementing formula logic in your pages.
Limitations The formulas that you create are compiled into SOQL code and it is this code that is executed when the formula is referenced at runtime. To ensure that each tenant in the Force.com platform doesn’t abuse the shared pool of resources, it is necessary to impose certain limits on formula field usage. Standard, custom and other formula fields can be referenced, but formula field self-references are not allowed. If a formula is dependent on a certain field, that field cannot be deleted until the reference is removed or the formula field is deleted. Formula fields cannot exceed 3900 characters in length (including spaces and line breaks). The backend SOQL compiled as a result of your formula cannot exceed 5000 characters in length and the only way to check this is to press the Check Syntax button. Cross-object formulas can travel no more than 5 relationships. You can reference 10 unique relationships per object across all formula fields for an object. No more than 10 uses of the VLOOKUP function can be used across all formula fields per object.
Best Practices It’s common to exceed the length for formula fields and it’s usually not because people are writing exceptionally long formulas! The issue is that if formula field A references formula field B then the length of formula field A is effectively (the character length of A) + (the character length of B). It’s therefore very important to bear this dependency in mind and adhere to some of the common best practices for keeping formulas short. 1. Refactor your mathematical formulas using Algebra. Using the fields A and B described above you might’ve written the value of A as: A = B + B * (0.1) This would result in the formula representation of field B being pulled into the compiled version of field A twice. We can write this as: A = B * (1 + 0.1) = B * 1.1 In this new representation the formula represented in field B will only appear once in A making your formula shorter by as many characters are in formula B. 2. Often you’ll need to validate that a user has entered one of a number of valid values e.g. country or area codes. Sometimes this validation is necessarily complex but often all you need is a picklist field. By their nature they help users avoid erroneous input values and you can avoid writing or referencing formulas. 3. Effective use of the available functions can help reduce the length of formulas so be sure to read through the list from time to time, making sure you understand what each does. For example if your formula examines two numeric field values and presents which ever has the smallest value you might write the following:
A quick look through the available functions you notice one called MIN allowing you to rewrite this formula as: MIN( X, Y) This of course is a simple example but treating each part of your formula with such thrift will certainly pay off in the long run. 4. This point repeats some of the message above but the use case is so common that it deserves independent mention. Oftentimes you’ll be tempted to use a number of IF-statements when trying to determine which value a formula field should display. This can be further complicated if the value you’re examining belongs to a picklist. Such an example might be:
At 197 characters this isn’t a whopper of a formula but it’s good to keep your house in order. In this type of situation it’s more economical to use a CASE-statement such as:
Not only is this easier to read, at 93 characters it is less than half as long as the original formula. 5. Sometimes you’ll just have to use a formula that can’t be accommodated by the limits of formula fields. In such cases you have two options, you can either use Workflow or Apex Triggers. For each you’ll need to create an object field of the type you’d like to present. The Workflow or Trigger would then update this value at creation, update or both of object records. With Workflow you’d do this by using Field Updates, and specifying the formula required. Note the formula restriction here is much larger than for regular formula fields. For triggers you’d have to translate the required logic into the Apex and write the value to the record’s field. As seasoned developers, we’d highly recommend writing formula code in a text editor with some concept of syntax highlighting and bracket matching. You’ll also save a lot of time if you lay your formula code out neatly, indenting it where necessary as well as breaking to a new line to
visually delimit function calls and conditional return values.
Examples Although formulas are bespoke and can be fairly complex in nature you’ll find that even the most intricate requirements often reuse combinations of smaller, common formulas. Salesforce.com has taken the time to document many of these and we’d recommend poring over them as a start, or even as a reference to more experience formula users 13.
Validating User Input In addition to workflow and formulas, validation rules are one of the most widely used features on the platform. Validation rules help ensure data integrity by verifying that the data a user enters meets certain standards. Validation rules fire whenever a user attempts to insert or change a record. These rules prevent incomplete or “junk data” from being entered by mistake, which in turn causes more issues to creep up down the road. To get started using validation rules, click Setup -> Customize, select the appropriate object from the menu, and then click Validation Rules. A validation rule can contain a formula or expression that evaluates the data in one or more fields and returns a value of “true” or “false.” The validation rule can be configured to display a custom error message to the user, either at the top of the page or next to a specified field. A validation rule will fire and display an error message even if the offending field is not displayed on the page layout.
Validation rules are a platform level service and not simply for the UI. Validation rules apply to all new and updated records for an object even when processed by one of the APIs or during the data loading process.
Administrators must be aware that adding new validation rules in production may break existing processes and integrations. Always test in a sandbox envirnoment before making production changes.
Building Public Websites Force.com Sites allows you to extend your salesforce.com applications and data by creating public websites and applications that run natively on the platform 14. Since your sites are hosted on the Force.com servers, there are none of those pesky data integration issues allowing you focus on creating highly interactive, scalable websites. Force.com Sites are built using Visualforce and Apex, and thus can leverage the data, content and logic that resides in your Org. You can set up your site to be wide-open to the public or require a username and password to access it (via Customer or Partner Portals). Force.com takes care of your site’s infrastructure headaches freeing you up to concentrate on building applications such as:
Corporate website - create a public-facing website using standard web elements such as CSS, Flash and JavaScript frameworks (e.g.,
jQuery, YUI)
Employee intranet - set up a company intranet that uses single sign-on, restricts access by IP address and/or time of day Collect new ideas - host a public community forum for sharing and voting on Salesforce Ideas regarding your company’s products and services
Microsites - create microsites to collect feedback or allow people to sign up for webinars or marketing information Expose product information - publish your company’s product catalog on a subdomain of your existing website with detailed descriptions, current pricing and product images all pulled seamlessly and in real-time from your Org. Setting up a new Force.com Site is relatively easy. Start by clicking Setup -> App Setup -> Development -> Sites . Choose an available Force.com domain name, enter the name of your site, pick a site administrator and the platform spins up a new site for you in a matter of seconds. You can then create page templates to give your site a consistent look and feel that matches your corporate branding. Your site template provides the page layout and stylesheet for your site and overrides formatting inherited from any associated portal that you may use. You can then start adding standard or Visualforce pages by associating them with your site. Apex controllers and classes provide the logic for your site. Configuring permissions for your site looks relatively familiar 15. Visitors to your site use a Guest user license and a Sites-specific profile. You configure the permission for this Sites-specific profile like you would any other profile in salesforce.com. You can configure tab and record type access, page layout assignments, field-level security for standard and custom objects and object permissions (read, create, edit and delete) for each site’s users. It is important to note that salesforce.com does impose some additional access restrictions for Sites visitors. For instance, while visitors can read, create, edit and delete custom objects they can only read and create standard objects. Some objects such as products and price books only offer read access. Be sure to check the documentation before designing your Force.com Site.
Sites impose limits based upon edition but they are fairly liberal. For instance, with Enterprise Edition the maximum page views per month is 500.000 and the bandwidth limit (per rolling 24-hour period per site) is 40 GB. You can purchase more page views if needed. The number of individual Force.com Sites you can create is determined by your edition. You can run your site off of a Force.com domain name (http://acmecorp.force.com/intranet) or use your own company branded domain set up with a redirect via DNS.
You can monitor Sites users by adding them to the Debug log. However, for public websites this only provides a generic view of their actions. You can also preview a site as an administrator and view debug info by adding some tags to the Visualforce footers.
Going Global With more and more global companies adopting salesforce.com, it’s no surprise that internationalization and localization is an important aspect of the platform. Salesforce.com supports geographical segmentation, advanced multi-currency and translation of the UI into 20+ languages.
Divisions Divisions allows you to segment your data into organizational “buckets” providing users with a view of data that is relevant to their needs 16. You can set up divisions any way that makes sense to your company such as geographically, line of business (i.e., commercial or government) or any other type of internal corporate grouping. Divisions do not restrict data access but makes data easier to manage and find for larger Orgs. For instance, a sales manager in South American may want to run reports or forecast sales only for South American and not be concerned with European data.
Contacts salesforce.com Support to enable divisions for your Org. Divisions are meant for segmentation purposes only and do not enforce any type of security constraints. When divisions are enabled, a division called “global” is automatically created and all records are automatically assigned to this division by default. You can create up to 100 divisions but you should carefully plan your strategy in advance for handling multiple divisions. You will also need to set the default division for each user. This is the division that applies to all newly created accounts, leads, and custom objects for which divisions are enabled (unless the user explicitly chooses a division). You can also enable the Affected by Divisions permission for profiles so that users can set their current “working” division. Users can set their “working” division using a drop-down list in the left sidebar thus limiting search results to records in the selected division. Users without this permission still have a default division, can view division fields, change the division for a record and specify a division while creating new records. However, these users will always see records in all divisions. The permission also filters list views by division and allows users to run reports for a single or all divisions.
Locale A user’s Locale setting affects the formatting of names, numbers, date and date/time fields and calendars. The Locale determines the order that first and last names are displayed for users, leads, and contacts. For instance, Mike Smith in the English (United States) locale displays as “Mike Smith”, while the same name in the Chinese (China) locale displays as “Smith Mike”. Dates and times are also displayed per a user’s Locale. A date in the English (United States) locale will display as “04/28/2000” while it displays as “28/04/2000” in the German locale. Times in the English (United States) locale display using a twelve-hour clock with AM and PM (e.g., 3:00 PM), while in the German locale, they display using a twenty-four-hour clock (e.g., 15:00).
Dates are stored in the database in GMT and converted on-the-fly using the user’s Locale. To import data for a user with EST, use the format 2010-06-25T18:25:00.000-04:00 with the 4 hours time zone offset.
Currencies The Force.com platform has support for multiple currencies baked in from the ground up17. It provides advanced support for multiple currencies for opportunity management, forecasting and reporting. With multi-currency enabled each international division can track, forecast and report on opportunities in local currencies, while providing enterprise-wide forecasting and reporting in a single common currency.
Contact salesforce.com Support to enable multiple currencies for your Org. Once enabled, the link will visible and you can manage currencies by clicking Setup -> Administration Setup -> Company Profile -> Manage Currencies. Once multiple currencies are enabled, you’ll need to set up a “corporate currency” which reflects the currency used by the corporate headquarters. You can then create and maintain multiple currencies in which you do business and their conversion rates relative to the corporate currency. Every user must have their “personal currency” configured. When new records are created, the user’s personal currency is automatically used unless another currency is selected manually. The personal currency is also used as the user’s default currency for quotas, forecasts, opportunities and reports, however other active currencies are also available. Only active currencies can be used in currency amount fields.
When administrators change an existing conversion rate, all currency amounts are immediately updated with the new rate across the entire Org. This includes all conversions within opportunities, forecasts, and other amounts that use the current conversion rate. Previous conversion rates are not stored and you cannot track revenue gain or loss based upon currency fluctuations. If currency changes severely impact your company, you may want to investigate using Dated Exchange Rates.
An opportunity’s currency cannot be modified once a product has been added to it with the default currency. You will need to remove all product records first before you can modify the opportunity’s currency.
Advanced Currency Management Advanced currency management allows you to manage dated exchange rates for opportunities. Dated exchange rates allow you define a conversion rate for a specified currency’s date range. For example, a company’s exchange rate in the 3rd quarter and 4th quarters are 1 USD to .60 EUR and 1 USD to .75 EUR, respectively. All opportunities that close in the 3rd quarter use the 3rd quarter exchange rate (1 = .6) while those that close in the 4th quarter use the 4th quarter rate (1 = .75). This retains the historical conversion rates and tends to be very beneficial to most large companies. Dated exchange rates are used in conjunction with opportunities, opportunity products, opportunity product schedules, campaign opportunity fields and reports related to these objects and fields. Static conversion rates, instead of dated exchange rates, are used in forecasting, currency fields in other objects and currency fields in other types of reports. When advanced currency management is initially enabled, your existing static exchange rates automatically become your first set of dated exchange rates. These rates are valid until you define another set of exchange rates. Dated exchange rates are defined using a conversion rate and a start date. Each conversion rate is effective until the day before the next start date for that currency or until either the end of time.
When advanced currency management is enabled, Visualforce inputField and outputField components cannot display currency fields. If you enable advanced currency management, you cannot create roll-up summary fields that calculate currency on the opportunity object.
Enabling multicurrency may have some unintended consequences regarding SOQL queries and aggregate functions. Be sure to check the documentation for the implications of enabling multicurrency.
Translating the User Interface Salesforce.com allows users to work in their language of choice with a simple language attribute on the users’ record. The salesforce.com UI is available in Danish, German, English, Spanish, Finnish, French, Italian, Japanese, Korean, Dutch, Portuguese (Brazil), Russian, Swedish, Thai, Chinese (Simplified) and Chinese (Traditional). To translate customizations that you’ve made to your Org or to override translations from managed packages, use the Translation Workbench to translate virtually everything from custom picklist values to custom fields into a supported language 18. These customizations are also available for partner and customer portal users. As an administrator you add translatable languages to your Org and optionally assign a user responsible for translating customizations. The admin interface allows you to translate the text for buttons and link labels, custom fields, standard field help, record types, picklist values, web tabs and plus much more.
Once enabled, the Translation Workbench imposes some changes to your salesforce.com Org: Picklist values must be edited individually and you can no longer mass update picklist values (mass add is still available) When sorted alphabetically, picklists are sorted alphabetical by the Org’s default language Reports may have a language drop down for certain filter criteria Web-to-Lead and Web-to-Case require a language selection before generate the HTML
Not everthing in salesforce.com is translatable. You are currently not able to translate Visualforce tabs, homepage components elements or record type descriptions.
Using Analytics You’ve spent a lot of time, effort and money putting your important data into salesforce.com and you want to be able to view it, report on it and analyze it in a coherent, user-friendly manner. One of the advantages of the Force.com platform is that it includes a complete system for building reports, securing and scheduling them and assembling collections of them into user-friendly dashboards. It’s not as powerful as say Crystal Reports but it also doesn’t have the steep learning curve and associated price tag. While the topic of analytics is extremely important, a deep-dive is beyond the scope of this book. Reporting is well documented in the user guide and there are numerous tutorials to help get you started19. The best way to learn about analytics is to simply start building reports and assembling them into dashboards. We’ll cover some topics from a high level. The Winter ‘11 release sports a new and greatly improved visual, real-time report builder. The new report builder allows you to add, reorder, and remove columns, summary fields, formulas, and groupings with ease. You can even change the report format and display options, add a chart and preview data in real-time.
Choosing the format of the report drives a number of options that are available when actually building the report. There are three types of reports you can choose from:
Tabular - Tabular reports are analogous to spreadsheets and are best for creating lists of records or a list with a single grand total. They consist simply of an ordered set of fields in columns, with each matching record listed in a row. Tabular reports can’t be used to create groups of data or charts, and can’t be used in dashboards unless rows are limited.
Summary - Summary reports are the most widely used report type. These are similar to tabular reports but also allow users to group rows of data, view subtotals, and create charts.
Matrix - Matrix reports are similar to summary reports but are much more powerful and complex. This format allows you to group and summarize data by both rows and columns. This format is particularly useful for comparing related totals, especially if you have large amounts of data to summarize and you need to compare values in several different fields, or you want to look at data by division and by product, account rep, or sales region. When saving a report one of the confusing aspects is providing access to the report. There are a number of public report folders into which you can save your report. However, if you want to restrict access to the report you do not configure this at the report level. Instead, you must create a new report folder and grant access to it for specific Public Groups, Roles and Roles and Subordinates. Only these specified users will have access to the folder and any reports in it. You can schedule reports to run and have the results automatically emailed salesforce.com users.
The information a users sees in a report is only the data to which they have access. This includes records they own, records to which they have read or read/write access, records that have been shared with them, records owned by or shared with users in roles below them in the hierarchy, and records for which they have “Read” permissions. Therefore, reports may display differently based upon the user running the report.
Running Dynamic Reports Salesforce.com has a little undocumented and unsupported feature that allows you to run reports dynamically20. Typically if you would like to display the number of widgets sold by a specific account for a practice, you would have to run the report and choose these selections from the individual picklists. To run these reports dynamically you simply add a custom link or button to the account’s detail page that passes these variables to the report using merge fields or other coded values. Create the report in the format that you want but leave the values for the criteria blank. You then append the variables to the URL where pv0 is the first parameter, pv1 is the second and so on. The code for the URL for your custom link or button would look like:
Custom Report Types
Salesforce.com come with a large set of report types pre-defined. The first step in creating any report is choosing a report type. But what if you would like to provide your users with the ability to report on data based upon your customizations or from different aspects? For instance, if your Org contains a shipment custom object, you may want users to run and customize reports based on accounts with open opportunities and shipments that include specific fields from all three objects. Salesforce.com enables you to create custom report types that allow you to connect up to four related objects in order to expand the scope of your Org’s reporting ability 21. Once you have defined a custom report type, users can create custom reports from it. You can create new custom report types by clicking Setup -> App Setup -> Create -> Report Types.
When creating a new custom report type, the objects available for you to choose from are based on the primary object’s relationships to other objects. For example, if you choose accounts as the primary object, then you can only choose standard and custom objects associated with accounts (e.g., contacts, opportunities). This also applies to subsequent objects added to the custom report type. So, if account is selected as the primary object and opportunity is selected as the secondary object, then you can only select objects associated with opportunities as the third object for your custom report type.
Dashboards A dashboard is a collection of components (reports, Visualforce pages and S-Controls) that graphically displays a snapshot of key metrics and performance indicators 22. Report components can display as gauges, tables, horizontal and vertical bar charts, line charts, pie charts, donut charts and funnel charts. You can select up to 20 different components for each dashboard but only summary and matrix report formats can be used with them. As with reports, folders control user access to the dashboards however the Running User determines access to the actual data. The running user for the component can be:
A named user – The dashboard runs using the security settings of a single, named user. All users with access to the dashboard see the same data, regardless of their own personal security settings. Use this approach for sharing the “big picture” of support cases across a division, or motivating a sales team by showing peer performance within a team.
The current user – These dynamic dashboards run using the security settings of the user currently viewing the dashboard. Each user sees the dashboard according to their own security and access settings. Use this approach to share one common set of dashboard components to users with different levels of access. Salesforce.com recently introduced the Dashboard Builder 23, a drag-and-drop interface for creating and modifying dashboards. The new builder is a dramatic improvement over the previous multi-screen approach and allows you to drag-and-drop components and datasources; configure, rename and move components; edit component titles, chart types and settings and configure dashboard properties.
Your Org can have up to three dynamic dashboards which must be refreshed manually. You can’t schedule refreshes for dynamic dashboards so ensure that you plan accordingly.
Analytic Snapshots Reporting is a static function by its very nature. When you view a report it represents the current state of your data in salesforce.com. If the underlying report data changes, a minute or a day after the report for instance, the existing report does not reflect these changes. By creating analytic snapshots you can report on trending and changing data in your Org24. For instance, you may set up an analytic snapshot to track daily inventory levels in your warehouse and allow users to report on it. You can create new analytic snapshots by clicking Setup -> Adminstrative Setup -> Data Management -> Analytic Snapshots . To create a new analytic snapshot you essentially create a new report and then pipe the output of the report on a scheduled basis to a custom object that you define. Users can then use the data in this custom object to create reports or construct dashboards.
Triggers and workflows on a target object are not executed as a result of an analytic snapshot run. In fact, you are not allowed to use an object with a trigger as the target of a snapshot. Adding a trigger to a target object results in the snapshot run failing.
Overriding Link, Tabs and Labels Salesforce.com allows you to rename tabs, objects and fields to make the UI more closely reflect your company’s terminology. For instance, you can rename “Accounts” to “Organizations” if your company operates with this terminology. Click Setup -> Customize -> Tabs and Labels -> Rename Tabs and Labels to make these Org-wide changes.
Salesforce.com also provides a way to override the behavior of standard buttons and links for each object25. So instead of displaying the standard details page when you click on a link for an opportunity’s details, you can have each opportunity display in a customized Visualforce page. Overrides are global throughout the salesforce.com UI as they control the action behind the each button and link. For example, if you override the View link on opportunities, your replacement action takes effect wherever that action is available:
The opportunities tab home page Any opportunities related lists on other objects such as accounts Any link representing the record displayed in the UI Any browser bookmarks for this salesforce.com page To use a Visualforce page instead of the standard details page, click the Override button for the View link. In the Override Properties section, select the Visualforce Page radio button to display the list of available Visualforce pages for the opportunity object. Only Visualforce pages that implement the opportunity standard controller will be displayed in this list.
The standard buttons and links section will now show that your Visualforce page is being used instead of the default salesfore.com details page. You can click the Reset link to revert back to the default details page.
Sending Mass Email Salesforce.com has the ability to send mass emails but is not designed to be an email marketing solution26. Your email distribution lists can consist of contacts, leads, person accounts, or users that are accessible to your user in salesforce.com. However, you can only send email to a maximum of 1,000 external email addresses per day and the number of external email addresses in your list is dependent on your edition. You can, however, send an unlimited amount of email to internal users. For use with mass emails, you can create email templates using plain text or HTML27 (with and without letterheads) that include record-specific data via merge fields, graphics and attachments. Mass emails can be sent immediately or scheduled for delivery. Users can view and cancel mass emails they schedule by clicking Setup -> Email -> My Mass Emails while Administrators can view and cancel mass emails scheduled by all users in their Org by clicking Setup -> Monitoring -> Mass Email. Some potential issues with sending mass email from salesforce.com include: The “from” email field is automatically generated with the sending user’s email address and cannot be changed. You cannot send a mass email using a Visualforce email template. You can only track the first date an email was opened, the number of times it was opened and the date it was most recently opened. Salesforce.com has some issues with whitelisting of mass emails that may cause your mail to in up in the recipient’s spam folder. If your Org has more complex mass email requirements or needs to send very large volumes of mail, you will need to look at one of the many mass email applications available on the AppExchange. Pricing typically depends upon volume but these applications do offer some attractive features such as the ability use pre-designed templates, easily build segmented lists, track post-launch statistics (opens, clicks, bounces, unsubscribes, etc.) and opt-in/out management all from within salesforce.com.
Importing Data
Importing data into your Org is almost a required task for new implementations or ongoing maintenance. There are a number of options and avenues that you can use to get data into your Org28. Salesforce.com offers a number of import wizards to easily import records for accounts, contacts, leads, solutions and custom objects using CSV files. The wizards attempt to dedupe records but the matching functionality is limited. All users can use the Import My Contacts wizard however only administrators can use the Org-wide Import My Organization’s wizards to import accounts, contacts, leads, solutions, or custom objects for multiple users. Individual users may only import data into fields that are accessible via their page layout or field-level security settings while administrators can import into any of the listed fields regardless of security settings. Salesforce.com offers a client application for inserting, updating, upserting, deleting and extracting records called the Data Loader. The Data Loader can move data into and out of virtually any type of object using CSV files. To prevent duplicate records from being created during the import process, you can use an ID from an external system (referred to as an “external ID”) as a unique key. An external ID is a custom field that has the “External ID” attribute checked. When you select the upsert option during the import process, the import wizard and Data Loader will detect existing records in salesforce.com that have the same external ID and upsert the record matching records instead of creating a new one.
Make sure that the user performing the import has the Modify All Data permission checked on their profile for the objects being imported so that any sharing rule checks are skipped. You can download the Windows version of the Data Loader from Setup -> Administration Setup -> Data Management -> Data Loader while the Mac OS X version, LexiLoader, is available at http://www.pocketsoap.com. Both versions of the Data Loader use the same Web Services API so the only difference is the client interface.
The Data Loader can also run unattended from the command line (aka Command Line Interpreter) in scenarios where human interaction is not required. The CLI uses the same engine as the GUI interface thus supports the same operations for inserting, updating, upserting, deleting and exporting data.
The Data Loader has built in support for the Bulk API providing a fast and efficient way to upload extremely large sets of data. You can also import attachment and documents into salesforce.com using the Data Loader. A number of third-party applications are available on the AppExchange (mostly for a fee) for loading, updating, deduping and cleansing data. DemandTools from CRMfusion is a widely popular favorite among administrators. However, if price is an issue, you can also build your own data loading application using any client-side language that is supported by the Web Services API. For loading extremely large sets of data, salesforce.com offers a REST-based Bulk API with management and monitoring features built into the salesforce.com UI.
Deploying Code to Production Salesforce.com requires you to write your Apex code in a sandbox or developer Org, provide unit tests to ensure your code performs as intended and then deploy it to your production Org. Even though it is possible to make configuration changes directly in your production Org, the
best practice is to do this is a sandbox or developer Org and then test the impact. There are a number of ways that you can deploy code and configuration changes to your production Org.
Force.com IDE The Force.com IDE is a free, salesforce.com supported Eclipse plug-in that facilitates and simplifies development on the Force.com platform. The Force.com IDE has a built in wizard for deploying code, resources and other configuration changes to production.
Force.com Migration Tool This migration tool is a command line, Apache Ant tool for scripting deployments. The process of using the Force.com Migration Tool is more complex that deploying with the Force.com IDE and may require some Java experience. This tool is well suited for repetitive deployments such as testing deployment plans or installing code into production Orgs during setup.
The Force.com IDE and the Force.com Migration Tool will be covered fully in later chapters.
Unmanaged Packages Unmanaged packages are the “old school” way to deploy code and components. An unmanaged package contains components such as code, objects, reports, or email templates, for instance, which can be uploaded to share with others privately or publicly.
Change Sets Change sets are the newest method for deploying code and components and provides some enhanced functionality29. Changes sets use packages in the background but provide the ability to move code from not only sandbox to production, but from sandbox to sandbox and production to sandbox. While deployment with the Force.com Migration Tool and the Force.com IDE are tasks typically performed by developers, change sets are focused more for administrators. For larger companies this allows multiple developers to create change set that are deployed by administrators who may have more intimate knowledge of their entire salesforce.com landscape. Before deploying change sets administrators must setup trusted deployment connections between their Orgs. Deployment connections can’t be created between arbitrary Orgs. By default a deployment connection is created between all Orgs affiliated with a production Org (e.g., sandboxes). Connections are created between each sandbox and between each sandbox and production Org. A deployment connection alone doesn’t enable change sets to be sent between Orgs. Each Org must be authorized to send and receive change sets. This added level of security enforces code promotion paths and keeps an Org’s metadata from being overwritten by mistake.
When sending changes from your current Org to another Org, you create an outbound change set. The process to create and deploy a change set is relatively straightforward. You first create a new change set and then walk through a series of screens adding the component that you want to deploy. Once you Upload the change set, the receiving Org sees it as an inbound change set and can accept and deploy it with a few clicks. A change set is deployed as a single transaction. If the deployment fails for any reason, the entire change set is rolled back. After a deployment completes successfully, all changes in the set are committed to your Org and the modifications cannot be rolled back.
Unfortunately, as of Winter ’11, change sets do not support deploying components with respect to profile security. Therefore, new components will not automatically be available to non-SysAdmin users. You will need to edit each profile individually and adjust the field-level security and access levels as required for each component deployed.
Storing Application Metadata Salesforce.com recently introduced Custom Settings in Winter ‘10, which allows you to store custom data sets and associate them on an Orgwide, profile or user basis 30. Custom Settings are essentially custom objects that are exposed in the application cache and are accessible via their own API. They are managed by clicking Setup -> App Setup -> Develop -> Custom Settings. You can certainly build your own custom objects to store settings (many people do) but using custom settings is much quicker (again they are stored in the application cache) and do not count against SOQL limits when fetched. You can also use custom settings in formula fields, validation rules, Apex code and the Web Services API.
List Custom Settings List custom settings allow you to store Org-wide static data that is frequently used. For instance, salesforce.com does not have ISO country codes baked into the platform. Many companies maintain this list of countries and their ISO codes in a separate custom object. So whenever they need this data they have to query this custom object, which brings with it additional overhead pertaining to the SOQL limits. Using a list custom setting companies can store these codes and use them virtually anywhere needed and retrieve them quickly from the application cache. When you create a new custom setting the platform creates a custom object in the background for you. You then add additional fields to the custom setting in the same manner that you do for custom objects (you are limited to checkbox, currency, date, date/time, email, number, percent, phone, text, text area and URL fields). After you’ve set up your custom settings and added your fields, you can select the Manage link on the Custom Settings page to add, edit and delete records. List custom settings have their own instance methods to allow easy access to cached values.
Hierarchy Custom Settings Hierarchy custom settings allow you to personalize your applications for different profiles and/or users. The interface has baked-in logic that drills down into the Org, profile, and user level (based upon the current user) and returns the most specific or lowest value in the hierarchy. Hierarchy custom settings are extremely useful for those “one off” occasions. For instance, suppose you want to authorize your sales teams to be able to offer a specific discount to customers. You might set up an Org-wide custom setting of a 1% discount that everyone is authorized to offer. Now, of course, you have a set of high-producing sales people that are in their own profile and are able to offer a 5% discount. However (and here is the “one off”), there is that one sales person in that same profile that has lobbied the VP of Sales to be able to offer a 15% discount. With hierarchy custom settings you can accommodate all of these scenarios. After you’ve set up your custom settings and added your fields, you can select the Manage link on the custom settings page to add, edit and delete values for the entire Org, a specific profile or individual users.
Developers can programmatically access hierarchy custom settings based upon the running user and return their most appropriate value (Orgwide, profile or user) in formula fields, validation rules, Apex code and the Force.com Web Services.
You can only access hierarchy custom settings in formula field and validation rules. List custom settings are somewhat limited and not available for formulas or validation rules. The generic syntax for using a hierarchy custom setting in a formula field is:
Monitoring your Org Salesforce.com provides some level of insight into the platform with various debug screens and job queues.
Debug Logs For application development, the debug log is your best source of information to uncover what is actually taking place on the platform. The debug log records database operations, debug statements, warnings, system processes, and errors that occur when executing a transaction or while running unit tests. The platform generates a debug log every time a user executes a transaction that is included in the filter criteria. You can specify to generate debug logs for any user on the platform to help track down issues with particular user or processes.
Email Logs Email logs provide access to all emails sent and received through the platform for the last 30 days. The log files contains both to and from addresses, date and time sent or received, the salesforce.com user and any associated error information.
Login History This log displays the last 20 user logins (successful and failed) via browsers, SAML, APIs, Remote Access Clients and partner products. You can also download the login history for the last six months.
View Setup Audit Trail The setup audit trail tracks recent setup changes that administrators have made to your Org. The last 20 changes are displayed by default but you can download a CSV files containing all changes for the last six months. The log tracks a wide range of changes including App Exchange installs, security modifications, password changes, new fields added to objects, changes to the user interface and import wizard usage, just to name a few.
Time-Based Workflow Queue This queue displays any time-dependent actions that were created by workflow rules. You can filter and view pending actions for more information plus cancel them if necessary.
Scheduled Jobs The All Scheduled Jobs page displays all jobs scheduled by users including analytic snapshots, Apex jobs, emailed reports and dashboard refreshes. With the right permissions, users can also delete scheduled jobs.
Outbound Messages An outbound message is a workflow, approval, or milestone action that sends information to an external service via a SOAP message. The Outbound Messaging Delivery Status page displays messages queued for delivery plus failed messages with delivery debug and retry information.
Apex Job Queue The Apex job queue lists all Apex jobs that have been submitted for execution. This includes jobs fired from Apex @future methods, Scheduled Apex, Batch Apex and Apex sharing recalculations.
Import Queue Displays the details of data imported into your Org and allows you to cancel a pending import.
Mass Email Queue Displays the status of scheduled mass emails and cancel them if necessary.
Case Escalation Rule Queue This queue displays any time-dependent actions that were created by case escalation rules. You can filter and view pending actions for more information plus cancel them if necessary.
Entitlement Process Queue This queue displays any time-dependent milestone actions that were created by entitlement processes. You can filter and view pending actions for more information plus cancel them if necessary.
Bulk Data Load Jobs This page displays the status of current and recent bulk data load jobs created by the Data Loader and other Bulk API client applications. The page also displays your Org’s current batch import quota for the current 24-hour period.
Google Integration It’s no surprise that salesforce.com and Google have a close relationship given their long history of complimentary product offerings and the fact that both dominate the cloud space. A number of Google services are baked into the Force.com platform allowing you to take advantage of them without leaving the salesforce.com environment31. Administrators typically need to simply activate these features to get started using them.
These services are designed for business users and require a Google Apps account. The Google Apps domain you set up in salesforce.com must be the domain you registered with Google for your company rather than consumer account (i.e., Gmail.com).
Add Google Docs to Salesforce.com When activated, the Add Google Docs to Salesforce.com service allows you to collaborate and share Google docs with any user in your Org; use Google Docs & Attachments as a related list on any salesforce.com record to create, edit, or view Google docs and easily associate them to a record; use the “Add Google Doc to Salesforce.com” browser button to associate Google docs with salesforce.com records even when not currently working in the salesforce.com UI; centralize the administration of Google docs by allowing salesforce.com, Customer Portal and Partner Portal users to add Google docs to Salesforce CRM content.
Google Docs Tab When activated, the Google Docs tab allows you to access all of your Google docs from a simple docs home page without leaving the salesforce.com UI. The home page not only displays all documents, spreadsheets and presentations that you have created by all docs that have been shared with you. You can even create a Google doc from within the tab and associate it to any record in salesforce.com with a few simple clicks.
Gmail to Salesforce.com Gmail to Salesforce.com allows you to seamlessly route emails sent from the Gmail UI to records in salesforce.com. Once set up, the Force.com platform will generate a unique email address for your account. Simply add this email address to the bcc field of your outgoing Gmail message and it will be routed to salesforce.com and created as an activity on matched leads, contacts, opportunities, and other records that support activity history. Gmail to Salesforce.com works for chats as well.
Gmail Buttons and Links Gmail Buttons and Links is a quick and convenient way to use Gmail from within the salesforce.com UI. The service adds a Gmail link next to email fields on all records and a Compose Gmail button on the Activity History related lists for leads and contacts. When you click one of these two buttons, the salesforce.com UI pops up a new window, automatically logs you into your Gmail account and populates the To field with the correct email address.
Google Talk Sidebar Component If your company uses Google Talk for instant messaging, you can enable the service to display below the sidebar search on the left pane of the salesforce.com UI. The Google Talk interface allows users to stay within the salesforce.com environment and allows them to toggle it off, on or even expand into its own window. Chats for contacts and leads can also be easily logged as an activity their records.
Google AdWords For marketing efforts, Salesforce for Google AdWords connects salesforce.com with Google AdWords, allowing you to track the effectiveness of your online advertising investments. When a visitor clicks on your Google ad they will be directed to your website that hosts a Web-to-Lead form. When the visitor enters their information into the Web-to-Lead form, a lead is created in your salesforce.com Org. Leads that originate from Google AdWords have a Lead Source value of “Google AdWords” and an activity record that shows the Google AdWords campaign, ad group, ad headline, and keyword that drove the lead to your website. You can then track the effectiveness of your advertising with a Google AdWords
dashboard and several Google AdWords reports are pre-built in salesforce.com. There are also a large number of Google-related apps on the AppExchange for additional functionality such as synching contacts and calendars, integrating with Google Maps and using Chatter with Google Alerts.
Working Remotely Force.com Connect for Microsoft Office This product integrates Microsoft Office with salesforce.com and has add-ins for both Word and Excel. The Word add-in is used for creating mail merge templates for use with the salesforce.com mail merge utility. You create Word templates that contain salesforce.com merge fields, upload the template and then simply choose the template when running the mail merge from the salesforce.com UI. The Excel add-in is used for delivering salesforce.com reports into Excel so that you can customize the report with formulas, charts or pivot tables, for example, to extend the reach of your salesforce.com data. These reports can then be distributed, analyzed or archived depending upon your business processes.
Salesforce for Outlook In Winter ‘11, salesforce.com released Salesforce for Outlook, a huge upgrade from its previous product called Connect for Outlook. Salesforce for Outlook is a free, fully supported Outlook add-in that provides the following functionality: Send out-bound email and associate it with a contact in salesforce.com Attach in-bound email to a contact in salesforce.com Create support cases from in-bound emails Synchronize contacts between salesforce.com and Outlook Synchronize calendar appointments between salesforce.com (as events) and Outlook Synchronize to-do items between salesforce.com (as tasks) and Outlook Upload email attachments to salesforce.com
Force.com Connect for Lotus Notes Connect for Lotus Notes is an add-in for IBM® Lotus Notes® that allows you to interact with salesforce.com conveniently from Lotus Notes. It offers the following functionality: Use leads and contacts from salesforce.com as email recipients Associate email messages to accounts, assets, campaigns, cases, contacts, contracts, custom objects, leads, opportunities, or products in salesforce.com. Create support cases from in-bound emails Synchronize calendar appointments between salesforce.com (as events) and Lotus Notes Synchronize to-do items between salesforce.com (as tasks) and Lotus Notes Upload email attachments to salesforce.com
Force.com Connect Offline Connect Offline is a client application that provides browser-based access to a subset of salesforce.com data while disconnected from the internet. You can use Connect Offline to view, edit, create, or delete accounts, activities, contacts, opportunities, leads, and custom object records (including relationship groups). Administrators control a user’s access to data with “briefcase configurations”. These profile-specific configurations determine which actual records and types of records are available offline for specific groups of users. When online, users sync their records with salesforce.com to ensure that everyone has access to the latest information. There is also a built-in conflict resolution tool in the event that updates conflict with newer versions of the same record. 1 users 2 profiles 3 roles 4 groups 5 security-data 6 record-types
7 workflow 8 approval-processes 9 intro-to-formulas 10 cross-object-formulas 11 validation-rule-examples 12 delivering-static-resources 13 useful-validation-formulas, formula-cheatsheet 14 sites 15 profiles 16 internationalization 17 currency-management 18 translation-workbench-overview 19 reports 20 reports-dynamic 21 custom-report-types 22 dashboards 23 dashboard-builder 24 analytic-shapshots 25 overriding-links-buttons 26 mass-email 27 email-templates 28 importing-data 29 change-sets 30 custom-settings 31 google-services
Programmatic Development Tools & Strategies
In previous chapters you’ve seen how salesforce.com removes a lot of the cost and complexity around software development infrastructure. Now imagine that as a developer you never need to worry about database connectivity, whether the web stack is up or whether there may be servers that need to be bounced before taking an improvement live. This would leave you with a lot more time to do the “real work”. Wouldn’t that be great? Salesforce.com’s Platform as a Service (PaaS), also known as Force.com, does exactly this and that’s only the tip of the iceberg. Force.com is comprised of a set of tools, APIs and programming languages that enable administrators, developers and architects to build anything from smallto large-scale enterprise applications quickly, and without compromising quality. They have catered for IT personnel at all levels providing tools and support specific to those roles. Of course tools work better with processes to support them and salesforce.com together with a few community evangelists have grown a number of best practices that govern areas such as unit testing strategies; collaborative development; object-oriented principle implementations, and much more. In this chapter you’ll learn more about the tools and strategies required to build, test and deploy applications on Force.com. Not only that but we’ll advise which tools are required when and provide usage best-practices where required.
A New but Familiar Development Infrastructure Traditional software development tools and processes are mature and have been widely accepted. Salesforce.com has taken what might be considered the best of these approaches and tools, and built their platform on this sturdy foundation.
That’s Old School In a simple traditional development topology, one or more engineers develop on desktop computers whilst sharing and integrating code through a Version Control System (VCS). Next, code is tested in a Quality Assurance (QA) environment, and then moves into a User Acceptance Testing (UAT) environment. If the software successfully passes each stage it is finally packaged and deployed to a production environment.
Developing in the Clouds Force.com uses a similar setup but we find that instead of having our environments sit within the usual hardware infrastructure they are now cloud-bound. In figure 3 - 2 we see that developers still create code locally, but something to note is that code isn’t compiled locally. Instead it is deployed (in real-time by default) to developer environments, which compile the source-code and form our development runtime environments.
Developers can also create and edit applications directly in their browser thereby leap-frogging the local development step, but this is generally not advised for large applications and/or collaborative development. Thankfully you still have the option of committing code to your favorite VCS and it is generally advised. A packaging step is not required with the Force.com platform as we can deploy directly into any developer and/or production environment.
In figure 3-3 we’ve noted an alternative setup with a build manager handling the deployments directly from the VCS repository. Using build managers can be a neat practice for a number of reasons including predictable deployment rhythms, code quality checks, automated testing and build/deployment history.
From what we’ve seen, development managers usually employ a combination of the methods shown in figures 3 - 2 and 3 - 3 with developers deploying directly to developer environments and using build managers to deploy code to their production environment.
As you’ll see later, Force.com projects can be deployed using Apache Ant. This means that server applications such as Hudson (http://hudson ci.org) can be used to manage and deploy code.
The Importance of Metadata In previous chapters you saw that metadata plays a very important role in salesforce.com. It describes the structure of objects and their fields, as well as the page layouts associated with them. In fact, metadata describes many more structures in Force.com but what you might ask is, “Why use metadata at all?” Metadata is a simple lightweight language (based on XML) for describing the structure of salesforce.com and Force.com development artifacts. Later on you’ll see that Force.com code can be organized into projects, which are essentially groupings of metadata files. Instead of the traditional development approach of code-compile-package-deploy, with Force.com you only need to code. The magic here is that the metadata is zipped and transferred to the Force.com servers (much faster than uploading compiled code) where it is unzipped and compiled on your behalf. Not only is this super fast, but your changes are immediately available through any web browser, and there’s no downtime at all!
The Right Tool for the Right Job
Now that you’re equipped with an overview of how your cloud-based development network might be organized, it is important that you learn: What Force.com developer tools exist When it is appropriate to use specific tools How to use these tools In this section we will discuss everything you need to create, test and deploy your Force.com code whilst being mindful of the above points. We will also touch on desktop applications or areas of Force.com that you’ll need when analyzing and monitoring your code, as well as the various support options available to you.
Certain tools overlap several development tasks, and some development tasks overlap each other. It’s for this reason that the first two points are so important when discussing development toolsets.
Developing Applications on the Force.com Platform Creating code in any modern language is usually done through an Integrated Development Environment (IDE) that offers a number of advantages over coding through a simple text-editor or something equally archaic. By the end of this section you’ll know which IDEs Force.com offers and when to use each of them.
Force.com App Builder Tools Salesforce.com has created one of the best browser-based development environments in the world and it delivers most, if not all, of the core functionality you’d expect from a desktop-based IDE. There are two ways to access the functionality, each of which presents a slightly different experience. The first way involves clicking Setup -> Develop as a logged in user. From there you have access to each Force.com area of development, namely:
Apex Classes Apex Triggers Components Pages
S-Controls are now deprecated and all the functionality they provided is now available through Visualforce pages. Each section presents you with a list of code units of that type in your Org, as well as the option to edit the list items, and - in the case of Apex Classes, Components, and Pages - create new code units. We won’t go into the language specifics right now (we’ll cover each language and coding component later) but essentially touch on key areas of the development environment to demonstrate their strengths. In figure 3 – 4 you can see the list of Apex classes that are created when you sign up for a new Developer Edition (DE) Org 1. Notice the link labeled Edit on the left and the button label New at the top of the list.
If you click the New button you will be presented with a screen similar to the one shown in figure 3 – 5. We’ve taken the liberty of declaring a class and a single member method in order to demonstrate syntax highlighting. It has other features such as marking syntax errors, search and replace, and tabbed indentation (not such a simple feat in a browser window). You’ll also notice a button labeled Version Settings. You will only need to modify the values on this tab if your class needs to maintain specific behavior not supported in subsequent releases.
You might have already noticed the two save buttons, which might seem confusing. The difference is that the Save button will save any changes and drop you back at the list-view page, while the Quick Save button will save your code and keep you on the same page. For keyboard shortcut junkies, pressing Ctrl/Cmd-S will also quick save. Coding Apex Classes and Triggers in this environment offers very similar experiences but there are some surprises when developing code in the Pages and Components sections. It’s in these sections that you can create and modify the pages (or page components) that your users interact with, and here the browser editor offers some bonus features. In figure 3 – 6 we’ve started coding by typing an open angle bracket and have been presented with a pop-up list of code completion suggestions.
This auto-completion feature is superb for beginners and is comprehensive for these code unit types. In addition to this you’ll notice an extra button labeled Component Reference at the top of the page which links through to a library documenting the language components along with working examples. The second way to access the Force.com App Builder Tools development environment is by enabling Development Mode; this can be found by clicking Setup -> My Personal Information -> Personal Information, clicking Edit and then checking Development Mode as shown in figure 3 – 7.
This feature allows you to code and view the compiled results within the same browser window. It offers all the features we mentioned previously but adds a real-time view of the code you’re amending or creating. In figure 3 – 8 you can see that the development environment (also known as the Development Mode Footer) is unobtrusive, and more than this it has the component reference handy as well as offering the expected assistance when syntax is incorrect or if particular dependencies are missing. For all these reasons we proclaim this to be “King of Beginner Development Tools”.
From our commentary it’s quite obvious that the Development Mode Footer is superb for beginners, but some would contend that it’s also just as good for quick changes. We would disagree arguing that a good development infrastructure loses a lot of value without good development practices. We would consider some of these to be: All changes must be tested, and this usually involves several test-phases. All changes should be committed to a VCS (at very latest) prior to deployment. All changes should be validated and accepted as correct by a colleague. All testing should be validated and accepted as correct by a colleague. These principles are especially important if you’re working in development teams as this increases the potential for overriding valid code or working with the wrong code version.
It is easy to overwrite code in these browser-based environments and this has the potential to cost hours or even days of work. Bugs can often be introduced when making “quick” changes through the browser as little thought goes into their implementation.
Force.com IDE Developers will be pleased to learn that they can use the Eclipse IDE to code with the help of the Force.com IDE plug-in2. The Force.com IDE is a definitive interface for rapid development, testing and deployment of code on the Force.com platform. It also provides the ability to explore your salesforce.com schema, as well as tools to execute database queries and execute short code scripts on the fly. The theme of this section is “How to create code” and as such we’ll only explore that feature for now. Once the IDE is installed you will have a new development perspective available to you. Open this up by clicking Window -> Open
Perspective -> Other -> Force.com at which point you’ll be presented with a page detailing information and other resources for the Force.com IDE.
To get started coding, right-click in the “Package Explorer” window and click New -> Force.com Project. If you’ve signed up for a DE (or any) Org you’ll have a set of credentials that need to be entered in this window. If you haven’t signed up yet, click the Sign Up Now! link to the right of the “Environment” drop-down box.
Many people get confused, as they’re not sure what the difference between a “Security Token” and a “Password” is. In Force.com jargon a security token is a randomly generated alphanumeric string that adds strength to your credentials in conjunction with your password. If you don’t have a security token you can get a new one emailed to you by logging into your target Org and clicking Setup -> My Personal Information > Reset My Security Token -> Reset Security Token. It’s also important to note that if you change your password, a new security token is issued invalidating the previous one.
If you’re having trouble logging in and you’re certain that your username, password and security token are correct then the likely culprit is that the wrong environment type has been selected. Most developers will only work with “Production/Developer Edition” or “Sandbox” Orgs, so trying each of these should solve the problem. As an additional handy tip, if you use http://login.salesforce.com to login then means that you’re developing in a the first option is correct, whereas a login URL of http://test.salesforce.com sandbox. Clicking the Next button in the wizard presents a page similar to that in figure 3 – 10. Here we encounter metadata once more, selecting those components you’d like to pull into your project. You can select a default set of components, customize the selection or choose none.
A lot of what you see in this window might be unfamiliar at this point (e.g. Apex Component, Apex Trigger, Static Resource) but you can revisit this page at any time during development and customize which metadata components you’d like to work with in Eclipse. The important concept here is that Eclipse wants to download a subset of your Force.com application in the form of metadata into a local project, thereby setting up a twoway subscription to application changes. The default option is fine for now so you can click Finish to complete the wizard. Looking at figure 3 – 11 you’ll see that we’ve expanded our project and opened the class that we created through the Force.com App Builder Tools IDE.
On the left, the project is laid out in a neat folder structure, grouping code unit types in their particular folders. On the right we have the code editor where you’ll notice that the code layout and highlighting is consistent with what we saw before. At the bottom of the right pane you can flip between the “Source” view – where you add actual code – and the “Metadata” view that shows how Force.com describes this class, as demonstrated in listing 3 – 1.
Listing 3 - 1. Example of Apex Class Metadata
To create new code in the Force.com IDE right-click on any folder or file in your Force.com project and highlight New. The available options are shown in figure 3 – 12 and as you can see there’s a mixture of programmatic development and declarative programming elements.
Feel free to experiment with creating declarative elements such as custom objects as this will give you feel for how they’re represented under the hood. Beyond experiment though, we’d advise steering clear of editing these files by hand as it’s error prone, and can be tough to debug if something goes wrong. This chapter will only cover the programmatic elements and since the creation wizard for each element is a little different, these will be discussed in later sections.
Earlier we highlighted how integral metadata is to the platform and how a Force.com project is a collection of metadata files. To expand on this, each time you create or save a file in the Force.com IDE the metadata representation of that file is zip-archived and sent to the Force.com servers for compilation. The result of the compilation is then returned to your IDE to let you know whether it was successful or whether there were problems encountered. All of this is achieved at break-neck speeds via the Metadata API, which will be discussed at length in a later chapter.
This process is similar to what is usually termed deployment, although in the Force.com programming paradigm that name is reserved for another process. Deployment in the Force.com sense of the word will be discussed later in this chapter. After working with the Force.com IDE for some time you will realize that it’s much richer than the browser-based version offering code completion for Apex classes, system classes and schema objects; verbose syntax and compilation error messages; quick code navigation including keyboard shortcuts (courtesy of Eclipse); better code organization and VCS integration. There are also features that enable deployment, analysis and testing. It is for these reasons that this IDE is the only true project development tool available to us. Luckily it’s excels in this role.
As you move from a beginner through to an intermediate, and finally to a guru Force.com developer you’ll use the Force.com IDE more, and in most cases will stop using the browser-based IDE completely. That’s not to say the Force.com IDE is a tool for advanced developers, more that the browser-based IDE is a beginner-to-intermediate level tool. If you’d like more detail there is an official Force.com IDE article3, as well as a frequently asked questions (FAQ) document 4 and the IDE release notes5. After you’ve gotten your feet wet we’d suggest checking them out.
Anonymous Blocks Anonymous blocks provide a way to execute Apex code on the fly. The code that is executed in anonymous blocks is not persisted in the way that you’ve seen in the IDEs; instead it is lost when you “close” the anonymous block. Because they execute immediately and create debug logs in their wake they are valuable when performing analysis, executing data fixes on
the fly, experimenting with chunks of functionality, running batch jobs, or scheduling jobs. There are three ways to access the anonymous block functionality namely: System Log Console Force.com IDE A Web Services API call Strictly speaking the third method sits outside of Force.com and as such will not be discussed here. In a nutshell the system log console is the browser-based method used to execute anonymous blocks, and the Force.com IDE has a pane that delivers this functionality from the desktop.
System Log Console To access the system log console you need to log into your Org and then click the System Log link6. Figure 3 – 13 shows the System Log Console window that pops up.
Clicking in the input area in the top left corner of the window will pop up an additional window that allows you to enter the code you wish to run. If you click the Execute button and your code runs successfully each of the windowpanes will populate with a different type of information concerning your script execution.
Logs - A line will appear for each application transaction executed. Clicking on any of these will populate the other panes with information about that transaction.
Stack - A top-down navigable tree of items e.g. DML operations, trigger invocations or method calls, as they are called in the process of executing your code. The pane below is the back trace, or bottom-up view, of the same tree.
Execution Log - This is similar to the old bare-bones debug log and system console output, but with some important enhancements. Options in this pane allow for a number of filtering options making the output easily readable.
Source - Displays the executed source code or metadata definitions of items used in the execution process. The pane is context sensitive in that selecting items in other panes filters the output.
Executed Units - A granular view of the resources consumed by individual process items. Buttons at the bottom of the tab allow you to filter out unwanted information.
Limits - Shows the limits involved in your code execution (by name) as well as how close you are to hitting them. Besides being used to run scripts as Anonymous Blocks the System Log Console can also be used as a full fledge debugging tool. As shown later you can enable debugging on a per user basis; if you’ve done this for your currently logged in user and keep the System Log Console open during your development and testing, log entries will populate the Logs pane. Each entry will detail every transactional event during your application interactions. This is incredibly useful in testing either user-flows or the smallest application unit. Using this tool you can pinpoint elusive bugs or even just narrow down inefficiencies within your application.
Force.com IDE The Force.com IDE provides a cut down version of the functionality provided in the System Log Console through the “Execute Anonymous” view.
In figure 3 – 14 we’ve expanded this pane and run through the process of entering some Apex code and clicking Execute Anonymous . The labels and process here are a touch different but the result is similar to that of the execution log pane in the System Log Console. Similarly filtering functionality is available through this interface although the help for each option isn’t as explicit as in the web interface. The choices are quite straight forward and with you being able to set the verbosity (“+” is more verbose while “-” is less) for each “Log category”.
Version Control Unless you’re a developer working in isolation then version control is essential. Even if you are the sole developer version control systems work as effective backups. Version control system are used to track changes in files assigning each subsequent change an incremental version number e.g. the initial file version might be 1, the first change would then become version 2. Typically these systems provide functionality to avoid and/or merge conflicting changes, thereby allowing teams of developers to work on overlapping source code. Additionally these systems record a history of changes allowing comparisons or reversion to a historical source code state. This has large advantages over traditional backup systems as the access is provided in real-time, usually with line-by-line comparison tools, and allows the developer to step back further than a single version.
Force.com IDE The Force.com IDE provides a mechanism to compare a local and server-side version of any file, although in reality this isn’t suitable as a fullblown VCS. As an example consider that you have two developers working on the same Apex class ClassA. Each developer initially has the same version of the class in their local project. The first developer then creates the method doAction() in a shared sandbox. Later the second developer adds in a second method getBoolean() without first fetching the updated code from the server. When she saves the class she’ll get an error in the IDE stating: Conflict found while preparing to save ‘ClassA.cls’ to server. Remote instance has been updated since last save or sync. Use the Synchronize Perspective to resolve the conflict. Right-clicking on the problem file and then selected Force.com -> Synchronise with Server brings up a dialog box asking if you’d like to the Team Synchronizing perspective. Clicking Yes, a new view will appear with a little two-way red arrow indicating the conflicted file. Double click the file to enter the “Text Compare” mode, which will look similar to figure 3 - 15.
The options relevant to this type of conflict are available in the top-right hand corner, offering to overwrite the highlighted local code, with the source code on the server. In this situation however you’ll want to merge the changes into one file, so select the doAction() method in the right pane and copy-paste it into the left pane. Saving the change you’ll notice the IDE doesn’t yet know the conflict has been resolved. Right click on the
conflicted file and select Apply Project to Server. The file is now saved and you can return to the Force.com perspective.
When you move from any perspective back to the Force.com perspective the “Force.com Start Page” is opened and given focus. This page is useful but this behavior isn’t always desirable. To prevent this open Eclipse preferences and click Force.com -> Start Page and deselect Display when Force.com Perspective is opened. The “Synchronize with Server” feature can be used for incoming, outgoing and conflicting changes, as well as any combination of all three types.
Subclipse There are a number of version control server applications on the market and in this section we’ll discuss one of the best, namely Subversion (SVN). If you don’t have an SVN server installed you can download the software for free from http://subversion.apache.org or you can use one of the on-demand SVN services such as Google Code. Subclipse is an SVN client that can be installed as a plug-in for Eclipse (available from http://subclipse.tigris.org ) and which allows your Force.com projects to work with an SVN server7. Working with Force.com and Subclipse usually includes: Copying your source code to the SVN server. The copying process is called “committing” and the area where the code exists is called the “repository”. Development team members will import the project code and mark it as a Force.com project by right-clicking on the project and selecting Force.com -> Assign Force.com Nature. Development progresses with engineers resolving conflicts, importing, merging, branching, and tagging code. The commit history allows code comparisons and the ability to revert to earlier versions of the source code. The topic of version control has transcended technical debate and for some has even become philosophical. The good part is that tools such as SVN and Subclipse are platform-independent so once you’re experienced the skills are transferrable. The bad news is that each has several books detailing how to gain said experience.
Although the details of forming a version control strategy are beyond the scope of this book it is important to note that Subversion doesn’t work particularly well with large files. If a development team is working with metadata or source code files larger than 1000 lines you may have difficulty combining the changes. The value of version control systems is worth the steep learning curve. Significant time can be saved (when used properly) because of the versioning history, and tools to manage and merge source code. Additionally it is possible to have other tools plug into a source code repository offering valuable services such as checking code quality, feeding information to project management suites or automatically building committed changes into production environments.
Deploying Applications on the Force.com Platform Deployment on the Force.com platform can be summarized as the process of migrating metadata from one Org to another. Usually this feature would be used when promoting code from a sandbox or DE Org into a production environment. The Metadata API facilitates deployment using either the Force.com IDE or the Force.com Migration tool. The Force.com IDE deployment process is the simpler of the two using a deployment wizard. The Force.com Migration Tool is a more advanced tool (at least for those without Apache Ant experience) but its own set of advantages. Assuming you’ve reached the point where you’ve created and tested a collection of source code files, the next step to deploy them to a QA, UAT or production environment. We’ll demonstrate the steps necessary to achieve this with each tool.
Salesforce.com won’t allow you to deploy changes to an Org unless the total unit test coverage for all code in that Org is 75% or above. Not only does this ensure a high quality of deployed code, it goes a long way towards making sure that tenants on their platform don’t write code that negatively impacts their neighbors.
Force.com IDE In the IDE select the files you wish to deploy (hold CTRL/CMD while clicking for multiple selections). You can also select entire folders, or the
project root folder. Right-click on the selection and choose Force.com -> Deploy to Server. The first page of the deployment wizard will appear and you’ll need to enter your username, password and security token for the target Org. The next page will allow you to backup your project and destination environment, the defaults (backup the target environment) are sufficient. Page three of the wizard will list the files you are deploying. If you’d like to deploy a subset of the files listed you’ll need to uncheck the unwanted files. The wizard color codes the changes to visually let you know if a source code file has changed (yellow), is new (green), or has not changed (grey). Clicking on “Validate Deployment” performs a test deployment but doesn’t commit the changes. Clicking next will attempt deploy your code and metadata.
Often your deployment packages have dependencies on other file elements, objects and their fields. If these dependencies are creating issues or you’re simply performing pre-deployment checks, the Force.com IDE is the only tool through which you can perform key word searches through all of your metadata. If all goes well, the last page will notify you if the deployment succeeded, otherwise you’ll arrive at a page that details the failures. After a successful deployment your new functionality will be available in the target Org.
Deployments can take up to fifteen minutes to complete because all current and new unit tests are run as part of the migration process. Things that can slow down deployments include a large numbers of unit tests, large amounts of data in your Org, lots of files, the types of components, record locking, server availability and inefficient unit tests.
The Force.com Migration Tool The Force.com Migration Tool uses the Java-based build tool called Apache Ant to move metadata and source code from a directory on a local machine to a salesforce.com Org. This process is more complex than using the deployment wizard in Eclipse but salesforce.com has documented the tool comprehensively8. The official documentation covers everything you might need to use with the tool so a summary should be sufficient. The tool uses configuration files to determine which Org and credentials to use in the connection. It also uses a file called package.xml (which you may have noticed in your Force.com project) to determine what needs to be deployed. The deployment becomes highly configurable through customization of these files allowing granular control over what is deployed, where it’s deployed to, and even which unit tests are run. There are also configuration files that can destroy metadata to the target Org allowing you to perform house-keeping prior to any deployment. Once the tool is executed it behaves similarly to the deployment wizard in that it archives the files, sends them to salesforce.com for compilation and posts the results to the command line. Ant is a popular tool and there are a number of Java-based servers and applications that can execute and monitor Ant builds. Using some of these tools you can have deployments build automatically on any VCS commits, monitor the quality of code and gather build statistics.
Hudson was mentioned in a previous chapter, and besides performing the role of continuous integration server it supports a number of plugins that facilitates the aforementioned features. Some of these can be found at http://wiki.hudson-ci.org/display/HUDSON/Plugins.
Packages Packages on Force.com are collections of code that can be distributed without using the Force.com Migration Tool or the Force.com IDE. At a minimum all you need is a salesforce.com Org and the URL for the package to install it. Packages come in two varieties, managed and unmanaged, each with its own purposes9. In short unmanaged packages are used to organize code into compartments, you might think of them as libraries or templates. For example they work very well as open source projects. Managed packages are typically used for commercial products as they hide the application source code from the package consumer and restrict certain customizations.
Be aware of the limitations of managed packages before diving into a project. Not all application components can be packaged (although more have become packageable with each release), and data is currently not packageable. This typically means some post installation configuration is necessary for the package producer. The producers of managed packages also have some useful tools at their finger tips including license management of installed packages, the ability to push upgrades, code deprecation and application versioning. For a package to appear publicly on the AppExchange it has to be managed.
A Deployment Alternative There is another method of migrating code, born more out of process than technology. The method we will describe is fast, and because of the inclusion of a VCS minimizes the risks associated with migrating code. Note that this method only works for migrations between sandboxes and/or DE Orgs. For this type of deployment you’ll need two Force.com IDE projects, each connected to its own Org but sharing the same VCS repository. From figure 3 - 17 it can be seen that changes are made in a development project, committing changes to your VCS at milestone points. When you are ready, import the required changes into the deployment project and push them to the target Org.
You might ask why not use the Force.com IDE deployment wizard or the Force.com Migration Tool. The answer to both is that it’s a matter of saving time and reducing risk. With the Force.com IDE deployment wizard you need to find and enter credentials for each target Org, and all tests are run on each deployment, which can occupy your IDE for 15 minutes at a time. With the Force.com Migration Tool you’ll need to manage deployment descriptors and potentially fiddle with configuration files. Both of these methods also allow you to skip the VCS step. We therefore gain time because all we need to do is move from one Force.com IDE project to the other, and we reduce risk since the VCS forms our deployment conduit. Note that you can have several target deployment projects all connected to the same VCS repository. Then it’s just a matter of pulling source code into the appropriate Org for “deployment”.
Monitoring Deployments We previously noted that deployments could take upwards of 15 minutes to complete. If you’d like to monitor these deployments, or view a history of past deployments you can access such a control panel by clicking Setup -> Deploy -> Monitor Deployments.
Developing Applications that Scale As larger and larger companies build applications on the Force.com platform, scalability and performance with large data volumes becomes something that administrators and developers need to be concerned about. Any of the following factors indicate that you should start to think about ways to scale your applications:
Record ownership - If an Org has a private sharing model with individual users that own 10,000 - 100,000+ records, it may degrade performance due to the querying of the share tables and the number of records involved in those tables
Sharing model - Private sharing models tend to be slower that public models as objects need to do an extra JOIN to look up the sharing privileges for each record.
Role hierarchy - A deeply nested role hierarchy (10-12 levels) can impact scalability. Number of territories - When an Org has to deal with thousands of territories that are deeply nested, it may degrade look ups, list views and reports associated with accounts. You should become concerned when your Org approaches 10,000 territories.
Public groups - Deeply-nested public groups (thousands of public groups) may cause performance issues as the platform has to traverse these trees to determine record access.
Large volumes of records - Once an object contains 1-2M records it starts to suffer from performance issues in a number of areas (e.g., search, list views, reports, SOQL queries). There are a number of strategies you can implement to make your applications more scalable.
Using Divisions Divisions are most often cited as the best way to speed up an Org. Using divisions associates users and their data into a structure similar to a database partition. Data should be divided into logical data sets that are meaningful to end users. For example, if your company operates from a regional perspective then divisions could be partitioned into three regions: East, Central and West. Divisions allows you to segment your data into organizational “buckets” providing users with a view of data that is relevant to their needs. You can set up divisions virtually any way that makes sense such as geographically, line of business (i.e., commercial or government) or any other type of internal corporate grouping. Divisions do not restrict data access but simply makes data easier to manage and faster to access. Divisions should lead to better response times for things like list views and reports, for example. Divisions are designed to scale up to 100,000 users for Orgs based on data segmentation in the 1M+ range. Salesforce.com specifies that you should aim for less than 1M records per object per division. See chapter 2 for more information on Divisions.
Archive Data Determine if you can archive data in another custom object or system for records that are typically only needed for historical purposes. It may not make sense to force users to wade through millions of record that are, say, 5+ years old when all they are really concerned about are leads that have been created within the last 6 months.
Create Additional Indexes Any field marked as an “External ID” will automatically create an index. If your application consistently performs searches on the “Email” field, then marking that field as an “External ID” should significantly increase response time. You can also contact salesforce.com Support and discuss with them the possibility of creating multi-column or additional indexes on an object to speed up searches and reports. Salesforce.com periodically monitors queries and tries to detect new indexes that need to be created but you may be better off making the request formally via support channels.
Creating indexes may significantly increases data load and delete processing times as these indexes have to be maintained.
Optimize Security Model Use private sharing models sparingly and strategically when possible. The Force.com database is designed to be optimized by record owner to determine which user can see a record or group of records. Try to minimize the number of sharing rules per object. Performance begins to degrade when the number of sharing rules approaches 250. Also attempt to avoid unnecessary levels of role hierarchies, groups and territories as it has an impact on performance as well. A wide-open sharing model will always be more performant due to the lack of security checks when fetching records for display, list views, reports, etc.
Train Users to Search Effectively Provide end-user training so that users constrain their searches to provide better results with less time. So instead of searching for “Sm*” across all objects, have users enter a keyword that is more significant or impactful like a SSN or phone number. Another technique to speed up searches is to use the new advanced search to only search a specific object. Utilizing divisions will also speed up searches as it uses the user’s subset of records by default.
Use Asynchronous Apex Whenever possible, use Asynchronous Apex to process records or other operations in the background. If the user isn’t dependent on a process, don’t make them wait for it to finish. Perform it in the background while they go about their business. Asynchronous processes don’t compete with other running processes and kick-off when the server has free resources.
Use Schedule and Batch Apex For processes that are resource intensive and which may collide with active user processes, schedule them to run periodically or nightly with Batch Apex. You can take advantage of higher governors and limits while resources are available.
Experiment with Queries Use the Apex Explorer, Eclipse or SoqlXplorer to fine tune queries and see how changes to indexes or filters impact response times. For instance, with large data sets in a single object with no divisions, SOSL will actually result in better performance than SOQL.
Avoid constructing SOQL queries that use non-indexed fields. Salesforce.com automatically indexes relationship fields, fields marked as an “External ID” and some standard system fields as well (e.g., Name, LastModifiedDate, CreatedDate). In general, queries using system fields in the filter criteria perform better than those using External ID fields. Using the LIKE expressions on an External Id field works well when the ‘%’ sign is not the first character in the expression. Bad Query SELECT Id from Account where Name LIKE ‘%ACME’ Good Query SELECT Id from Account where Name LIKE ‘ACME%’
Testing Applications on the Force.com Platform Software testing on the Force.com platform inherits many of its principles and tools from the traditional programming paradigm. Like it’s traditional counterpart you’ll find that your test environment setup depends on circumstance (read money and resources) as well as the projects you have in mind i.e. smaller projects can be developed comfortably within some subset of a “full” test environment architecture.
An Adjusted Approach There are many aspects to testing which are largely platform-independent and as such we’ll only touch on the majority. Testing can be broken down into: Testing levels o Unit testing o Integration testing o System testing o Migration testing o Regression testing o User acceptance testing o Quality assurance testing Testing methods o Black box o White box Testing processes o Waterfall o Agile There are additional testing levels, methods and processes10 but we’d argue that the above are the most popular, and typically a development team won’t (although they should) even employ all of the testing levels and methods mentioned above. Each of these is well documented, spanning thousands of websites and many a book, so we’ll not detail them here. Instead we’ll introduce the areas that are most popular with Force.com developers.
Unit Testing Unit testing is common in software development and in short could be defined as the programmatic verification of application code at a granular level, typically per function or method.
Often time’s developers confuse unit testing with integration testing and instead of determining whether the functionality provided specifically by a code function works, they instead test whether it works with other elements of the system. On the platform both types of testing exist, but are largely referred to by the same name. Unit testing on the Force.com platform is a feature of Apex code and Apex triggers, and will be explored in their respective sections. It is important to note that you cannot deploy (in the Force.com sense) to an Org unless your unit tests execute at least 75% of the source code that has been written.
System Testing Developers will breathe a sigh of relief to learn that many aspects of system testing are handled without them having to lift a finger. Scalability,
stress, load, penetration and reliability testing are some of the types of testing that you no longer need to worry about (hoorah!) as they’re salesforce.com’s responsibility.
Testing Environments and Architecture One of our favorite testing features of the Force.com platform is the ease with which you can create replicas of your production environment. In traditional development topologies this is usually a nightmare as you need the hardware, software, licenses, staff, infrastructure, etc. to support the duplicated environments, and even then they typically will not be precise copies. Note that sandboxes are only available to salesforce.com customers who have purchased Enterprise or Unlimited Edition licenses11. There are different types of sandboxes that support copying data, configuration or both, and it is possible to have multiple, independent sandboxes at once.
If you do not have access to sandboxes with your salesforce.com edition then you can sign up for a free DE Org (http://developer.force.com). You could create a process that deploys code and data to this Org giving you near sandbox capabilities. For the rest of this section we will only mention sandbox and production environments but be aware that in most situations it is technically viable to replace “sandbox” with “DE Org”. It is widely regarded that development and testing environments should be kept separate. This implies testers and/or users can evaluate functionality without holding up developers. This setup was demonstrated in topology of figure 3 - 2 and figure 3 -18 shows that each phase of testing also serves as a feedback mechanism. If new features are requested or functionality is faulty, the requirements are analyzed and development returns to the first phase.
This development lifecycle coupled with a regular release schedule would form the heartbeat of your software output efforts. Note that salesforce.com has a book called “Development Lifecycle Guide” that extensively discusses development, deployment and testing strategies12.
Salesforce.com offer a free cloud-based service called the Force.com Security Code Scanner13. This developer tool will scan the code in the target Org for security (e.g., cross site scripting, SOQL injection) and code quality (e.g., DML statements or SOQL/SOSL inside loops, nonbulkified Apex methods) issues and send you a handy PDF with the details.
Analysis and Maintenance on the Force.com Platform Now you’re aware of the tools available to aid you in creating, testing and deploying applications, so what’s next? What if something goes wrong or it’s requested that some part of the application be changed or enhanced? It’s then that you need a sound knowledge of tools that can help you analyze and/or maintain your application code. Broadly speaking the tools available can be categorized as data-analysis tools, code-analysis tools, or both. Some tools are officially supported by salesforce.com while others are not.
Force.com IDE – Schema Explorer The Schema Explorer is a tool used for data and schema analysis, and is conveniently located within the Force.com IDE. Double-clicking on the file called salesforce.schema in any Force.com IDE project will open the schema for the connected Org. Figure 3 – 18 shows the typical DE Org schema. Expanding the schema tree in the right pane you’ll see all the objects in your Org, a description of each object’s field, as well as details of object relationships. Exploring the schema this way is often much quicker than navigating the objects through the salesforce.com UI.
Looking through the list of schema objects you’ll see objects such as ApexClass and ApexTrigger. Here you start to get a feel for how deeply metadata penetrates the platform. For example Apex classes are simply metadata (XML) plus persisted data, making for a powerful and incredibly flexible programming language. The left-most pane in the Schema Explorer let’s you run SOQL queries against that particular Org. You have the option of typing out the query manually, but for quick query building you can select the appropriate object fields in the right-most pane and Schema Explorer will generate the query for you. Clicking Run Me will yield the query results just below the query input area.
Force.com Explorer The Force.com Explorer is a Windows only tool offering the same functionality as Schema Explorer and more14. After logging in you’ll arrive at the main application window as shown in figure 3 – 18.
The password that Force.com Explorer expects is your password concatenated with your security token i.e. if your password is “Password” and your token is “Token” then your Force.com Explorer password is “PasswordToken”. You’ll find that if a tool does not explicitly ask for a token it assumes that you supply it with this concatenated password instead. The landing tab is immediately familiar in that it mirrors the Schema Explorer view. Note that the language used for querying here is structured object query language (SOQL), which we’ll discuss later. The next tab offers the ability to test structured object search language (SOSL) statements, and helps to learn the language with a search statement builder similar to that first seen in Schema Explorer. The “Data Editor” tab lets you examine data for any object, as well as arming you with some editing capabilities. Last but not least the “Documents” tab lets you interrogate a special object called Document. You can store binary large objects (BLOB) in the Document object; this allows you to upload images, office files, or most other large file types. For the most part Force.com Explorer falls into the “Analysis” category and also helps those starting off with the Force.com query and search languages (besides the query builders there are sample queries available from the application menu).
SoqlXplorer SoqlXplorer is a Mac application offering similar features to those of Force.com Explorer built by one of salesforce.com’s brilliant minds15. It doesn’t yet offer all the features available in Force.com Explorer but it is frequently updated and the schema exploring feature adds some nice eye candy.
Excel Connector This Force.com tool sits within Microsoft Excel (who would’ve guessed) and facilitates querying objects with the result written straight into spreadsheets16. This is incredibly convenient for local data-manipulation, as well as reporting and data logistics. Additionally you can write information back to your object giving any person familiar with Excel a bidirectional interface to salesforce.com objects. This tool straddles the analysis and maintenance roles, and is versatile in that you can hand the documentation to your admin staff and start building a team of salesforce.com super-users. Additionally developers find value in the Excel Connector when data consolidations or other complex data activities are required as Excel has features beyond the scope of other Force.com tools.
Data Loader Also known as Apex Data Loader it will become one of your closest allies in analysis and maintenance on the platform. As the name suggests it’s used to push data into a salesforce.com Org. Moreover you can extract, delete and modify data using Data Loader. Data is extracted and imported using comma-separated value files, making them workable from most spreadsheet applications. You can download the tool from a logged in salesforce.com session by clicking Setup and under Administration Setup -> Data Management -> Data Loader. Data Loader falls more into the maintenance category, and presents a simple wizard based interface for beginners, but includes a commandline interface for custom executions or for automating the extraction and/or uploading of data17. Note that Data Loader is a Windows only tool. If you need similar functionality for Mac, you’ll need the ported version called LexiLoader18.
Workbench This community built application stands out from the aforementioned tools. It’s web-based (although you’ll need to get it hosted) and performs most of the functions available in Force.com Explorer, Data Loader and anonymous blocks. Not only does it support describing, inserting, updating, deleting, undeleting, purging, querying and executing Apex, the interface is arguably better than in the other tools and the documentation is in-depth and precise19.
Since most of the features available from this application have been covered already it’s not necessary to revisit them. Don’t be deceived by the length of this summary though, Workbench is the bee’s knees as it’s a web-based one stop shop.
Force Metadata JDBC Driver for SchemaSpy
A superb tool created by a rising star of the Force.com community, it generates entity-relationship diagrams for your Org. Moreover it generates an interactive local site that describes your schema from the highest level down to the smallest detail. The tool sits firmly within the analysis arena, and its implementation might be regarded as medium to difficult, although Jeff Douglas has written up an article that makes its implementation clear20.
Debug Logs Logging is part-and-parcel of any developer’s life. Debug logs for Force.com can be accessed through a salesforce.com instance by clicking
Setup, and under “Administration Setup” clicking Monitoring -> Debug Logs. Debug logs can’t run continuously and instead are requested on a per user basis, with 20 logs being provisioned at a time i.e. one log “file” will be created for each user transaction which for a typical page or API transaction would include: Any controller code run on a page load Any controller code run as part of an AJAX request Any trigger, workflow, validation rule or database activity initiated from the page Transactions can also be more nuclear, and not necessarily user-initiated. After clicking New and selecting a user you have the ability to delete, reset or apply filters to the request. The delete option is obvious, the “reset” option will refreshes the debug log request so that you once again have 20 logs available, and the filter option works precisely like those seen in anonymous blocks i.e. it controls the log verbosity.
Although only 20 logs should be available at any time, it seems that for each click on Reset an additional 20 logs are provisioned. Don’t tell anyone we told you though. The output of the log is necessarily complex as it has to track code at several levels, and to be of any use, needs to be granular to the subatomic level. We would highly recommend that instead of just reading through the logs line-by-line that you instead fire up the System Console Log (System Log) as the tools available there make for a far superior debugging experience. Note that you will still need to have the official log output guide21 close at hand until you gain a fair amount of experience.
Tools to Assist Productivity & More Every developer has tools that whilst not used directly in their development aid them in one way or another. List here are a notable few.
Force.com Utility Belt This Google Chrome Extension provides shortcuts to some of the most commonly used salesforce.com documentation, a quick search
interface for most salesforce.com documentation plus a large number of other sites (e.g., Message Boards, Snipplr, Code Share, AppExchange), links to number salesforce.com resources and a 15-digit salesforce.com ID converter.
Available from http://blog.jeffdouglas.com/force-com-utility-belt
Trapdoor This neat Mac OS tool will keep track of your salesforce.com credentials. As an example we currently “own” more than 20 salesforce.com Orgs so this tool is handy.
Available from http://www.pocketsoap.com/osx/trapdoor
Setup Enhancer for Salesforce Those familiar with GreaseMonkey are aware that it’s a browser plug-in that allows developers to create JavaScript tweaks to websites. The Setup Enhancer is one such script, and it simply injects a search dialog box into the top of the navigation pane in the setup menu. Typing in the search box will filter the setup menu items in real-time. This simple tool makes the setup menu less intimidating, and helps beginners find the proverbial needle in the haystack.
Available from http://userscripts.org/scripts/show/60438
Application Support on the Force.com Platform Many platforms have fallen flat simply because of support issues, Force.com is not one of these. Support is available in a variety of forms and you’ll find that salesforce.com, as well as the developer community, are always willing to extend a helping hand.
Official Support Channels Force.com Discussion Boards A live, evolving support option, this channel is invaluable for beginners. The forums are broken into many channels, and you’ll eventually learn the names of the experts in each section. We’d like to stress that no question is too silly to ask as most people that browse the boards answering questions were educated from the forums.
You can find the discussion boards at http://boards.developerforce.com
Direct Support There are levels of direct support offered by salesforce.com. The basic support option is available to all customers and includes telephonic, email and case-based channels. At the higher levels of support the turn-around times are much shorter, and even offer administrative services. To drill down into the support offerings open up the below URL and check out the links under “Related Documents”.
Available from https://www.salesforce.com/ap/services- training/customer-support
Twitter One of the newer support options, this channel is available for concise questions. Turnaround times on questions asked via twitter are typically fast, although due to its nature questions cannot be complex or require long explanations. There are also a number of sub-channels each available
from the below URL.
Available at http://twitter.com/Salesforce
Documentation Documentation is one of the most important support “channels”, and salesforce.com has lots of it. Google can help you find the right documentation a lot of the time, but some of the jewels of the platform are found in PDFs that aren’t Google-indexed22.
Most developer documentation is available from
http://wiki.developerforce.com/index.php/Documentation Visiting the page the first few times seems like an information overload, so we’ll list the documents you’ll most need to start out with (assuming your intention is to become familiar with the Force.com platform languages). Introduction to Force.com - Core Resource Articles Force.com Workbook: Getting Started Building Your First App in the Cloud Force.com Fundamentals: Custom Application Development in the Cloud Visualforce Quick Start Tutorial Apex Tutorials Under Reference Guides o All documents under “General” o All documents under “Apex and Visualforce” (core language reference documents) Force.com Cookbook: Code Samples and Best Practices All documents under “Developer Cheat Sheets”
Unofficial Support Channels Blogosphere A number of talented individuals have setup blogs to share their experiences and advice with the Force.com community23. The topics here range from the salesforce.com CRM to advanced topics of integration.
Twitter Many Force.com developers that you can befriend through Twitter will freely offer support and advice. It was realized by Quinton Wall that perhaps anyone looking for community support should use the #askforce hash tag, and this has played out quite well. For more in-depth questions it’s customary to post on the Forums and then link to the issue in a tweet with said hash tag.
Salesforce.com Certifications Message boards, LinkedIn and staffing firms are constantly trying to fill salesforce.com positions with qualified professionals. The industry is booming and that is great for people looking for jobs. One of the best ways to demonstrate to potential employers that you have the skills and experience necessary to do the job is to become certified. Salesfoce.com offers certification for consultants, administrators and developers. There are five levels of certification — two for administrators, two for developers, and one for consultants.
Training videos for DEV-401, DEV-501 and Admin to Hero with Force.com are available for free on iTunes. Simply search the iTunes store for “salesforce.com”. Salesforce.com offers training classes to prepare you for the certification test but they are not required. Training is recommended but nothing
prevents you from studying on your own (study guides are freely available) and taking the test at a local test center or online. The certification exams feature multiple-choice and multiple-select questions (60-70) that cover a broad range of topics in that area. The Advanced Developer exam also includes a programming assignment and short-answer essay exam. Most certification exams cost $200 however the Advanced Developer certification exam is $400. You’re considered qualified once you’ve successfully passed your exam. However, to maintain your certification over subsequent releases, you are required to take interim exams that test your knowledge of the new release features. The cost of these interim release exams is included in the initial certification fee for 1 year. After that year, maintaining your certification requires a yearly maintenance fee of $100.
Visit http://www.salesforce.com/services- training/training_certification/certification for more information. 1 Developer-edition-signup 2 force.com-ide-download 3 force.com-ide-docs 4 force.com-ide-faq 5 force.com-ide-relnotes 6 system-log-console-docs 7 force.com-ide-svn 8 force.com-migration-tool 9 application-packages 10 software-testing 11 environment-types 12 force.com-development-lifecycle-guide 13 apex-security 14 force.com-explorer 15 soqlxplorer 16 excel-connector 17 dataloader 18 lexiloader 29 workbench 20 force-metadata-jdbc-driver-schemaspy 21 understanding-debug-log 22 official-documentation 23community-blogs
Programmatic Development Languages
In this chapter you’ll learn more about how to create and maintain applications on the Force.com platform. In doing so you’ll encounter Apex, Visualforce, Structured Object Query Language (SOQL) and Structured Object Search Language (SOSL), which together form the core languages that are used to create software on the platform. These will be explained within the context of the Model-View-Controller pattern; a prolific architectural pattern that calls for the separation of application logic, data and user interface in order to reap the benefits of easier collaboration and maintenance. By the end of the chapter, not only will you be aware of what you need to develop applications using Force.com, but you will also have a feel for the best practices in each area.
MVC in the Cloud We’ve addressed the topics of software development models and the tools that you’ll need as a Force.com developer. A natural next step is the exploration of the languages and technologies that you’ll use to take your projects from specification document to real-world application. Model-view-controller (MVC) is a prevalent architectural design pattern in modern software development. In short it promotes the separation of an application’s logic, user-interface, and data storage from one another. This architecture has risen in popularity as this isolation of data (the model), user-interface (the view) and logic (the controller) allows each component to be developed, tested and maintained independently. The Force.com platform’s development architecture fits conveniently within the MVC pattern allowing development teams to take advantage of the separation of responsibilities. If you consider figure 4 - 1 and imagine the following scenario: You have created a Visualforce page (the view) with a text field and a “Save” button. The text field holds your last name, and this is persisted in a custom object (the model). When the page loads the field on the view requests the stored first name value from the custom object; this communication happens via the page controller. You might want to update your last name in which case you’d change the text field value and click the “Save” button. This click would trigger an event handler in the controller, which would feed the information from the page to the custom object.
The model, the view and the controller clearly have separate domains of operation and this allows you to work on each component independently. Since the Force.com platform alludes to this design pattern we will discuss each platform language and technology within the context of these roles.
Salesforce.com is a multitenant architecture as explained in chapter 1. In order to prevent any application from consuming more than their fair share of the platform resources they have introduced restrictions on measurable program operations. These restrictions fall under the names governors and limits and together they force the developer to create code that is efficient such that all “tenants” get an equal share of the resource pie. Developers don’t like Governor Limits very much as their development style is forced into certain practices used to remain within these limits. However these practices ensure a code base that is neat in architecture and quick in execution. Governor Limits are applied differently to each area of the development platform and will be discussed those contexts.
The Model Within the Force.com platform data persistence is provided through what are termed Objects. These come in two broad flavors as shown in chapter 2. Objects are an excellent way to abstract away the database and it’s corresponding fields as this allows developers to work with data in an object-oriented way i.e. instead of working with data rows, on the Force.com platform data is encapsulated in a class-like structure with the data fields accessible via member variables. If we peek into the controller domain briefly you’ll see, as show in listing 4 - 1, that objects can be
instantiated, and their member variables can be assigned values in much the same way as class variables.
Listing 4 - 1. Object Manipulation in an Apex Class
What do developers expect from the model? Usually you’d need several abilities to be exposed: o Data Creation o Data Retrieval o Data Update o Data Deletion o Data Security The first four features are sometimes referred to as create, retrieve, update and delete or CRUD. Data retrieval is the most complex of CRUD on the platform having two languages devoted to this sole purpose. The other operations are semantically quite similar, and vary only in syntax and result and therefore make a good starting point.
Data security is configured using a combination of features such as profiles, roles and field-level security. These topics are discussed in more detail in chapter 2.
Data Creation, Manipulation, Update and Deletion With most types of databases you’ll encounter operations to insert1, update2 and delete3data. Force.com is similar in this regard, with listing 4 - 2 demonstrating how to insert, update and delete a data record.
Listing 4 - 2. Insert, Update and Delete a Record with Apex Code
Note the distinction between data manipulation and data update at the third and fourth lines. Line three is manipulating the value of the member field “firstname” and line four stores the changed value. There’s an additional command available that can perform inserts or updates, and knows which action is appropriate in a given situation. This command is called upsert4 and its usage is demonstrated in listing 4 - 3.
Listing 4 - 3
Each of these commands is simple and extensively documented so there is little else we can add. Instead we’ll detail the more interesting topic of data retrieval.
Data Retrieval using SOQL and SOSL Data retrieval from data stores usually requires a query language. Probably the most common is structured query language (SQL), which comes in many varieties, which are syntactically similar. The Force.com platform uses two languages for data retrieval, each of which has specific use-cases; essentially SOSL is capable of performing text searches across objects and returning several object types in the results whereas SOQL allows complex querying of data returning a single object type. Of the two you’ll find that structured object query language (SOQL), which has its roots in SQL5, is the one you’ll use more frequently. This is another topic that is covered by torrents of documentation, so we’d like to give you a guiding hand on where to start.
SOQL Syntactically SOQL is more or less a subset of SQL6 with each individual statement structured as shown in listing 4 – 4.
Listing 4 - 4
Querying with SOQL Looking at listing 4 – 5 you can see how this syntax can be applied with the Apex programming language, as well as how you can work with the results of a query7.
Listing 4 - 5
Note that queries will always return data as complete object records unless aggregate functions are used (more on these later). In the second query we’ve demonstrated how you might retrieve a single field value by dereferencing the name field. The above example assumes that exactly one record will be returned by the query, and this is often a dangerous assumption to make. If the query were to return zero or greater than one result, your application would throw a runtime error. In some cases it would be better to feed the results of a query into a list of objects as shown in listing 4 – 6.
Listing 4 - 6
Here you see the Apex syntax for lists of objects but don’t panic, it will be revisited later in more detail. This query is not capable of creating runtime errors; if no records are found the list will be empty, and if more than zero are found they’ll be added to the list.
There is another way to deal with a query that returns zero results. At times it’s better to implement an Apex language feature called exception handling to avoid this type of runtime error; this feature will be examined in a later section.
Apex Variables in SOQL Once you dive into SOQL programming with Apex you’ll often find the need to filter your queries using the value in an Apex variable. As an example consider the query in listing 4 – 6, but imagine that now, at development time, we don’t know what the last name might be as it’s determined by user input. In this case you’d use the syntax presented in listing 4 – 7.
Listing 4 - 7
Here we’ve declared the variable that will hold the last name value, and delimited said variable with a colon. Using a local variable within a SOQL statement is known as a bind, and they can be simple variables (as shown above) or formed by expressions8.
Object Relationships & SOQL In modern development most databases are relational i.e. records in one table are related to records in other tables through an established relationship. The situation is similar with salesforce.com objects and we’ve seen in previous chapters the types of relationships that can exist. On any platform you’ll need a way to traverse these relationships and salesforce.com encapsulated this is a concise and powerful way. From an object point of view you can either be related to a parent or a child object. The difference in the syntax for each situation is shown in listing 4 – 8.
Listing 4 - 8
Be careful when using the first type of SOQL query as it can be difficult to predict (and restrict) the number of data rows returned i.e. each account can have any number of child contacts. Later we’ll see that there are operational limits on things such as the number of data rows retrieved by a single query or within a transaction. The syntax for each of these query types is quite different but simple nonetheless. Accessing the related objects for each type of relationship is also different as is shown in listing 4 – 9 with follows on from listing 4 - 8.
Listing 4 - 9
Through these Apex variables you would have access to the contents of either the children or parent of the object in question9. Be aware that the syntax when dealing with custom object relationships. Consider the example in which we have a parent object called Father__c related to a child object called Son__c. Listing 4 – 10 shows the equivalent of the above code for custom object relationships.
Listing 4 - 10
It’s important to point out that the nested SOQL statement within the first query interrogates Sons__r. This “object” name is the relationship name given when the link between the objects is first established. It can also be changed later by editing the relationship field. Figure 4 – 2 shows where this option is first presented.
Dynamic SOQL Dynamic SOQL is a feature of the platform lets an application dynamically build a SOQL string at runtime 10. This way the value of a query string can be determined by user-input as is essential with any data centric application. The syntax for the query string is the same as that of SOQL but the query execution requires a system method call as shown in listing 4 – 11.
Listing 4 - 11
Another superb feature of dynamic SOQL is that the query results can be returned as concrete objects (as above) or they can be returned as the generic sObject data type akin to listing 4 – 12. Variables of this object type can hold any type of object value, be it standard or custom. This allows you to write applications that cleverly reuse code and deal with data polymorphically.
Listing 4 - 12
Using dynamic SOQL also requires extra care as it involves more coding and error checking, and potentially exposes your application to SOQL injection attacks11. All the same, it is a powerful tool when used correctly.
SOQL Governor Limits SOQL Governor Limits 12 are one of the most discussed topics in the developer forums and many of the questions are nearly identical. The primary issues concern hitting the limit imposed on: 1. The total number of SOQL queries issued 2. The total number of records returned across your SOQL queries The first limit is typically hit when developers execute queries within some repeated structure such as a loop which will result in the following exception: System.Exception: Too many SOQL queries As it’s one of the most common limits that beginners encounter we’ll demonstrate an example of the issue in action, as well as the solution. Listing 4 - 13 shows a SOQL for-loop that contains another related query.
Listing 4 - 13
Depending on the executing code’s entry point the Governor and Limit value that is applied will vary e.g. if the first code to execute is within an Apex class you can issue 100 queries within the lifetime of that invocation. If execution began in a trigger however you can only issue 20 queries. This problematic pattern is to be avoided at all cost. Salesforce.com restricts the number of queries because database round trips are expensive and can quickly affect the performance of the multitenant environment. The idiom used to resolve this is show in list 3 - 15. Note that you’ll need to be familiar with the Set and Map collection types in order to understand and implement this pattern effectively.
Listing 4 - 14
Although the code is commented we’d like to point out that the crux of this idiom is that there are no SOQL queries contained in any loops. The second limit is less likely to be caused by an efficiency flaw and is a natural consequence of a growing data set. One common solution to this problem is to fire asynchronous method calls to run over your data set in batches of 10,000 (The limit for the number of SOQL queries executed through Apex). Since these would run in their own transactional context, each batch would be subject to fresh limits. The process of creating and managing these batches can be complex and error prone, and if your situations allows for it you should take a look at using Batch Apex. Batch Apex will be discussed in the section title “Controller”, but in brief this technology is implemented using a certain type of Apex class, and the limit on the number of records fetched in these classes is currently 50 million. This covers the basics of data retrieval but you will certainly want to dive into more detail after just a few experiences with SOQL13. Important advanced concepts to get familiar with early on are aggregate functions14, working with very large queries15 and SOQL for loops16.
SOSL Structured object search language (SOSL) is a language used to make very fast, broad-sweep searches through your objects’ fields. Many object fields are text-indexed for SOSL making this type of query faster than an equivalent search made using SOQL. When might you use SOSL instead of SOQL? An example might be when building search functionality into a Force.com Site. You need to let users find data based on keyword searches, and the results could be from a number of objects. Building an equivalent SOQL “search engine” would require a number of queries, as well as complex multi-level logical branches. It is also likely that SOSL will perform this type of search more quickly. Listing 4 – 15 shows the syntax of an SOSL statement17.
Listing 4 - 15
Be aware that SOSL cannot search these objects or field types:
Fields that are defined as not searchable. You can interrogate an object for this property by calling its describeSOjects() method and examining the value of the property named searchable. Number, date and checkbox fields. Textarea fields aren’t searched unless you specify ALL FIELDS for the search group. Certain attachment records for some standard objects. It’s important to know that you’ll use SOSL sparingly as its role is quite niche. However, when the time comes to build bespoke search functionality very few languages can compare with SOSL for simplicity and speed.
Searching with SOSL SOSL search statements are human friendly as is apparent in listing 4 – 16.
Listing 4 - 16
The syntax is quite different from that of SOQL, and the search results are organised differently as well. Firstly the result is a list of lists of sObject types. The reasons here are: You are potentially searching multiple objects, and therefore need a list to house each object type. In the above example you would thus have one list of Accounts, one list of Contacts, and a list that holds each of these lists. A variable of the SObject type can hold any other object type, so it doesn’t matter which objects your are searching through the results will always “fit” into this structure. Listing 4 - 17 shows how you might assign the search results to variables of the specified types.
Listing 4 - 17
When planning on using SOSL it’s important to note that18: The lists of objects in the search results are in the same order as they appear in the query. SOSL queries can only be issued from Apex code or anonymous blocks. They cannot be used in triggers. Text searches for a single or no characters cannot be executed. Unit tests for SOSL searches require initialization using Test.setFixedSearchResults(List
testIds). Searching with SOSL has its place and makes serving search functionality very simple and quick. Consider having to build a small application that searches all fields of the Telephone type within your Org. Listing 4 - 18 shows how easy this is with SOSL.
Listing 4 - 18
Knowing when to use SOSL as opposed to SOQL requires some thought initially, but with a little experience you’ll easily discern which tool to apply to specific situations.
Apex Variables in SOSL Needing the use of dynamic bind-variables within SOSL statements is commonplace. You’ll find that the syntax requirement is similar to that of SOQL, with the only noticeable difference being their positioning with a statement19. Listing 4 - 19 is a contrived example showing the use of bindvariables in SOSL.
Listing 4 - 19
Object Relationships & SOSL Currently there is no way to search a child and return the parent, or vice versa with SOSL. You would overcome this by searching through either child or parent objects and then discovering the counterpart through that object’s relationships and/or Id.
Dynamic SOSL Again Dynamic SOSL operates in much the same way as Dynamic SOQL, and supports the same features as static SOSL as well as being constrained by the same rules20. Dynamic search statements are executed using the search.query(sosl_string) method where sosl_string is a string variable whose value is a valid SOSL search-statement. Listing 4 - 20 shows such an example.
Listing 4 - 20
Of particular interest here are the backslashes in the search string. These are used to escape special characters within the string so that they can be included in the string definition. In the above example the single quotes are a required part of the SOSL syntax, but if they weren’t escaped, the second quotation mark would “close” the string and the third would “open” a new string; this would not compile as it violates Apex syntax rules. The ability to dynamically build search statements based on user input opens up your code to injection attacks. A simple way to avoid this is to use the String.escapeSingleQuotes(myString) method, which adds a backslash to any single quote not yet escaped. Listing 4 - 21 shows such an example.
Listing 4 - 21
SOSL Governor Limits There are two SOSL limits that mirror the SOQL limits mentioned previously 21. The first of these (regarding the number of search statements executed) is moot as one of the selling features of SOSL is its ability to search many objects and fields at once. The second limit (concerning the number of data rows retrieved) is quite small and is more difficult to work around. The two popular solutions call for either searching multiple times or (more commonly) using SOQL instead of SOSL.
The Controller The most complex area of the Force.com platform is largely regarded to be the Apex language and it’s implementation. Apex classes together with Apex Triggers form the Controller in the MVC pattern; they provide an interface to the Model and expose their logic and functionality through the View. In fact Visualforce is so heavily supported by Apex that as a newbie it’s prudent to learn about the Controller before discussing the View.
The Apex Programming Language Apex code, Workflows, Formulae, and Approval and Business Processes provide application logic on the Force.com platform but only Apex code falls into the programmatic development category. Apex is a strongly typed, object-oriented language similar in syntax to Java or C#, and (in certain areas) Oracle PL/SQL. It provides the conditional logic, various looping constructs, data retrieval and manipulation, transactional control, expression evaluation and error handling common to its class of programming languages. We’ve shown how universal metadata is used within the context of the Force.com platform, and figure 4 - 3 shows its role within the Apex language domain.
Here you see that a developer creates code locally and upon save the source code file(s) are sent to the platform applications servers. The code is then compiled into instructions that the Apex runtime compiler understands. These instructions are stored as metadata and when a user triggers the Apex code, these metadata instructions are interpreted and evaluated presenting the user with the results. Notice that only the Apex source code is written locally, compilation and execution happens on the Force.com platform. There is a lot of documentation on Apex, and one of the driving forces behind this book has been the need to help developers, business analysts and company owner’s focus on the most important resources. Through this section we will highlight the most important aspects of Apex, especially for those interested or beginning with the platform. If you’d like to expand on the tidbits we touch upon, we’d recommend reading the documents listed below. You can find all of the following links by using the official-documentation tag at delicious.com.
Apex Code: The World’s First On-Demand Programming Language A summary for anyone who needs an overview of the Apex languages features22.
An Introduction to Force.com Apex Code As the title suggests this is a primer on the language including a light touch on the syntax, Dynamic Apex and its role in the Model and View, unit testing, web services23.
Apex Cheatsheet This short reference document highlights important syntax across the Apex language24. An excellent resource for developers at all levels.
Apex Code Best Practices This wiki article should be used in conjunction with any code design and review sessions as it details common patterns that will ensure your Apex code is efficient and scalable25.
Security Tips for Apex and Visualforce Developers An article that explores a number of security attacks and how to a developer might avoid them. All developers should read and be familiar with this document26.
Force.com Workbook This excellent, short book that covers more than just the Apex language with 10 tutorials in total 27. Each tutorial builds on the last to build a warehouse application, but the most important Apex tutorials are numbers 5 and 6.
Force.com Cookbook This book extensively documents many features of the Force.com platform28. It contains scores of useful code samples and best practices. All developers starting on the platform should keep this close at hand as many beginner questions are answered in this book. Salesforce.com recently launched a companion website aptly called the “Force.com Cookbook”. This online version is, of course, more up to date and recipes are submitted by not only salesforce.com but by community members as well. Bookmark this site.
New and updated Force.com code recipes can be founds at http://developer.force.com/cookbook
Force.com Apex Developer’s Guide Every Apex developer’s friend, this reference document details all areas of the language together with a number of code samples29. From beginner to guru you should always keep this site at the top of your bookmark list.
Development with the Force.com Platform: Building Business Applications in the Cloud This book by Jason Ouellette of Appirio is an extensive guide to building applications on the platform 30. It is an essential guide for anyone looking for structured, concise way to get business applications up and running. It delves into the depths of the language, explores many advanced topics and include numerous tips and tricks not available in other documentation.
Key Concepts As a developer your role is often to translate a set of business needs into technical requirements. On the Force.com platform, most logic that supports those technical requirements will be implemented with Apex. In order to create logic with Apex there are certain language artifacts and constructs that are required, a few of which are shown in figure 4 – 4.
Listing 4 - 22
Much of what is shown will be familiar to developers. As Apex is a strongly-typed language, you’ll need to explicitly declare variables before you can refer to them. In the above example we’ve declared a variable that can hold a number, or Integer, as well as a list of the type Contact.
In Java and other languages there are distinct collection-types called arrays and lists. In Apex they are interchangeable in that you can declare a collection as an array (or vice versa) and then refer to the array and it’s elements using array notation, or refer to it as a list and it’s elements using the List member methods. Next in the listing you’ll see an SOQL statement (as shown previously). Following that we’ve included one of several loop-structures available in Apex, as well as an example of an if-statement used for code branching. Again both of these will be familiar to most developers. Lastly we’ve shown variable manipulation and the execution of a database update-statement.
Exceptions You can expect a large part of your development effort to be focused on preventing and dealing with runtimes errors. Some of these errors are expected behavior but there are others that you can’t anticipate, and on the Force.com platform these are called exceptions31.
There is some jargon to get familiar with when working with exceptions. When an exception happens developers will typically say that an exception has been thrown. To deal with an exception gracefully you would usually say that the exception needs to be “caught”. An exception that is caught is considered to be “handled”. Some situations where exceptions might be thrown are: You attempt an insert operation on a record that is missing required data.
Assigning a query result that returns no rows to a single variable. Accessing a member variable on an object whose value is null. To catch exceptions requires a special construct called a try-catch block; this is common in other languages and works in much the same way32. The syntax of a try-catch block is demonstrated in listing 4 - 23.
Listing 4 - 23
Best practice dictates that you don’t just catch exceptions; you should handle them appropriately too. This often depends on the situation but as an example it might be suitable to send an email to an administrator or write a record to a custom object used for logging.
Hitting a Governor Limit will throw an exception that can’t be caught (all processing stops immediately). To avoid this situation you can use the methods of the Limit class to gracefully stop a process before a limit is encountered33. There will be times when you’ll need to throw an exception based on predefined conditions. To do this you’ll have to first declare a custom exception using syntax similar to that shown in listing 4 - 24.
Listing 4 - 24
Catching custom exceptions is done the same way as shown in listing 4 - 23.
CRUD Operations Creating, retrieving, updating and deleting data is done through Apex commands as seen previously. The most common commands as seen previously are insert, update, delete and upsert (two that appear less frequently are undelete34 and merge35). We’ve also seen how to fetch and work with the results of an SOQL query. Apex also has a system class called Database, which allows more control over these operations, as well as providing transaction-control features36. As an example consider the example in listing 4 - 25.
Listing 4 - 25
On the first line we’ve used a feature not seen before, namely Save Points. For those who play games on computers or consoles, this is like a “saved game” and allows you to jump back to a previous point should you choose to. In the try-part of the try-catch block we are attempting to insert a record in a different manner from before. We have used the insert method of the Database class with the record we want to insert as the first parameter. The next parameter is optional and determines whether to allow partial success of the operation i.e. if you are inserting a list of records and one of those records is problematic, should the process move onto the next record or fail outright. The next parameter is also optional and
allows you to specify additional DML options such as assignment rule information. Note that with this method a SaveResult is returned which contains information about any errors that might have occurred and whether the transaction as a whole was successful. Should the above DML operation fail, thereby throwing an exception, the rollback method of the Database class will be invoked and any DML performed between the savepoint and the rollback will be undone. You will find this feature important when inserting many interdependent records in a single transaction where a failure to insert any single record should remove all related information written in that transaction.
Anytime you insert a new record, the variable used to hold the record will then also contain that record ID in the database. Trying to insert that record a second time will yield an error stating that you cannot insert a record that already has an associated ID. One convenience most developers don’t initially realize is that DML can be performed directly on collections of objects; this helps conserve DML operations keeping you safe from Governor Limits (a while longer at least). Additionally objects are passed by reference meaning that when a variable containing an object is passed around your application the variable just contains a pointer to the true object. We’ve demonstrated this in listing 4 - 26.
Listing 4 - 26
Here you see that you can loop through a list of Contacts changing the first name value of each individually. On the last line you’ll notice we’ve applied the DML operation to the entire list, and the result of this is that each contact in the list will have their first name updated to the value “Zack”. Essentially we have “indirectly” modified the field value and committed all of these changes in a single DML operation.
Dynamic Apex Dynamic SOQL, Dynamic SOSL, sObject and field describe information, and Dynamic DML are the headline technologies that fall under the umbrella of Dynamic Apex. The first two have been covered already so we’ll start with the third feature37. As mentioned previously all objects are specific implementations of the sObject type. This implies that all methods available to the sObject type are also available to any other standard or custom objects. It also means that a variable of type sObject can hold a value whose type is any standard or custom object. List 3 - 26 demonstrates some valid examples of these two implications.
Listing 4 - 27
Notice that you can ask an sObject which specific type it has implemented (as shown in the if-statement). There are other methods available that allow you to interrogate just about all of the metadata that describes an sObject38. Additionally you also have access to field describe
information39, which yields all field related details such as the default value, the type of field, the field length, whether it’s unique, etc. By combining field and object describe information you can write source code capable of dealing with objects in a generic way thereby creating neat reusable components.
A common use of field describe information is the programmatic retrieval of picklist values. Fetching this information directly from the object fields ensures that you avoid hard-coding values in your source code. It is also sensible at this juncture to point out that Apex describe information is split into two data structures viz. sObject/field token and sObject/field describe result. An important difference between the two is that a token is a reference to an actual entity but the describe result is an object that contains all the describe properties for said entity. An example of referring to a token is shown in the if-statement of the above listing, with a token being issued either side of the equality operator. In the else-branch of the same listing we’ve demonstrated the retrieval and usage of an sObject describe result. Not only can you dynamically fetch and describe data (or data constructs), Apex also supports the ability to perform DML on this data. Aptly termed Dynamic DML40 this feature also allows you to construct sObjects dynamically, and write the resulting records to the database. Listing 4 28 bring all of these concepts together: Dynamic SOQL to fetch a record. The type is determined at runtime by the string passed to the dynamicDML() method. An sObject of the same type as the queried type is instantiated using the token’s newSObject() method. In the if-else statement we determine the object type, and copy the queried object’s field values to the new object. We use the get() and put() field assignment methods for the sObject type. Without knowing the object type up front a record is inserted into the appropriate object.
Listing 4 - 28
A little documented feature is the ability to use fields in the same generic manner as objects. The Object class is to fields what the sObject class is to objects. Listing 4 - 29 should make this concept clearer.
Listing 4 - 29
Together the capabilities of Dynamic Apex form a flexible framework with which to build code components that are intelligent in design and reusable across projects.
Don’t feel that it’s necessary to make every area of your applications reusable and smart with Dynamic Apex. The real world is not perfect so not all project pieces are destined to be reusable. It is important to be aware of Dynamic Apex and it’s capabilities during the application design process so that when an opportunity arises you are ready.
The Future Annotation As you might have guessed the Apex language syntax includes a number of keywords and annotations, but one comes up so often and has such great utility that it deserves independent mention. You would annotate a method with the future keyword when you need said method to operate asynchronously from the context in which it is called41. Some use cases for future methods are: Your application needs to make a web service call to a third party and to reduce latency you wish to make the callout asynchronous. When invoking an Apex method that performs a callout from a trigger, the method must be annotated with the future keyword. Governor Limits within triggers are typically smaller than those of Apex classes. Firing a future method from trigger code ensures that all operations within the context of the future method are subject to Apex class limits instead of trigger limits. Two method signatures are shown in listing 4 - 30; the first shows a simple annotation and the other indicates that the method will perform a web service call out.
Listing 4 - 30
Before architecting solutions that use future calls it’s important to note some of these imposed limitations: You can’t make more than 10 future calls per Apex invocation. Methods annotated as future can only take primitive types, collections or arrays of primitive types as their parameters. Methods annotated as future must be static and can only have void as their return type. Getters, setter and constructors of Apex controller cannot use the annotation. You cannot call a future method from a future method either directly or indirectly.
For each salesforce.com license in your Org you can make 200 future calls per 24 hours. For example, if you have 100 user licenses then you Org has a bucket of 20,000 calls it can issue in a rolling 24-hour period. A common pitfall concerns the second to last point above. Developers will often mark methods that are called from triggers as future. If these methods then perform DML statements there is a chance that the calling trigger might be fired again. In this case you will have inadvertently created a recursive loop42 and the future method will indirectly be invoked by itself causing a System.AsyncException to be thrown. For clarity the process is shown in figure 4 - 4.
One effective solution is to maintain a global static Boolean variable whose initial value is set to false. The value of this variable is interrogated when the trigger fires and if the appropriate the callout is made. Within the callout method the variable value is set such that if the trigger fires again the Boolean value will prevent the callout being made. Listing 4 - 31 shows the source code for this design pattern and figure 4 - 4 demonstrates the corresponding application flow.
Listing 4 - 31
Be aware that (unless built in) you will have no way of determining if a future callout has been made in an installed managed package. You thus cannot use the above design pattern to avoid the System.AsyncException in such a case.
Common System Utility Classes The Apex programming language has a number of system classes that handle common development tasks such as parsing XML or making HTTP call outs. These reduce the amount of boilerplate code you can expect to write, and in doing so speeds your development efforts. Here we will outline some of the most commonly used of these.
System Class A versatile class this is used for all the common system functions such as determining system time, killing and scheduling jobs, debugging, unit testing, resetting passwords and more43.
DOM Classes The Document Object Model (DOM) classes facilitate the creation and parsing of XML strings 44. Usually the DOM represents a nested tree of XML nodes. The XmlStream classes offer some low level support to the DOM classes45.
HTTP Classes This suite of classes presents the core functionality available in HTTP requests and responses46. All the typical features including request types, headers, contents, and status codes are available through these classes.
EncodingUtil Class A simple class used to encode and decode strings as URLs, Blobs or hexadecimal47.
Crypto Class Quite often used in conjunction with the EncodingUtil class, this class facilitates the creation of Message Authentication Codes (MAC), digests and signature through the use of standard algorithms such as AES, SHA and MD5 48. Furthermore it provides the ability to encrypt and decrypt information for secure transmission and internal security.
Test Class Used to setup test information such as faux Visualforce page references and to force asynchronous methods to run synchronously49.
Limit Class Since Governor Limit exceptions cannot be caught it is important to know how near a specific limit is within the running context50. This class provides a number of methods to not only retrieve how close you are to a limit within the current context, but also the maximum value of that limit (within the executing context).
Cookie Class This class allows server side access to any HTTP cookies that are relevant for the current domain51.
PageReference Class Used to retain a reference to an instantiation of a page (Visualforce or other), this class enables convenient access to the URL, parameters, header, cookies and content of the page in question52. PageReferences can be instantiated or - if they are Visualforce pages - fetched using the page name e.g. for a page called “MyPage” you could assign it’s value to a variable using PageReference pr = System.MyPage;
Message Class Use this class for collection data validation errors53. For example if you present your users with a form, several fields might require adherence to a pattern such as URLs. In this case your Apex code would validate the user input, and if it didn’t conform you would instantiate an error message and add it to the page.
Apex Triggers Triggers are common in most modern databases and are typically code units that are invoked before, during and/or after DML have taken place. Apex triggers are akin to these but use the Apex language for their syntax 54. In this way Apex triggers are associated with salesforce.com objects the same way that database triggers are “connected” to tables. Triggers are convenient and reduce risk in data consistency, which can be demonstrated with an example. Consider an application on a platform that has no access to triggers but still has the concept of data persistence. If it was required that for every record you insert, an audit record needs to be created, you would have to manually ensure that code existed to insert audit information after each insert action. If your code has 100 places where inserts might occur, you’d need 100 calls to insert the audit information. Imagine missing one insert! Imagine the testing involved! On the Force.com platform such a situation would simply require one Apex class that handled the audit inserts, and a trigger on each audited object that made calls to the Apex class. If you have 100 insert statements across 5 audited objects, you’d only need to maintain a few lines in 5 triggers and 1 Apex class; the bulk of your testing would run over the Apex class. So you’ve reduced your risk since triggers will always fire on DML operations and you’ve reduced redundancy in your code through Apex code reuse. That said, Apex triggers can be tricky especially when you have a number of them that run on different DML events and at different times. In summary triggers can be set to fire before or after the following DML operations: Insert Update Upsert Delete Undelete Merge There are also specific rules concerning which actions are available during particular trigger events and timings55; it is important to know when certain triggers fire, as well as where they fall within the greater order of things. Any object-record subjected to a DML operation will move through the following ordered events: 1. The original record is loaded from the database (or initialized for an insert statement) 2. The new record field values are loaded from the request and overwrite the old values 3. System validation occurs, such as verifying that all required fields have a non-null value, and running any user-defined validation rules 4. All before triggers execute 5. The record is saved to the database, but not yet committed 6. All after triggers execute 7. Assignment rules execute 8. Auto-response rules execute 9. Workflow rules execute 10. If there are workflow field updates, the record is updated again 11. If the record was updated with workflow field updates, before and after triggers fire one more time (and only one more time) 12. Escalation rules execute 13. All DML operations are committed to the database
14. Post-commit logic executes, such as sending email
You would be wise to keep the documents that detail the order of trigger execution close at hand as the rules are complex and not always intuitive. If you have before- and after- insert, update, upsert and delete triggers on the same object, each data row will be subject to their workings, the order of which will be key.
Syntax Trigger syntax is similar to that of Apex classes with the notable differences being the trigger definition and a number of context variables only available within a trigger. The declaration of a trigger adheres to the standards shown in listing 4 - 32.
Listing 4 - 32
In the above trigger_events is a comma-separated list of one or more of the following: before insert before update before delete after insert after update after delete after undelete Observe that there is no before undelete as there wouldn’t be any data available before the undelete operation has occurred. The context variables specific to triggers allow your application to determine what type of trigger is firing, whether the trigger is firing, the number of records in the trigger invocation as well as access to the old and new values (if appropriate) of the records moving through the trigger56.
Triggers always execute in bulk i.e. each trigger is passed a list of objects which are contained in Trigger.new, Trigger.old or both. It’s therefore important to design your trigger code realizing that anywhere from 1 to 200 records can be processed in a single transaction. Designing triggers thusly is called making them “bulk safe” and it’s essential to get into this habit early on or you will encounter issues down the road. Listing 4 - 33 demonstrates the usage of some trigger context variables in preventing Account names to be changed.
Listing 4 - 33
If this trigger were invoked via the insert DML command and any Account record had an error added during trigger execution the entire operation would fail although all “erroneous” records would be marked so. Using the Database.insert() method however you could specify that partial success was acceptable57. It’s also worth mentioning that the simple comparison functionality is purely for demonstration and a validation rule is probably more apt in a real world scenario. Trigger context variables also have a number of caveats, most of which are logical when given some thought 58. Some important considerations are: trigger.old and trigger.new cannot be used in DML operations. You can only change the value of objects through the trigger.new variable in before triggers. Changing in it after triggers has no meaning and will yield an error. trigger.old is read-only. trigger.new cannot be deleted.
Relationship lookup objects in triggers are null59. So a trigger on Child__c will have access to all fields available on this object including Child__c.Parent__c but it will not have access to Child__c.Parent__r.AnyField without querying that object. Salesforce.com does this to reduce the overhead involved when running data through triggers. Imagine the resource waste if they selected all related object data for every trigger execution!
There is no way to delete or deactiviate a trigger once deployed to a production Org. One workaround is to run your deployment in Eclipse from a sandbox (not the one you actually deployed the original code from) to production. During the deployment process, deselect everything and then check the box next to “Delete” for the unwanted trigger. Executing the deployment will delete the trigger.
Controlling Recursion It was previously shown how easy it is to create recursive loops with triggers and future calls. This type of infinite loop can occur just as easily if we take the future calls out of the equation60. A contrived example might involve a “reminder” Task being created for every Task that is inserted. Without a control structure the inserted reminder would itself trigger the same event and try to insert another reminder. This would continue ad infinitum. Avoiding this recursion is achieved much the same way as was shown with future calls. Listing 4 - 34 displays the code necessary to prevent the infinite looping.
Listing 4 - 34
Using the remindersCreated flag, your code can determine if a reminder has already been created and can deal with that situation appropriately.
Bulkifying Triggers Although Governor Limits are applied throughout the platform they tend to be a bit tighter if your Apex invocation begins within a trigger. It is therefore even more important to learn the coding patterns that will make your code more efficient, as well as those that are to be avoided. In the section on SOQL Governor Limits we showed the importance of fetching data upfront as opposed to executing queries within loops. A similar pattern is essential when coding triggers that are bulk safe. This ensures that the number of queries issued within a trigger is constant, and independent of the amount of data passing through the trigger. In the same way you will need to make sure that a constant number of DML operations are executed for each trigger invocation. We’ll build upon listing 4 - 14 to first illustrate the wrong way to write a trigger. Listing 4 - 35 details such an example.
Listing 4 - 35
Running 101 records (or 21 records if the entry point is a trigger) through this trigger would yield the same error as in listing 4 - 14, namely: System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AddOwnerColor: execution of BeforeInsert caused by: System.Exception: Too many SOQL queries: 101
Again you would get this error because you are violating the Governor Limit that restricts the number of SOQL queries you can issue. In this flawed design the number of queries is directly related to the amount of data moving through the trigger and can be remedied by fetching all the required data outside of a loop. As previously mentioned, in order to write bulk safe triggers it is critical that you understand and utilize sets and maps61. Sets are used to isolate distinct records, while maps are name-value pairs that hold the query results retrievable by record id. The correct way to bulkify this trigger is shown in listing 4 - 36 and is similar in many ways to listing 4 - 15.
Listing 4 - 36
When the above trigger fires, you initially create a set containing every distinct OwnerId for the records being processed. Then you query to find all of the User records for each OwnerId in the set. This returns a map with the UserId as the key and the User object as the value. You then iterate over the list of Accounts in the trigger, use the map’s get method to fetch the correct User object by its OwnerId and write the User’s favorite color into a custom field (Owner_Favorite_Color__c) on the Account. In using this idiom you will have guaranteed that no matter the number of records that are pushed through the trigger there will only be a single query executed.
Testing Triggers One of the most common questions asked by new developers is, “How do I test triggers?” Although unit testing (modular pieces of code that test your source code) will be detailed in a later section it makes sense to introduce some of the concepts here. In order to test the above trigger you’d need to contrive a set of scenarios which might cause the trigger to fire, as well as know the expect outcome of each of those scenarios. We’ve written one such unit test in listing 4 - 37.
Listing 4 - 37
The above code tests the situation in which a user with the Standard User profile owns a number of accounts, but a user with the Marketing User profile permissions performs the record insert. The first few blocks of code setup the User and Profile records. Next, 200 Account records are instantiated but not committed; then we’ve switched user context and inserted the records as the Marketing User. The last loop is used to check
that our assumption was correct i.e. the Owner_Favorite_Color__c field value on each Account should be the same as the Account owner’s Favorite_Color__c field value.
The unit test above contains lots of unfamiliar syntax that will be explained later. The fundamentals points to note here are that when testing triggers you should think about which situations might cause your trigger to fire, how you might setup test data to mock up these situations, and what results you’d expect from each.
Unit Testing This topic is another contender for “Most Discussed” on the Force.com Discussion Forums, and is a key component of robust, high-quality software output. Unit testing is not a new concept and is common in most modern programming languages. One important difference is that salesforce.com will not allow you to deploy code to production that has less than 75% unit test code coverage. The primary goal of unit testing is to isolate the smallest piece of testable code (called a unit) from the rest of the application and determine whether it behaves as expected in a number of situations. Each of these units would be tested independently before integrating them to test their interactions. Unit testing is highly effective (bugs are discovered early on) and by its very nature it reduces complexity and increases testing rigor. For example if you had created two units, which need to be integrated with one another, a defect might occur in any of the following: The first unit The second unit Both units The interaction between the units Any of the tests The easiest way to find a bug in this scenario would be to start with the granular code units. Once you’re sure the units are comprehensively tested you can confidently test their interaction. Unit tests are also code, and in most cases are units themselves (don’t worry; you won’t need to test them). On the Force.com platform unit tests are written using Apex, and a unit is largely considered to be an Apex class method, or (if they’re very simple) an Apex trigger. We’ve introduced the “What” and to some extent the “Why” of unit testing and the next burning question would typically be “How”. Most times asking this question will result in someone talking you through a working example, and while that is important we think that it’s necessary to step back and throw an analogy into the mix. Imagine that instead of building software you are coordinating the construction of a simple car. You have specialists working in teams to create each type of part e.g. the tires, brakes, chassis etc. It would be the responsibility of each team to test the parts that they manufacture i.e. the team making the tires would run tests for durability, balance, strength etc. They would do this by simulating real world situations that would make use of these parts in normal, and probably not so normal ways. Likewise each of the other teams would test their respective car parts in simulated situations relevant to whatever they made. Once all of the parts were tested and you were confident in their capacities you would start assembling the parts into more complex parts e.g. tires, rims and brakes, and apply further tests. After each successful testing-iteration you would integrate more parts until you finally had a entire car, and even then there would be some testing to do. It is much easier to test the parts of the car individually than it is to build the entire car, and then try to figure out what to test and how to abstract away the interdependencies. You can also be assured that you’ve tested the right situations, and that you’ve worked in a logical way instead of scrambling at the end trying to establish a testing methodology. If you consider that each initial car part is very simple then the tests that were initially performed would be considered analogous to unit testing. Everything beyond that would probably be considered integration and/or system testing and indirectly relies on the rigor and quality of the initial unit tests.
Running Unit Tests Unit tests do not run as part of your application execution processes but instead need to be invoked explicitly. There are a number of ways to run unit tests viz. from the browser, in the Eclipse IDE, via the Web Services API or with the Force.com Migration Tool 62. Each of these methods allows you to run your unit tests individually as well as executing them all at the same time. Since all of these features are well documented they will not be detailed in this book.
Syntax Although some syntax will be explained within the context of code examples there are some core keywords that are important from the start. It is possible to define unit test methods in the Apex class whose methods they are testing as well as in an Apex class of their own. The case for using a separate class is strong with the following being some of the key reasons: Keeps each class smaller and more manageable Separates responsibility of classes i.e. one application code class and one test code class
Although a VCS will help you merge code where developers’ work overlaps, keeping the test and application classes separate makes maintenance simpler Code contained in test classes is not counted against you 1MB Apex limit By moving the test code out of the class that it will test you remove the temptation to test private and protected methods. Methods with these modifiers shouldn’t be unit tested directly as that would reduce agility when reworking public methods.
isTest & testMethod Test methods defined in an application or a test class share the same method signature as is shown in Listing 4 - 38.
Listing 4 - 38
From this example you’ll notice that unit test methods are always static, use the testMethod keyword, take no arguments, and don’t have return types (void).
Test methods cannot be defined within triggers although you can often test a trigger by setting up test records, performing the required DML and checking for the expected results. To define your own test class is necessary to use the isTest annotation and the class must use the private access modifier as shown in listing 4 - 39.
Listing 4 - 39
Test.startTest() & Test.stopTest() You will often need to create tests that ensure that your code can handle large datasets. But one best practice proponent that we’ll discuss later is that you initialize your own datasets, so this setup process can consume some of the resources that you need to test for. Realizing this salesforce.com has made two methods available to you, Test.startTest() and Test.stopTest(). With the correct entry points, code that is executed between these methods is subject to a “fresh” set of Governor Limits; this allows you to prepare your test data within the unit test prior to testing. The limits that are applied will depend on the “entry point” defined between these methods. It’s important to know that you’ll need to fire a trigger or method between these methods to give the running unit test an execution context. Listing 4 – 40 shows that you can execute code between these methods that will still consume the unit tests resources.
Listing 4 - 40
This test method will fail as it’s exceeded the Governor Limit for DML rows with the following profiling information: Number of SOQL queries: 0 out of 100 Number of query rows: 0 out of 500 Number of SOSL queries: 0 out of 20 Number of DML statements: 2 out of 100 Number of DML rows: 600 out of 500 ******* CLOSE TO LIMIT Number of script statements: 1207 out of 200000 Maximum heap size: 0 out of 1500000 Number of callouts: 0 out of 10 Number of Email Invocations: 0 out of 10 Number of fields describes: 0 out of 10 Number of record type describes: 0 out of 10 Number of child relationships describes: 0 out of 10 Number of picklist describes: 0 out of 10 Number of future calls: 0 out of 10 Number of find similar calls: 0 out of 10 Number of System.runAs() invocations: 0 out of 20 The “fresh” limits haven’t been applied as we have told the test what context to run them in. Now consider the code in Listing 4 – 41.
Listing 4 - 41
This code executes without error and notice below that you now have two sets of profiling information, one for the unit test (with the appropriate limits) and another for the performDml method call (with Apex Class limits).
An important consideration is that you can only use Test.startTest() and Test.stopTest() once within a unit test.
System.RunAs() In a system that has various levels of access to data records it important to test that security has been correctly applied; you might need to ensure that users with a certain level of privilege are the only ones that can create records of a certain type. For this purpose salesforce.com has provided the System.runAs() method.
Your Apex code usually runs in system mode i.e. record-level and functional restrictions are not taken into account. You can change this by using the with sharing keyword. Using System.runAs() lets you choose the running user-context, whether it is for a new or existing user. In Listing 4 – 38 it was shown how to use this method, which would typically require the following: 1. Create a new Profile and create a new User that uses this Profile, or select a current system User 2. Using this User and a System.runAs() block execute the code in question. When using this method you should be aware that: You can next System.runAs() calls but only 20 calls are allowed in a single transaction Creating Users within a System.RunAs() doesn’t require that you have available user licenses The original system context is started again after the System.runAs() method completes
Setting an Example There are a number of programming situations that require the application of a specific testing approach. It’s important to understand when each might be applied as well as what each approach is designed to achieve.
Testing Essentials Continuing the analogy from earlier, assume you’re building an application that models a car, and in doing so you’ve created a class called Tire. Listing 4 - 42 shows what such a class might look like.
Listing 4 - 42
Essentially we’ve explored the property of tire pressure and some actions we might want to expose as methods. From the code you can see that a Tire has an initial pressure and a maximum pressure, and can be inflated or deflated. There are rules around inflation and deflation, and if a Tire is overfilled it might burst i.e. an OverfilledException is thrown. As a rule you need at least 3 test methods for this class, one for each of the public methods and another for the constructor.
You might think that testing such a simple constructor is unnecessary but the simple act of setting up the unit test will aid in the design process. Later when other developers add functionality to the constructor they will be guided by the sturdy foundation you will have laid. After creating such a class you need to consider how you might test each of these methods. For the constructor the test is simple, pass in an argument and check that the value of the member variable pressure is the same as that of argument. For the inflate method the obvious situations to test are inflating the Tire within the maximum range, and filling it too much. Other tests you might want to perform are filling the Tire by zero units, or filling it to exactly the maximum pressure. These last two tests are called border case tests and are important as developers often make logical errors on these fringes. Testing the deflate method is similar to similar to testing inflate. You’ll want to test deflating the Tire by a small amount that results in some pressure being left, deflating the Tire by more units of pressure than it contains and deflating it by zero units.
It was mentioned before that salesforce.com requires at least 75% unit test code coverage but what does this mean? In short you’ll need at least 75% of your code (excluding unit tests) to be executed by code that is invoke from within a unit test. For example in the inflate method there are three lines of code that could be executed; the line that throws the exception will only be run by a test method if the exact conditions of the surrounding if-statement are met. If the condition isn’t met only 2 out of 3 lines will be executed when the method is called giving a code coverage rate of 66%. Now that you know what you need to test, the next step is to figure out how to test. Before we discuss the unit test code it’s worthwhile examining some of the best practices63 in this regard: For all conditional logic you need to execute all code branches e.g. in the above deflate method you need to execute both the if and the else branches of the method body Execute both positive and negative tests64 i.e. test your methods within their thresholds, but also force errors to occur Don’t just catch exceptions, handle them properly i.e. send an email or “log” the error Always check the results of your code execution using System.assert Each class method should have at least one unit test method Comment your tests in detail stating what you’re testing and the expected outcome Cover as many lines of code as you can, although it’s not necessarily best practice to achieve 100% If a bug is uncovered write a unit test specifically for that bug to ensure that it isn’t accidentally reintroduced Each unit test should have a neatly defined test criterion and should only test one aspect of your code at a time Unit test should function independently of each other
On the last point you might find that you’ve hardcoded some piece of information - such as a URL - into your application code and this needs to change from environment to environment. In this case consider replacing this value a Custom Setting (as mentioned in chapter 2). With these points in mind we’ve created the unit tests that cover the important scenarios with regards to the Tire class. Listing 4 - 43 contains the unit test code.
Listing 4 - 43
We’ve added a positive and negative unit test for each method including the class constructor although there are other negative tests you could add e.g. passing method parameters that are null. You will find that in sufficiently complex methods you could write hundreds of unit tests to cover every possible scenario although this is not always necessary; instead test to a level that makes you confident in your code and if you do find bugs, add a test to explicitly cover that section of code.
A high rate of code coverage and thorough unit testing are not necessarily the same thing. It’s quite easy to achieve high code coverage rates since all you need to do is execute 75% of the application code. However a thorough set of unit tests might run over the same code many times, testing granular aspects of the functionality in various ways. The distinction and combination of these facets is vital, and if your unit tests are thorough it is likely that you will haven’t more than sufficient code coverage.
Data Initialization for Unit Tests The translation of the car parts analogy into application code does well as an introduction to the initial concepts of unit testing. To advance your ability to effectively test code it is now important to introduce the best practices when testing methods that work with object record data. Consider the simple trigger in Listing 4 - 44. This after update trigger adds a Task to an updated Account if the Industry is “Software Development”.
Listing 4 - 44
One obvious positive test case is to ensure that the Task record is correctly created for such Accounts. To do this you need to mimic the way your application would initiate the firing of this trigger, and then check the end result. There are two mistakes that developers commonly make in this regard and the unit test code in Listing 4 - 45 demonstrates both of them.
Listing 4 - 45
If you have the correct data in the environment that you’re coding in this test will pass; deploy it to an environment where there is no data, or there is the wrong type of data and it will fail. This is because you’re populating the Account variable with data selected from your objects and are thus dependent on the environment data and will most likely fail on deployment. The second issue here is that you should always test data-driven code (and especially triggers) in bulk working with as many test records as possible. Although the trigger in Listing 4 - 44 is bulk safe the unit test should double-check this (and this type of test will catch any future changes that make the trigger bulk sensitive). Knowing these two potential design flaws you can add the following points to your testing best practices list:
Each unit test should be portable between environments i.e. they can be deployed - without alteration - to DE, sandboxes or production Orgs and still execute successfully. They should therefore not rely on record Ids, data, or other environment information (such as URLs). As far as possible unit tests should operate in bulk Listing 4 - 46 shows the improved unit test.
Listing 4 - 46
We are asserting the same requirement in this unit test, but instead of relying on existing data we have setup our own records initially. We’ve had to insert the records first, and then perform an update as we are testing an after update trigger. We’ve also used 200 records in this test to ensure that the trigger is bulk safe. It is not necessary to write another test for the case of a single DML record as bulk safe code should work for any number of records (including zero).
Data created within the context of a unit test is only available for the lifetime of that test. It is also only available to that specific test. You can even delete non-test data within the context of a test without affecting that same data outside of the test i.e. it is not really deleted.
It is often the case that a number of unit tests share the same setup data, and it therefore makes sense to move the data initialization into it’s own method(s). For example in the unit test above we might have created methods to “initialize” account records as is shown in Listing 4 - 47.
Listing 4 - 47
Any other unit tests for this trigger can quickly get access to a list of Account objects. Note that this method has to be static in order to be used within the test method.
Further Examples In addition to the core testing principles explored in this section there are a number of technology specific examples in the Force.com documentation. We highly recommend that you bookmark the examples on testing Visualforce controllers and Apex callouts 65, Virtual Callout testing66, SOSL testing67 and bulk testing68.
Additional Considerations Governor Limits Governor Limits in the context of unit tests are typically much tighter than for code that executes in other contexts. It is therefore key that your test code is bulk aware, or if you are testing for limits then you must use the Force.com provided Limit class to interrogate limit values.
Some Limitations You cannot send emails or make web service callouts from unit test code. There are therefore two considerations here: 1. How do you test methods that make use of either of these technologies? 2. How do you test the actual email or callout? The answer to the first question is easy for sending emails; the sendEmail method will just be “skipped”. For web service call outs it’s considered best practice to reduce the method that contains the callout to as few a lines as possible. You would then skip the callout method but test as much of the rest of your code as possible. To answer the second question you would need to employ integration testing as opposed to unit testing. For email sending you might outline several scenarios that vary the content of the email and manufacture a process to achieve each email type. With a web service call you would typically use external tools or setup a test endpoint to receive the method calls, testing the call content and returning appropriate responses.
Test Driven Development Test Driven Development (TDD) is a development process that works within very short cycles. The premise here is that you write your unit tests first knowing what functionality you expect to deliver with your application. For example if you are asked to write a method that returns the 10 most recently created Contact records before you write the method you know that the following might occur: No records are returned 10 records are returned Somewhere between 0 and 10 records are returned You could write unit tests to examine each of these situations. Obviously the method doesn’t yet exist so the tests will fail, but then you go about writing application code that forces the tests to pass. Once that is done the code is reviewed and optimized, and the tests are run again to ensure they still pass. This process is illustrated in Figure 4 - 6. Test Driven Development is an incredible advancement in software development. It ensures that tests aren’t created as an after thought, but that they form a type of documentation describing the application components that you are building. It also forces developers to think through the
design process in greater detail saving much time (in the form of code refactoring) later on. Although TDD results in writing more tests, it has been found that the total development time is shorter since fewer defects are introduced during the development process.
Scheduling Apex In nearly any company there will be a situation where a particular piece of code needs to run at certain intervals over a specified period. This is typical when batch operations, or timed data updates are required. Salesforce.com provides two methods of scheduling Apex69. The first method is simple but less flexible and simply requires you to click the “Schedule Apex” button on the screen shown in Figure 4 - 7. You can navigate to this screen by clicking Setup -> Developer -> Apex Classes.
You’ll be presented with a simple interface that let’s you choose a class and a restricted execution schedule i.e. the most often a class can be set to run is once a day. While this might be sufficient some of the time you’ll often need more flexibility than present here. The second option requires some development but is well documented and quite easy to use. For this approach you will typically need 3 classes or pieces of code: A class that implements the Schedulable interface. In doing this you will have to implement the execute method; this allows you to schedule the running of said class A method or piece of code that is invoked from within the execute method above. This will perform the scheduled work A call to the System.schedule method; this will dictate the execution schedule as well as the code that should be invoked. You can even make this call once off in an anonymous block Listing 4 - 48 is a simple example that demonstrates all 3 of the above. You can get more detailed examples from the Force.com blog or in the Force.com Apex Code Developer’s Guide.
Listing 4 - 48
The System.schedule method accepts three parameters. The first parameter is the name or description of the job you’re scheduling. The second is a String value representing the schedule timing and uses the following format: Seconds Minutes Hours Day_of_month Month Day_of_week optional_year The third parameter is the class you’d like to execute. Figure 4 - 8 shows how to use the combination of the two classes above to schedule an Apex job.
The syntax used in the schedule parameter takes some time to get used to so you should bookmark the documentation70. Note that we have wrapped the call to the System.schedule method in our own static method making it accessible from Visualforce pages too. The stop method above simply stops the job with the passed job Id. To see the status of a scheduled job you’ll need to log into your Org and click Setup -> Monitoring -> Scheduled Jobs. From here you can also alter the schedule or delete the job. A few things to be aware of when working with the Apex Scheduler are: Be wary of scheduling jobs from triggers. Only 10 classes can be scheduled at a time; if your trigger performs any bulk operations that result in a violation of this constraint you will receive an error Jobs are added to a queue but the actual execution time varies depending on available resources The users time zone will be used as the schedule basis Callouts made from scheduled jobs must use the @future annotation Do as much of the processing as possible before calling the execute method
Batch Apex Governor Limits are a good way of keeping all tenants on the Force.com platform in check, but sometimes you’ll have to work with massive sets of data e.g. data cleansing activities or archiving. Salesforce.com has created Batch Apex exactly for this purpose71. Similarly to Scheduled Apex you need to implement a specific interface in order to use the feature. The interface in question is Database.Batchable and requires that the following 3 methods be implemented: start execute finish Listing 4 - 49 is an example implementation of the required interface and methods.
Listing 4 - 49
The start method is called first and gathers all the records you’d like to work with. Notice that the method can return either of the following:
Database.QueryLocator reference. Use this when the scope of your batch is a simple SOQL query. Note that your Governor Limit here is 50 million records An Iterable. Used if the scope of your job is complex, or if you want to define your own process of iterating through the list items. Normal Governor Limits are enforced in this case The start method, as well as the other two, each accepts a Database.BatchableContext object as an argument; it is this object that is used to track the progress of the batch processing. The execute method does the processing for each batch that it is passed. It accepts as it’s parameters the Database.Batchable context object as mentioned previously and a list of sObjects or parameterized types. If you have chosen to work with Database.QueryLocator then the list returned by the start method should be used as this second parameter. The finish method, as its name implies, will be used for any post processing activities such as sending emails.
To allow callouts from your batch class you’ll also need to implement the Database.AllowsCallouts interface. If you’d like to maintain state information across batches you’ll need to implement the Database.Stateful interface. Once you’ve created your class you need a way to execute the batch and for that you’d use the Database.executeBatch method. Listing 4 - 50 shows such an example.
Listing 4 - 50
Some important considerations are:
Each batch is discrete in its execution i.e. if the data you submit is broken into 2 batches and execution fails during batch 2, all changes made in batch 1 will still be persisted. As with Scheduled Apex it’s important to be cautious when invoking Batch Apex from triggers. Only 5 batches can be queued or running at any one time. Calling the Database.executeBatch method adds the process to the queue but actual execution will only begin when system resources become available Batch processes run asynchronously so you’ll need to use the Test.startTest and Test.stopTest methods in unit tests to ensure that the test batches complete before asserting the results You can only invoke the execute method once within a unit test. You need to limit the scope of the batched records so that you do not violate this limit You can only implement one callout in each start, execute and finish method. Methods that are declared as future cannot be called from a class that implements the Database.Batchable interface. Nor can future methods be called from batch Apex methods. The Database.executeBatch method cannot be called from any batch Apex method. For every batch that runs a record is created in the AsyncApexJob object. Querying this object will give you information about the job’s status, number of errors, progress and submitter All methods must be declared using the global access modifier. You can also schedule batches to run using Scheduled Apex. Have a look through the official documentation72 for more examples and a comprehensive syntax description.
Governor Limits Although we’ve mentioned Governor Limits and best practices in avoiding some of them it’s time to step back and go into a bit more detail about why they exist and how they work. We’ve explored some of the detail regarding why such limits exist noting that in a shared environment it’s key that each community member doesn’t hog memory, processor or database resources 73. This also goes a long way towards ensuring the scalability of the platform, as the resource consumption is defined and therefore predictable. Determining how a limit is calculated is up to 3 factors: The Apex entry point The number of data rows responsible for the invocation The type of Governor Limit
Apex Entry Points The Apex entry point can be described as the application area where the code was first invoked. For example if a web services method is called and this in turn causes a trigger to fire the Apex entry point is the web service context. Apex can be invoked in the following ways: Apex Trigger Apex standalone class Apex web service Anonymous block Visualforce page controller (or extension) Unit Tests The official documentation describes the limits based on entry point in detail74. As an example consider a class that is called from a trigger as well as a Visualforce page controller. When invoked by the controller the class can issue up to 100 SOQL queries. If it is called from a trigger however it can only issue 20. It’s essential to know that any other code or triggers that run based on the entry point invocation will contribute to total consumer resources i.e. if a web service is called and in turn fires a trigger as well as calling a method in a utility class, all code and data accessed through the trigger and utility class will contribute towards the Governor Limit.
Data Volume Some Governor Limits scale with the amount of data being processed. For example the limit on DML rows when the entry point is a trigger is 100. If you were to pass the trigger batches of 10 rows the limit becomes 1000; if your batches are 100 records in size the limit is 10,000. Effectively this limit is the batch size multiplied by the listed Governor Limit.
When reworking very large datasets - during paginating for example - you can often achieve much faster results by using client-side languages such as Flash or JavaScript75 to perform any manipulations. This has the added advantage of skipping any concerned Governor Limit impositions.
Governor Limit Type Different limit types have different values but the difference between the types isn’t always obvious to beginners. For example, the limit for “Total number of SOQL queries issued” for triggers is 20, but the limit for “Total number of records retrieved by SOQL queries” is 1000 (and this scales with batch size). The difference here is that the first limit concerns how many times the executing code calls a “SELECT value FROM Object” statement, whereas the second limit governs how many records all of the statements collaboratively fetch.
Executing Code Asynchronously Previously we have mentioned that it is advantageous to use the future annotation to split off an asynchronous execution from the current users context to improve performance. We’ve also lightly discussed how this can be used to step around certain Governor Limits. Exploring this in a bit more detail, you’d typically invoke code asynchronously when there is a large amount of processing to undertake and you don’t want to force the users to wait for it to complete. This approach is also popular when avoiding certain Governor Limits76. When invoking such code it forks from the executing context (which is synchronous) and moves into a transaction of it’s own. By doing this you save the user time, and that thread starts it’s Governor Limits afresh; the limits applied are those specific to Visualforce controller or web service entry point limits.
Testing As mentioned in the section on unit testing, it is key that you test your code with sufficiently large datasets. Always test triggers, for example, with at least 200 records to test the appropriate limits.
Debugging Apex Earlier in the chapter we detailed Anonymous Blocks, the System Log Console 77 and the Debug Logs78. Each of these can be used to test your application, from small sections of code to fully features application areas. It can often take time to understand79 the output of the logs, but you can set filters80 on each of these tools to tailor the verbosity of their output. What we haven’t covered yet is how to populate these logs with data that you think is important when debugging. Although we’ve discussed the Force.com System class before we have not detailed how to use it when bug hunting. System.Debug is an overloaded method that accepts 1 String parameter (the message to output), 1 enumerated parameter (a logging level), or two parameters (the message to output as well as the enumerated logging level). The syntax for each is shown in Listing 4 - 51.
Listing 4 - 51 // Set the logging level. Similar to using the debug log filters
The method with a single parameter implicitly sets the logging level to debug. Notice how the logging levels are correlated to the filter options when debugging? Using logging levels, you control what output is seen when a certain log filter is applied. Logging levels obey the following hierarchy (from lowest to highest): ERROR WARN INFO DEBUG FINE FINER FINEST That is, any debug messages set with a level of ERROR will always appear in the logs, but messages set with a logging level of FINEST are only output if the debug filter is set to “Finest”.
While calls to System.debug are not counted for unit test code coverage they do each count as a line against the Scripted Statements Governor Limit.
The View With the Model and Controller parts of MVC out of the way it’s time to detail the View. The View on the Force.com platform can be created in one of two ways; the page layouts seen in chapter 2 or highly customizable Visualforce pages. Visualforce is a component-based framework for the Force.com platform81. It is uses an XML tag-based language to build dynamic components and pages that are rendered as HTML and JavaScript at runtime. The language includes a large, well-documented component library as well as the ability to create your own components. Standard and custom components include a number of convenient functions familiar in most front-end languages, as well as baked-in AJAX functionality. Additionally you can include any amount of HTML and JavaScript in Visualforce pages allowing for the creation of sophisticated, modern user interfaces. These
interfaces can also be context aware in that they render differently when viewed on different devices such as slate computers or mobile devices.
The System Architecture Figure 4 - 9 shows the Visualforce system architecture for developers while Figure 4 - 10 demonstrates the same system for users.
When developing Visualforce pages the source code is sent to the application server for compilation (on every save by default). Here it is checked for errors, and if none exist it passes the compiled page code to the metadata store as well as to the page renderer. The renderer parses the Visualforce code outputting the resulting HTML page.
End users would skip the compilation step necessary with developers. Instead a page request is issued to an application server, which is passed along to the metadata store. From here the stored page definition is passed to the page renderer, which outputs the resultant HTML page. As mentioned previously the components of an MVC framework are decoupled in their interdependence but it is necessary to bind them together to achieve the desired functionality. The tie between view and model here is achieved through the controller, which also provides the core application logic. These controllers take a number of forms namely: The standard object controllers (these are automatically generated) Apex controller extensions with object standard controllers Custom controllers written in the Apex programming language Knowing when to use each is largely based on experience but the following rules go some way towards assisting in the decision-making: Standard controllers on objects functionality such as data views, data creation, data modification and data deletion. Since they are automatically generated you do not need to write any Apex code, create any unit tests or undertake any of the risk associated with writing your own code. Use this controller type when your intention is to display and edit information specific to an object and any of its related objects
Use controller extensions when your pages need to be object-specific but there are additional features required that couldn’t be exposed with standard controllers alone. Controller extensions require a constructor that accepts as a parameter the standard controller that it is extending. Custom controllers will be required on pages that aren’t tightly associated with an object, or if the page requires technically complex functionality. They are also useful when creating mashups by integrating with third-party technologies such as Twitter or Google Docs.
MVC: Bringing it all Together You are finally in a position to understand how Apex, Objects and Visualforce all come together to form a system based on the MVC design pattern.82 Although Visualforce syntax will be discussed later it’s prudent to analyze the code in listing 4 - 52 to gain an understanding of how these components synergize. The code listed here is a complete Visualforce page that uses a standard controller.
Listing 4 - 52
Visiting this page in a browser would render an HTML document as shown in Figure 4 11.
Notice how the model, view and controller come together to create a page that allows you to manipulated persisted information. From the code listing, the Account object’s standard controller fulfills the “controller” role. The ability to fetch object field values as well as the save action all fall into the controllers domain. The Account object itself, along with the data it holds is the “model” in this case, and the Visualforce markup (including components) forms the “view”.
When starting out with Visualforce development it will be highly advantageous if you use the Development Mode Footer mentioned earlier. In using this environment all of your tools (including reference materials) are in the same convenient location, and you’ll have access to
Visualforce code completion as well as convenient functionality e.g. it will provide a hotlink to create a controller extension if you reference one that does not yet exist. Additionally every time you save the results of your coding efforts are present in the same window giving you instant results.
When would you use Visualforce? Standard pages are good for creating, displaying and editing data stored in standard or custom objects. You can quickly manipulate the field layouts with the layout editor, but there will be times when you need an additional field on the page that doesn’t need to be associated with an object. Or perhaps you’d like to include, for instance, visually complex dashboards in your standard pages. These situations call for the use of Visualforce pages, although it isn’t necessarily obvious up front. The following list will aid you when making such decisions: Upon clicking a button on a standard page, such as save or new, you’d like the user to be redirected to a bespoke page. This page would be Visualforce and you would override the standard functionality on the object in question to redirect to this page. Note that if appropriate, object information such as the Id will be passed to your page as request parameters Customizing the detail tab for an object would require the creation of a Visualforce page which would override the standard tab page In order to create tabs that aren’t directly associated with an object you can create custom Visualforce tabs To embed custom functionality in standard pages you can create Visualforce pages and add them to the standard page detail layouts inline Creating custom components using third party technologies - such as Google Visualizations requires the use of Visualforce Visualforce pages can be used to create wizards for custom processes or workflows You will use Visualforce pages when building public facing Force.com Sites
Advantages of Using Visualforce In addition to Visualforce fitting neatly into the MVC design pattern there are a number of other gains to be made, both by developers and platform users. User-friendly development environment. The in-page IDE is an example of developer web applications. It’s intuitive for beginners and works well. When you’re more comfortable with the Force.com platform you’ll naturally start working in Eclipse which itself is superb tool Easy integration with just about any other technology that can be embedded in or work alongside HTML Neat, cross-browser compliant UI components Highly configurable and intelligent component library. For example, instead of defining field types for email address, select lists and dates you can use one intelligent component which will recognized the field type and apply the appropriate display style and functionality Visualforce pages are hosted on the Force.com platform making their performance just as good as that of standard pages, no matter the volume of data Upgrades are automated and backward compatible. You will never have to change any code, or worry about compatibility issues
Visualforce Controllers Controllers provide business logic for your Force.com application e.g. what data to present in a page or which action to perform when a button is clicked. There are several types of controllers each powerful when used appropriately. Determining when to use each is best taught through demonstration. If we were to rank all controller types in increasing order of complexity and flexibility the list would be: Standard Controllers (including list controllers) Controller Extensions Custom Controllers You can use this - to some degree - to guide you in making the choice of when to use each controller type. Of course it will take some experience with the platform to learn what Force.com defines as complex.
Standard Controllers Standard Controllers are automatically generated for each standard and custom object that can be queried using the Force.com API83. They contain the same logic and functionality found in standard pages using the Save method of a standard controller equates to the same as clicking Save in a standard page. Any page that uses a standard controller will automatically inherit that objects standard page styles.
To help you understand some of the upcoming topics please consider Listing 4 - 53.
Listing 4 - 53
Note that any code between the symbols are comments and will be ignored (and in fact stripped out) by the compiler. In the first line of the code we are opening the page tag and setting the standardController attribute equal to Account. This is how you associate an object’s standard controller with a Visualforce page. This means that you can now access any of the object’s available fields as well as any standard controller methods. Further on we’ve used {!account.name} to retrieve and display the value of the name field for the object record in question. Near the end of the code we’ve used a commandButton component that makes a call to a save function by using the syntax {!save}. As the method name suggests this will save any record changes.
Even though we’ve used the same component (inputField) for both the Account name and industry fields, when the page loads the name field is rendered as a text input while the industry field is rendered as a list of selections. This intelligent feature is a big time saver, but be aware that it will only work with objects fields i.e. using a controller property declared as a data type that isn’t an object will only ever result in the field being rendered as a text input. This page can be used in two contexts, either record editing or record creation. If the above page were named MyPage then you would request the page using the following URL: https://[salesforce_domain]/apex/MyPage All you would need to do is enter a value in the name field, click the Save button and a new Account record would be created. In order to use this page for editing, the Id of a record needs to be specified as a URL parameter. You would need to use: https://[salesforce_domain]/apex/MyPage?id=[Account Record id] Take note that the Id specified must refer to an object record type that is the same as the object standard controller type specified in the page84 i.e. for MyPage above only a valid Account record Id would result in a properly rendered page.
We’ve used the syntax {!account.field_name} to refer to Account record fields for both read and write operations. This takes some getting used to but it results in concise, intuitive code. You will have gathered by now the {![action | object.field_name]} syntax is used to refer to controller variables and methods. Not only can you use this syntax to work with standard controller object fields, but you can also traverse relationships quickly; for child-to-parent relationships you can interrogate up to five children deep e.g. a page that uses the Contact object standard controller you can use {! contact.account.owner.firstname} validly. For parent-to-child relationships you can traverse one level e.g. {!account.contacts} would return a list of contacts associated with the Account that is in context.
Standard List Controllers Standard List Controllers are used to create Visualforce pages that display and act on sets of data. Examples of standard pages that use list controllers are list pages, related lists, and mass action pages. Standard List Controllers can be used with most, but not all objects. The following objects are permissible: Account Asset Campaign Case Contact Contract Idea Lead Opportunity Order Product2 Solution User Custom objects In order to specify that a page uses a list controller and the attribute recordSetVar is required in the page component declaration. Such a page is shown in
Listing 4 - 54
The code is commented appropriately but notice how we have declared a recordSetVar in the page element and used this later in a pageBlockTable element to iterate over each item in the list. Here you can see that it’s not only possible to access each list item but you can also filter what is seen by using a combination of the {! filterId} and {!listviewoptions} particular to Standard List Controllers. By combining all of these list controller features we’ve very quickly created a page that is easily customizable and serves as a filterable view and mass update screen. We have named this page AccountListPage and access it by typing https:// [salesforce_domain]/apex/AccountListPage into our browser. The rendered
page is displayed in Figure 4 - 12.
In addition to the two methods above, there are other actions available to specific components when using Standard List Controllers85 that control save-behavior and list navigation.
Another notable component in this page is pageMessages. If any standard or validation errors occur on the page they will automatically be displayed in the position of this tag. This component is available for all controller types. Creating list pages is obviously quite simple but you’ll often want to navigate to such a page from one of the standard object pages86. In this case all you’ll need to do is specify that the custom button that is added to your standard page have a Display Type of List Button, and on your list page use the {!selected} expression to access the record collection. The following considerations are important when working with Standard Set Controllers: Only 10,000 records can be returned by a list controller If no filter is specified then the last used filter for the object is used Records sort on the first column of data You can traverse relationships in the same way and to the same degree as with Standard Controllers Tabs can be overridden with Standard List Controller pages in the same way as with Standard Controllers
Controller Extensions There is a lot of overlap in the detail of Controller Extensions and Custom Controllers although the former serve as a neat introduction to the later. Each are implemented using the Apex programming language and have all of the language features available to them. The dividing line between the two is in the way each is “initialized” and the situations that make each appropriate to use. Controller Extensions are used to augment the functionality provided by Standard or Custom Controllers. Standard Controllers have a number of valuable features so if your aim is to add a few small actions (such as a web service call) to an otherwise simple page you can create a Controller Extension and add it to the page. You might consider creating Custom Controller extensions when you have functionality that you need to reuse in a number of areas and that functionality can be neatly packaged into an extension.
It is of the utmost importance that you remember that Custom Controllers and Controller Extensions operate in system mode i.e. they ignore profile-based permission and field-level security. To force adherence to a users permissions and security within these classes you must declare them using the with sharing keywords. Strictly speaking, a Controller Extension is any class that has at least one constructor that accepts a single argument of either ApexPages.StandardController or CustomControllerClass where CustomControllerClass is a class that you’ve defined as a page controller.
Do not define Controller Extension methods with the same name as any of the Standard Controller actions e.g. save. The page will not be able to determine which controller method you wish to call (would you?). As of the current version it will favor the Standard Controller method. Listing 4 - 55 shows the controller extension and Visualforce page code.
Listing 4 - 55
The extension source code demonstrates how to retrieve the object record from the controller object. Your extension then has access to the object that the standard controller is working with. Looking at the code for the page you can see that it’s possible to refer to all the functionality of the Standard Controller as well as that of the Controller Extension.
Controller Extensions can only reference object fields that are used in the page. For example, if the above Controller Extension tried to reference the createdDate field of the Contact object record we would receive an error message saying SObject row was retrieved via SOQL without querying the requested field: Contact.CreatedDate. To use object fields in Controller Extensions that aren’t in your page you’ll need to fetch them with an SOQL query, or include them in an inputHidden component in your Visualforce page. It is possible to add more than 1 controller extension to a page. This is achieved by comma-separating the list of extensions like so, extensions=“Ext1, Ext2”. If two or more extensions have methods that share the same name, preference is given to the first extension in the list. Be aware of the following considerations when building Controller Extensions (and Custom Controllers): DML is not allowed in getters (any method whose name starts with “get”), setters (any method whose name starts with “set”) or class constructors
The future annotation is not allow in getters, setters or class constructors Primitive Apex data types are passed by value. Lists and non-primitive data types are passed by reference87 You cannot predict the order in which methods and variables are processed in Custom Controllers or Controller Extensions. If a method relies on the execution of other code be sure to include it in the constructor or call it directly from your method
Custom List Controllers This type of controller has much in common with both Standard List Controllers and Controller Extensions, most of which has already been covered88. To use Custom List Controllers as Custom Controllers ensure that at least one method that works with the ApexPages.StandardSetController object. You can tailor this object to iterate over custom sets. If you’d like to integrate a Custom List Controller with a Standard Controller you’ll need to include it in your page as an extension. To use it as a Custom List Extension your class needs to accept an ApexPages.StandardSetController argument in it’s constructor instead of the ApexPages.StandardController.
Custom Controllers When business requirements demand a high level of complexity you should consider using Custom Controllers89. These controllers are used to completely implement business logic, integration and data activities required in Visualforce pages. They are the most flexible of all the controllers, but are often (necessarily) involved and require you to consider testing and security in their designs. To designate an Apex class as a Custom Controller it is necessary that it have at least 1 constructor that has zero arguments 90. Listing 4 - 56 outlines the source code of a simple Custom Controller.
Listing 4 - 56
The if-statement in the zero-argument constructor checks for a request parameter called “Id”. If it finds a value it fetches the record with that Id from the database. If the parameter has no value it instantiates a new Account object. In this way we have created a controller that can be used to either edit or create new Account records. The page that uses this controller can be seen in Listing 4 - 57.
Listing 4 - 57
The notable part of this page is the page component’s controller attribute. This instructs the page to use the specified Custom Controller.
Force.com projects do not have namespaces so it is necessary to use naming conventions to organize your code effectively. In our own projects we often use [name_of_project] [class_description] [‘Controller’|’Ext’].cls to organise our classes. So if we were working on an Answers project and we created a controller class used to edit and save Answer records we’d name it AnswersEditController.cls. It is worth noting that the considerations listed previously for Controller Extensions also hold true for Custom Controllers.
Controller Methods Controller and extension methods that are directly accessible in Visualforce pages can fall into the following categories: Getter Setter Apex Property Action Getters and setters expose and relay data between a page and controller whilst action methods are use to encapsulate and execute business logic as well as control navigation on page events91. Properties are similar to getter and setter methods although their syntax is quite different.
Getters & Setters Getters are methods that pass controller values to Visualforce pages. For any controller value to be used in a page, even if it isn’t display, a getter method is required. Methods of this type are required to have a name that starts with “get”, and must have a return type. When calling a getter within a Visualforce page it is necessary to omit the “get” part of the method name. For example a method declared with the name getName would be referenced in the page as {!name}. Setter methods perform nearly the opposite function of getters. They pass user-specified or calculated values from the Visualforce page to the controller. It is guaranteed that setter methods will be called before action methods are executed. It is not required that you supply a setter methods for each getter listed in your controller. For those getters that do have an partnered setter method i.e. the setter method for getName would be called setName, the {!name} syntax will call the getter on page load (or AJAX refresh), and it will call the setter on form submission. Note that setter method names must start with “set”.
Apex Properties Properties are conceptually somewhere between variables and getter/setter methods92. In Listing 4 - 56 for example we’ve denoted a property with a get and set accessor on the account variable. Here the property serves as shorthand for both the getter and setter and a Visualforce page can work with the variable using the same {! account.field_name} notation.
Action Methods These method types are the event handlers for buttons, JavaScript events, page loads etc. Their return type is either void or a PageReference object with the former resulting in a page refresh. Thus action methods often result in navigation to a page, even if it’s the page the event is initiated from. In Listing 4 - 58 we’ve defined an action attribute for the commandButton component. The value of this attribute is set to {!save} ; this means that when the button is clicked a method called save will be invoked in the page’s Custom Controller. The following components support the action attribute:
commandButton - creates a button that calls an action commandLink - creates a link that calls an action actionPoller - periodically calls an action actionSupport - makes an event (such as onclick or onmouseover) on another named component call an action actionFunction - defines a new JavaScript function that calls an action page - calls an action when the page is loaded Salesforce.com has also simplified the use of AJAX for partial pages refreshes. To demonstrate this we’ve modified the source code from previous code listing as shown in Listing 4 - 58.
Listing 4 - 58
We’ve made two small changes: The pageBlock component now has an Id attribute The commandButton component includes a rerender attribute whose value is the Id of the pageBlock Clicking on the button now would not redirect the user but would instead just refresh the pageBlock. The return type of the action method is thus ignored and the new changes are loaded more quickly.
Testing Custom Controllers & Controller Extensions Both Custom Controllers and Controller Extensions are comprised of Apex code and it’s therefore necessary that they their public methods are unit tested93. Much of the testing practices covered earlier are applicable here too, but unit test initialization works a little differently. An important difference is that controllers often expect request parameters and so to test them requires that unit tests be programmatically set with dummy values. To this end you can initialize a PageReference object setting parameter values and then assign this object to the Test.setCurrentPageReference. Doing this “tricks” your application code into thinking that it’s running under real world conditions allowing you to test appropriately. Listing 4 - 59 illustrates a contrived unit test for the Custom Controller shown previously.
Listing 4 - 59
Visualforce Page Syntax As mentioned previously Visualforce markup is standards compliant XML compiled and rendered using Force.com technologies. Having detailed the various types of controllers and how the constituents of this MVC framework work together it is now appropriate to learn more about Visualforce page syntax. Visualforce pages can include any bespoke HTML and JavaScript you wish to include. You can mix these with the Standard Component library or you can define your own set of Custom Components, which themselves can include HTML, JavaScript or Standard Components.
Standard Component Library The standard component library consists of XML components that accept a number of required or optional attributes. These provide the component with additional instructions on how to behave and/or look. Components can be used for input, output, organization or to execute actions. Although the library is well documented94 it is valuable to highlight some of the more common elements. As a requirement each Visualforce page must include the page tag, which as you’ve seen is written like so: . We’ve also demonstrated some of the attributes that this component accepts such as standardController, extensions, controller, action etc.
Output Components Components in this grouping are used to present read-only information to end-users. Many of them also provide automatic. The detail component outputs the entire detail page as defined by the page layout for a particular object outputField, outputLabel, outputLink and outputText are used to display data, labels or links on a page. Nesting outputField components in pageBlockSection components equates to nesting a pageBlockSection item in a pageBlockSection message and messages are used to output any information such as error details in a page. The former is used to target a specific component and the latter is a catch-all pageMessage and pageMessages are similar to the previous components but have additional attributes to control when and how error messages are displayed. They both use standard salesforce.com styling for display relatedList components output the records that are related to the parent record that is the subject of the Visualforce page. For each related object you can specify one of these components actionStatus components can be referenced from action components and provide the user with feedback during an AJAX activity. For example, if a user clicks a button the actionStatus component can output the message “Working…” while the action is being executed.
Input Components These components allow users to enter data, which you then capture through the use of a page controller. inputText and inputTextArea are useful when getting text input from a user. The latter is typically used when you expect long string inputs. The inputTextArea is also capable of rendering as a WYSIWYG editor by setting richtext=“true” Use inputSecret to mask what the user is entering, as with password fields
inputHidden is not displayed on the page but is used to submit data with forms when action methods are executed. As an example you might use this component when passing state data to the controller inputField is an “intelligent” input component in that when it is bound to an object field it is will determine the field type and render appropriately Use inputFile when you want to allow users to upload files inputCheckbox will render as a checkbox on a Visualforce page. selectRadio will display radio buttons The selectList and selectOption/selectOptions components can be used to render combo boxes (called picklists on the Force.com platform) param components are usually nested in other components such as commandLinks. They can be used to assign values to controller setters (or properties) explicitly or they can be referenced by their name attribute value through the PageReference object
Organizational Components
The page component is the ultimate organizational component and is the root tag of any Visualforce page pageBlock, pageBlockSection and pageBlockSectionItem are usually nested in the order listed. The first two are used to break pages into logical groupings with optional titles and subtitles. pageBlockSectionItem is used to group labels and output (or input) components such as outputText (or inputText). dataTable and pageBlockTable are used to iterate over datasets and can be used to create tables of output or input items. Use the former when you want a greater degree of control over the table styling. pageBlockTable can be nested in pageBlock or pageBlockSection components where they will inherit automatic styling dataList and repeat iterate of sets of data and can be used to display each record in the chosen manner. Both input and output components can be nested in their bodies panelGroup is nested in panelGrid to organize information into table rows and cells outputPanel is used to group page items either within HTML span tags (default) or in div elements by setting layout=“block”. This component is often used to wrap page areas that will be the target of a rerender Any components that call action methods, together with input components that you’d like to submit on the action invocation, must be contained within a form tag. Best practice dictates that you should only use one form per Visualforce page. If you need more than one form in a page you can split the form into “sub-forms” using the actionRegion component95.
Action Components As mentioned earlier these components allow the user to do things like save, edit or navigate. commandButton - creates a button that calls an action commandLink - creates a link that calls an action actionPoller - periodically calls an action actionSupport - makes an event (such as onclick or onmouseover) on another named component call an action actionFunction - defines a new JavaScript function that calls an action page - calls an action when the page is loaded
Custom Components Standard components encapsulate functionality in such a way that they’re reusable in any Visualforce page you create. If you find that you commonly require a chunk of Visualforce markup in multiple areas of your application you might consider breaking it out into a custom component. For example your application might use a specifically styled banner in many application areas. Since the core Visualforce code is repeated and only the message changes you could create a custom component that encapsulates the core code, and instead make a 1 line call to the component instead96. Listing 4 - 60 shows the source code for such a component.
Listing 4 - 60
The component markup is very similar to Visualforce page markup97. The obvious difference is that instead of using the page component the root element of a custom component is the component tag. Reading the documentation for this component98you’ll notice that components, like pages, can have controller and extensions99. The use of objects and their methods in components is identical in Visualforce pages and Custom Components.
If you’re attempting to perform DML within a Custom Component controller but are getting a “DML not allowed” error you’ll need to set the allowDML attribute of component to true. In the example we’ve also included the option attribute component - of which you can have any number. The attribute component is used to pass information to the component markup, controller or extension. The markup can reference attributes using the {!attribute_name} notation while the attributes can pass their assigned values to Apex code using the assignTo=“{!setter_method}” attribute100. Each attribute requires three tags viz. name, type and description. All that is required to use this component is to include in your page. Notice that it’s only mandatory to pass the component a value for the title attribute as it has been marked as required. In Figure 4 - 13 shows a Visualforce page that has included the component in its source code.
Interestingly custom components are self-documenting thanks to the tag-requirements of attributes. If you examine the component reference in an Org where you have declared custom components you will find their descriptions alongside the standard component documentation. Figure 4 14 shows the documentation that was generated for the Banner component.
There are a number of custom component examples in the documentation but some of the best educational resources are custom component libraries that have been made available of the Force.com Code Share and Wiki sites101.
Visualforce Templates When building websites you’d normally expect each page to share some common elements such as a header, footer and navigation menu. The same can be said of Visualforce pages where you wish to build the look and feel from scratch. Salesforce.com, anticipating this requirement, has created a handful of components so that you define templates for the overall page layouts, customizing the contents of each.
Custom components can be viewed as a type of cookie cutter tool but the templates referred to here are entire Visualforce pages. Note that custom components can and should be used in Visualforce templates. To use such templates requires two things, the Visualforce page that serves as the template and the Visualforce page that provides the content.
The Template The template page can include any markup that a “normal” page might use; it can also include controllers and/or extensions. To define a Visualforce page as a template, all that is required is that it contains one or more insert components. In Listing 4 - 61 we define a Visualforce template that includes two calls to the custom component we created earlier, as well as two insert components. Each component is required to have a unique (to that page) name attribute value; this will be referenced in the “content” Visualforce page.
Listing 4 - 61
The name attribute value is case-sensitive i.e. if your content page tried to reference “sectiona” instead of “sectionA” the template would not render as expected.
The Content The Visualforce page that delivers the content can also include any Visualforce markup, controllers and extensions. However, in order to reference a Visualforce template the page must use the composition and define components. The first type registers your intention to use a template and refers to a template by name (the Visualforce page name of the template). The define component may appear in the page once for each insert component in the template page. Any markup wrapped by this component will duly be inserted into the template. Listing 4 - 62 details the source code of the page that uses the above template; the template page has been saved with the name “Template”.
Listing 4 - 62
The Visualforce page rendered as a result of this source code is shown in Figure 4 - 15.
Be aware that any markup that is wrapped by the composition tag that isn’t inside wrapped by a define component will not be rendered in the resulting page.
If you are exposing Visualforce pages using Force.com Sites and your page resources (such as images) are caching unexpectedly, you will need to set the cache attribute on both the template and content pages to false. Using Visualforce is obviously a timesaver as you can easily reuse page layouts, componentry and navigation. Not only this but when a change to the template is made it is seamlessly available throughout all pages that implement said template.
Using Visualforce to create PDF files Visualforce pages render as HTML by default but by declaring the page component as your page will be output as a PDF file102. The value in this simple ability is obvious when you consider that you can dynamically generate professional looking invoices or other documents very quickly. Using the Force.com platform you can store these in your application and even add them as attachments in emails.
You should also include showHeader=“false” in your page component declaration. Setting this attribute thusly ensures that the salesforce.com header and side panel are not shown in your output PDF. The only skills you’ll need to create a simple PDF file are Visualforce and some basic CSS knowledge. To create files that are a bit more flamboyant you’ll need to brush up on some of the more advanced CSS topics103. PDF generation is quite flexible and salesforce.com has made it easy to include niceties such as page numbering and pagination in the generated files.
Although it is unsupported, it is also possible to render Visualforce pages as Microsoft Word and Excel documents104 by specifying the appropriate MIME type in the contentType attribute for the page component.
Static Resource in Visualforce Pages As with any web-based user interface is necessary to include static files such as images, JavaScript, Flash or CSS in your Visualforce pages. These files are called static resources on the Force.com platform and can be uploaded and managed using the salesforce.com browser interface. You can access the static resource management pages clicking Setup -> Develop -> Static Resources. There you’ll see a list of all current files (which you can edit or delete) and an option to create a new resource. The new resource window resembles a typical file-upload; be aware that the name of the static resource is what you’ll use to reference it later in your code. Static resources can be uploaded individually or as archived bundles (using JAR or ZIP files). We suggest grouping resources into archives as it makes maintenance simpler, and in some situations it is required. An example of when it might be required is when you have CSS that refers to image files in background-image properties. If you upload the images and CSS as separate resources you would have to hardcode the URL of the former in the latter; this is the antithesis of best practice in code. To use static resources in Visualforce pages or components requires you to use the {! $Resource.Static_Resource_Name} syntax for individual files105. An image that you might have uploaded with a name of MyImage could be referenced as . Referencing resource inside of archives is somewhat different and frustrates many beginner developers. Resource access in this case requires the use of the URLFOR function which follows the syntax {!URLFOR($Resource.Static_Resource_Name, ‘[path_to_resource]’}. Consider for example a CSS file called styles.css that includes the property background-image: url(‘/images/logo.jpg’). If the CSS file exists at the root folder then you’d expect a folder structure of: /styles.css /images/logo.jpg Archiving these files into the same bundle and uploading then as a static resource called MyCss, you would then include the CSS in your page using . Your style sheet will automatically be able to “see” the image. You can reference the image directly using {! URLFOR($Resource.MyCss,’/images/logo.jpg’)}.
Visualforce & the Web Since Visualforce is consumed over the web it’s important that it be able to use other prominent Internet technologies. Since Visualforce renders as HTML this is thankfully quite easy to do so you’ll find it easy to create elegantly styled pages using CSS and JavaScript. There are, however, as few nuggets that will help you in integrating these technologies.
CSS Although CSS files can be uploaded as static resources it can take a lot of time going through the code-upload-refresh cycle. There are two alternatives both with their advantages: If you upload a style sheet file as plaintext and ensure the metadata is included in your Force.com project you can edit the style properties directly in Eclipse. Unfortunately you will not be able to reference images (unless you use external URLs) in the CSS You can create a Visualforce page component with contentType=“text/css” and code any styles between style tags in that page106. Since your CSS is contained in a Visualforce page you can refer to any images and you can use Visualforce or Apex to dynamically determine styles If you’re not looking to recreate styles but instead wish to apply the salesforce.com styles in your own page you can either use the standard components, or - using firebug to interrogate the class names - you can add the style class names to your page components107.
JavaScript JavaScript libraries can be uploaded as static resources, included from URLs or dumped into Visualforce pages similarly to CSS. Including libraries is simple but there are some lessons to be learnt in integrating JavaScript with Visualforce. If you’d like to reference Visualforce component in your JavaScript you’ll typically need the component Id108. Although you can assign Ids to components, salesforce.com generates different Ids when the page is rendered as HTML to ensure Ids are unique. The rule here is that the Force.com platform will generate HTML Ids by concatenating all parent Visualforce Ids with the current Visualforce element into a colon-separated string value109. Even dastardlier if you don’t explicitly assign Visualforce Ids to components they will have Ids generated for them. Knowing this, there are two common ways to retrieve Visualforce component Ids. The first approach requires that you assign Ids to all components in the required tree. Consider the example in List 3 - 64.
Listing 4 - 63
If you had an in-page script which needed to fetch the HTML id for the outputText component you would have to declare the variable as var id = ‘{! $Component.thePage.theBlock.theText}’ . This is a bit dangerous because when your page structure changes you’ll need to update any JavaScript that might be affected. The second approach calls for you to declare a JavaScript variable at the same point in the page component tree as the component that it references. Doing this allows you to refer to the component directly using {!$Component.theText}. Although this “disrupts” the flow of the source code it is more maintenance friendly, as structural page changes are less likely to affect your JavaScript code. List 3 - 65 demonstrates such an approach.
Listing 4 - 64
Visualforce Email Templates Email templates and mail merging are an important part of most enterprise applications. Salesforce.com has made this simple on the Force.com platform with Visualforce email templates110. These offer total customization with the (now familiar) Visualforce syntax providing simple integration with your salesforce.com data111. Creating Visualforce email templates is done through the salesforce.com interface. You can easily style your email using CSS and have the option of adding attachments. When setting up the email template you specify the object you wish to include in the template as well as any of its related objects. If you wish to have a greater degree of freedom in which objects you use and how you use them, you can include custom components in your Visualforce Email Templates112.
Mobile Visualforce Pages Early on salesforce.com realized that mobile access to platform data is essential. To fill this gap they created Salesforce Mobile 113, which currently runs on BlackBerry, iPhone and Windows Mobile devices. The application interacts with the platform servers over the mobile networks and stores a configurable subset of the data in a database local to the users phone. A separate license is required for users that want to use Salesforce Mobile; DE and Unlimited Orgs get 1 free mobile license and other Org types need to purchase them separately. Mobile Lite is a free version of the mobile application but does have additional restrictions114. The application is a composite native (to the phone) client application and web browser. Each of these communicates with salesforce.com through the API and Internet respectively. Although some restrictions apply, the following are more or less available to mobile users: Some standard and all custom objects Permissions, record types and page layouts Related lists Dashboards and reports Custom list views Visualforce tabs and web tabs Note that even though Visualforce is available for the mobile application, page designs that work in a computer browser are often not suited for mobile interfaces115.
Security Visualforce renders as HTML and can be vulnerable to the same types of attacks as traditional web sites. In general there are three attack types that you should be aware of when coding:
Unescaped output and formulas in Visualforce pages116. If you’ve used components with their escape attribute set to false then there is a chance that users can enter malicious code that can gain access to user or application information. You should encode and potentially insecure strings appropriately Cross-site scripting (XSS) can be thought of as a range of techniques used to inject malicious code into your application pages117. The platform includes some protection against these attacks but you can add additional security by encoding certain inputs appropriately With cross-site request forgery (CSRF) attackers often take advantage of lingering sessions118. They might include a URL in their page that attempts to execute an action in one of your application pages; if you were previously logged into salesforce.com and your session had not timed out then the forgery might succeed. The Force.com platform includes protection when using standard controller and methods in your pages, but it is largely up to you to secure other custom areas. In chapter 3 we mentioned the Force.com Security Source Code Scanner, which will highlight non-secure areas of your application and suggest appropriate actions. On the Force.com security site there are also a number of educational, analytic and best practice articles to guide you in your quest to build secure applications119.
Order of Execution When a Visualforce page loads it initializes the controller, extensions and component controllers. This all happens in a particular sequence and can thus affect the way you develop these classes and what the user might see on the page. To provide a deeper understanding to the order of this execution it is necessary to examine the life cycle of a Visualforce page. This lifecycle is dependent on two facts, the content of the page as well as how the page is requested. There are two ways that a Visualforce page can be requested: Get requests are made when a user enters a URL in the browser or clicks a button or link that navigates to a different page120 Postback requests are made when an action is fired that requires a page update. These requests occur when parts of your page are rerendered or a redirect is issued to a page that uses the same controller and a proper subset of controller extensions of the initial page121
Visualforce View State Any Visualforce page that contains a form will additionally have an encrypted hidden field that maintains a record of the contents and state of the page122. Inefficient programming can lead to large or brittle view states so it’s worthwhile knowing why view states exist and how to use them efficiently.
With Winter ’11, salesforce.com released the View State Inspector, which is a browser-based tool that helps you view, debug, and optimize the view state in order to improve page performance. Since HTTP is a stateless protocol, information about groups of actions need to be maintained elsewhere. If, for example, a user enters the wrong type of data into a validated form field and then clicks the submit button an error message will be displayed to them. From the user’s perspective a change has occurred in the page based on a previous state but to do this salesforce.com has had to maintain a state with a temporary store, the view state. To ensure that your pages load quickly and work well it is important that you: Mark any Apex variables that aren’t necessary to the view state as Transient. This is especially true of variables of type Blob, which can be enormous Only use one form per Visualforce page and demark sub-forms with actionRegion components Create wizards with as few pages as possible Use outputLink components instead of commandLink or commandButton components where possible as they don’t need to be nested in a form Fetch only the bare minimum of required fields via SOQL
Development Best Practices Now that we’ve detailed the different aspects of developing on the Force.com platform, let’s take a look at some of the things you should and should not do when developing. These best practices will not only help you write better, more scalable code but will also make your life easier down the road in terms of maintenance. You may have to dig into the salesforce.com documentation for more information on some of these bullet points as they are beyond the scope of this book.
Apex
Since Apex is case insensitive you can write it however you’d like. However, to increase readability, follow Java capitalization rules. Use Asychronous Apex (@future annotation) for logic that does not need to be executed synchronous. Asychronous Apex should be “bulkified”. Apex code must provide proper exception handling. Prevent SOQL and SOSL injection attacks by using static queries, binding variables or the escapeSingleQuotes method. When querying large data sets, use a SOQL “for” loop Use Apex Limits Methods to avoid hitting governor exceptions. No SOQL or SOSL queries inside loops No DML statements inside loops No asynchronous methods (@future) inside loops Do not use hardcoded IDs
Triggers
There should only be one trigger for each object. Avoid complex logic in triggers. To simplify testing and resuse, triggers should delegate to Apex classes which contain the actual execution logic. See Mike Leach’s excellent trigger template for more info123. Bulkify any “helper” classes and/or methods. Triggers should be “bulkified” and be able to process up to 200 records for each call. Execute DML statements using collections instead of individual records per DML statement. Use Collections in SOQL “WHERE” clauses to retrieve all records back in a single query Use a consistent naming convention including the object name (e.g., AccountTrigger)
Visualforce
Do not hardcode picklist values in Visualforce pages; include them in the controller instead. JavaScript and CSS should be included as Static Resources allowing the browser to cache them. Reference CSS at the top and JavaScript a the bottom of Visualforce pages as this provides for faster page loads. Mark controller variables as “transient” if they are not needed between server calls. This will make your page load faster as it reduces the size of the View State. Use to iterate over large collections. Use the cache attribute with the component to take advantage of salesforce.com CDN caching when appropriate.
Unit Testing
Use a consistent naming convention including “Test” and the name of the class being tested (e.g., Test_AccountTrigger). Test classes should use the @isTest annotation. Test methods should create all data needed for the method and not rely on data currently in the Org. Use System.assert liberally to prove that code behaves as expected. Test each branch of conditional logic. Write test methods that both pass and fail for certain conditions and test for boundary conditions.
Test triggers to process 200 records – make sure your code is “bulkified” for 200 records and doesn’t throw the dreaded “Too many SOQL queries: 21″ exception. When testing for governor limits, use Test.startTest and Test.stopTest and the Limit class instead of hard-coding governor limits. Use System.runAs() to execute code as a specific user to test for sharing rules (but not CRUD or FLS permissions). Execute tests with the Force.com IDE and not the salesforce.com UI. We’ve seen misleading code coverage results when running from the salesforce.com UI. Run the Force.com Security Source Scanner to test your Org for a number of security and code quality issues (e.g., Cross Site Scripting, Access Control Issues, Frame Spoofing)
For all security resources including the Force.com Security Source Scanner, visit http://wiki.developerforce.com/index.php/Security.
Miscellanea Besides the mentioned major features of Visualforce there are a number of utilities that you’ll often need to reference.
Global Variables Developers often need a way to access information about the current user and environment and a lot of this information is conveniently available from global variables124. Available using the {!$Global_Variable.variable_name} syntax you have access to information about field labels, page URL parameters, user details, static resources and much more.
Functions & Operators To facilitate common functions and operations, salesforce.com has exposed a number of tools available directly in Visualforce 1258. These include mathematical and logical operators as well as date, time, text, logical, informational and encoding functions. 1 dml-insert-docs 2 dml-update-docs 3 dml-delete-docs 4 dml-upsert-docs 5 soql-vs-sosl 6 soql-syntax 7 working-with-soql-results 8 soql-bind-variables 9 soql-relationship-queries 10 dynamic-soql-docs 11 dynamic-soql-example 12 governor-limit-docs 13 soql-primer 14 soql-aggregate-functions 15 soql-very-large-queries 16 soql-for-loops 17 sosl-syntax 18 sosl-best-practices
19 soql-syntax 20 dynamic-sosl 21 governor-limit-docs 22 apex-ondemand 23 apex-intro 24 apex-cheatsheet 25 apex-best-practices 26 apex-security 27 force.com-workbook 28 force.com-cookbook 29 apex-developer-guide 30 development-force.com-platform 31 intro-exceptions 32 exception-methods 33 limit-class 34 dml-undelete-docs 35 dml-merge-docs 36 database-methods 37 apex-describe-info 38 sobject-describe 39 field-describe 40 dynamic-dml 41 future-method 42 recursive-future-calls 43 system-methods 44 dom-classes 45 xmlstream 46 http-classes 47 encodingutil-class 48 crypto-class 49 test-class 50 limit-class 51 cookie-class 52 pagereference-class 53 message-class 54 intro-triggers
55 trigger-order-execution 56 trigger-context-variable 57 trigger-exceptions 58 context-variable-considerations 59 trigger-lookup-null 60 trigger-recursion 61 bulk-trigger-idioms 62 running-unit-tests 63 write-good-unit-tests 64 unit-test-example 65 intro-unit-tests 66 virtual-callout-testing 67 sosl-testing 68 bulk-testing 69 using-scheduled-apex 70 apex-scheduler 71 batch-apex-intro 72 batch-apex 73 governor-limits-intro 74 governor-limits 75 client-side-data-manipulation 76 too-many-dml-rows 77 system-log-console 78 howto-view-debug-logs 79 understanding-debug-logs 80 debug-log-filters 81 intro-visualforce 82 mvc-visualforce 83 standard-controllers 84 standard-controller-tut 85 standard-list-controller-actions 86 custom-list-buttons 87 by-value-or-by-reference 88 custom-list-controller 89 custom-controller-tutorial
90 custom-controllers 91 controller-methods 92 apex-properties 93 custom-controller-tests 94 standard-component-library 95 multiple-forms-single-page 96 define-custom-component 97 custom-component-markup 98 custom-component-root 99 custom-component-controllers 100 custom-component-attributes 101 custom-component-examples 102 page-component 103 professional-pdf-from-visualforce 104 visualforce-word-excel 105 delivering-static-resources 106 dynamic-css 107 salesforce-css-in-visualforce 108 referencing-js-visualforce 109 component-id-best-practices 110 intro-visualforce-email-templates 111 visualforce-email-template-sample 112 component-in-visualforce-template 113 salesforce-mobile 114 salesforce-lite 115 developing-pages-for-mobile 116 security-unescaped-output 117 security-xss 118 security-csfr 119 force.com-security 120 visualforce-get-requests 121 visualforce-get-requests 122 intro-view-state 123 trigger 124 visualforce-global-variables 125 visualforce-functions-and-operators
Integration with the Cloud
Integration between platforms has been a valuable advantage since the creation of the Internet. It is often the flexibility and ease of these integrations that determines how successful an application or platform becomes. Salesforce.com foresaw that delivering software, infrastructure and development as a service in the real world would require them to expose their CRM and development platform via technologies such as SOAP- and REST-based web services, ERP connectors, email and syndication feeds. Having created these channels they’ve helped developers on other platforms leverage the inherent value they are providing. Some examples of library-assisted integrations include Amazon, Facebook, Wordpress, Java, Microsoft Outlook, SAP, Twitter, Adobe Flex, .Net, Mac OSX and Google. This list gives you an idea of the range of potential integrations but it is far from exhaustive. As long as the application you’d like to integrate with is web services capable it can be plugged into the Force.com Platform. The type of integration you’ll require is largely based on two things: The goal of your integration e.g. export data from the platform The platform or language that you’re integrating with, although the coupling here is quite loose
As part of the Force.com Platform offering salesforce.com advertises the 5 paths to integration success. Which of these 5 paths you use is dependent upon the software you currently use and in some cases the available budget. In this chapter we’ll examine each type of integration so that when the time comes you’ll know which channel best suites you.
Path 1: AppExchange The AppExchange is a marketplace with nearly 1000 applications built on the Force.com platform. Here you can buy or sell business applications and services, usually with the option to test-drive applications that you’re performing due-diligence upon. Applications are grouped according to the following categories:
Key Attributes - how much does it cost and rating e.g. whether the application is free or paid; is it a top-rated application Edition - which editions will it work on e.g. Group or Professional Type of App - what role or platform does the application work in e.g. whether it is a full-blown application or an add-on Industry Solutions - which industry is the application categorized under e.g. Communications, Health Care, or Retail Function - what business area does the application best cater for e.g. Analytics, Marketing, Sales Of equal importance are the nearly 300 services offered on the AppExchange. These are grouped by:
Key Attributes - a subset of those mentioned above Industry Specializations - largely the same as Industry Solutions above Type of Service - Business Consulting, Custom App Development, System Integration, and training Publishing to the AppExchange In order to publish applications to the AppExchange it’s necessary to work through a few key steps with salesforce.com. These steps protect you as the publisher but also ensure that that the products that consumers acquire through the marketplace are secure and of high quality.
These requirements are: 1. Join the Salesforce.com Partner Program1. Once considered a partner you’ll be given access to a number of resources only available through this program e.g. previews of upcoming functionality and access to marketing channels. 2. Build your application on the Force.com Platform and bundle it into a Managed Package for distribution. The Force.com discussion forums will form a large part of your support in this phase. 3. Capture the details of your software within the publishing wizard2 e.g. the title, description, features and requirements. Then submit your application to salesforce.com for review. Once it passes the review you are free to publish it to the AppExchange. As part of the publishers framework you’ll also have the ability to present screenshots, read-only test drives, as well as fully functional trial versions3 of your applications to prospective clients. Although your company will do the bulk of the heavy lifting, salesforce.com will provide comprehensive assistance every step of the way.
The AppExchange from a Consumers Perspective Marketplaces are just as much for those buying products as selling them, and AppExchange makes it as easy as selecting a potential product and clicking the Get It Now button. Of course you’ll want to do some investigation before purchasing an application and to this end you’ll typically have access to application demos, screenshots and/or trial versions. Be sure to check the ‘Spec’ tab to make sure that the application supports your purchased edition. Besides the paid applications you’ll find there are a number of free applications on the AppExchange 4. One of the most prolific and popular free application publishers is Force.com Labs. All applications under this publisher are created by salesforce.com employees and include everything from common utilities to save you time to Chatter plug-ins to enhance your salesforce.com experience (and they’re all free!).
Indispensible Applications As you work with the Force.com Platform you’ll discover applications from the AppExchange that are useful to your business. Some of these will be quite specific to what your company does whilst others provide a more general utility. To save you some time we’ll mention some that we’ve found useful.
Adoption Dashboards By Force.com Labs This app consists of three Adoption Dashboards, and their associated reports. Downloading this app will create an “Adoption Dashboards AppExchange” Dashboard folder along with a Reports folder called “Dashboard Reports - Adoption.”
Appirio Cloud Storage By Appirio Economically store unlimited numbers of files of all sizes directly through the salesforce.com interface.
Appirio Professional Services Enterprise By Appirio Manage your people, customers, projects and transactions with an end-to-end services management application, built on Force.com. With Chatter enabled, PS Enterprise brings real-time collaboration with full business context to your services organization.
SalesView FREE: Drive Sales Productivity with Integrated Sales Intelligence By InsideView SalesView, the #1 rated app on AppExchange, finds sales opportunities across both traditional and Web 2.0 sources like Capital IQ, Reuters, Jigsaw, NetProspex, LinkedIn, Twitter and Facebook. Deliver integrated sales intelligence directly in Salesforce.
Draggin’ Role By DrivEnable Manage your role hierarchy with ease! Now you can drag and drop your way through any hierarchy modifications. Draggin’ Role is a free application that allows you to view and manipulate users AND roles from a single Custom Tab.
Intacct Financial Management By Intacct Corporation Intacct is the Preferred Provider of Financial Applications for AICPA business solutions and is seamlessly integrated with Salesforce. Intacct cloud financials completes Lead-to-Order, Order-to-Cash and provides 360° real-time business visibility.
DBAmp/Pro By ForceAmp.com DBAmp/Pro for AppExchange connects Salesforce.com with Microsoft SQL Server. With DBAmp, you can easily access your Salesforce.com objects using SQL Select, Update, Insert and Delete statements. DBAmp can also replicate those objects as local SQL tables.
Appirio Contact Sync for Salesforce & Google Apps By Appirio Appirio Contact Sync for Salesforce & Google Apps is a simple tool to select and sync contacts between your Google and Salesforce address books. (Unsupported)
Action Plans By Force.com Labs Action Plans encapsulates best practices into reusable task templates. An Action Plan can be created for an Account, Opportunity, Contact or Lead. Template tasks can be preassigned to a specific individual or assigned to the running user.
Ribbit for Salesforce By Ribbit Ribbit for Salesforce is the only sales productivity tool that unifies mobile voice and SMS communications, Salesforce CRM, email, and voiceto-text transcriptions. Built-in automation helps you work less and sell more.
SnapShot Change And Release Management By DreamFactory Software Snapshot is the ultimate tool for change management, change reporting and compliance documentation for Salesforce Orgs. With SnapShot’s rich interactive GUI, admins can compare and diff Orgs, monitor changes to Orgs, and push customizations between Orgs.
Conga Composer By AppExtremes One click to proposals, account plans, contracts and more from multiple objects and related lists. Easily customize Spring ‘10 Quotes with line item sort. Output to Word, Excel, PPT or PDF to print/attach/email in single or batch operations. See Reviews!
VerticalResponse for AppExchange By Vertical Response Send marketing emails & postcards from Salesforce in minutes. Use opted-in contacts & leads for lists, build professional campaigns & track statistics. Share instantly on Facebook & Twitter.
Geopointe - Force.com with Google Maps and MapQuest By ArrowPointe Corp Geopointe is the premier Force.com geo/mapping solution providing numerous ways for end-users, administrators and developers to take advantage of geo data and maps.
DemandTools 2.0 By CRMFusion Inc DemandTools is an admin toolkit for a variety of data quality needs including merging duplicate records (dupes), backup, batch normalization, ETL, batch deletion, duplicate prevention, comparing external data to data in Salesforce, Lead to Contact etc.
ActiveRecruiter Business Edition By JobPartners ActiveRecruiter Business Edition is a comprehensive solution for streamlining your corporate recruitment activities. Easy-to-use and fully deployed in as little as 48 hours, ActiveRecruiter Business Edition automates your end-to-end recruiting process.
Address Validation & Auto-complete from Postcode Anywhere By Postcode Anywhere Look up and auto-complete worldwide address info. Zip code and postcode lookups return clean, correct international address. Essential address validation for int’l trading.
Salesforce Integration - Informatica Cloud Services By Informatica Corp Designed for non-technical users. Easily integrate Salesforce with on-premise & ERP and back-office apps (SAP, JDE, Oracle), databases, files, spreadsheets. Load, migrate, extract, sync, and replicate data on demand.
Path 2: Build Your Own In our world of APIs and web services the Force.com integration options discussed in this chapter give you a multitude of integration options. Salesforce.com and some community members have also created libraries and tools to make said integrations quicker and less error prone.
SOAP Based Web Services SOAP is a meta-protocol for defining the exchange information using web services. It uses XML to define its request and response format and is typically transmitted over HTTP or RPC. Several areas of the Force.com platform have defined their integration points using SOAP providing WSDL files that enable you to automatically generate client libraries in the language of your choice.
Data Integration with the Web Services API The Force.com Web Services API, often just called “API”, is a data services API that exposes all standard and custom objects allowing you to create, retrieve, update or delete records using web service calls5. Other functionality such as password maintenance and searching are also available6.
Each new salesforce.com release will include an update to the API. API versions are supported across releases and are backward compatible. Salesforce.com does reserve the right to stop supporting API versions that are 3 or more years old. There are two web services each with their own Web Service Definition Language (WSDL) file for API access. These are called the Enterprise and Partner WSDL files and each have their own strengths and weaknesses7.
Partner WSDL The Partner WSDL is analogous to dynamic Apex. It doesn’t recognize specific object types such as Contact or MyCustomObject__c; instead it understands the concept of a generic SObject. These variables of the SObject type can be recognized as Contact or MyCustomObject__c by examining that SObject describe information. This means that with the Partner WSDL you could develop a single version of an external application or library that works across multiple salesforce.com Orgs. Listing 5 - 1 shows how you can insert a Contact record using Java and libraries generated from the Partner WSDL.
Listing 5 - 1
Since this represents a loosely typed version of the Force.com data model the generated library is a bit more difficult to work with. The main advantage is that you have the freedom to modify your metadata without the necessity of regenerating the WSDL and the consequent libraries each time your salesforce.com data model changes.
It is strongly advised that integrations with third parties use this WSDL type. It provides you with the freedom to modify your Org’s metadata without worrying about the impacts on running integrations. For a comprehensive sample application that uses the Partner WSDL check out the Force.com developer site8.
Enterprise WSDL The Enterprise WSDL, on the other hand, is more static (or strongly-typed) in nature. After generating your language-libraries from this WSDL you’ll notice that you’ll have classes (or other structures) that directly define your objects. Listing 5 - 2 shows how to use code generated from the Enterprise WSDL to achieve the same result as Listing 5 - 1.
Listing 5 - 2
Here you can see that accessing a Contact object record and fields is simple and more intuitive making integrations quicker and less error prone than with the Partner WSDL. The major disadvantage here is that if you add a new field to the Account object, or altered its metadata in some other way you would probably need to regenerate the WSDL and consequent libraries. Be sure to have a look at the sample project available on the developer site9.
Replication API This API is a subset of the Web Services API and provides a mechanism to simplify the one-way push of data from the Force.com platform to another data store. There are just two calls for data replication namely getUpdated and getDeleted. The first simply fetches all records that have been updated on the specified object during the indicated time span. The getDeleted calls removes records in a similar fashion. The typical order of events when fetching records using the Replication API calls might be: 1. getUpdated is called and returns a list of record Ids 2. External application makes a retrieve call using the list of Ids and fetches the appropriate object fields 3. Object data is then written to a local (or external application) data store The process for the delete call is nearly identical. Typically the very first getUpdated call establishes a data baseline and then it’s up to you to pass the appropriate time span in subsequent calls. These calls save you the trouble of writing frameworks that recognize when a record is updated or deleted; or even worse, performing a full export of your Force.com object records for every data replication.
If the only changed value on a record belongs to a formula field, that record will not be recognized as being “updated”. This is because formula fields are only calculated on the fly and are not considered to be true data.
A few points to note when using the replication calls are: The calls facilitate replication i.e. data copying from a source to target (as opposed to two-way copying) The calls can only see objects and records that the API user has access to DateTime values will have their seconds portion truncated You should not poll the API more often than once every 5 minutes Outbound messaging can be used to trigger replication calls The API checks for data changes in your Org. To check for changes to object structures you would have to use the Metadata API.
Outbound Messaging Salesforce.com offers outbound messaging so that even non-developers can expose their Org’s data for integration with external platforms10. The technology is a feature of workflow rules with a typical setup requiring you to specify the conditions under which the workflow will begin, the object record fields that you wish to transmit and the endpoint that will receive the data. To create an outbound message click Setup -> Create -> Workflow & Approvals -> Outbound Messages. From here you can create, view and track outbound messages. Clicking on any available outbound message name will give you the details for that record. Once you’ve defined your outbound message you’ll need to download the WSDL document that defines the target web service and use that to generate the platform client libraries that will receive and parse the message contents. The service uses the notification call to send SOAP-based messages over HTTP(S).
Some helpful baked-in features of outbound messaging are: Up to 100 notifications can be included in a single SOAP message If an object changes after a message is sent, but before it is delivered, the updated information will be delivered Messages are queued, and if the delivery fails, sending will be retried until the message is 24 hours old The official salesforce.com documentation has a number of examples showing how to build listener services from an Outbound Messaging WSDL11. Outbound messaging is a quick and simple alternative to building your own outbound web service calls. You won’t be able to use it for more complex integrations but when only simple services are involved, it saves time both in terms of implementation and maintenance.
Apex Web Services The Partner and Enterprise WSDL expose a rich set of common functionality that might be required within integrations. However there will be times when you require specific business functionality to be available for integrations. The Force.com platform makes it easy for developers to mark Apex classes and methods as web services; a WSDL file is automatically made available for any classes defined this way. Apex classes that contain web services need to be declared using the global access modifier. This means that all Apex code can access this class. Web service methods require the webservice and static keywords in their signature. Listing 5 - 3 details the definition of an Apex web service method.
Listing 5 - 3
This simple web service will return a list of Contact Ids given a specific Account id. To use this web service from your chosen platform you’ll need to generate code from the WSDL for this Apex class. Click Setup -> Develop -> Apex Classes to view all of your Apex classes. Next click WSDL next to the class in to be used. Figure 5 - 3 shows the class listing for the MyWebServices class.
It is also possible to define custom types to be used by your web services e.g. you can define global inner classes that can be used as return types or parameters of Apex web services. To make any variable within a global class accessible via a web service it must be declared with the webservice keyword. Some points to note when using the webservice keyword: The keyword can only be used to define top-level methods and variables of top-level or inner classes. It cannot be used on the class itself or anywhere in an interface Methods defined with the keyword must also be static Member variables marked with webservice cannot be declared as static There aren’t SOAP equivalents for all Apex structures. This means that the following cannot be used as parameters or return types of web service methods: Maps, Sets, Exception Objects, Pattern Objects, Matcher Objects
Generating SOAP Based Web Service Libraries Whether generating the API or Apex web services there are a number of common steps and approaches12. First of all you’ll need to generate the WSDL file. We’ve mentioned how to do this for Apex web services already, for Enterprise and Partner WSDL files you’ll need to navigate to Setup -> Develop -> API and click the appropriate link. The next step will be to import the WSDL file into the development platform you’ve chosen e.g. Eclipse or Microsoft Visual Studio. There are tools to help you do this for most popular language platforms. The result of this import is typically a set of classes that form your salesforce.com library. Using these classes or libraries you’ll be able to log into the Force.com platform. This login step will give your application access to a session Id and server URL, which are used in all subsequent calls to ensure secure communications.
Libraries generated from Apex web service WSDL files will not contain the functionality required to log into the Force.com platform. It is therefore necessary to use the Partner, Enterprise or OAuth libraries to obtain a session Id and server URL before using Apex web service functionality.
Apex Callouts While all the integration options discussed so far expose data and functionality to services outside of the Force.com Platform, it is possible to consumed SOAP-based web services using Apex code. Force.com provides a service used to translate WSDL documents into Apex code called WSDL2Apex. This process is similar to generating external language libraries from the aforementioned WSDL files. To begin the generation process, navigate through Setup -> Developer -> Apex Classes and then click on Generate from WSDL button at the top of the page. Figure 5 - 4 shows where to find this feature.
The results of a successful generation will include Apex versions of the types represented by the third party WSDL document. These client stubs can be used to do all the dirty work of serializing and de-serializing the SOAP packets between your underlying Apex code and the third party platform. Consider these guidelines when using Apex Callouts: You cannot use WSDL2Apex with WSDL files that are more than 1MB in size It is required that you white list any external sites that you wish to access through the Force.com platform. This can be done by clicking Setup -> Security Controls -> Remote Site Settings and creating a New Remote Site The generated Apex code cannot be more than 100,000 lines in length. Whether the generated code exceeds this limit or not the resultant Apex code will be displayed to you. If it exceed 100,000 lines you will not be able to save the code, but can manually copy and paste the code into smaller portions that can be later saved If an Apex reserved words are contained in the WSDL document, the generated Apex code will be suffixed with _x
RESTful Web Services Representational State Transfer (REST) is an architectural style for building communication systems within computer networks. It is not a framework but instead a style that you might adopt in building your web services. The World Wide Web is the most commonly cited REST example and in a similar way you can use HTTP technologies to build your own RESTful web services. When building applications that will consume or create REST-based web services you will find the following classes useful: Http - Used to initiate HTTP requests and responses HttpRequest - Used to programmatically create GET, POST, PUT and DELETE HTTP requests HttpResponse - Handles the HTTP response returned by HTTP XmlStreamWriter and XmlStreamReader - Simplify the reading and writing of XML strings Document and XmlNode - Document Object Model (DOM) utilities for creating and parsing XML documents EncodingUtil - Utility capable of encoding and decoding String variables into a number of formats Crypto - Enables encryption and decryption using a number of popular algorithms A simple HTTP callout using a POST request is detailed in Listing 5 - 413.
Listing 5 - 4
It’s not required that you annotate your callout methods as @future but be aware that if you don’t, your application will effectively wait for the external system to respond before allowing the user or process to proceed. REST-based web services are generally more flexible than their SOAP-based counterparts, and the communication overhead tends to be smaller. However SOAP-based web services are quicker to build on the Force.com platform primarily because of the tools supplied.
Managing Data with the Bulk API A common task in contemporary development projects is the loading of very large data sets, especially where system integrations are concerned. The standard Force.com Web Services API facilitates this type of integration but can be burdensome for large datasets as you’re required to implement complex processes to upload data in bite-sized chunks, monitor results and retry failed records. The Force.com Bulk API was designed specifically to offload the complex and time consuming process of importing large data sets from your client application to the Force.com platform. The Bulk API and supporting web interface allows you to upload and create import jobs, monitor and manage these jobs through an easy to use web interface, and receive notifications when the jobs complete. The REST-based Bulk API was developed specifically to simplify the process of uploading large amounts of data. It is optimized for inserting, updating, upserting, and deleting large numbers of records asynchronously by submitting them in batches to Force.com, to be processed in the background.
Processing Uploaded records are streamed to Force.com to create a new job. As the data rolls in for the job it is stored in temporary storage and then sliced up into user-defined batches (max of 10,000 records). Even while your data is still being sent to the server, the Force.com platform submits the batches for processing.
Some compelling reasons to use the Bulk API are: Fast processing speed Less client-side programming logic GUI for monitoring job Status Automatically retry failed records Support for parallel and serial processing Fewer API calls Fewer dropped connections Easily modify batch size
Monitoring Monitoring Bulk API jobs can be done by going to Setup -> Administrative Setup -> Monitoring -> Bulk Data Load Jobs . Options here include the ability to manage running jobs, view completed jobs and view your processing quota.
Integration Since the Bulk API is REST-based it is possible to integrate it with any development platform capable of work with HTTP. The bulk API is capable of working with both CSV and XML files using GET or POST HTTP methods. As with the other APIs and inbound web services you’ll need a valid URI endpoint and session. As with Apex web services the Bulk API cannot authenticate your application so you’ll need to use the Web Services API or OAuth to establish a Force.com session. Once authenticated you can execute specific operations by polling function-specific URIs. As an example consider the following:
Create a Job To create a job you would need to issue a POST request to the URI below.
https://instance_name—api.salesforce.com/services/async/APIversion/job Get the Status of a Job Retrieving the status of a job would require a GET request the following URI.
https://instance_name—api.salesforce.com/services/async/APIversion/job/jobId Close a Job To close a job and prevent more batches from being added you could send a POST request to the below URI.
https://instance_name—api.salesforce.com/services/async/APIversion/job/jobId Note that for the last two examples you can specify which job the request should deal with using the jobId value. For those operations initiated with a POST request a valid XML packet is required in the request body. These documents specify information such as the operation type and object type. All response bodies will contain XML that contains information such as the job Id and the job status. Details of these document structures can be found in the Bulk API documentation.
Common Best Practices In order to effectively architect your bulk solutions it is important to bear the following restrictions in mind: Records are processed in batches of 200. It is therefore important that your triggers are bulk safe Any imports that you perform using the Web Service API should continue to work with the Bulk API as it uses the same save logic The timeout on batches is 10 minutes so you may have to experiment with batch sizes in order to remain within this limit. It is recommended that you use as large a batch as possible while avoiding these timeouts Batch API jobs send the same success or response CSV file as the Web Services API Null values are processed differently, so instead of sending a blank value in the CSV file, you need to use #N/A instead There is no field truncation header option Binary files such as images or Zip-archives cannot be processed using the Bulk API Be sure to bookmark the Bulk API limits14 Always test in a Sandbox until you are happy with the processing results Parallel processing is quicker than the serial alternative but test thoroughly to make sure your operations do not create record lock errors
Deployment and Modifying the Model with the Metadata API This API is quite distinguishable as instead of working with your salesforce.com data it’s used to customize your application e.g. it can be used to manage your application customizations programmatically as well as export and migrate meta data.
In earlier chapters you’ve seen that the deployment tools built into Eclipse, as well as the Force.com Migration Tool both use the Meta Data API to retrieve and modify your Orgs structure. Salesforce.com has made this asynchronous API available to you so that you can build your own client applications on top of it. To use this API you’ll need to download the WSDL document by clicking through Setup -> Develop -> API -> Download Metadata WSDL. The Metadata API supports two methods of development namely file-based and CRUD-based.
File-Based Metadata API Calls The file-based (or declarative) Metadata API deploy and retrieve calls are used to move metadata between a salesforce.com Org and a local file system. It does so by transferring a zip-file that contains a set of folders and components that represent some or all of your Org’s metadata. Within the zip-file is a project manifest file called package.xml that determines which metadata components will be considered by the operation. An example of a package.xml file is shown in Listing 5 - 5.
Listing 5 - 5
In this example the XML markup defines a manifest that says “Fetch or deploy all components that are Apex classes”. The full markup syntax can be found in the Metadata API Developer’s Guide along with all the metadata types that can be specified in the manifest file.
If a source code file is removed from the local file system it is not definite that the destructive change will be deployed to the Force.com servers. You can guarantee the removal of application components by creating and using a manifest file called destructiveChanges.xml. Two examples applications that use these API calls are the Force.com IDE and the Force.com Migration Tool.
CRUD-Based Metadata API Calls The create, update and delete calls typified by this area of the API work with Metadata in much the same way that the Web Services API operates on your Force.com data. You can think of these calls mimicking the browser interface when managing application metadata. Although CRUD means Create, Read, Update and Delete there isn’t an explicit read-call available for this Metadata API call set. Instead you’ll have to use the retrieve call that is a part of the declarative Metadata API call set. The Metadata API doesn’t include calls to authenticate a session so you’ll need to use the Web Services API or OAuth to get a session Id. All subsequent calls need to be directed at the URL specified in the metadataServerUrl variable of the LoginResult. All CRUD-based calls are asynchronous and you can use the checkStatus API call to interrogate the progress of other calls. Note that all responses are of type AsyncResult. An example of call ordering with the CRUD-based calls is: 1. Logged in service call makes a create call to Metadata API 2. An AsyncResult object is returned with status information. Operations can be queued to completed, or in an error state 3. Call checkStatus in a loop until an end state is reached
Check the Metadata API reference to see the types that you can read and write. For example you could build a Java application on this API that builds zip-archives and deploys them as static resources on the Force.com servers.
Force.com Web Service Connector (WSC) The WSC is a high performing web service client stack that makes it much easier to use the Force.com API15 from Java. It can be used to generate libraries from the Partner and Enterprise WSDL; the resulting library is simpler to use than those generated using Axis or similar web stack tools16. The connector also includes a library to integrate the Force.com platform with applications running on Google App Engine.
Tolerado
This framework forms a set of web service client wrappers over the Metadata, Enterprise, Partner and Apex WSDL APIs 17. The primary aims of this projects are to: Increase fault tolerance Cache session information Provide web service utilities to simply API usage Simply migration between web stacks
OAuth Open Authorization (OAuth) is a popular open-standard that allows you to share resources between sites without each site having to expose your credentials; instead trusted sites pass tokens back and forth as a security measure. OAuth has been widely adopted as a mechanism to integrate sites and web services. Salesforce.com have thus provided the ability to use a baked-in service as an OAuth provider18, and Apex is rich enough to support Force.com applications that are required to be OAuth consumers19.
Path 3: Native ERP & Desktop Connectors Many companies have SAP and/or Oracle system deeply embedded in their architecture. Connecting these system to the Force.com platform is essential20 for coherence of data and is highly adventitious with regards to data mining. You won’t find much about these connectors on the Internet so either contact salesforce.com through your product manager or log a case to learn more. Salesforce.com has also created tools to allow you to connect your salesforce.com Org to Lotus Notes21 and some of the products in the Microsoft Office Suite22. These add the convenience of quickly synchronizing your desktop application data, such as calendar information or data in a spreadsheet, to the Force.com platform.
Path 4: Middleware Connectors Applications in this category can largely be considered adapters from one system to another. Most of these can be found on the AppExchange and can be used to integrate SQL databases, Google Contacts, Google AdWords, Jigsaw, QuickBooks, payment gateways, file storage and much more.
Path 5: Toolkits Software in this category is aimed at assisting you to quickly connect a technology platform or application suite to the salesforce.com cloud. A large number of these target integration specifically with the SOAP-based Force.com Web Services API. Salesforce.com has created many of these toolkits but third parties as well as independent developers have also made many noteworthy contributions.
PHP Toolkit The PHP toolkit provides an easy way to make Force.com Web service API method calls from within PHP 23. It supports both the Enterprise and Partner WSDL but only works with version 13 thus limiting functionality. Rumor has it that it should be updated soon to support later versions.
Self-Service Portal Toolkit for PHP 5 Simplifies the task of embedding a Salesforce Self-Service Portal within a PHP application24. Requires an older version of the PHP Toolkit.
Standalone PHP Bulk API Client Although this client toolkit forms a part of Workbench it is also available as a standalone download25. It provides a library to help PHP developers easily work with the Bulk API.
AJAX Toolkit The AJAX Toolkit is a powerful and widely used JavaScript wrapper around the Web Services API 26. You can use it to execute any call from the API, and access any API objects that you normally have access to. It functions asynchronously with callback functions to handle returned results. It is based upon the partner WSDL since there is no type checking in JavaScript.
Adobe Flash Builder for Force.com The Adobe® Flash® Builder™ for Force.com allows developers to create powerful, engaging offline and web-based applications running on the Force.com platform. The product, codename Stratus, is a jointly developed Eclipse-based IDE that combines the Force.com IDE, Flex 4 Builder, Flash 4 and LiveCycle Data Services and is tightly integrated with Force.com Connect Offline. It also includes a SQLite database embedded within the Adobe AIR runtime that provides the offline data cache of Salesforce.com data. The framework includes: Login functionality including a UI and error messages.
An API for making multiple, asynchronous, web service requests to the Force.com cloud to retrieve, save, or delete records. UI components and data classes for displaying, editing, and managing local data changes. The automatic creation and management of a local data store of salesforce.com data for offline support. When importing the Salesforce.com Enterprise WSDL, Stratus generates ActionScript classes for your objects on the Force.com platform. An API for saving changes to both the local store and the Force.com cloud. Automatic periodic synchronization of data between the local data store and the Force.com cloud. Online and offline data synchronization and management. Support for “select *” SOQL queries.
Salesforce Python Toolkit There are two Python adapters, Beatbox27 and one that uses Suds28, for handling SOAP messaging with the API in Python.
Force.com Toolkit for Google Data APIs The Google Data APIs toolkit allows you to access Google authentication and multiple APIs (Contacts, Documents, Spreadsheets, Calendar, Blogger) natively from Apex29. Each API within the Google Data APIs is thoroughly documented for this toolkit.
Force.com Office Toolkit The Office toolkit provides a Component Object Model (COM) interface for developers who want to write client applications for Microsoft Office products that use COM technology to access salesforce.com data30. The toolkit acts as an intermediary between COM clients and the API, handling certain tasks implicitly so that client applications are simpler to code.
Force.com for Google App Engine The App Engine toolkit (Java and Python) allows developers to access the API from Google App Engine 31. The Java Toolkit fully supports the Partner API whereas the Python Toolkit is only capable of making the core API calls.
iOS Toolkit for Force.com A creation of Simon Fell, this Objective-C and Cocoa toolkit allows developers to build native OSX (Mac) and iOS (iPhone) applications for the Force.com platform32.
Force.com for Amazon web services The toolkit enables access to Amazon S3 and EC2 for building Force.com applications that integrate with Amazon Web Services 33. The toolkit provides a framework for authentication, native access to the AWS Simple Storage System for data manipulation and pre-built Amazon Machine Images.
Force.com for Facebook The new Force.com for Facebook provides developers with direct access to the Facebook APIs from Apex code 34. It provides support for the Graph API, OAuth2 for authorization, JSON data exchange, social plugins, extended permissions and more.
ActiveSalesforce ActiveSalesforce is a Ruby on Rails framework connection adapter that provides direct access to Force.com data via the Web Services API and Rail’s Active Record model layer35.
Perl Toolkit A Perl class that provides a simple abstraction layer between SOAP::Lite and Force.com36.
Force.com for PayPal X Payments Platform The toolkit allows you to extend your Force.com applications to easily handle payments, preapprovals for payments, refunds, and the use of foreign exchange currency conversion rates. The toolkit provides direct access through native Apex code to the Adaptive Payments and Adaptive Accounts APIs
SalesforceCFC - A ColdFusion Toolkit for Force.com An Adobe ColdFusion CFC that allows you to connect and work with Force.com by generating SOAP requests and parsing their responses 37. 1salesforce-partner-program
2 package-publisher-home 3 appexchange-howto-create-trial 4 appexchange-popular-free-apps 5 api-quickstart 6 web-service-api-cheatsheet 7 partner-enterprise-wsdl 8 partner-api-java-code-sample 9 enterprise-api-code-sample 10 outbound-messaging 11 building-outbound-messaging-listener 12 api-quick-start-steps 13 restful-web-service-sample 14 bulk-api-limits 15 sfdc-wsc 16 axis-vs-wsc 17 tolerado-web-service-client-wrappers 18 salesforce-oauth-provider 19 salesforce-oauth-consumer 20 erp-connectors 21 lotus-notes-connector 22 connect-outlook, excel-connector 23 php-toolkit 24 self-service-portal-php-toolkit 25 php-bulk-api-client 26 ajax-toolkit 27 beatbox-python-toolkit 28 suds-python-toolkit 29 toolkit-google-data-apis 30 toolkit-office 31 toolkit-google-app-engine 32 zkSforce 33 toolkit-amazon-web-services 34 toolkit-facebook 35 toolkit-ruby-on-rails 36 toolkit-perl 37 toolkit-coldfusion
Advanced Development Examples
Through the course of our journey with salesforce.com and the Force.com Platform we’ve discovered a number of common patterns and best practices in the programmatic development arena. Having molded these cookie-cutter solutions and noticed their overlap with common questions around the community we’ve posted a number of these on various blogs and forums. In this chapter we’ve collated many of our most useful articles into a single area for you to use as training exercises or reference material when encountering a complex development problem.
Using External ID Fields Salesforce.com has baked in some “magical” features into its platform. Two of our favorites are the upsert command and the use of External IDs. If you are new to the platform, you’ve probably seen the option of making a field an “External ID” during the new field creation process.
The External ID field allows you to store unique record IDs from an external system, typically for integration purposes. So if you have a bespoke marketing system running on SQL Server, it is may be easier to load, update and reference these external records in salesforce.com using unique IDs from SQL Server. Salesforce.com allows you mark up to 3 fields as External IDs and these fields must be text, number or email field types. Values in these External ID fields must also be unique and you can also determine whether or not values are case sensitive. There are three ways that you typically use External ID fields.
Loading Data from External Systems When you load data from external systems you may want to track the record from the external system for reference or if you want to make updates back into the external system. Simply mark a field as an External ID and the Force.com platform will ensure that each value is unique and that you don’t load duplicate records from the external system.
Making Fields Searchable When searching for custom object records from the sidebar the following fields are searchable: Name All custom auto number fields You can make fields searchable by marking them as an External ID. Some people “cheat” and mark fields that do not necessarily contain external record IDs so that they are searchable. For the advanced search, the following fields are searchable: All custom fields of type text Text area Email Phone So if you have a numeric field that is an External ID it will not be searchable via the advanced search. You could create a text External ID field and then write a workflow that updates this field from the numeric External ID field. This way your external ID is searchable.
Data Integration This is where the External ID field really earns its keep. When using the upsert command during data loading, you can reference the External ID field instead of the salesforce.com ID. This is a huge advantage because you typically don’t want to maintain the salesforce.com ID in your external system. When uploading data with the Import Wizard, Data Loader or (most) ETL tools like Boomi or Informatica, there is a setting to specify that a field is an External ID.
Salesforce.com Import Wizard
Data Loader
Boomi Atomsphere
If you are loading data from an external system, External IDs will definitely become your best friends.
Visualforce Component Ids & JavaScript Salesforce.com used in conjunction with JavaScript and Ajax can be very impressive. One simple frustration we’ve come across is that of retrieving elements by Id. Salesforce.com has an intelligent scheme in place, which ensures that HTML elements don’t have duplicate Ids and therefore conform to W3C standards. Consider the following Visualforce code in Listing 6 - 1.
Listing 6 - 1. A Simple Visualforce Page
The generated element Id for the outputText field would be thePage:theBlock:theText and not simply theText. In terms of web-standard conformity this is great, but for the beginner combining JavaScript and Visualforce this can be a nightmare. Imagine you have an outputText field nested ten levels deep within the page. Were you to hardcode the Id of this element within your JavaScript you have to bear the following in mind: Salesforce.com give elements random Id values if you don’t assign them explicitly. To prevent this you have to assign an Id to each parent element. If you change the page tree structure that precedes said element, you have to change the Id referenced in your JavaScript. Not the most fun you’ve had, and a lot of hard work if you ask me. Luckily there is a simple solution, and it’s easily maintained as well as flexible. All you have to do is assign the element value to a JavaScript variable just after it appears in the page (or at the same level within the DOM tree). The code would become:
Listing 6 - 2. JavaScript Variable Bound to Visualforce Component
Now you can reference the JavaScript variable theText from within you JavaScript code without worrying about changes to the DOM or assigning Ids to all parent elements.
Passing JavaScript Values to Apex Quite often we’ve needed to manipulate variable values in-page (Visualforce) with JavaScript, and then pass these modified values to Apex or a Standard Controller. The proposition is that you should be able the grab the input elements in a Visualforce page and then, using JavaScript, modify or add values to a form just before it’s submitted. An example is shown in Listing 6 - 3.
Listing 6 - 3 . Assigning JavaScript Values to Visualforce Components
If you were to click the button you’d save “Hello World” as a field value for that Experiment__c record. The great Dave Carroll has documented another neat approach to this solution on the Force.com Blog1.
ActionSupport with Facets and JavaScript You can make your UI much easier on your users by giving them clues on what is taking place when they click buttons, enter text or choose items in a picklist. This example shows how you can notify a user that something is taking place in the background when you are performing actions asynchronously. For the sake of example, it uses both facets and JavaScript. In this example the user simply enters their name in the text box. In Listing 6 - 4 below we’ve added an actionSupport component to the inputText component. This allows us to invoke a method (specified in the action attribute) in the controller as the result of a JavaScript event. The attributes for the actionSupport component indicate:
action – the method to be invoked in the controller event – the JavaScript event that invokes the method reRender – the IDs of the components that are redrawn as a result of the AJAX update request returned from the controller status – the ID of the component that displays the status of the AJAX update request So when the user enters their name and removes focus from the text box, the JavaScript event fires and invokes the method in the controller. The status component is also invoked to display the messages to the user. In this case the start attribute calls the JavaScript start() method, which dynamically modifies HTML elements on the page. When the AJAX call returns from the controller, the actionStatus component specifies that the stop facet should be displayed as well as the stop() JavaScript method. This modifies HTML elements and displays messages to the user. The actionSupport component invokes a reRender of the pageMessage and thankyou outputPanel components so that our new messages from the controller display properly.
Listing 6 - 4. Providing Feedback to Users in Visualforce
The controller for this example is fairly simple as seen in Listing 6 - 5. The constructor simply initializes the value of counter to 0 when initially
loaded. Each time that the user removes focus from the textbox, the processName() method is called. This method increments the counter and passes text to the addThankYou and addPageMessage methods. These methods construct the text for the messages displayed to the user.
Listing 6 - 5. The Controller for the page in Listing 6 - 4
} Not every Visualforce component supports partial page refreshes. If you are using one that is not supported, you can wrap it in an outputPanel component in order to action a reRender.
Passing Parameters with a CommandLink Listing 6 - 6 is a small example of how you can pass a value to another method via a commandLink. When the link is clicked, the setter fires for the public member nickName. The button click then calls the processLinkClick() method where you can do something like process the variable further with DML statement or running a SOQL query with the value.
Listing 6 - 6. Commandlink Passing Parameter Values to a Controller
The processLinkClick() method in Listing 6 - 7 is called after the setters fire, performs some processing and returns a null PageReference allowing the Visualforce page to refresh.
Listing 6 - 7. The Controller Extension
Passing Parameters with a CommandButton In theory you should just be able to switch out the CommandLink component with a CommandButton component and be golden. However there seem to still be a bug with the CommandButton component. Listing 6 - 8 is a Visualforce page with the CommandButton instead of the CommandLink.
Listing 6 - 8. Visualforce Page with CommandButton and Param
As with the CommandLink, when the user clicks the button the setters should fire and then call the processButtonClick() method to allow further publishing. However, the setter for nickName is never called!
Listing 6 - 9. Controller Extension for the page in Listing 6 - 8
} You can make the CommandButton function as advertised if you use a reRender attribute and hidden pageBlock component. If you run the Visualforce page in Listing 6 - 10 with these modifications the setter will actually fire and set the value of nickName correctly.
Listing 6 - 10. CommandButton with Params Hack
Using Anonymous Code Blocks Anonymous blocks provide the ability to execute a section of Apex code on the fly. As an example, imagine that you need to clean your salesforce.com data. Either you’ve changed your logic and that data is affecting functionality, or perhaps you need to remove data en masse. This is simple with Anonymous Blocks; just write up a short script that will restore your data to a cleaned state and save it for future use. Any time things get messy just run your script the baseline will be reestablished. The scripts would be written in Apex code without the need for the enclosing class structure (although feel free to declare classes within your scripts).
One danger with code executed in Anonymous Blocks is that the ease with which the scripts can be invoked makes it tempting to run code without first testing it. Rather spend 20 minutes testing scripts in a sandbox than run them immediately in production; and then working for several days to fix corrupt data. You can execute code in this fashion from 3 separate areas: 1. The in-browser System Log
2. The Force.com IDE
3. The executeAnonymous Force.com Web Services API call ExecuteAnonymousResult executeAnonymous(String code)
Considerations There are a number of considerations when working with Anonymous Blocks, the only one we encounter often being that you cannot reference variables before their declaration within the code i.e. if a variable is declared at line 40, a method declared before this line cannot reference said variable.
Use an Inline Visualforce Page with Standard Page Layouts Using standard page layouts is easy; throw some field on the page, arrange some related lists and then essentially forget about the page. However, if you really need to customize the user experience you are almost always forced to write a custom Visualforce page that may require maintenance in the future. But what if you just want to tweak the page layout and give it a little Visualforce oomph? Perhaps a custom related list from multiple objects, a Flickr mashup or a Google map of your contact’s current location? You can add Visualforce pages to standard page layouts in the same way you could with S-Controls. The use case is that you have accounts with hundreds of opportunities each and users are getting tired of scrolling through pages and pages of records to find the ones that they need. In this example you’ll develop a Visualforce page and controller extension that provides them with an opportunity search interface on the account details page. Figure 6 - 7 shows what we’re looking to build.
First we need to create the Visualforce page and controller extension as detailed in Listing 6 - 11. Your Visualforce page must use the standard account controller (as shown in Listing 6 - 12) or it will not show up on the list of available Visualforce pages on the page layout.
Listing 6 - 11. The Search Page Controller Extension
Listing 6 - 12. The Visualforce Search Page
Now all you simply have to do is add this new Visualforce page to your page layout and the job is done.
Apex Search with Checkbox Results using a Wrapper Class This demo is a single Apex custom controller, two Visualforce pages and a wrapper class allowing the user to search an object by keyword (via Dynamic SOQL) and return the results in a pageBlockTable with corresponding checkboxes. Selecting one or more checkboxes and clicking the See Results button displays the list of the selected items. This is a very common function, as you typically want to search for records and then process the selected subset.
You can run this sample at http://jeffdouglas-developer- edition.na5.force.com/examples/category_search
Listing 6 - 13. Custom Controller for Searching Categories
Listing 6 -14 . The Visualforce Search Page
Listing 6 - 15. Visualforce Results Page
Listing 6 - 16 . The SObject Wrapper Class
Dependent Multi-level Pick Lists This demo details how to create a Visualforce page with 3 picklists which operate in a hierarchy i.e. the values available in the second picklist are dependent on what has been selected in the first, and the values in the third picklist are similarly dependent on the value selected in the second picklist. In this example the picklists span 3 separate custom objects.
Figure 6 - 9. Visualforce Page Showing Dependent Picklists Listing 6 - 17. Visualforce Page Containing Picklists
Listing 6 - 18. Corresponding Controller Extension
Uploading a Document using Visualforce
The salesforce.com documentation for the inputFile Visualforce component has an example of uploading a document using the Standard Controller. Here is a quick example of using a Custom Controller in case you want to make the upload process part of a larger transaction.
Figure 6 - 10. Visualforce Form for Uploading a File Make sure you take a look at the finally-block in the controller below. The finally-block always executes when the try block exits regardless if an error occurs or not. You need to ensure you clear out document's body (document.body = null) so that the blob is not automatically included in the serialized image of the controller. If you do not clear out the body, you'll get the following view state error:
Maximum view state size limit (128K) exceeded. Actual viewstate size for this page was… Listing 6 - 19. File Upload Visualforce Page
Listing 6 - 20. Custom Controller to Perform Server-Side Upload
Uploading an Attachment using Visualforce This demo builds upon the previous one, showing an example for uploading an attachment for a contact. The Visualforce page and Controller is very similar with a few exceptions.
Figure 6 - 11. Visualforce Form for Uploading a contact Attachment Attachments are different than Documents and are only available for the following objects: Account Asset Campaign Case Contact Contract Custom objects EmailMessage EmailTemplate Event Lead Opportunity Product2 Solution Task Salesforce.com restricts an attachment size to a maximum size of 5 MB. For a file attached to a Solution, the limit is 1.5MB. The maximum email attachment size is 3 MB. You can contact salesforce.com support and possibly have them increase these limits. They should be able to increase the document and attachment size to 25MB. They cannot increase the limits for emails.
Listing 6 - 21. Visualforce Code for Upload an Attachment
Listing 6 - 22. Corresponding Controller for Uploading Attachments
Visualforce and CSS When you start working on the Force.com platform, CSS is an area that can seem fraught with clunky hurdles. Overriding the salesforce.com CSS is a nightmare and we would recommend you either use the styles as salesforce.com has created them or start from scratch. Whether using the standard stylesheets or starting from scratch, the incorporation of CSS into your page can be very time consuming, especially if you are using images within your CSS. The typical process of developing CSS within Visualforce might be: 1. Create a stylesheet with however many styles. At this point (unless you've used an external editor) you have no way of quick-viewing the result. 2. Include said stylesheet and all referenced images in a zip file. Take care to preserve the directory structure so that you can reference all stylesheet and image files correctly. 3. Upload the zip file as a static resource. 4. Create references to the stylesheet in appropriate pages. 5. View page. If at this point you need to adjust your coded CSS you'll need to go through the process from steps 1 to 5 once again. Luckily there are a few neat solutions to this problem.
Visualforce Pages as Stylesheet Documents The Visualforce page component has an attribute called contentType. Setting this attribute to text/css will instruct the page to render as a CSS document. You can then use the stylesheet component to include this "CSS page" in the pages you wish to style.
Pros
Quick prototyping of stylesheets as they can be edited in the Force.com IDEs Can include calls to controller methods and global variables so values can be dynamic Can include static resources as images
Cons
Not efficient as can't be minified or compressed You lose the neat organization of the traditional arrangement of files and folders
Plaintext Static Resources as Stylesheet Documents Here you'll need to upload an empty text file or an existing stylesheet - in their plaintext form - as a static resource. Next you'll need to subscribe to the metadata for that static resource in an Eclipse project. Double clicking on the file in the IDE will open it in plaintext in it's own tab and (voila!)
you'll be able to edit the contents directly. To include the stylesheet in a page all you'll need is the standard stylesheet component, and then refer to the static resource by name.
Pros
Quick prototyping of stylesheets as they can be edited in the Force.com IDEs
Cons
Can't reference any resource outside of the file Not efficient as they're not minified or compressed You lose the neat organization of the traditional arrangement of files and folders, and will probably end up with a proliferation of CSS static resource files In reality we tend to use one of the above approaches until our CSS reaches a relatively complete state with regards to our project goals. Once we are done we bundle the CSS and images into a well-organized folder structure which we then compress and upload as a static resource. Of course then you'll need to update any pages that referenced the old static resource.
Can you guess how to minimize risk here? What about wrapping the reference to the stylesheet in a component and using that in all your pages? Or perhaps using a Visualforce page as a site template and only including stylesheets there? Either way you only need to make change in one place.
Redirecting Users to Different Visualforce Pages If your Org has a large number of records types, page layouts and Visualforce pages you'll eventually be required to route users to various pages depending on roles and/or profiles. Unfortunately, you cannot assign Visualforce pages by record type so you have to implement a hack around it. What you need to do is create a "dispatcher" Visualforce page and accompanying controller extension, and then override the appropriate button/link action (view, edit or new) with this new dispatcher Visualforce page. The code is slightly different depending on whether you are doing view, edit or new so we'll be showing them all. When a user clicks the view button/link for appropriate object, it loads the new Visualforce page. The Visualforce page loads the controller extension and performs some logic to determine if the user should be dispatched to your new view page (Contact_View_1) or the standard salesforce.com view page. You'll need to override each link and button to call the specific Visualforce page as described in Chapter #2.
Listing 6 - 23. Dispatcher Page for Viewing contacts
Listing 6 - 24. Controller Extension for the "View" Dispatcher Page
The code is somewhat similar for the edit and new use cases but does have some notable differences.
Listing 6 - 25. Dispatcher Page for Editing contacts
Listing 6 - 26. Controller Extension for "Edit" Dispatcher Page
Listing 6 - 27. Dispatcher Page for Creating contacts
Listing 6 - 28. Controller Extension for "New" Dispatcher Page
RESTful Web Service Callouts using POST The addition of asynchronous Web service callouts to external services is a feature that developers have been requesting for quite awhile in salesforce.com. Using the new @future annotation, your methods execute the callout when salesforce.com has resources available. One of the great benefits is that it allows you to perform callouts during trigger executions. One method of performing callouts is to import your WSDL and let Apex do all of the heavy lifting (WSDL2Apex). The major problem that we found is that Apex does not support RPC/encoded services at this time. Apex does support HTTP service classes which will allow you to create RESTful services as an alternative. The HttpResponse class provides a simple GET example but it was hard to find any examples using POST.
Listing 6 - 29. Apex Class to Perform HTTP POST
You can execute your callout in a trigger as in Listing 6 - 30.
Listing 6 - 30. Example Usage of HTTP Method Call from a Trigger
A couple of things to remember when using the future annotation: No more than 10 method calls per Apex invocation No more than 200 method calls per salesforce.com license per 24 hours The parameters specified must be primitive data types, arrays of primitive data types, or collections of primitive data types. Methods with the future annotation cannot take sObjects or objects as arguments. Methods with the future annotation cannot be used in Visualforce controllers in either getMethodName or setMethodName methods, nor in the constructor.
Force.com & Case-Sensitivity The Force.com platform is mostly case-insensitive. It's difficult to find information on which areas are case-sensitive so we've compiled this list of what we've discovered thus far.
Visualforce Templates The name attribute of the define component when referring to an insertcomponent name. A suitable example might be that your application uses a Visualforce page as a template and this template has an insert component, which allows you to merge other page content with the template. The code for the two pages is shown in Listings 5 - 31 and 5 - 32.
Listing 6 - 31. A Visualforce Template Page
Listing 6 - 32. A Visualforce Content Page that Implements the Template Page
Note the name of the insert component is "Content". Were you to change the name of the define component to "cOTenT", the define component would be ignored. This behavior isn't obvious, nor is it consistent since the string value used by the template attribute of composition component is case-insensitive.
Apex Sets and Maps Listing 6 - 33 shows that Set values are case-sensitive; the uppercase and lowercase "A" are considered to be two separate values.
Listing 6 - 33. A Set with Two Values
From this you can deduce that the range of key-values in a Map is also case-sensitive (they are contained in a Set).
Component Ids & ReRender Visualforce component Ids are case-sensitive when used in a reRender attribute. Our guess is that this area is case-sensitive because JavaScript (a case-sensitive language) is being used behind the scenes.
Salesforce.com 15 character Ids 15 character IDs are case-sensitive, but 18-character IDs are case-insensitive. There is an algorithm for changing between the two, but the easiest ways to do this are Use the FIXID() formula in the Excel Connector Use Jeff Douglas' Force.com Utility Belt for salesforce.com Assign an Id contained String-value variable to an Id-value variable in Apex
Most String methods This area of case-sensitivity is quite logical since these methods are tasked with working specifically on text. More information on String methods can be found in the salesforce.com Documentation.
Calling a REST Web Service (XML) This is an example of calling a REST web service with Apex. You enter your address and the Apex code fetches the geo coordinates from Yahoo! Maps. The service returns the data as XML. If you want to run this demo in your own Org, you will need to do the following: Add a "Remote Site"(Setup - Security Controls -> Remot Site Setting) with the URL: http://local.yahooapis.com
You can run this sample at https://jeffdouglas-developer-edition.na5.force.com/examples/RestDemo The Visualforce page in Listing 6 - 34 presents the user with address fields that they submit to the controller. The controller calls the REST web service and then displays the resulting geo coordinates to the user.
Listing 6 - 34. Visualforce Address Search Using Yahoo! Maps
The submit method in Listing 6 - 35 is invoked from the Visualforce page when the user clicks the submit button. It passes the address info to the getMap() method which does the GET call to the REST service. We've used the XmlDom class to parse through the results and construct a GeoResult object (from the inner class) and then present the info as a String to the user on the Visualforce page.
Listing 6 - 35. Controller used to make RESTful Call to Yahoo! Maps API
Calling a REST Web Service (JSON) Using JSON RESTful Web Services with salesforce.com opens up your Org to a number of third-party integration opportunities (Google, Yahoo!, Flickr, bespoke, etc.). JSON support isn't baked into the Force.com platform but Ron Hess at salesforce.com has ported the JSON parser that will do the heavy lifting for you. We've put together a small demo where you enter your address and the Apex code fetches the address and coordinates from the Google Maps. The service returns the data as a JSON object.
You can run this sample at https://jeffdouglas-developer-edition.na5.force.com/examples/RestDemoJson To get started, you'll need to download the JSONObject class and install it into a Developer Org or Sandbox. Unfortunately there is no documentation for the parser so you have to extrapolate from the json.org website. You'll also need to sign up for a Google Maps API key in order to use their geocoding service. We would also recommend that you take a look at the docs for Google Maps geocoding service. Listing 6 - 36 is the Controller for the demo. The interesting stuff is in the getAddress() and toGeoResult() methods. In getAddress() the userentered address is used to construct the URL for the GET call to the geocoding service. Make sure you properly encode the address or you may receive undesirable results returned from Google. One thing to point out is line #58. Google is returning a line feed in their JSON response that causes the JSON parser to choke. We simply replace all like feeds with spaces and that did the trick. Ron was going to look into making this change to the JSONObject class in the near future. We were also having some problems with the geocoding service so we hard-coded the returned JSON object for testing. We checked around and it seems to be a common problem that the Google Maps API randomly returns 620 errors when overloaded. You might want to take a look at the JSON response returned for the hard-coded address. We will give you a little insight for the parsing process. The toGeoResult() method parses the returned JSON response and populates the GeoResult object with the appropriate data. We chose this Google Maps example because it shows how to parse simple values, nested JSON objects and arrays. The coordinates for the address can either be returned as integers or doubles so we've had to check each one.
Listing 6 - 36. Controller to Make RESTful Calls using JSON
The Visualforce page is fairly simple and presents the user with a form to enter their address. If the geocoding services is experiencing issues, the user can check "Use hard-coded Google JSON response?" and the Controller with use the hard-coded JSON response instead of making the GET call to the geocoding service. Once submitted, the address is processed and the outputPanel is refreshed with the resulting address and coordinates.
Listing 6 - 37. Visualforce Page used to Geocode Address Information
Locking sObject Records Salesforce.com has the ability to lock sObject records while they are being updated to prevent threading problems and race conditions. To lock records, simply use the FOR UPDATE keywords in your SOQL statements. You do not have to manually commit the records so if your Apex script finishes successfully the changes are automatically committed to the database and the locks are released. If your Apex script fails, any database changes are rolled back and the locks are also released.
Listing 6 - 38. Locking Records During Updates
The Apex runtime engine locks not only the parent sObject record but all child records as well. So if you lock an opportunity sObject all of its opportunity Line Items will be locked as well. Other users will be able to read these records but not make changes to them while the lock is in place. If your record is locked and another thread tries to commit changes, the platform will retry for roughly 5 -10 seconds before failing with a "Resource Unavailable" error. For end users, we believe if they try to save a locked record from the salesforce.com UI, they will receive an error message stating that the record has been changed and that they should reload the page. We can't confirm but we've seen this in the past.
Automating Approval Processes with Triggers This question came up on LinkedIn asking how to automatically fire off an approval process when an opportunity reaches 30% probability. The trigger fires when an opportunity is updated and is submitted for approval if the opportunity's probability has moved from less than 30% to greater than or equal to 30%. For the trigger to work you need to have an approval process with matching criteria. Mine is fairly simple and is where the opportunity owner is the current user (there is only one user in a DE Org). The trigger makes no attempt to trap for errors if an approval process doesn't exist.
Listing 6 - 39. Trigger to Fire Off Approval Process
Here is the test class but you might want to enhance it to handle bulk operations and opportunities that are not submitted for approval because their probability is not greater than 30%.
Listing 6 - 40. Test Class for Approval Trigger
Enhancing the Lead Conversion Process During the salesforce.com lead conversion process you can create an account, contact and opportunity for the lead that is being converted. The process is pretty straightforward and salesforce.com provides some tools for customizing it: Salesforce.com allows you to automatically map standard and custom lead fields to account, contact, and opportunity fields.
Apex triggers are fired and universally required custom fields and validation rules are enforced only if validation and triggers for lead convert are enabled in your Org. However, there may be some instances when a use case requires more complex processing. For instance: Whenever a new contact is created from a lead, a custom object is created that is associated to the contact. Whenever a new account is created, a callout is made to an external web service. Whenever a new opportunity is created, a number of standard products are added to the opportunity. Listing 6 - 41 is a sample trigger that, for simplicity, does not operate for bulk inserts but gives you a good head start. Check the salesforce.com documentation on the conversion process.
Listing 6 - 41. Trigger to Enhance the Conversion Process
Using Email Templates with Apex There are often a number of new questions in the forums asking how to use email templates from Apex classes. The documentation on the topic is spread over many articles so we've collated those and other findings here. To start with note that there are a number of email template types: Text HTML Custom
Visualforce Each has its own application and you can easily make them professional. Salesforce.com stores these as records in the EmailTempate object allowing you to query for them by name. As shown in Listing 6 - 42 you'll then need to assign this template to the mail you're sending.
Listing 6 - 42. Assigning an Email Template to an Email
Notice how there's no need to specify the to-addresses, the subject, or the email body; they're all pulled from the template. Some important considerations are: When querying for an email template always use the developerName field. If a power user decides to change the name of the template they're less likely to change the unique name too, this way you have a (small) safety net. Of course you should always wrap this query in an exception handler. Visualforce templates can't be used in bulk emails. After you've created a template you need to make sure that you set it as Available to Use (an option on the template detail page), or emails using the template won't be dispatched.
Writing an Inbound Email Service Creating an inbound email service for salesforce.com is a relatively straightforward process but there are a few tips that can make your life easier. The email service is an Apex class that implements the Messaging.InboundEmailHandler interface which allows you to process the email contents, headers and attachments. Using the information in the email you could for instance create a new contact if one does not exists with that email address, receive job applications and attached the person's resume to their record, or have an integration process that emails data files for processing. You access email services from Setup -> Develop -> Email Services. This page contains the basic code you will always use to start your Apex class. Simply copy this code and create your new class with it. Click the New Email Service button to get started and fill out the form. There are a number of options so make sure you read carefully and check out the docs. One handy option is the Enable Error Routing, which will send the inbound email to an alternative email address when the processing fails. You can also specify email address(es) to accept mail from. This works great if you have some sort of internal process that emails results or files for import into salesforce.com. Just like Workflow, make sure that you mark it as Active or it will not work. After you save the new email service, you will need to scroll down to the bottom of the page and create a new email address for the service. An email service can have multiple email addresses and therefore process the same message differently for each address. When you create a new email service address you specify the "Context User" and "Accept Email From". The email service uses the permissions of the Context User when processing the inbound message. So you could, for example, have the same email service that accepts email from US accounts and processes them with a US context user and another address that accepts email from EMEA accounts and processes them with an EMEA context user. After you submit the form the Force.com Platform will create a unique email address like the following: testemailservice@8q8zrtgg1w37vpomrhpqftj25.in.sandbox.salesforce.com This is the address you send your email to for processing. Now that the email service is configured you can get down to writing the Apex code. Listing 6 - 43 is a simple class the creates a new contact and attaches any documents to the record.
Listing 6 - 43. Inbound Email Handler Class
One of the difficult things about email service is debugging them. You can either create a test class for this or simply send the email and check the debug logs. Any debug statements you add to your class will show in the debug logs. Go to Setup -> Administration Setup -> Monitoring -> Debug Logs and add the Context User for the email service to the debug logs. Send an email to the address and check the debug log for that user. One thing we wanted to see was the actual text and headers that are coming through in the service. Figure 6 - 12 shows virtually all fields and headers in a sample email.
The code in Listing 6 - 44 will give virtually 100% code coverage for the previous class.
Listing 6 - 44. Unit Test for Inbound Email Handler
Unit Tests & Code Coverage The most common question with regards to unit testing seems to be, "Why can't I get code coverage for my entire class?" The trick here is to think like a runtime engine, and consider how you might journey through all possible testing paths. In this article we'll touch on some of the more common test-situations.
If-Else Statements This situation comes about when we have a piece of code something like that in Listing 6 - 45.
Listing 6 - 45. Class with If-Else Branches
Assume that a field on a Visualforce page sets the variable var during normal operation. Your test methods have to mimic this behavior and set the value programmatically. Not only this, but your need to set the variable var to each of the values required to step through each branch of the if-else statement. Further to this, we would suggest a test method for each of the values that var can assume. This requires a lot of work but it makes for test code that is easier to understand and maintain. The test code for this class is shown in Listing 6 - 46.
Listing 6 - 46. Test Class for If-Else Branches
For-Loops A contrived for-loop example is detailed in Listing 6 - 47.s
Listing 6 - 47. Class Using a For-Loop
If you're not getting code coverage in methods similar to aMethod() and anotherMethod() you probably have an empty or null list i.e. the list accounts is empty, or the SELECT id FROM Account WHERE condition = truequery is not returning any values. A few well-placed System.debug() messages will tell you where you're going wrong.
Exceptions The last – and trickiest – case we'll cover is exception handlers. The reason they're more complex is that you need to test expected input and situations as well as erroneous input or unexpected situations. Listing 6 - 48 shows the class to test.
Listing 6 - 48. Apex Code That Throws Exceptions
We would suggest writing a single test method to cover the try-part, and a separate test method to cover the catch-part as shown in Listing 6 49.
Listing 6 - 49. Test Code for Exception Handlers
Testing exceptions can be further complicated where you need to catch more than one type of exception as in Listing 6 - 50.
Listing 6 - 50. Try-Catch Block with Multiple Exception Handlers
Here we'd suggest we have a test case for the try-part, as well as one for each of the catch-statements. Some other helpful tips when unit testing are: Always run your tests from the Force.com IDE There are different schools of thought on this but we'd recommend only testing your public methods Read through the Force.com IDE code coverage report. It will tell you which lines of code haven't yet been tested Split out your test methods into separate classes from those they are testing. This allows you to use the @isTest annotation so that test code isn't counted against your Org. It also makes maintenance (especially in teams) much easier These samples are relatively simple, but you'll notice that even your most complex code is a mixed bag of these situations. One feature of good software development is being able to break a complex problem down into smaller parts and analyze those independently.
Programmatically Creating Sharing Rules Listing 6 - 51 is a small Apex Trigger that demonstrates how to programmatically create sharing rules for objects with a private sharing model.
The example scenario is that the object has a private sharing model (contacts in this case) so that only the record owner and users higher in the role hierarchy have access to it. We've added a checkbox to the contact object called "Make Public" that when set to TRUE, creates a sharing record for a specific group (e.g., All Internal Users). When set to FALSE, it deletes all manual-sharing rules for the record. You can modify this to add multiple groups or even make it operate on the reverse (public by default and then remove the sharing rules).
Listing 6 - 51. Trigger to Create Sharing Rules
Listing 6 - 52. Test Code for the Previous Trigger
Something to remember when transferring accounts and their related data is that all existing sharing rules will be removed. Any relevant sharing rules are then applied to the records based upon the new owners. You may need to manually share these accounts and opportunities to grant access to certain users and/or groups.
Rolling Back Transactions with Database Savepoints
Transaction control is an important part of any system that interacts with a database and salesforce.com has neat ways of implementing said control. Anyone that's worked with SQL databases will be familiar with savepoints and rolling back, and salesforce.com has implemented similar constructs. For those who haven't heard of these terms Wikipedia describes them thus:
A savepoint is a way of implementing subtransactions (also known as nested transactions) within a relational database management system by indicating a point within a transaction that can be "rolled back to" without affecting any work done in the transaction before the savepoint was created. A rollback is an operation, which returns the database to some previous state. Listing 6 - 53 demonstrates a single method that inserts two object records, which are related by a master-detail relationship.
Listing 6 - 53. Code to Insert Related Records
If the DML operation on the Parent__c object record fails, the Child__c object record will have been inserted but not attached to any master record. Depending on your data model this can lead to an erroneous data states and/or unnecessary storage usage. Luckily savepoints and rollbacks are a very easy to implement and solves this issue robustly. The revised code is shown in Listing 6 - 54.
Listing 6 - 54. Related Record Inserts Using Savepoints
Some points to consider when using savepoints and rollbacks are: You can continue processing after a rollback but note that only database DML will be undone, variable values will not be rolled back. You cannot rollback across triggers. You can only set five savepoints across all contexts. For this reason we find it's usually a good idea to have at least a one-to-one ratio between class and test methods
Enforcing Security With Sharing Keywords Security is a major foundation of the Force.com platform. Not only is security available declaratively but it is also baked into the Apex language itself. Most Apex scripts run in system context without respect to the current users permissions, sharing rules and field level security. This ensures that triggers and web services have access to all records in the Org, which is usually a good thing. However, to ensure that you don't expose sensitive data to unauthorized users, you can specify that an Apex script does enforce the running user's profile-based permissions, field-level security, and Org-wide defaults by using the with sharing keywords when declaring your class. This can affect SOQL and SOSL queries as well as DML operations.
Listing 6 - 55. Class Implemented With Sharing
You can also use the without sharing keywords to ensure that Apex scripts do not enforce the sharing rules of the running user.
Listing 6 - 56. Class Implemented Without Sharing
It's best practice to use these keywords when declaring new classes because if they are not used the current sharing rules remain in effect. For example, if a class calls another class with no sharing-keywords specified then the sharing is enforced by the first class. You can also declare inner classes and outer classes as with sharing as well. The sharing setting applies to all code contained in the class including initialization code, constructors, and methods but inner classes do not inherit the sharing setting from their container class. One exception is executeAnonymous, which always executes using the full permissions of the current user.
Working with Person Accounts Out of the box (so to speak) salesforce.com is a B2B product. But what if your company provides home healthcare services or lawn care services or any other type of service for individual consumers. You don't hear a lot of talk about it but salesforce.com can be tweaked for this scenario using "person accounts". By default, person accounts are not enabled. You'll need to call support to have them enabled and they will repeatedly ask you if you really want to do this and if you understand the consequences. Once enabled, person accounts cannot be disabled. We would recommend you enable a Developer Edition Org first and test out your solution there before enabling your Production Org. So what actually happens when you enable person accounts and what are the consequences? The salesforce.com Help has a lot of good info on person accounts but we wanted to dig in and really see what was happening in the background. In most situations, you can use person accounts as if they were contacts. You can include them in all contact list views except the Recent Contacts list on the contacts home page. So when person accounts are enabled you'll see a new set of menu items under Setup -> App Setup -> Customize -> Accounts. You can configure person account page layout like you would any other type of page layout. You'll need to go and assign the new record type to each of the profiles that need access to it.
Once you've done they you will be able to create accounts for Business and Personal record types. When you click the New Account button you'll receive a picklist asking you which type to create.
So what happens when you create a new person account? A person account is a combination of both an account and contact record. When person accounts are enabled, the following fields are added to the account object: 1. FirstName 2. LastName 3. IsPesonAccount 4. Languages_pc 5. Level_pc 6. PersonAssistantName
7. PersonAssistantPhone 8. PersonBirthdate 9. PersonContactId 10. PersonDepartment 11. PersonEmail 12. PersonEmailBouncedDate 13. PersonEmailBouncedReason 14. PersonHomePhone 15. PersonLastCURequestDate 16. PersonLastCUUpdateDate 17. PersonLeadSource 18. PersonMailingCity 19. PersonMailingCountry 20. PersonMailingPostalCode 21. PersonMailingState 22. PersonMailingStreet 23. PersonMobilePhone 24. PersonOtherCity 25. PersonOtherCountry 26. PersonOtherPhone 27. PersonOtherPostalCode 28. PersonOtherState 29. PersonOtherStreet 30. PersonTitle 31. RecordTypeId 32. Salutation The following fields are not available for person accounts: 1. Parent Account 2. View Hierarchy 3. Reports To You can go to the person account page layout and add these fields to the page layout. However, you cannot add the contacts related list to the page layout. The Partner related list is available though so you can relate person accounts to one another.
When you create new person account records, salesforce.com creates not only an account record but also a contact record in the background. You cannot access the account record directly (it always relocates you back to the person account record) but it is needed for the functionality that requires a contact (emails, customer portal, etc.). Figure 6 - 16 and 6 - 17 show what the records look like from SOQL.
Some other things to take into consideration for person accounts include: 1. Person accounts can be associated with activities using either the Name or Related To fields. 2. Person accounts can be invited to group events and requested meetings. 3. Person accounts can be added to Campaigns and have a Campaign History related list. 4. For cases, person accounts can be entered in the account Name field, the contact Name field, or both. 5. You can add person accounts to the contact Roles related list on cases, contracts, and opportunities. 6. Custom objects with relationships to either accounts or contacts can be added as related lists on person accounts. 7. Person accounts can be enabled as users for your Customer and Self-service portals.
8. Person accounts are currently supported in Connect Offline and Connect for Outlook version 3.2 and later. They are not currently supported in Connect for Lotus Notes. 9. You can send individual emails and mass emails to person accounts. 10. For field history, account fields for person accounts can be tracked using the account field history settings, but contact fields for person accounts are configured on the contact field history settings page. 11. Person accounts have a unique import wizard so make sure you check the salesforce.com Help for more info. 12. Leads with a blank Company field are converted to person accounts. The default person account record type for your profile is applied to the new person account. 13. You cannot add a contact formula field that references the account object to person accounts page layouts. 14. Contact sharing is not available if you have enabled person accounts. The Org-wide defaults for contact is set to Controlled by Parent and is not editable. 15. If your company has customized your contact sharing settings and you want to enable person accounts, change your Org-wide default for contact to Controlled by Parent, which removes all your contact sharing rules and manually shared Contacts. 16. Person accounts count against both account and contact storage because the API considers each person account to consist of one account as well as one contact. 17. Creating or editing a person account triggers account workflow rules. 1 passing-javascript-values-to-apex
Summary
We had a great time writing this book. We really enjoy working on the Force.com platform and hope this book makes this apparent. We wanted to expose you to a large number of features rather than dive too deeply into any one area. We hope we’'ve armed you with a broad understanding of the possibilities of salesforce.com and the Force.com platform, and we look forward to seeing your innovative applications come to life.