Packaging Apex Enterprise Patterns (AEP) Into Salesforce DX

Standard

Recently I wrote about “Architecture Enterprise Patterns (AEP) and Salesforce DX” and how I believe they are going to dramatically change the landscape for Salesforce developers everywhere. Today I wanted to briefly outline my progress with this reality. As part of the Salesforce DX Pilot this year, I got a first hand look at what the future holds when it comes to managing your Salesforce orgs. In addition to that, this year, as we expand to a global footprint, I’ve made it my personal mission to prepare my company for enterprise level development. Thankfully with the help of contributors like Martin Fowler and Andrew Fawcett, I believe I’m off to a great start.

Prerequisites

I will make this guide as simple to follow along as possible, but it should be noted that in order to fully grasp the benefits of this package and its practices you should at least familiarize yourself with the following

Also, for the purposes of this tutorial I will assume that you are already using DX or familiar with it and simply guide your through my steps for an ideal packaging of AEP within the DX structure.

NOTE: I will continue to update this article as more of my perspective on DX and the AEP evolve.

Getting Started

You should already have the SFDX CLI installed and setup, as well authorized your Hub Org.

1. Create a DX workspace

Traditional Salesforce workspaces might include .config and .deploy meta folders as well as the src directory that houses /classes, /triggers, /etc. but a DX workspace is likely to follow the following structure.

<project root> / <package name> / <module name> / <your source in whatever directory structure you want>

Which could look something like this:

  • MyProject/main/default/classes
  • MyProject/main/test/classes
  • MyProject/main/test/classes

Now as DX becomes official this should become more clear, but either way the aim is to allow for more flexibility to decouple your APEX and meta data based on projects, packages, and modules. All that to say that we are going to setup a DX workspace just for our AEP project so that it can be managed in its own repository. To begin, run this from the directory you wish to store your workspace:

sfdx force:workspace:create -n apex-enterprise-patterns

This will create a /apex-enterprise-patterns directory with the default /force-app folder already setup. Once that’s created be sure to change directories into your new workspace:

cd apex-enterprise-patterns

2. Clone AEP packages to your workspace

We are going to now clone what I will refer to as the traditional or metadata api (mdapi) versions of the ApexMocks and ApexCommons (aka fflib) to our workspace (I’ve chosen to maintain this within the workspace so that I can more easily track future contributions to these public projects). We will begin with ApexMocks since it is a dependency of ApexCommons:

git clone [email protected]:financialforcedev/fflib-apex-mocks.git Packages/fflib-apex-mocks

Followed by:

git clone [email protected]:financialforcedev/fflib-apex-common.git Packages/fflib-apex-common

*NOTE: I deployed these to a /Packages directory so that I can more clearly indicate its purpose in the workspace

3. Convert MDAPI to Source

Next we need to convert the traditional mdapi structure to the new DX structure.

sfdx force:mdapi:convert -r Packages/fflib-apex-mocks/src -d force-app/apex-mocks

and

sfdx force:mdapi:convert -r Packages/fflib-apex-common/fflib/src -d force-app/apex-commons

*NOTE: Unfortunately at the time of this writing this conversion will create the following structure to include /main but in the future it may be possible to remove this unnecessary folder.

(Optional) As a preference I’m going to remove the /main directory and move the files respectively with the following:

mv force-app/main/default

Conclusion

In the future I may update this post with more details but rather than delay publishing my current progress I’m going to conclude my findings here for the moment. This should demonstrate some of the key differences between working with traditional mdapi and the new DX layout. With that said, keep in mind that only components within the DX model can be deployed through the force:push command. In addition, mastering the abilities of this new command interface does not have to be a daunting task of your development team, rather the aim should be to use these new abilities to script automated deployments and interactions.

Hopefully this brief example can still add some benefit to your adoption of Salesforce DX. If there is anything specific that you would like to see addressed still feel free to comment below and I will look to update the article accordingly in time. Thanks for reading!

Architecture Enterprise Patterns (AEP) and Salesforce DX

Standard

At this point many have heard about the rave behind Salesforce DX and the hope it brings. As DX begins to rollout in the following year, this is going to create an architecture paradigm shift in the entire Salesforce developer community in a very good way. In the past, Saleforce has been a foe to many developers, with its multi-tenant constraints, steep learning curve and uncooperative metadata structure, it has ranked as on of the most dreaded platform to develop on by the Stack Exchange Developer Survey in back to back years.

2016

2016 Stack Exchange Survey Results

2017

2017 Stack Exchange Survey Results

Salesforce Architecture for the Win!

DX is definitely a difference maker, but it alone is not the solution to better Salesforce development experience. One major aspect that is neglected in all programming, but can be detrimental to working with the Salesforce platform, is the lack of architecture.

As Martin Fowler put it, “Architecture is the sensibility behind the code” or in other words, “stuff that’s hard to change.” Too often we create our own obstacles writing software that we can’t manage as the project evolves, and likewise can’t be supported by others who all to quickly will refer to it as legacy code. But good architecture is a game changer, it is the difference maker.

We happen to be in a time where the stars are aligning and two opposing forces are working as one. The Salesforce organization is creating an overall better development cycle for devs, and the Salesforce community is embracing a more serious conversation about good architecture. On one end you wait expectantly on the GA release of DX, and on the other side you see the emerging conversation of Apex Enterprise Patterns (AEP). DX allows for Separation of Concerns (SOC) with the integration and deployment cycles, while AEP structures the SOC of your org or app’s codebase.

Conclusion

Based on these two developments, I’ve already begun to restructure our monolithic Salesforce org to a more modular structure; using AEP as a foundation while building separate projects, apps and features within their own separate repositories, capable of being provisioned together again. Check out “Packaging Apex Enterprise Patterns Into Salesforce DX” (coming soon) for a first-hand walk through of my initial experience bringing these two together.

Would love to hear any thoughts or feedback you have about this perspective on the future of Salesforce development. Thanks for reading!

Salesforce Certification Guide: Development Lifecycle & Deployment Designer

Standard

If you have ever attempted to get a Salesforce certification, you may find it stressful knowing how to best prepare for such a task. I attended Salesforce University 2017 and managed to get 2 certification within my 3 attempts. As a historically horrible test take this was a proud accomplishment for myself. As a self-taught developer, currently positioned as a Technical Architect, with ambitions to obtain the highly coveted Salesforce CTA title, I will never forgot the many people who gave back to the community to help me grow in this field.

With that said, I thought in a small way I could give back to anyone else with similar ambitions looking to prepare for the Salesforce Development Lifecycle & Deployment Designer Certification. After failing the test on my first attempt I felt mislead, I understood the concepts of everything the exam guide outlined, I can confidently say that I even feel comfortable teaching a class on it. So how could I have failed? Well for one the details on the test are not just conceptual understandings but specific terms and use cases that can’t necessarily be found by scouring Salesforce’s documentation even if you know what you’re looking for (which again the guide will not help you with).

Retrospective Guide

After absorbing my failure, I wrote down everything that I would need to get a more comprehensive understanding about so that I could debunk every tricky question I would encounter during my retake the following morning. This “retrospective guide” that I comprised that night helped my to pass the certification and I’m posting it in in case it can help you as well. This should not be your only source of study but I would definitely consider it your cliffnotes to make sure you know what to study so that you can be prepared. Good Luck!

Development Lifecycle & Deployment Design Guide:

I will put the important terms in headers with a description of what you need to know about it and any related bullet points I came across along the way.

Governance

Governance improves agility by ensuring all members of your team are working together to achieve. Three elements of a responsive, adaptable framework for governance are:

1. Circle of Excellence

A center of excellence (CoE) is a group of people who promote collaboration and best practices to ensure great business results. Need to understand the responsibility of this group and what decisions they are responsible for within the organization and throughout a given project

2. Release Management

Learn, educate, plan, communicate, test, go live, iterate. Understand the cycle of a release what challenges may arise. Keep in mind the Change Control Boards role within a release. Understand available tools like change sets and a sandbox to manage changes, and when it is appropriate to use them. Many question around scenarios that you must advise as a Technical Architect what is the best tool or solution to provide to ensure a release is deployed smoothly and on time.

3. Design Standards

When design or architectural questions arise you need to understand how the standards will dictate the direction going forward. Who governs and enforces these standards?

  • Standard naming conventions
  • Consistently using the Description field
  • Bulkified code
  • Standard methods for deprecating classes and fields
  • Consistent data architecture across all projects

The architect or architecture team in your center of excellence defines your company’s design standards

Roles

Program Sponsor

Need to know what their role is and what governance they have, meaning what decisions and/or will fall under their jurisdiction.

  • Executive responsibility for success of the project
  • Execution
  • Drives success

Steering Committee

Who makes up this committee? What is their responsibility within an organization and within a given project?

  • “Team of Champions”
  • Related to “Circle of Success”
  • Prioritize request
  • Review feedback
  • Cross-functional
  • Share decision-making: set and monitor the direction in alignment to the objectives
  • Info Resource – requirements gathering
  • Standardized Data – scale beyond 1 department

Change Control Board (CCB)

Who makes up this board? What responsibility do they have within an organization or a given project?

  • Decide whether the project/scope changes are implemented
  • When there is a diversion from the baseline requirements
  • Made up of stakeholders or their representatives
  • Ensure acceptance of project by client
  • Related to “Release Management”

Environments

Need to have a strong understanding of the different editions and their expected and appropriate use cases. Be aware of limitations when developing in a given edition with certain requirements or development team size. Also be able to advise a deployment plan against certain requirements including around Salesforce’s release schedule.

  • What edition org should be used for different types of testing?
  • When is the appropriate time to refresh a sandbox within a dev cycle?
  • How should you resolve a regression expected from upcoming Salesforce release?
  • What are the challenges of a large development team? Deployment, sandbox structure, etc.

Aloha Apps

There was one question where this appeared and it was the correct response to the scenario presented, in which the production org is approaching limits but still needs a new feature. Aloha Apps don’t count against your system limits for apps, tabs, and objects—no matter which salesforce.com edition you’re using

Change Sets

Don’t be fooled by the exam guide, this feature appears in more than 5% of the exam. The right answer may only be connected to 5%, but the feature itself appears several times throughout the exam.

You must understand the steps necessary to setup a change set, as well the limitations when attempting to use them

  • Cannot be used with developer orgs or orgs not related to your companies production or sandbox orgs.
  • The target site metadata will be locked during deployment.
  • Users can still read/write records (I found one question VERY confusing/tricky on this topic).

Methodologies

Depending on your experience or bias you may misunderstand some of the questions revolving around methodologies concerning a dev cycle. Keep in mind that both Agile and Waterfall have pros and cons and both can be used a wrong way and a right way. There is one question specifically that attempts to lead you towards agile alone given the time and budget constraints but Salesforce is using that to promote that waterfall too can adhere to those constraints if you use it correctly.

You don’t necessarily need to understand everything about the two approaches other than their main differences

Waterfall

Known for its structure, the ability to take on very large projects with massive requirements and provide documentation and actionable task towards a complete and through release. Praised for its completeness and adherence to governance but criticized for its clunkiness and heavy maintenance.

Agile

Known for its speed and efficiency, no project to big or small but thrives in small achievable deliverables. Criticized for its reckless nature of diving into the task without complete documentation of the requirements. It has the potential of providing immediate results with rapid deployment as its focus, but if not done properly it can miss the mark on the expected result for the end user.

Tools/Matrices

RTM (Requirements Traceability Matrix)

Used for tracking project requirements, great for outlining functional test that need to be accounted for during planning and project management. When refactoring code this can be helpful for creating regression test. Be aware of which scenarios this should be used

R.A.C.I. (Responsible, Accountable, Consulted, Informed)

Used to define each team member’s role and assists with reducing confusion on expectations, in turn, increasing project efficiency.

  • Responsible – Who is completing the task.
  • Accountable – Who is making decisions and taking actions on the task(s).
  • Consulted – Who will be communicated with regarding decisions and tasks.
  • Informed – Who will be updated on decisions and actions during the project.

Testing

Stress Testing

Gauge performance during abnormal/extreme conditions. Understand that stress testing is not necessary on the Force.com platform because Salesforce has already stress tested the platform so it is not necessary for you to

Load Testing

Gauge performance under expected conditions with varying loads. There are times where this is necessary but if so keep the following in mind:

  • Load testing on a sandbox will not provide the same benchmarks as a production environment. Variables include load patterns, database caching queue for @futures
  • In order to load test you must create a “test plan” that you submit to Salesforce for approval
  • TPS = Transactions Per Second. Used as metric for load testing.

Performance Testing

Gauge performance under particular workloads. This includes both stress and load testing collectively. You can test in sandbox to uncover conflicts between request (locking issues) or to test performance of external web services.

Apex Hammer

Mentioned at least a couple times during the test, but never appropriately from what I remember. At least understand that the Apex Hammer is a real thing (made that mistake my first attempt). Salesforce sometimes refers to this as “Hammer time”, and they do this during every release as a means of regression management.

In short, they use your unit test (even without asserts), to test against potential issues from their upcoming release. First they run all your test on its current version, then they run them again using the new version, its not important that the test pass or fail, but that the do not change results from the first or second attempt. If there is a difference in results then you will receive an email notification to update your Apex.

Tip: Even if the multiple choice suggest it, no you can not make arrangements with Salesforce to move the release date back, you will need to prioritize a fix by leveraging a sandbox that has the update.

Continuous Integration (CI) Considerations

You don’t need to use CI, but you need to understand its purpose and some considerations when advising its implementation as a technical architect

  • Uses Force.com migration tool
  • For small dev teams the only benefit is automated testing
  • For large dev teams you will benefit from commercial CI and custom builds.
  • Proper CI creates a new environment per a build cycle, this is not possible in Salesforce until the official release of Salesforce DX
  • This is a source control driven flow development workflow

Conclusion

I hope that helps someone out there cramming for their exam; if it does please comment below with any feedback. Also I don’t have everything listed (had over 20-30 tabs opened that night), but below are some of the references I used along the way as well as my original scratch notes. Also, remember to not limit yourself to Salesforce resources alone, some of the depth of the details you may need may be found elsewhere. Good luck!

Original notes

References

Buddypress: Set Up A Custom BP_Component

Standard

A BuddyPress component is the perfect approach to adding custom functionality to your BuddyPress installation.

BP_Component

These components are actually the same components used to provide Groups, Activities, Blogs, Forums, Profile Extensions, etc. to BuddyPress out of the box. Other than the code snippet thrown on the codex, there currently wasn’t any tutorials to guide a developer when getting started.

For that reason I’m posting my discoveries here, although I don’t claim to have all the answers myself, I’m simply trying to fill in the gaps while I attempt my first custom component. Most of my findings came from digging through the “BuddyPress Skeleton Component” plugin, as advised from the forums.

First off, we must hook and include our custom class:

function bp_example_load_core_component() {
    global $bp;
    $bp->example = new BP_Example_Component;
}
add_action( 'bp_loaded', 'bp_example_load_core_component' );

Our custom class must extend the BP_Component class:

“BP_Component is the base class that all BuddyPress components use to set up their basic structure, including global data, navigation elements, and admin bar information. If there’s a particular aspect of this class that is not relevant to your plugin, just leave it out.”

The Constructor

When constructing a BP_Component, although many things can happen here, at minimum you should invoke the parent::start() function in order to begin setup routine. This function receives 3 parameters:

  1. $id – A unique identifier for the component. Letters, numbers, and underscores only.
  2. $name – This is a translatable name for your component, which will be used in various places through the BuddyPress admin screens to identify it.
  3. $path – The path to your plugin directory. Primarily, this is used by BP_Component::includes(), to include your plugin’s files.

Next you’ll want to add any include files, depending on your components needs, this can include the following suggestions from the skeleton component plugin:

  • actions.php – Functions hooked to bp_actions, mainly used to catch action requests (save, delete, etc)
  • screens.php – Functions hooked to bp_screens. These are the screen functions responsible for the display of your plugin’s content.
  • filters.php – Functions that are hooked via apply_filters()
  • classes.php – Your plugin’s classes. Depending on how you organize your plugin, this could mean: a database query class, a custom post type data schema, and so forth
    activity.php – Functions related to the BP Activity Component. This is where you put functions responsible for creating, deleting, and modifying activity items related to your component
  • template.php – Template tags. These are functions that are called from your templates, or from your screen functions. If your plugin contains its own version of the WordPress Loop (such asbp_example_has_items()), those functions should go in this file.
  • functions.php – Miscellaneous utility functions required by your component.
  • notifications.php – Functions related to email notification, as well as the BuddyPress notifications that show up in the admin bar.
  • widgets.php – If your plugin includes any sidebar widgets, define them in this file.
  • buddybar.php – Functions related to the BuddyBar.
  • adminbar.php – Functions related to the WordPress Admin Bar.
  • cssjs.php – Here is where you set up and enqueue your CSS and JS.
  • ajax.php – Functions used in the process of AJAX requests.

Add to Active Components Array

Put your component into the active components array, so that bp_is_active( 'wizard'); returns true when appropriate. We have to do this manually, because non-core components are not saved as active components in the database.

$bp->active_components[$this->id] = '1';

Register Custom Post Type (Optional)

Hook the register_post_types() method. If you’re using custom post types to store data (which is recommended), you will need to hook your function manually to init.

add_action( 'init', array( $this, 'register_post_types' ) );

Setup Navigation Tabs (Optional)

If you intend to set up screens for your component and you would like navigation tabs then you will need to configure a setup_nav() method (see class-bp-component.php for details). Here is a quick example

/**
 * Setup BuddyBar navigation
 */
function setup_nav( $main_nav = array(), $sub_nav = array() ) {
    // Add 'Example' to the main navigation
    $main_nav = array(
        'name' => __( 'Example', 'bp-example' ),
        'slug' => bp_get_example_slug(), // setup in bp-{component}-template file
        'position' => 80,
        'screen_function' => 'bp_example_step_1',
        'default_subnav_slug' => 'example-step-1'
    );

    $example_link = trailingslashit( bp_loggedin_user_domain() . bp_get_example_slug() );

    // Add a few subnav items under the main Wizard tab
    $sub_nav[] = array(
        'name' => __( 'Example', 'bp-example' ),
        'slug' => 'example-step-1',
        'parent_url' => $example_link ,
        'parent_slug' => bp_get_example_slug(),
        'screen_function' => 'bp_example_step_1',
        'position' => 10
    );

    parent::setup_nav( $main_nav, $sub_nav );

    // If your component needs additional navigation menus that are not handled by
    // BP_Component::setup_nav(), you can register them manually here. For wizard,
    // if your component needs a subsection under a user's Settings menu, add
    // it like this. See bp_wizard_screen_settings_menu() for more info
    bp_core_new_subnav_item( array(
        'name' => __( 'Example', 'bp-example' ),
        'slug' => 'example-admin',
        'parent_slug' => bp_get_settings_slug(),
        'parent_url' => trailingslashit( bp_loggedin_user_domain() . bp_get_settings_slug() ),
        'screen_function' => 'bp_example_screen_settings_menu',
        'position' => 40,
        'user_has_access' => bp_is_my_profile() // Only the logged in user can access this on his/her profile
    ) );
}

Register Component

Add the component to the registered buddypress components in order to be activated and deactivated like the core BP components by hooking into bp_core_get_components filter.

/**
 * Register component information in the buddypress settings
 */
add_filter( 'bp_core_get_components', array( $this, 'register_component' ), 10, 2 );

/**
 * Register the component
 * @param array $components
 * @param string $type 
 * @return array 
 */
function register_component( $components, $type ) {
   if( $type == 'optional'){
       $component = array(
           'wizard' => array(
               'title' => __( 'Profile Wizard', 'buddypress' ),
               'description' => __( 'Create a process to encourage new members to fill out their profiles on first login', 'buddypress' )
           ),
       );

       /* Add this component to registered optional components array */
       $components = array_merge( $components, $component );
   }
   /* Return component */
   return $components;
}

Custom Template Page (Optional)

If you do not wish to keep you content within the buddypress screen container you can replace the template with the following filter hooks:

/* Setup the component's page template */
 add_filter( 'bp_template_include', array( $this, 'set_template' ), 10, 2 );
 /* Setup a template hierarchy for the component */
 add_filter( 'bp_located_template', array( $this, 'add_template_directory' ), 10, 2 );

These will first include your component template

/**
 * Setup the component's page template
 *
 * @param string $template Path to template (probably single.php).
 * @return string
 */
function set_template( $template ){
    /* If this is not an example page than don't filter the template */
    if ( !bp_is_current_component( 'example' ) )
        return $template;

    if( bp_is_example_component() ){  // defined in bp-example-templates.php
        /* This is going to look in theme/buddypress/example/index.php */
        bp_core_load_template( apply_filters( 'example_directory_template', 'example/index' ) );
    }
    return '';
}

/**
 * Setup a template hierarchy for the component
 *
 * @param string $found_template
 * @param array $templates
 * @return string
 */
function add_template_directory( $found_template, $templates ){
    /* If this is not an example page than don't filter the template */
    if ( !bp_is_current_component( 'example' ) )
        return $found_template;

    foreach ( (array) $templates as $template ) {
        if ( file_exists( STYLESHEETPATH . '/buddypress/' . $template ) )
            $filtered_templates[] = STYLESHEETPATH . '/buddypress/' . $template;
        elseif( file_exists( TEMPLATEPATH . '/buddypress/' . $template ) )
            $filtered_templates[] = TEMPLATEPATH . '/buddypress/' . $template;
        elseif ( file_exists( dirname( __FILE__ ) . '/' . $template ) )
            $filtered_templates[] = file_exists( dirname( __FILE__ ) . '/' . $template );
    }
    $found_template = $filtered_templates[0];

    return $found_template;
}

 

 

Setup Local SSL

Standard

In development security is obviously an important variable to the whole equation but it can be difficult to understand the many layers of security that take place from the request of a client to the delivery from a server. One of those layers that you may be aware of but unfamiliar with is Secure Sockets Layer (SSL); predecessor to Transport Layer Security (TLS). Essentially SSL is defined as:

the standard security technology for establishing an encrypted link between a web server and a browser. This link ensures that all data passed between the web server and browsers remain private and integral.

So if you are transferring sensitive data from a browser to a web service then in order to prevent data hijacking you must send the sensitive data through a secure socket (essentially a path that thieves and bandits can’t loot your messenger through on his way to the Emerald city where he will make your request). I’m not claiming to be an expert on this subject but in the development process it can be difficult to established said connection on a local environment so I wanted to provide a short tutorial of my successful attempt.

Environment Details

The process is similar no matter your environment so there still be some helpful nuggets here, but for the most part my instructions are based on the following:

  • Windows OS
  • XAMPP Version 1.8.2
  • Using VHosts (virtual host)

1) Create SSL Cert & Public Key

The first thing we need to do is create a SSL Certificate the will contain our public key and a server private key. Fortunately XAMPP already provides a couple things. 1) A pre-made solution which is included in everyone’s instance, so not the most secure. 2) A script for generating a brand new Certificate and public key. To execute this script/batch file, do the following:

From your Windows Command prompt or equivalent (I use Console2), change directory to your apache installation (my installation is in dropbox so may differ from typical installations:

cd c:\xampp\apache //Enter the path to your installation

From there you should see/run a .bat script called makecert:

ssl-to-local_01

NOTE: You may need to open this in your IDE or text editor to edit some path values, I had an issue with the OPENSSL_CONF set to the wrong path. Also if you want to set a new name for your certificates and key you can do that here. Once the script is as you would like it to be then run it:

makecert //that was easy

This will begin to walk you through generating the certificate and key so fill in each value accordingly. The value that matters the most is the “common_name”, this MUST be the domain address that you are trying to secure. So if I’m developing a site using a virtual host like, myproject.dev then common_name = myproject.dev

Enable Port 443 for Vhost

Usually around line 19 you will find the line you need to add or uncomment

NameVirtualHost *:80 // Around line 19
NameVirtualHost *:443

Also make a default for each port

<VirtualHost *:80> // Port 80
    DocumentRoot "c:/xampp/htdocs"
    ServerName localhost
</VirtualHost>
<VirtualHost *:443> // Port 443
    DocumentRoot "c:/xampp/htdocs"
    ServerName localhost
    ServerAlias localhost
 
    SSLEngine On // notice we turn on SSL
    SSLCertificateFile "conf/ssl.crt/server.crt" // path to your SSL certificate
    SSLCertificateKeyFile "conf/ssl.key/server.key" //path to your private key

    <Directory "c:/xampp/htdocs"> 
        Options Indexes FollowSymLinks Includes ExecCGI 
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Now that you have a vhost setup for a non-secure URL, apache will use your project’s directory. Now we just need to direct that url to HTTPS by updating your .htaccess file

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{SERVER_PORT} !^443$ // Add these 2 lines
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

Add Certificate and Public Key to Vhost & Require SSL

As you may have noticed from the previous step there a couple things happening when setting up a virtual host to use SSL

<VirtualHost myproject.dev:443> // Individual Vhost set to use port 443
   DocumentRoot "c:/xampp/htdocs/myproject.dev"
   ServerName myproject.dev
   ServerAlias myproject.dev

   SSLEngine On // notice we turn on SSL
   SSLCertificateFile "conf/ssl.crt/myproject.crt" // path to your SSL certificate
   SSLCertificateKeyFile "conf/ssl.key/myproject.key" // path to your private key

   <Directory "C:/xampp/htdocs/myproject.dev">
       Options Indexes FollowSymLinks ExecCGI Includes
       Order allow,deny
       AllowOverride All
       Allow from all
       SSLRequireSSL
   </Directory>
</VirtualHost>

Force Redirect http:// (:80) to https:// (:443)

This is not a requirement to your HTTP url to HTTPS but it is likely necessary considering that as a secure page you cannot load insecure content. This includes images, css, js, etc. If you are including/referencing resources they must be retrieved via HTTPS as well. Not to mention, what good is your site if the user forgets the “s” and sees a broken page, they won’t assume its their fault, they will assume your site is broken. So to start, below your :443 virtual host we need to make an :80 version (this way it exist to apache so that once it reaches your root directory you can THEN use .htaccess forces the HTTPS.

<VirtualHost myproject.dev:80> // Individual Vhost set to use port 80
   DocumentRoot "c:/xampp/htdocs/myproject.dev"
   ServerName myproject.dev
   ServerAlias myproject.dev

   SSLEngine On // notice we turn on SSL
   SSLCertificateFile "conf/ssl.crt/myproject.crt" // path to your SSL certificate
   SSLCertificateKeyFile "conf/ssl.key/myproject.key" // path to your private key

   <Directory "C:/xampp/htdocs/myproject.dev">
       Options Indexes FollowSymLinks ExecCGI Includes
       Order allow,deny
       AllowOverride All
       Allow from all
       SSLRequireSSL
   </Directory>
</VirtualHost>

Conclusion

If this is working properly you should see the green padlock in your address bar that will indicate a secure connection:

ssl-to-local_02

If you have any questions along the way feel free to post them and I will answer them or update the article accordingly the best I can. Again I’m no expert but I was able to get this working after many hours of research and figured this would help save you some time. If you would like I’ve included resources below as well

Resources

Here is a list of some of the resources I used to help me through this setup process

How to Deploy a Release Package in Salesforce

Standard

With each new feature release, bug squashing, and spring cleaning of your code base there is the inevitable deployment process which can be daunting at first and frustrating if not structured well. Develop and deploy faster! After many deployments I’ve setup a process streamlines this task within development.

Setup a Release Package

deploy releasesIn your local Salesforce environment create a folder called “Releases“. Inside of that folder create another folder and name it after your release. For this example we’ll call it 1.0.3

This is where you will setup your release package and eventually ZIP it into a deploy-able package.

Inside your release folder you will need to place any Salesforce component folders that are part of your package. For example, if you are deploying a trigger and some classes then you will need a triggers & classes folder, along with the .trigger and .cls files that are being deployed inside of them each respectively.

 

Create a Package.xml

Once all the files/folders are in your package as needed, all that’s left is to create a package.xml that declares which files you are deploying. The developer of the HaoIDE Sublime Text plugin has a short video showing this process. Otherwise just copy a package.xml from your Production project and modify it appropriately so that it only contains the elements that you intend to be deployed in the package. Here is a simple example:

package-example

Zip Your Release Package

release-exampleOnce the package is complete you should have something that looks like this. Then you will need to select the contents and zip them (make sure this includes your package.xml). Once you have a ZIP, drag and drop to open it in Sublime Text (optional step but easier than alternative), once in Sublime Text right click in order to get the context menu and select “Copy File Path“.

Deploy Your Release Package

Now all that’s left is to deploy the ZIP package. From Sublime Text, click HaoIDE > Metadata > Deploy Package.zip and in the input field paste the path to the zip file that you copied just previously.

Here’s a sample video

Destructive Changes

If you need to do destructive changes then you will need to also create a destructiveChanges.xml (version 32.0 and prior), or destructiveChangesPost.xml and/or destructiveChangesPre.xml for package version 33.0; the latter of the two is the easiest (Post means to destructive AFTER deploying changes and Pre is used for destructive changes BEFORE deploying the package).

Here is an example of what this file would look like:

destructiveChangesPost-xml-example

 

As you can see the structure is the same as when building a package.xml, the only difference is this file is declaring what will be destructed and when (based on Post/Pre appending).

NOTE: If you only need to destruct changes and are not deploying anything, then at the bare minimum you need your destruct XML and a package XML that includes the version number

 

Conclusion

Hope that helps, there’s not much to it. Essentially whenever you are deploying to any environment, if you are using the context options within HoaIDE or MavensMate, etc., they are essentially doing this process for you. When releasing portions of code its more effective to package releases together so that you there are no dependency issues during the attempt that would cause it to fail. Good luck!

For more information when using HaoIDE be sure to see the deployment documentation

Hello World: Development for the Community

Standard

Its been said that, “it takes a village to raise a child”, and I would adapt that to say “it takes a community to raise a developer.” The truth is any type of development is a continual process that never really ends, rather it transitions into stages. Whether you’re a seasoned developer or a complete newb, it is a fact that you will need support in order to be successful.

Think Community, Not Just Networking

Sure life has a lot to do with “who” you know, but I think that as developers become more abundant the shift you’re going to see is not just about “who” you know, but “how” you know them. Relationships are important! Yes, for the nerds glued to technology 24/7, I’ll say it again, relationships are important. Therefore networking needs to evolve out of its negative business connotation into a personal experience that people enjoy because deep down I believe we all really do. That’s why social networking is so great.

What’s the point?

Basically, development is an amazing industry to be in, no matter what language it is, progress for a better future is always inspiring. So with that let’s inspire one another! There is so much opportunity before us; any one who tells you otherwise is selling something…. seriously they are trying to make their opportunity look more valuable for their own selfish gain. The fact of the matter is there truly is an abundant pie; plenty to go around. So let this be an encouragement to the developer community in what ever capacity you are passionate about.

As a developer this is my “Hello World” post and I essentially wanted to use that declaration opportunity to say that is what this site is dedicated to. My hope is to encourage and train other developers with tutorials, case studies, and personal testimonies of my journey as a developer. There truly is a lot of life in code, so hopefully I can express some of it along the way.

Stay classy! Stay gold! Just stay put and stick around as there is more to come.