Skip to content
Browse files

Version 1.3.8

  • Loading branch information...
1 parent e8980b6 commit 23a2eb41f49ef21fc851aa1df3af87a3677078fd @logoscreative logoscreative committed Jan 28, 2014
View
4 README.md
@@ -95,6 +95,10 @@ Go to Settings > Pardot Settings and click 'Reset Cache'. This should reinitiali
## Changelog ##
+### 1.3.9 ###
+
+Fixes a small bug with a JS library being called in the wrong place
+
### 1.3.8 ###
1. Add Chosen selector to forms and dynamic content
View
250 tags/1.3.7/README.txt
@@ -0,0 +1,250 @@
+=== Pardot ===
+Contributors: cliffseal, NewClarity, MikeSchinkel
+Donate link: http://pardot.com
+Tags: pardot, marketing automation, forms, dynamic content, tracking, web tracking
+Requires at least: 3.7
+Tested up to: 3.8.1
+Stable tag: 1.3.7
+License: GPLv2 or later
+License URI: http://www.gnu.org/licenses/gpl-2.0.html
+
+Integrate Pardot with WordPress: easily track visitors, embed forms and dynamic content in pages and posts, or use the forms or dynamic content widgets.
+
+== Description ==
+
+Say hello to marketing automation simplicity! With a single login, your self-hosted WordPress installation will be securely connected with Pardot. With the selection of your campaign, you'll be able to track visitors and work with forms and dynamic content without touching a single line of code. You can use the widget to place a form or dynamic content anywhere a sidebar appears, or embed them in a page or post using a shortcode or the Pardot button on the Visual Editor's toolbar.
+
+== Installation ==
+
+1. Upload `pardot-for-wordpress` to your `/wp-content/plugins/` directory or go to Plugins > Add New in your WordPress Admin area and search for Pardot.
+1. Activate the plugin through the 'Plugins' menu in WordPress.
+1. Go to Settings > Pardot Settings to put in your email, password, and user key.
+1. Select your campaign (for tracking code usage).
+
+== Frequently Asked Questions ==
+
+= How can I use the shortcodes without the Visual Editor? =
+
+Two simple shortcodes are available for use.
+
+= Form Shortcode =
+
+`[pardot-form id="{Form ID}" title="{Form Name}" class="" width="100%" height="500"]`
+
+Use `[pardot-form]` with at least the `id` parameter. For instance, `[pardot-form id="1" title="Title"]` renders my Pardot form with an ID of 1.
+
+Optional parameters:
+
+The `title` parameter is included when using the toolbar button, but it's not required for display. There is no default.
+
+The `class` parameter allows you to add additonal classes to the iframe element. There is no default, but the class `pardotform` is now automatically added, regardless of any additional classes.
+
+The `width` parameter will set the width of the iframe in pixels or percentage. For example, "500", "500px", and "80%" are all valid. The default is 100%.
+
+The `height` parameter will set the height of the iframe in pixels only. For example, "500" or "500px" are valid. The default is 500px.
+
+= Dynamic Content Shortcode =
+
+`[pardot-dynamic-content id="{Dynamic Content ID}" default="{Non-JavaScript Content}"]`
+
+Use `[pardot-dynamic-content]` with at least the `id` parameter.
+
+The `default` parameter is used for accessibility. Whatever is placed here is wrapped in `<noscript>` tags and is shown only to users who have JavaScript disabled. By default, it will automatically be your "Default Content" as designated in Pardot. So,
+
+`[pardot-dynamic-content id="1" default="My default content."]`
+
+would render something like:
+
+`<script type="text/javascript" src="http://go.pardot.com/dcjs/99999/99/dc.js"></script><noscript>My default content.</noscript>`
+
+...which would show the dynamic content to users with JavaScript enabled, and 'My default content' to users with it disabled. Note that, due to the way the WordPress Visual Editor works, HTML tags for the parameter will be URL encoded to avoid strange formatting.
+
+= How do I change my campaign? =
+
+Simply choose another campaign in Settings > Pardot Settings and click 'Save Settings'.
+
+= Some of my form is cut off. What should I do? =
+
+Since every WordPress theme is different, embedded forms won’t always automatically fit. You’ll want to make a Pardot Layout Template specifically for your WordPress theme:
+
+1. Go to <a href="https://pi.pardot.com/form" target="_blank">Forms</a> in Pardot. Find and edit the form that needs updating.
+1. Click ahead to the 'Look and Feel' step of the wizard and select the 'Styles' tab.
+1. Set 'Label Alignment' to 'Above' and click 'Confirm and Save.'.
+1. Click the link to the layout template being used by the form.
+1. Edit the layout template and add the following to the <code><head></code> section of the template:
+`<style type="text/css">
+ #pardot-form input.text, #pardot-form textarea {
+ width: 150px;
+ }
+</style>`
+
+A width of 150px is just a starting point. Adjust this value until it fits on your page and add additional styles as you see fit. For styling help, reference our <a href="http://www.pardot.com/help/faqs/forms/basic-css-for-forms" target="_blank">Basic CSS for Forms</a> page.
+
+= I just added a form or dynamic content, and it's not showing up to select it yet. =
+
+Go to Settings > Pardot Settings and click 'Reset Cache'. This should reinitialize and update your Pardot content.
+
+== Screenshots ==
+
+1. Settings area
+1. Pardot button in the Visual Editor toolbar
+1. Choose from any form or Dynamic Content
+1. Use forms in a widget
+1. Use dynamic content in a widget
+1. A form widget (with corrected styling)
+1. A page can have two forms! Here, one is in the body and one in a widget.
+
+== Changelog ==
+
+= 1.3.7 =
+
+1. Add Chosen selector to campaign settings
+1. Fix authentication issue
+
+= 1.3.6 =
+
+1. Adds support for 400+ campaigns, form, and dynamic content blocks
+1. Updates branding
+
+= 1.3.5 =
+
+1. Fixed a bug where pardotform class might be applied to closing iframe tag (thanks palpatine1976!)
+1. Optimize code to remove some debug messages
+1. Improve campaign retrieval for over 200 campaigns
+
+= 1.3.4 =
+
+Fixed a bug where tracking code might show the wrong ID.
+
+= 1.3.3 =
+
+1. Accounts for a minor API change in the tracking code
+1. Adds support for 200+ campaigns
+
+= 1.3.1 =
+
+Fixed a bug with `shortcode_exists` fatal error
+
+= 1.3.1 =
+
+Fixed a bug with `has_shortcode` fatal error
+
+= 1.3 =
+
+Use new asynchronous loading for Dynamic Content
+
+= 1.2 =
+
+1. Added ability to specify height, width, and class on the form
+1. Added class 'pardotform' to every iframe for easier styling
+
+= 1.1.5 =
+
+1. Add some helpful links to the Reset Cache button
+2. Minor UI tweaks
+3. Updated the Pardot logos
+4. Updated screenshots for 3.5
+
+= 1.1.4 =
+
+1. Fix TinyMCE modal bug when no forms or dynamic content is present
+1. Support for 200+ forms and dynamic content items
+1. Other minor checks
+
+= 1.1.3 =
+
+Checks for mcrypt and falls back safely if not (fixes blank admin screen bug)
+
+= 1.1.2 =
+
+1. Clear cache when resetting all settings
+1. Be more forgiving with login whitespace
+1. Make some security improvements
+
+= 1.1.1 =
+Make `<noscript>` default to Default Pardot Content
+
+= 1.1.0 =
+1. Added dynamic content shortcodes
+1. Added title field to form widget
+1. Added 'Reset Cache' option
+
+= 1.0.3 =
+Added form caching for faster rendering and less requests
+
+= 1.0.2 =
+1. Fix a caching issue that was causing the most recently-used form to render on all posts/pages
+1. Extended API cache timeout
+
+= 1.0.1 =
+Fix bug with form order in content
+
+= 1.0 =
+Initial release.
+
+== Upgrade Notice ==
+
+= 1.3.7 =
+
+This update improves campaign selection and fixes a bug with settings where certain user credentials would fail to authenticate.
+
+= 1.3.6 =
+
+This update adds support for 400+ campaigns, forms, and dynamic content blocks (cheers to Twig Interactive). We've also updated some branding.
+
+= 1.3.5 =
+
+This update fixes a bug where pardotform class might be applied to closing iframe tag (thanks palpatine1976!), optimizes code to remove some debug messages, and improves campaign retrieval for over 200 campaigns. <3
+
+= 1.3.4 =
+
+Fixes a bug where tracking code might show the wrong ID.
+
+= 1.3.3 =
+
+Accounts for a minor API change in the tracking code; adds support for 200+ campaigns
+
+= 1.3.2 =
+
+1.3.2 fixes two fatal error bugs that were showing on install. With today's overall 1.3 update, you can now load multiple pieces of Dynamic Content without a performance hit with our new asynchronous loading technique!
+
+= 1.3 =
+
+Load multiple pieces of Dynamic Content without a performance hit with our new asynchronous loading technique!
+
+= 1.2 =
+
+Thanks to your feedback, we've added the ability to specify height, width, and additional classes on the form iframes; the 'pardotform' class is also automatically added to every form iframe for easier styling
+
+= 1.1.3 =
+
+Fixes blank admin screen bug (by checking for mcrypt and falling back safely if not)
+
+= 1.1.2 =
+
+1. Clear cache when resetting all settings
+1. Be more forgiving with login whitespace
+
+= 1.1.1 =
+Make `<noscript>` default to Default Pardot Content
+
+= 1.1.0 =
+1. Added dynamic content shortcodes
+1. Added title field to form widget
+1. Added 'Reset Cache' option
+
+= 1.0.3 =
+Added form caching for faster rendering and less requests
+
+= 1.0.2 =
+1. Fix a caching issue that was causing the most recently-used form to render on all posts/pages
+1. Extended API cache timeout
+
+= 1.0.1 =
+Fix bug with form order in content
+
+= 1.0 =
+Initial release.der in content
+
+= 1.0 =
+Initial release.
View
BIN tags/1.3.7/images/pardot-logo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
539 tags/1.3.7/includes/pardot-api-class.php
@@ -0,0 +1,539 @@
+<?php
+/**
+ * PHP class for interacting with the Pardot API.
+ *
+ * Developed for the Pardot WordPress Plugin.
+ *
+ * @note $URL_PATH_TEMPLATE and $LOGIN_URL_PATH_TEMPLATE are private static rather than const because const cannot be made private
+ * and both these are "convenience" constants to ensure they are placed close to the top of the file but their
+ * architecture is not robust enough to expose for external use as an update would create a breaking change.
+ *
+ * @note Requires WordPress API because of its use of wp_remote_request(), wp_remote_retrieve_response_code() and
+ * wp_remote_retrieve_body() but otherwise independent of WordPress. Could be made standalone if these functions
+ * replaced with CURL equivalents.
+ *
+ * @author Mike Schinkel <mike@newclarity.net>
+ * @version 1.0.0
+ *
+ */
+class Pardot_API {
+ /**
+ * @const string The root URL for the Pardot API.
+ *
+ * @since 1.0.0
+ */
+ const ROOT_URL = 'https://pi.pardot.com/api';
+
+ /**
+ * @const string The supported version of the Pardot API, this value is embedded into the API's URLs
+ *
+ * @since 1.0.0
+ */
+ const VERSION = '3';
+
+ /**
+ * @var string Defacto constant defining the URL path template for the API.
+ * @note This classes defines and replaces the three (3) template variables %%ITEM_TYPE%%, %%VERSION%% and %%ACTION%%.
+ * %%ITEM_TYPE%%: One of 'login', 'account', 'campaign' or 'form'.
+ * %%VERSION%%: Pardto_API::VERSION
+ * %%ACTION%%: For %%ITEM_TYPE%% == 'account' otherwise 'query'
+ * @note This is defined as a variable because it made need to change and thus should be internal to Pardot_API.
+ *
+ * @since 1.0.0
+ */
+ private static $URL_PATH_TEMPLATE = '/%%ITEM_TYPE%%/version/%%VERSION%%/do/%%ACTION%%';
+
+ /**
+ * @var string Defacto constant defining the URL path template for the API's login URL.
+ * @note This class defines and transforms the template variable %%VERSION%% which Pardto_API::VERSION replaces.
+ * @note This is defined as a variable because it made need to change and thus should be internal to Pardot_API.
+ *
+ * @since 1.0.0
+ */
+ private static $LOGIN_URL_PATH_TEMPLATE = '/login/version/%%VERSION%%';
+
+ /**
+ * @var string A user entered email address that is expected to have a valid Pardot account.
+ *
+ * @since 1.0.0
+ */
+ var $email;
+
+ /**
+ * @var string A user-entered password for the valid Pardot account indentified by $this->email.
+ *
+ * @since 1.0.0
+ */
+ var $password;
+
+ /**
+ * @var string A user-entered but Pardot-supplied key the user accesses from their Pardot account.
+ *
+ * @since 1.0.0
+ */
+ var $user_key;
+
+ /**
+ * @var string A key returned on authentication by Pardot's API based on email, password and user_key.
+ *
+ * @since 1.0.0
+ */
+ var $api_key = false;
+
+ /**
+ * @var boolean Used to flag the API for retry in case the api_key has expired.
+ *
+ * @since 1.0.0
+ */
+ var $api_key_maybe_invalidated = false;
+
+ /**
+ * @var string Flag to indicate an API request failed.
+ *
+ * @since 1.0.0
+ */
+ var $error = false;
+
+
+ /**
+ * Creates a Pardot API object.
+ *
+ * If more than one value is passed for $auth it will pass to set_auth() to save the auth parameters
+ * into the object's same named properties.
+ *
+ * @param array $auth Values 'email', 'password', 'user_key' and 'api_key' supported.
+ *
+ * @since 1.0.0
+ */
+ function __construct( $auth = array() ) {
+ if ( is_array( $auth ) && count( $auth ) )
+ $this->set_auth( $auth );
+ }
+
+ /**
+ * Call Pardot API to authenticate and retrieve API Key
+ *
+ * The $auth parameters passed will be used to authenticate the login request.
+ * If successful $this->api_key will be set.
+ *
+ * @param array $auth Values 'email', 'password', 'user_key' and 'api_key' supported.
+ * @return string|bool An $api_key on success, false on failure.
+ *
+ * @since 1.0.0
+ */
+ function authenticate( $auth = array() ) {
+ if ( count( $auth ) )
+ $this->set_auth( $auth );
+ $this->api_key = false;
+ if ( $response = $this->get_response( 'login', $auth, 'api_key' ) ) {
+ $this->api_key = (string)$response->api_key;
+ };
+ return $this->api_key;
+ }
+
+ /**
+ * Determine is the API has authenticated.
+ *
+ * Authenticated will be determine by having a non-empty api_key property.
+ *
+ * @return bool True if there is an non-empty API key.
+ *
+ * @since 1.0.0
+ */
+ function is_authenticated() {
+ return ! empty( $this->api_key );
+ }
+ /**
+ * Returns an array of campaign objects from Pardot's API
+ *
+ * The structure of the campaign objects are based on Pardot's API returned XML format captured using PHP's SimpleXML
+ * and converted to an array of stdClass objects.
+ *
+ * @param array $args Combined authorization parameters and query arguments.
+ * @return array|bool Array of campaign objects, or false if API call failed.
+ *
+ * @since 1.0.0
+ */
+
+ function get_campaigns( $args = array() ) {
+ $campaigns = false;
+ if ( $response = $this->get_response( 'campaign', $args ) ) {
+ $campaigns = array();
+ if ( $response->result->total_results >= 200 ) {
+ $limit = 200;
+ } else {
+ $limit = $response->result->total_results;
+ }
+
+ for( $i = 0; $i < $limit; $i++ ) {
+ $campaign = (object)$response->result->campaign[$i];
+ if ( isset($campaign->id) ) {
+ $campaigns[(int)$campaign->id] = $this->SimpleXMLElement_to_stdClass( $campaign );
+ }
+ }
+
+ if ( $limit >= 200 ) {
+ $numpag = round($response->result->total_results/200)+1;
+ for( $j = 2; $j <= ($numpag); $j++ ) {
+ if ( $response = $this->get_response( 'campaign', $args, 'result', $j ) ) {
+ for( $i = 0; $i < ($response->result->total_results-200); $i++ ) {
+ $campaign = (object)$response->result->campaign[$i];
+ if ( isset($campaign->id) ) {
+ $campaigns[(int)$campaign->id] = $this->SimpleXMLElement_to_stdClass( $campaign );
+ }
+ }
+ }
+ }
+ }
+
+ }
+ return $campaigns;
+ }
+
+ /*function get_campaigns( $args = array() ) {
+ $campaigns = false;
+ if ( $response = $this->get_response( 'campaign', $args ) ) {
+ $campaigns = array();
+ for( $i = 0; $i < $response->result->total_results; $i++ ) {
+ $campaign = (object)$response->result->campaign[$i];
+ if ( isset($campaign->id) ) {
+ $campaigns[(int)$campaign->id] = $this->SimpleXMLElement_to_stdClass( $campaign );
+ }
+ }
+ }
+ return $campaigns;
+ }*/
+
+ /**
+ * Returns an account object from Pardot's API
+ *
+ * The structure of the campaign objects are based on Pardot's API returned XML format captured using PHP's SimpleXML
+ * and converted to an array of stdClass objects.
+ *
+ * @param array $args Combined authorization parameters and query arguments.
+ * @return object A stdClass account object, or false if API call failed.
+ *
+ * @since 1.0.0
+ */
+ function get_account( $args = array() ) {
+ $account = false;
+ if ( $response = $this->get_response( 'account', $args, 'account' ) ) {
+ $response = $this->SimpleXMLElement_to_stdClass( $response );
+ $account = $response->account;
+ };
+ return $account;
+ }
+
+ /**
+ * Returns an array of form objects from Pardot's API
+ *
+ * The structure of the form objects are based on Pardot's API returned XML format captured using PHP's SimpleXML
+ * and converted to an array of stdClass objects.
+ *
+ * @param array $args Combined authorization parameters and query arguments.
+ * @return array|bool Array of form objects, or false if API call failed.
+ *
+ * @since 1.0.0
+ */
+ function get_forms( $args = array() ) {
+ $forms = false;
+ if ( $response = $this->get_response( 'form', $args ) ) {
+
+ $forms = array();
+
+ if ( $response->result->total_results >= 200 ) {
+ $limit = 200;
+ } else {
+ $limit = $response->result->total_results;
+ }
+
+ for( $i = 0; $i < $limit; $i++ ) {
+ $form = $response->result->form[$i];
+ $forms[(int)$form->id] = $this->SimpleXMLElement_to_stdClass( $form );
+ }
+
+ if ( $limit >= 200 ) {
+ $numpag = round($response->result->total_results/200)+1;
+ for( $j = 2; $j <= ($numpag); $j++ ) {
+ if ( $response = $this->get_response( 'form', $args, 'result', $j ) ) {
+ for( $i = 0; $i < ($response->result->total_results-200); $i++ ) {
+ $form = $response->result->form[$i];
+ $forms[(int)$form->id] = $this->SimpleXMLElement_to_stdClass( $form );
+ }
+ }
+ }
+ }
+
+ };
+ return $forms;
+ }
+
+ /**
+ * Returns an dynamic content from Pardot's API
+ *
+ * The structure of the dynamic content objects are based on Pardot's API returned XML format captured using PHP's SimpleXML
+ * and converted to an array of stdClass objects.
+ *
+ * @param array $args Combined authorization parameters and query arguments.
+ * @return array|bool Array of form objects, or false if API call failed.
+ *
+ * @since 1.1.0
+ */
+ function get_dynamicContent( $args = array() ) {
+ $dynamicContents = false;
+ if ( $response = $this->get_response( 'dynamicContent', $args ) ) {
+
+ $dynamicContents = array();
+
+ if ( $response->result->total_results >= 200 ) {
+ $limit = 200;
+ } else {
+ $limit = $response->result->total_results;
+ }
+
+ for( $i = 0; $i < $limit; $i++ ) {
+ $dynamicContent = $response->result->dynamicContent[$i];
+ $dynamicContents[(int)$dynamicContent->id] = $this->SimpleXMLElement_to_stdClass( $dynamicContent );
+ }
+
+ if ( $limit >= 200 ) {
+ $numpag = round($response->result->total_results/200)+1;
+ for( $j = 2; $j <= ($numpag); $j++ ) {
+ if ( $response = $this->get_response( 'dynamicContent', $args, 'result', $j ) ) {
+ for( $i = 0; $i < ($response->result->total_results-200); $i++ ) {
+ $dynamicContent = $response->result->dynamicContent[$i];
+ $dynamicContents[(int)$dynamicContent->id] = $this->SimpleXMLElement_to_stdClass( $dynamicContent );
+ }
+ }
+ }
+ }
+
+ };
+ return $dynamicContents;
+ }
+
+ /**
+ * Returns an object or array of stdClass objects from an SimpleXMLElement
+ *
+ *
+ * @param SimpleXMLElement $xml
+ * @return array|object A(n array of) stdClass object(s) with structure dictated by the passed SimpleXMLElement object.
+ *
+ * @note Leading and trailing space are trim()ed.
+ *
+ * @see http://www.bookofzeus.com/articles/convert-simplexml-object-into-php-array/
+ *
+ * @since 1.0.0
+ */
+ function SimpleXMLElement_to_stdClass( $xml ) {
+ $array = array();
+ foreach ($xml as $element) {
+ $tag = $element->getName();
+ $e = get_object_vars($element);
+ if (!empty($e)) {
+ $array[$tag] = $element instanceof SimpleXMLElement ? $this->SimpleXMLElement_to_stdClass($element) : $e;
+ }
+ else {
+ $array[$tag] = trim($element);
+ }
+ }
+ return (object)$array;
+ }
+
+ /**
+ * Set the auth properties of the Pardot_API.
+ *
+ * Sets the properties of the object based on auth values passed via array,
+ * or in all but API_KEY based on these respective constants, if they exist:
+ *
+ * - PARDOT_API_EMAIL
+ * - PARDOT_API_PASSWORD
+ * - PARDOT_API_USER_KEY
+ *
+ * @param array $auth Values 'email', 'password', 'user_key' and 'api_key' supported.
+ * @return void
+ *
+ * @since 1.0.0
+x */
+ function set_auth( $auth = array() ) {
+ /**
+ * First clear all the auth values.
+ */
+ $this->email = $this->password = $this->user_key = $this->api_key = null;
+ if ( ! empty( $auth['email'] ) ) {
+ $this->email = $auth['email'];
+ } else if ( empty( $this->email ) && defined( 'PARDOT_API_EMAIL' ) ) {
+ $auth['email'] = PARDOT_API_EMAIL;
+ }
+ if ( ! empty( $auth['password'] ) ) {
+ $this->password = $auth['password'];
+ } else if ( empty( $this->password ) && defined( 'PARDOT_API_PASSWORD' ) ) {
+ $auth['password'] = PARDOT_API_PASSWORD;
+ }
+ if ( ! empty( $auth['user_key'] ) ) {
+ $this->user_key = $auth['user_key'];
+ } else if ( empty( $this->user_key ) && defined( 'PARDOT_API_USER_KEY' ) ) {
+ $auth['user_key'] = PARDOT_API_USER_KEY;
+ }
+ if ( ! empty( $auth['api_key'] ) ) {
+ $this->api_key = $auth['api_key'];
+ }
+ }
+
+ /**
+ * Checks if this Pardot_API object has the necessary properties set for authentication.
+ *
+ * @return boolean Returns true if this object has email, password and user_key properties.
+ *
+ * @since 1.0.0
+x */
+ function has_auth() {
+ return ! empty( $this->email ) && ! empty( $this->password ) && ! empty( $this->user_key );
+ }
+
+ /**
+ * Calls Pardot_API and returns response.
+ *
+ * Checks if this object has required properties for authentication. If yes and not authenticated, authenticates.
+ * Next, build the API user and calls the API. On error, attempt to authenticate to retrieve a new API key unless
+ * this is an authentication request, to avoid infinite loops. If reauthenticated and $args['new_api_key'] is a valid
+ * callback then callsback with new API key so caller can store it.
+ *
+ * @param string $item_type One of 'login', 'account', 'campaign' or 'form'.
+ * @param array $args Query arguments (but might contain ignored auth arguments.
+ * @param string $property Property to retrieve; defaults to 'result' but can be 'api_key' or 'account'.
+ * @return bool|SimpleXMLElement Returns API response as a SimpleXMLElement if successful, false if API call fails.
+ *
+ * @since 1.0.0
+ */
+ function get_response( $item_type, $args = array(), $property = 'result', $paged=1 ) {
+ $this->error = false;
+
+ if ( ! $this->has_auth() ) {
+ $this->error = 'Cannot authenticate. No email, password or user_key assigned.';
+ return false;
+ }
+
+ if ( ! $this->api_key && 'login' != $item_type ) {
+ $this->authenticate( $args );
+ }
+
+ $args = array_merge( $args,
+ array(
+ 'user_key' => $this->user_key,
+ 'api_key' => $this->api_key,
+ // Here for Pardot root-level debugging only
+ //'act_as_user' => 'test@example.com',
+ 'offset' => $paged > 1 ? ($paged-1)*200 : 0
+ )
+ );
+
+ $http_response = wp_remote_request(
+ $this->_get_url( $item_type, $args ),
+ array_merge( array(
+ 'timeout' => '30',
+ 'redirection' => '5',
+ 'method' => 'POST',
+ 'blocking' => true,
+ 'compress' => false,
+ 'decompress' => true,
+ 'sslverify' => false,
+ 'body' => $args
+ ), $args )
+ );
+
+ if ( isset($args['email']) ) {
+ $args['email'] = urlencode( $args['email'] );
+ }
+
+ if ( isset($args['password']) ) {
+ $args['password'] = urlencode( $args['password'] );
+ }
+
+ $response = false;
+ if( wp_remote_retrieve_response_code( $http_response ) == 200 ) {
+ $response = new SimpleXMLElement( wp_remote_retrieve_body( $http_response ) );
+ if ( ! empty( $response->err ) ) {
+ $this->error = $response->err;
+ if ( 'login' == $item_type ) {
+ $this->api_key = false;
+ } else {
+ $auth = $this->get_auth();
+ if ( isset( $args['new_api_key'] ) ) {
+ $this->api_key_maybe_invalidated = true;
+ $auth['new_api_key'] = $args['new_api_key'];
+ }
+ if ( $this->authenticate( $auth ) ) {
+ /**
+ * Try again after a successful authentication
+ */
+ $response = $this->get_response( $item_type, $args, $property, true );
+ if ( $response )
+ $this->error = false;
+ }
+ }
+ }
+
+ if ( $this->error )
+ $response = false;
+
+ if ( $response && empty( $response->$property ) ) {
+ $response = false;
+ $this->error = "HTTP Response did not contain property: {$property}.";
+ }
+
+ if ( $response && $this->api_key_maybe_invalidated && 'login' == $item_type && 'api_key' == $property ) {
+ if ( isset( $args['new_api_key'] ) && is_callable( $args['new_api_key'] ) ) {
+ call_user_func( $args['new_api_key'], (string)$response->api_key );
+ $this->api_key_maybe_invalidated = false;
+ }
+ }
+
+ }
+ return $response;
+ }
+
+ /**
+ * Returns array of auth parameter based on the auth properties of this Pardot_API object
+ *
+ * @return array containing email, password and user_key elements.
+ *
+ * @since 1.0.0
+ */
+ function get_auth() {
+ return array(
+ 'email' => $this->email,
+ 'password' => $this->password,
+ 'user_key' => $this->user_key,
+ );
+ }
+
+ /**
+ * Simple helper function to return the URL required for an $item_type specific Pardot API.
+ *
+ * This function could easily require significant modification to support the complete API which probably
+ * means a significant rearchitecture. However, it's a black box and it's $args 2nd parameter should enable
+ * it to evolve as needed assume the $item_type continues to be a central concept in the Pardot API.
+ *
+ * @param string $item_type Item type requested; 'account', 'form', 'campaign' and (special case) 'login' tested.
+ * @param array $args Authorization values ('email','password','user_key') for 'login', nothing for the rest.
+ * @return string Url for a valid API call.
+ *
+ * @since 1.0.0
+ */
+ private function _get_url( $item_type, $args = array() ) {
+ if ( 'login' == $item_type ) {
+ $this->set_auth( $args );
+ $base_url = str_replace( '%%VERSION%%', self::VERSION, self::$LOGIN_URL_PATH_TEMPLATE );
+ $url = $base_url;
+ } else {
+ $base_url = str_replace(
+ array( '%%VERSION%%', '%%ITEM_TYPE%%', '%%ACTION%%' ),
+ array( self::VERSION, $item_type, 'account' == $item_type ? 'read' : 'query' ),
+ self::$URL_PATH_TEMPLATE
+ );
+ $url = $base_url;
+ }
+ return self::ROOT_URL . $url;
+ }
+}
View
72 tags/1.3.7/includes/pardot-api-functions.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Functions to simplify calling the Pardot API.
+ *
+ * These functions call Pardot's API via Pardot_Plugin class which has a private static api property. These functions
+ * will use an instantiated API if already exists for the current page load or it will create one. Also it will grab
+ * the user, password, user_key and api_key from 'pardot_setttings' in wp_options or it will use auth if passed via
+ * an $args parameter.
+ *
+ * @author Mike Schinkel <mike@newclarity.net>
+ * @since 1.0.0
+ */
+/**
+ * Returns an API key via the Pardot API as implemented in the Pardot_Plugin class.
+ *
+ * @param array $args
+ * @return Pardot_API
+ *
+ * @since 1.0.0
+ */
+function get_pardot_api_key( $args = array() ) {
+ return Pardot_Plugin::get_api_key( $args );
+}
+
+/**
+ * Returns an account object via the Pardot API as implemented in the Pardot_Plugin class.
+ *
+ * @param array $args
+ * @return Pardot_API
+ *
+ * @since 1.0.0
+ */
+function get_pardot_account( $args = array() ) {
+ return Pardot_Plugin::get_account( $args );
+}
+
+/**
+ * Returns an array of campaigns via the Pardot API as implemented in the Pardot_Plugin class.
+ *
+ * @param array $args
+ * @return Pardot_API
+ *
+ * @since 1.0.0
+ */
+function get_pardot_campaigns( $args = array() ) {
+ return Pardot_Plugin::get_campaigns( $args );
+}
+
+/**
+ * Returns an array of forms via the Pardot API as implemented in the Pardot_Plugin class.
+ *
+ * @param array $args
+ * @return Pardot_API
+ *
+ * @since 1.0.0
+ */
+function get_pardot_forms( $args = array() ) {
+ return Pardot_Plugin::get_forms( $args );
+}
+
+/**
+ * Returns an array of dynamic content via the Pardot API as implemented in the Pardot_Plugin class.
+ *
+ * @param array $args
+ * @return Pardot_API
+ *
+ * @since 1.1.0
+ */
+function get_pardot_dynamic_content( $args = array() ) {
+ return Pardot_Plugin::get_dynamicContent( $args );
+}
+
View
308 tags/1.3.7/includes/pardot-forms-shortcode-popup-class.php
@@ -0,0 +1,308 @@
+<?php
+/**
+ * This is a simple convenience class to make it easier to manage the code for the Shortcode Select Popup easier.
+ * Consider it internal-use only.
+ *
+ * @author Mike Schinkel
+ * @since 1.0.0
+ */
+class _Pardot_Forms_Shortcode_Popup {
+ var $title;
+ var $jquery_url;
+ var $tiny_mce_popup_url;
+ var $js;
+ var $css;
+ var $body_inner_html;
+
+ /**
+ * Initialize the values used in the popup's HTML page.
+ *
+ * @since 1.0.0
+ */
+ function __construct() {
+ $this->title = __( 'Insert a Pardot Form or Dynamic Content Shortcode', 'pardot' );
+ $this->jquery_url = site_url( '/wp-includes/js/jquery/jquery.js' );
+ $this->tiny_mce_popup_url = site_url( '/wp-includes/js/tinymce/tiny_mce_popup.js' );
+ $this->js = $this->get_js();
+ $this->css = $this->get_css();
+ $this->body_inner_html = $this->get_body_inner_html();
+ }
+ /**
+ * Return CSS to embed into popup's HTML page.
+ *
+ * @return string The CSS to embed sans <style> tag.
+ *
+ * @since 1.0.0
+ */
+ function get_css() {
+ $css =<<<CSS
+#pardot-tinymce-popup { min-width:400px;width:400px;margin:0;padding:10px 0 0 10px;overflow:hidden;}
+#pardot-forms-shortcode-popup {padding:10px 20px 0 10px;width:376px;}
+#pardot-forms-shortcode-popup #pardot-forms-shortcode-insert-dialog {font-size:1.15em;}
+#pardot-forms-shortcode-popup h1 {font-size:1.5em;margin-bottom:0.5em;}
+#pardot-forms-shortcode-popup p {margin:5px 0;clear:both;}
+#pardot-forms-shortcode-popup p.well {padding:5px;background:#ccc;}
+#pardot-forms-shortcode-popup .mceActionPanel {text-align:center;margin:10px 0;}
+#pardot-forms-shortcode-select .spinner {vertical-align:-3px;}
+#pardot-forms-shortcode-select #formshortcode, #pardot-dc-shortcode-select #dcshortcode {font-size:1em;max-width:100%;float:left;}
+#shortcode-dc-input {width:70%;padding:3px 0;}
+.mceActionPanel {width:100%;float:left;}
+.mceActionPanel #insert {float:left;}
+.mceActionPanel #cancel {float:right;}
+CSS;
+ return $css;
+ }
+ /**
+ * Return Javacript to embed into popup's HTML page.
+ *
+ * This Javascript creates and initializes a tinyMCEPopup object and implements an insert into TinyMCE command.
+ *
+ * @see: http://www.tinymce.com/wiki.php/API3:class.tinyMCEPopup
+ * @see: http://tinymce.moxiecode.com/js/tinymce/docs/api/index.html#class_tinyMCEPopup.html
+ * @see: http://www.tinymce.com/wiki.php/How-to_implement_a_custom_file_browser (search for "File Browser Dialogue Initialization in TinyMCE3.x")
+ *
+ * @return string The Javascript to embed sans <script> tags.
+ *
+ * @since 1.0.0
+ */
+ function get_js() {
+ $js =<<<JS
+var PardotShortcodePopup = {
+ init:function() {},
+ insert:function() {
+ if ( ( jQuery('#formshortcode').length != 0 ) && ( jQuery('#formshortcode').val() != '0' ) ) {
+ var formval = jQuery('#formshortcode').val();
+ var formheight = jQuery('#formh').val();
+ if ( formheight ) {
+ formval = formval.replace('pardot-form', 'pardot-form height="'+formheight+'"')
+ }
+ var formwidth = jQuery('#formw').val();
+ if ( formwidth ) {
+ formval = formval.replace('pardot-form', 'pardot-form width="'+formwidth+'"')
+ }
+ var formclass = jQuery('#formc').val();
+ if ( formclass ) {
+ formval = formval.replace('pardot-form', 'pardot-form class="'+formclass+'"')
+ }
+ tinyMCEPopup.editor.execCommand('mceInsertContent',false,formval);
+ }
+ if ( ( jQuery('#dcshortcode').length != 0 ) && ( jQuery('#dcshortcode').val() != '0' ) ) {
+ var dcval = jQuery('#dcshortcode').val();
+ var dcheight = jQuery('#dch').val();
+ if ( dcheight ) {
+ dcval = dcval.replace('pardot-dynamic-content', 'pardot-dynamic-content height="'+dcheight+'"')
+ }
+ var dcwidth = jQuery('#dcw').val();
+ if ( dcwidth ) {
+ dcval = dcval.replace('pardot-dynamic-content', 'pardot-dynamic-content width="'+dcwidth+'"')
+ }
+ var dcclass = jQuery('#dcc').val();
+ if ( dcclass ) {
+ dcval = dcval.replace('pardot-dynamic-content', 'pardot-dynamic-content class="'+dcclass+'"')
+ }
+ tinyMCEPopup.editor.execCommand('mceInsertContent',false,dcval);
+ }
+ tinyMCEPopup.close();
+ }
+};
+tinyMCEPopup.onInit.add(PardotShortcodePopup.init,PardotShortcodePopup);
+JS;
+ return $js;
+ }
+ /**
+ * Returns the HTML to be used inside the <body> element for popup's HTML page.
+ *
+ * Mostly delegates to $this->get_dialog_html() but it presents an error message if an
+ * API key cannot be retrieved indicating the account has not yet been configured.
+ *
+ * @return string The HTML to display inside of <body> tag.
+ *
+ * @since 1.0.0
+ */
+ function get_body_inner_html() {
+ if ( get_pardot_api_key() ) {
+ $html = $this->get_dialog_html();
+ } else {
+ $page_link = Pardot_Settings::get_admin_page_link( array(
+ 'target' => '_blank',
+ 'onclick' => 'tinyMCEPopup.close();',
+ ));
+ $error_msg = __( 'It looks like your account isn\'t connected yet. Please configure your account credentials at your %s page.', 'pardot' );
+ $error_msg = sprintf( $error_msg, $page_link );
+ $html =<<<HTML
+<p>{$error_msg}</p>
+<div class="mceActionPanel">
+ <div class="cancel-button">
+ <input type="button" id="cancel" name="cancel" value="{#cancel}">
+ </div>
+</div>
+HTML;
+ }
+ return <<<HTML
+<div id="pardot-forms-shortcode-popup">
+{$html}
+</div>
+HTML;
+ }
+ /**
+ * Returns the HTML for the HTML popup dialog that allows selection of Pardot Forms
+ *
+ * Mostly delegates to $this->get_dialog_html() but it presents an error message if an
+ * API key cannot be retrieved indicating the account has not yet been configured.
+ *
+ * @note Uses WordPress AJAX to retrieve list of Pardot forms to avoid painful pause in initial dialog display.
+ *
+ * @return string The HTML to containing the <form> tag with it's <div> wrapper.
+ *
+ * @since 1.0.0
+ */
+ function get_dialog_html() {
+ /**
+ * AJAX url needed to load forms after popup is displayed.
+ * We do this since the forms may not be cached and will
+ * thus may take a few seconds to lookup via API. Not using
+ * AJAX results in a pause for the user where they can easily
+ * get confused and assume nothing is happening.
+ *
+ * Note that 'get_pardot_forms_shortcode_select_html' is defined in Pardot_Plugin class.
+ */
+ $ajax_url = admin_url( 'admin-ajax.php' );
+ /**
+ * Get the URL of a nice little indicator that something is happening.
+ */
+ $spinner_url = admin_url( '/images/wpspin_light.gif' );
+ /**
+ * Get the Settings Page url.
+ */
+ $pardot_settings_url = admin_url( '/options-general.php?page=pardot' );
+ /**
+ * Allow label to be translated into other written languages.
+ */
+ $formsec = __( 'Forms', 'pardot' );
+ $labelform = __( 'Select a form to insert', 'pardot' );
+ $formcust = __( 'Optional iframe Parameters', 'pardot' );
+ $dccust = __( 'Optional iframe Parameters', 'pardot' );
+ $labelformh = __( 'Height', 'pardot' );
+ $labelformw = __( 'Width', 'pardot' );
+ $labelformc = __( 'Class', 'pardot' );
+ $labeldch = __( 'Height', 'pardot' );
+ $labeldcw = __( 'Width', 'pardot' );
+ $labeldcc = __( 'Class', 'pardot' );
+ $dcsec = __( 'Dynamic Content', 'pardot' );
+ $labeldc = __( 'Select dynamic content to insert', 'pardot' );
+ //$labeldcalt = __( 'Default content to show JS-disabled users', 'pardot' );
+ $cache_text = __( '<strong>Not seeing something you added recently in Pardot?</strong> Please click the Clear Cache button on the %s.', 'pardot' );
+ $cache_link = sprintf( '<a href="%s" target="_parent">%s</a>', $pardot_settings_url, 'Pardot Settings Page' );
+ $cache_text = sprintf( $cache_text, $cache_link );
+ $formparam_text = __( 'Height and width should be in digits only (i.e. 250).', 'pardot' );
+ $dcparam_text = __( 'Height and width should be in px or % (i.e. 250px or 90%).', 'pardot' );
+ /**
+ * Use HEREDOC to make the form's HTML much more easy to understand.
+ *
+ * After form loads use AJAX to call back to WordPress to get the list of forms for user selection.
+ */
+ $html =<<<HTML
+<div id="pardot-forms-shortcode-insert-dialog">
+<form method="post" action="#">
+ <div class="fields">
+ <h2>{$formsec}</h2>
+ <label for="shortcode">{$labelform}</label>:
+ <br clear="all" />
+ <span id="pardot-forms-shortcode-select">
+ <input type="hidden" id="shortcode">
+ <img class="spinner" src="{$spinner_url}" height="16" weight="16" alt="Time waits for no man.">
+ </span>
+ <br clear="all" />
+ <h4>{$formcust}</h4>
+ <p><small>{$formparam_text}</small></p>
+ <label for="formh">{$labelformh}</label>:
+ <input type="text" size="6" id="formh" name="formh" />
+ <label for="formw">{$labelformw}</label>:
+ <input type="text" size="6" id="formw" name="formw" />
+ <label for="formc">{$labelformc}</label>:
+ <input type="text" id="formc" name="formc"/>
+ <br clear="all" />
+ <br />
+ <h2>{$dcsec}</h2>
+ <label for="shortcode-dc">{$labeldc}</label>:
+ <span id="pardot-dc-shortcode-select">
+ <input type="hidden" id="shortcodedc">
+ <img class="spinner" src="{$spinner_url}" height="16" weight="16" alt="Time waits for no man.">
+ </span>
+ <br clear="all" />
+ <h4>{$dccust}</h4>
+ <p><small>{$dcparam_text}</small></p>
+ <label for="dch">{$labeldch}</label>:
+ <input type="text" size="6" id="dch" name="dch" />
+ <label for="dcw">{$labeldcw}</label>:
+ <input type="text" size="6" id="dcw" name="dcw" />
+ <label for="dcc">{$labeldcc}</label>:
+ <input type="text" id="dcc" name="dcc"/>
+ </div>
+ <div class="mceActionPanel">
+ <span class="insert-button">
+ <input type="submit" id="insert" name="insert" value="{#insert}" class="button-primary" onclick="PardotShortcodePopup.insert();" />
+ </span>
+ <!-- If you're reading this, you're getting a sneak peek of a future relase. Well done! -->
+ <!--<span class="reload-button">
+ <input type="submit" id="reload" name="reload" value="Reload" class="updateButton" onclick="return refresh_cache();" />
+ </span>-->
+ <span class="cancel-button">
+ <input type="submit" id="cancel" name="cancel" value="{#cancel}" class="button-secondary" onclick="tinyMCEPopup.close();" />
+ </span>
+ </div>
+ <p class="well"><small>{$cache_text}</small></p>
+</form>
+</div>
+<script type="text/javascript">
+jQuery(document).ready(function($) {
+ $.ajax({
+ type:"post",
+ dataType:"html",
+ url:"{$ajax_url}",
+ data:{action:"get_pardot_forms_shortcode_select_html"},
+ success: function(html) {
+ $("#pardot-forms-shortcode-select").html(html);
+ }
+ });
+ $.ajax({
+ type:"post",
+ dataType:"html",
+ url:"{$ajax_url}",
+ data:{action:"get_pardot_dynamicContent_shortcode_select_html"},
+ success: function(lmth) {
+ $("#pardot-dc-shortcode-select").html(lmth);
+ }
+ });
+});
+function refresh_cache() {
+ tinyMCEPopup.resizeToInnerSize();
+ jQuery.ajax({
+ type:"post",
+ url:"{$ajax_url}",
+ data:{action:"popup_reset_cache"},
+ });
+ jQuery.ajax({
+ type:"post",
+ dataType:"html",
+ url:"{$ajax_url}",
+ data:{action:"get_pardot_forms_shortcode_select_html"},
+ success: function(html) {
+ jQuery("#pardot-forms-shortcode-select").html(html);
+ }
+ });
+ jQuery.ajax({
+ type:"post",
+ dataType:"html",
+ url:"{$ajax_url}",
+ data:{action:"get_pardot_dynamicContent_shortcode_select_html"},
+ success: function(lmth) {
+ jQuery("#pardot-dc-shortcode-select").html(lmth);
+ }
+ });
+}
+</script>
+HTML;
+ return $html;
+ }
+}
View
852 tags/1.3.7/includes/pardot-forms-widget-class.php
@@ -0,0 +1,852 @@
+<?php
+/**
+ * WordPress Pardot Forms Widget
+ *
+ * @author Mike Schinkel <mike@newclarity.net>
+ *
+ * @see: http://codex.wordpress.org/Widgets_API
+ *
+ * @since 1.0.0
+ *
+ */
+class Pardot_Forms_Widget extends WP_Widget {
+ /**
+ * @var int Timeout value for front-end widget form that can reset in a hook, if need be. Initially 30 days.
+ *
+ * @since 1.0.0
+ */
+ static $cache_timeout = PARDOT_WIDGET_FORM_CACHE_TIMEOUT;
+
+ /**
+ * Add the hooks needed by this Widget.
+ *
+ * This method is called once immediately at the end of the class definition.
+ *
+ * @static
+ *
+ * @return void
+ *
+ * @since 1.0.0
+ */
+ static function on_load() {
+ /**
+ * Use 'widgets_init' to register this widget
+ */
+ add_action( 'widgets_init', array( __CLASS__, 'widgets_init' ) );
+ /*
+ * Do the following for inline forms only; not needed for iframed forms.
+ */
+ if ( 'inline' == PARDOT_FORM_INCLUDE_TYPE ) {
+ /**
+ * Use the wp_head action to insert CSS into the header.
+ * Use priority == 0 so it will be added very early and thus will allow themer's to override CSS if required.
+ */
+ add_action( 'wp_head', array( __CLASS__, 'wp_head' ), 0 );
+ /**
+ * Use the plugins_loaded hook to check for the /pardot-form-submit/ path
+ * which is the path used for a postback from this widget.
+ */
+ add_action( 'plugins_loaded', array( __CLASS__, 'plugins_loaded' ) );
+ }
+
+ }
+
+ /**
+ * Register this widget with WordPress using the name of this PHP class.
+ *
+ * @static
+ *
+ * @return void
+ *
+ * @see: http://codex.wordpress.org/Widgets_API
+ *
+ * @since 1.0.0
+ */
+ static function widgets_init() {
+ register_widget( __CLASS__ );
+ }
+
+ /**
+ * Use the wp_head action to insert CSS into the header.
+ *
+ * This will be called with priority == 0 to allow themer's to override CSS if required.
+ * This will only be called for inline forms; not needed for iframed forms.
+ *
+ * @static
+ *
+ * @since 1.0.0
+ */
+ static function wp_head() {
+ $css = <<<CSS
+.pardot-forms-body .field-label { text-align: left; width:auto;}
+.pardot-forms-body form.form input.text { width:95%;}
+CSS;
+ echo "\n<style type=\"text/css\">\n{$css}\n</style>\n";
+ }
+
+ /**
+ * Use the plugins_loaded action to test for /pardot-form-submit/ path.
+ *
+ * The /pardot-form-submit/ path is the postback URL for inline forms.
+ * This will only be called for inline forms; not needed for iframed forms.
+ *
+ * @static
+ *
+ * @return void
+ *
+ * @since 1.0.0
+ */
+ static function plugins_loaded() {
+ /**
+ * Check for /pardot-form-submit/ path.
+ */
+ if ( preg_match( '#^/pardot-form-submit/\?(.*)$#', $_SERVER['REQUEST_URI'] ) ) {
+ /**
+ * Check to make sure that referrer is the current, i.e. that the HTTP_REFERER begins with the site_url().
+ */
+ $regex = '#^' . str_replace( '.', '\.', site_url() ) . '#';
+ $url = preg_match( $regex, $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : site_url();
+
+ /**
+ * Connvert the POST_ROOT_URL into a regex (escape the '.'s)
+ */
+ $post_root_url_regex = str_replace( '.', '\.', Pardot_Settings::POST_ROOT_URL );
+
+ /**
+ * Check to make the "url" parameter matches the post's root URL
+ */
+ if ( isset( $_GET['url'] ) && preg_match( "#^{$post_root_url_regex}/#", $_GET['url'] ) ) {
+ /**
+ * Post back to Pardot's website using the WordPress HTTP function.
+ *
+ * $_POST will contain the prior $_POST's body, just pass it along.
+ *
+ */
+ $response = wp_remote_post(
+ $_GET['url'], array(
+ 'body' => $_POST,
+ 'user-agent' => 'Pardot WordPress Plugin',
+ )
+ );
+
+ /**
+ * Inspect response for Status 200=ok, 'success' for 200, 'errors' otherwise
+ *
+ * $_POST will contain the prior $_POST's body, just pass it along.
+ *
+ */
+ $result = wp_remote_retrieve_response_code( $response ) == 200 ? 'success' : 'errors';
+
+ /**
+ * Add a URL parameter named 'pardot-contact-request' for success or failure.
+ *
+ */
+ $url = add_query_arg( array( 'pardot-contact-request' => $result ), $url );
+ }
+ /**
+ * Redirect back to this page or the root of the site if referrer is not this page and with success or error
+ * message if $_GET['url'] starts with Pardot_Settings::POST_ROOT_URL.
+ */
+ wp_safe_redirect( $url );
+ /**
+ * Terminate the page.
+ */
+ exit;
+ }
+ }
+
+ /**
+ * PHP object constructor calls parent to enable setting Widget classname and description.
+ *
+ * @since 1.0.0
+ */
+ function __construct() {
+ /**
+ * @var array Set Widget's objects, i.e. classname and description.
+ */
+ $widget_ops = array(
+ 'classname' => 'pardot-forms',
+ 'description' => __( 'Embed a Pardot form in your sidebar.', 'pardot' )
+ );
+ /**
+ * @var array Empty array lists to document that parameters for the WP_Widget parent constructor.
+ *
+ */
+ $control_ops = array();
+
+ /**
+ * Call the WP_Widget parent constructor.
+ */
+ parent::__construct( 'pardot-forms', __( 'Pardot Forms', 'pardot' ), $widget_ops, $control_ops );
+ }
+/*
+
+*/
+ /**
+ * Displays Pardot forms for Widget HTML on front end of site.
+ *
+ * Echos form defined in Pardot account and specified for this widget. Can display as IFrame or as inline HTML the
+ * latter of which is experimental.
+ *
+ * @param array $args Arguments passed by the sidebar. $args can be one of:
+ *
+ * - 'name'
+ * - 'id'
+ * - 'description'
+ * - 'class'
+ * - 'before_widget'
+ * - 'after_widget'
+ * - 'before_title'
+ * - 'after_title'
+ * - 'widet_id'
+ * - 'widget_name'
+ *
+ * @param array $instance Contains 'form_id' value set in $this->form() and $this->update().
+ * @return void
+ *
+ * @see WP_Widget::widget()
+ * @see: http://codex.wordpress.org/Widgets_API
+ *
+ * @since 1.0.0
+ */
+ function widget( $args, $instance ) {
+ /**
+ * @var string $title Allow the widget title to be modified by the 'widget_title' hook.
+ */
+ $title = apply_filters(
+ 'widget_title', ! empty( $instance['title'] ) ? $instance['title'] : false, $instance, $this->id_base
+ );
+ /**
+ * If no title specified by hook, give is a default value.
+ */
+ if ( empty( $title ) )
+ $title = __( '', 'pardot' );
+
+ /**
+ * Wrap a non-empty title with before and after content.
+ */
+ $title_html = ! empty( $title ) ? "{$args['before_title']}{$title}{$args['after_title']}" : false;
+
+ /**
+ * Grab form_id from the instance that we set in $this->update() and use it to grab the HTML for this Pardot Form.
+ */
+ $body_html = Pardot_Plugin::get_form_body( $instance );
+
+ /**
+ * After all that if the $body_html is not empty, we can use it as a form.
+ */
+ if ( $body_html ) {
+ /**
+ * Allow others to modify the form HTML if needed.
+ */
+ $body_html = apply_filters( 'pardot_widget_body_html', $body_html, $instance, $this, $args );
+ /**
+ * Use a HEREDOC to assemble the HTML for the form.
+ */
+ $html = <<<HTML
+{$args['before_widget']}
+<div class="pardot-forms-widget">
+ {$title_html}
+ <div class="pardot-forms-body">
+ {$body_html}
+ </div>
+</div>
+{$args['after_widget']}
+HTML;
+ /**
+ * Lastly let other modify the HTML if needed.
+ */
+ echo apply_filters( 'widget_html', $html, $instance, $this, $args );
+ }
+ }
+
+ /**
+ * Sanitize widget form values as they are saved.
+ *
+ * @param array $new_instance Values just sent to be saved.
+ * @param array $old_instance Previously saved values from database.
+ *
+ * @return array Updated safe values to be saved.
+ *
+ * @see WP_Widget::update()
+ * @see: http://codex.wordpress.org/Widgets_API
+ *
+ *
+ * @since 1.0.0
+ */
+ function update( $new_instance, $old_instance ) {
+ /**
+ * Default the 'form_id' to a non-selected form ID, i.e. '0'.
+ */
+ $instance = array( 'form_id' => 0 );
+
+ /**
+ * If the new instance has 'form_id' then capture it's value before returning.
+ */
+ if ( isset( $new_instance['form_id'] ) )
+ $instance['form_id'] = $new_instance['form_id'];
+
+ $instance['title'] = strip_tags( $new_instance['title'] );
+ $instance['height'] = strip_tags( $new_instance['height'] );
+ $instance['width'] = strip_tags( $new_instance['width'] );
+ $instance['class'] = strip_tags( $new_instance['class'] );
+
+ return $instance;
+ }
+
+ /**
+ * Display the widget configuration form in the Widgets section of the Admin.
+ *
+ * @param array $instance Contains 'form_id' value set in $this->update() and used in $this->widget().
+ * @return void
+ *
+ * @see WP_Widget::form()
+ * @see: http://codex.wordpress.org/Widgets_API
+ *
+ * @since 1.0.0
+ */
+ function form( $instance ) {
+ /**
+ * Check the cache and/or call the API to get the array of forms.
+ */
+ $forms = get_pardot_forms();
+ if ( ! $forms ) {
+ /**
+ * We have no forms!
+ * Create link text for the help link
+ */
+ $help_link_text = __( 'Settings', 'pardot' );
+
+ /**
+ * Merge the link and help text link into a help link.
+ */
+ $help_link = sprintf( '<a href="%s" target="_blank">%s</a>', Pardot_Settings::get_admin_page_url(), $help_link_text );
+
+ /**
+ * Create a variable for help text to be used in the HEREDOC
+ * Add the link into the help text.
+ */
+ $help_text = __( 'You have no forms yet, or there is a connection issue. Please check your %s.', 'pardot' );
+ $help_text = sprintf( $help_text, $help_link );
+
+ /**
+ * Finally create the HTML containing the help message about no forms.
+ */
+ $html = "<p>{$help_text}</p>";
+
+ } else {
+ /**
+ * We DO have forms!
+ *
+ * If the instance hasn't been initialized via $this->update(), give it's 'form_id' element
+ * a value indicating no Pardot form has yet to be selected by an admin user.
+ */
+ if ( ! isset( $instance['form_id'] ) )
+ $instance['form_id'] = 0;
+
+ /**
+ * Create an array to capture the HTML output into.
+ */
+ $options = array();
+
+ /**
+ * Give the zero (0) value meaning no form yet selected a default value.
+ */
+ $label_option = (object) array( 'id' => 0, 'name' => __( 'Please select a Form', 'pardot' ) );
+
+ /**
+ * Insert the 'no form yet selected' value to the beginning of the list of options.
+ */
+ array_unshift( $forms, $label_option );
+
+ /**
+ * For each Pardot form that the current account has configured
+ */
+ foreach ( $forms as $form ) {
+ /**
+ * For the selected value, assign $selected to be ' selected="selected"' for use in the <option> tag.
+ */
+ if ( isset($form->id) ) {
+ $selected = selected( $instance['form_id'], $form->id, false );
+
+ /**
+ * Add an array element containing the HTML for each option
+ */
+ $options[] = "<option value=\"{$form->id}\"{$selected}>{$form->name}</option>";
+ }
+ }
+
+ /**
+ * Convert array of HTML options to a string of HTML options
+ */
+ $options = implode( '', $options );
+
+ /**
+ * Get the Form ID into a variable for HTML id that can be used in the HEREDOC
+ * This will leave dashes.
+ */
+ $html_id = $this->get_field_id( 'form_id' );
+
+ /**
+ * Get the Form ID into a variable for HTML name that can be used in the HEREDOC
+ * This will convert dashes to underscores.
+ */
+ $html_name = $this->get_field_name( 'form_id' );
+
+ /**
+ * Create a variable for prompting the user to be used in the HEREDOC
+ */
+ $prompt = __( 'Select Form:', 'pardot' );
+
+ /**
+ * Create link text for the help link
+ */
+ $help_link_text = __( 'helpful Knowledge Base article', 'pardot' );
+
+ /**
+ * Merge the link and help text link into a help link.
+ */
+ $help_link = sprintf( '<a href="%s" target="_blank">%s</a>', Pardot_Settings::HELP_URL, $help_link_text );
+
+ /**
+ * Create a variable for help text to be used in the HEREDOC
+ * Add the link into the help text.
+ */
+ $help_text = __( 'If some of your form is cut off or the styling isn\'t quite right, please read our %s.', 'pardot' );
+ $help_text = sprintf( $help_text, $help_link );
+
+ /**
+ * Create a variable for parameters helper text.
+ */
+ $param_text = __( 'Height and width should be in digits only (i.e. 250).', 'pardot' );
+
+ /**
+ * Create link to Settings Page
+ */
+ $pardot_settings_url = admin_url( '/options-general.php?page=pardot' );
+ $cache_text = __( '<strong>Not seeing something you added recently in Pardot?</strong> Please click the Clear Cache button on the %s.', 'pardot' );
+ $cache_link = sprintf( '<a href="%s" target="_parent">%s</a>', $pardot_settings_url, 'Pardot Settings Page' );
+ $cache_text = sprintf( $cache_text, $cache_link );
+
+ /**
+ * Create the HTML for displaying the select of Pardot forms
+ */
+ $html = <<<HTML
+<p><label for="{$html_id}">{$prompt}</label><select id="{$html_id}" name="{$html_name}" style="max-width:100%">{$options}</select></p>
+HTML;
+ }
+
+ if ( isset( $instance[ 'title' ] ) ) {
+ $title = $instance[ 'title' ];
+ } else {
+ $title = __( '', 'text_domain' );
+ }
+
+ $html .= '<p><label for="' . $this->get_field_id( "title" ) . '">' . __( 'Title:' ) . '</label><input class="widefat" id="' . $this->get_field_id( "title" ) . '" name="' . $this->get_field_name( "title" ) . '" type="text" value="' . esc_attr( $title ) . '" /></p>';
+
+ $html .= '<p><strong>Optional Parameters</strong><br/><small>' . $param_text . '</small></p>';
+
+ if ( isset( $instance[ 'height' ] ) ) {
+ $height = $instance[ 'height' ];
+ } else {
+ $height = __( '', 'text_domain' );
+ }
+
+ $html .= '<p><label for="' . $this->get_field_id( "height" ) . '">' . __( 'Height:' ) . '</label><input id="' . $this->get_field_id( "height" ) . '" name="' . $this->get_field_name( "height" ) . '" type="text" value="' . esc_attr( $height ) . '" size="6" />';
+
+ if ( isset( $instance[ 'width' ] ) ) {
+ $width = $instance[ 'width' ];
+ } else {
+ $width = __( '', 'text_domain' );
+ }
+
+ $html .= '<label for="' . $this->get_field_id( "width" ) . '">' . __( 'Width:' ) . '</label><input id="' . $this->get_field_id( "width" ) . '" name="' . $this->get_field_name( "width" ) . '" type="text" value="' . esc_attr( $width ) . '" size="6" /></p>';
+
+ if ( isset( $instance[ 'class' ] ) ) {
+ $class = $instance[ 'class' ];
+ } else {
+ $class = __( '', 'text_domain' );
+ }
+
+ $html .= '<p><label for="' . $this->get_field_id( "class" ) . '">' . __( 'Class:' ) . '</label><input class="widefat" id="' . $this->get_field_id( "class" ) . '" name="' . $this->get_field_name( "class" ) . '" type="text" value="' . esc_attr( $class ) . '" /></p>';
+
+
+
+ $html .= <<<HTML
+<p><small>{$help_text}</small></p>
+<p><small>{$cache_text}</small></p>
+HTML;
+
+ /**
+ * Display whatever HTML is appropriate; error message help or list of forms.
+ */
+ echo $html;
+ }
+
+}
+/**
+ * Calls startup method that add actions and filters to hook WordPress for this widget.
+ */
+Pardot_Forms_Widget::on_load();
+
+/**
+ * WordPress Pardot Dynamic Content Widget
+ *
+ * @author Cliff Seal <cliff.seal@pardot.com>
+ *
+ * @see: http://codex.wordpress.org/Widgets_API
+ *
+ * @since 1.1.0
+ *
+ */
+class Pardot_Dynamic_Content_Widget extends WP_Widget {
+ /**
+ * @var int Timeout value for front-end widget form that can reset in a hook, if need be. Initially 30 days.
+ *
+ * @since 1.1.0
+ */
+ static $cache_timeout = PARDOT_WIDGET_FORM_CACHE_TIMEOUT;
+
+ /**
+ * Add the hooks needed by this Widget.
+ *
+ * This method is called once immediately at the end of the class definition.
+ *
+ * @static
+ *
+ * @return void
+ *
+ * @since 1.1.0
+ */
+ static function on_load() {
+ /**
+ * Use 'widgets_init' to register this widget
+ */
+ add_action( 'widgets_init', array( __CLASS__, 'widgets_init' ) );
+ }
+
+ /**
+ * Register this widget with WordPress using the name of this PHP class.
+ *
+ * @static
+ *
+ * @return void
+ *
+ * @see: http://codex.wordpress.org/Widgets_API
+ *
+ * @since 1.1.0
+ */
+ static function widgets_init() {
+ register_widget( __CLASS__ );
+ }
+
+ /**
+ * PHP object constructor calls parent to enable setting Widget classname and description.
+ *
+ * @since 1.1.0
+ */
+ function __construct() {
+ /**
+ * @var array Set Widget's objects, i.e. classname and description.
+ */
+ $widget_ops = array(
+ 'classname' => 'pardot-dynamic-content',
+ 'description' => __( 'Use Pardot Dynamic Content in your sidebar.', 'pardot' )
+ );
+ /**
+ * @var array Empty array lists to document that parameters for the WP_Widget parent constructor.
+ *
+ */
+ $control_ops = array();
+
+ /**
+ * Call the WP_Widget parent constructor.
+ */
+ parent::__construct( 'pardot-dynamic-content', __( 'Pardot Dynamic Content', 'pardot' ), $widget_ops, $control_ops );
+ }
+/*
+
+*/
+ /**
+ * Displays Pardot dynamic content for Widget HTML on front end of site.
+ *
+ * Echos dynamic content defined in Pardot account and specified for this widget.
+ *
+ * @param array $args Arguments passed by the sidebar. $args can be one of:
+ *
+ * - 'name'
+ * - 'id'
+ * - 'description'
+ * - 'class'
+ * - 'before_widget'
+ * - 'after_widget'
+ * - 'before_title'
+ * - 'after_title'
+ * - 'widet_id'
+ * - 'widget_name'
+ *
+ * @param array $instance Contains 'form_id' value set in $this->form() and $this->update().
+ * @return void
+ *
+ * @see WP_Widget::widget()
+ * @see: http://codex.wordpress.org/Widgets_API
+ *
+ * @since 1.1.0
+ */
+ function widget( $args, $instance ) {
+ /**
+ * @var string $title Allow the widget title to be modified by the 'widget_title' hook.
+ */
+ $title = apply_filters(
+ 'widget_title', ! empty( $instance['title'] ) ? $instance['title'] : false, $instance, $this->id_base
+ );
+ /**
+ * If no title specified by hook, give is a default value.
+ */
+ if ( empty( $title ) )
+ $title = __( '', 'pardot' );
+
+ /**
+ * Wrap a non-empty title with before and after content.
+ */
+ $title_html = ! empty( $title ) ? "{$args['before_title']}{$title}{$args['after_title']}" : false;
+
+ /**
+ * Grab form_id from the instance that we set in $this->update() and use it to grab the HTML for this Pardot Form.
+ */
+ $body_html = Pardot_Plugin::get_dynamic_content_body( $instance );
+
+ wp_register_script( 'pddc', plugins_url( 'js/asyncdc.min.js' , dirname(__FILE__) ), 'jquery', false, true);
+ wp_enqueue_script( 'pddc' );
+
+ /**
+ * After all that if the $body_html is not empty, we can use it as a form.
+ */
+ if ( $body_html ) {
+ /**
+ * Allow others to modify the form HTML if needed.
+ */
+ $body_html = apply_filters( 'pardot_widget_body_html', $body_html, $instance, $this, $args );
+ /**
+ * Use a HEREDOC to assemble the HTML for the form.
+ */
+ $html = <<<HTML
+{$args['before_widget']}
+<div class="pardot-dynamic-content-widget">
+ {$title_html}
+ <div class="pardot-dynamic-content-body">
+ {$body_html}
+ </div>
+</div>
+{$args['after_widget']}
+HTML;
+ /**
+ * Lastly let other modify the HTML if needed.
+ */
+ echo apply_filters( 'widget_html', $html, $instance, $this, $args );
+ }
+ }
+
+ /**
+ * Sanitize widget form values as they are saved.
+ *
+ * @param array $new_instance Values just sent to be saved.
+ * @param array $old_instance Previously saved values from database.
+ *
+ * @return array Updated safe values to be saved.
+ *
+ * @see WP_Widget::update()
+ * @see: http://codex.wordpress.org/Widgets_API
+ *
+ *
+ * @since 1.1.0
+ */
+ function update( $new_instance, $old_instance ) {
+ /**
+ * Default the 'form_id' to a non-selected form ID, i.e. '0'.
+ */
+ $instance = array( 'dynamicContent' => 0 );
+
+ /**
+ * If the new instance has 'form_id' then capture it's value before returning.
+ */
+ if ( isset( $new_instance['dynamicContent_id'] ) )
+ $instance['dynamicContent_id'] = $new_instance['dynamicContent_id'];
+
+ $instance['title'] = strip_tags( $new_instance['title'] );
+ $instance['height'] = strip_tags( $new_instance['height'] );
+ $instance['width'] = strip_tags( $new_instance['width'] );
+ $instance['class'] = strip_tags( $new_instance['class'] );
+
+ return $instance;
+ }
+
+ /**
+ * Display the widget configuration form in the Widgets section of the Admin.
+ *
+ * @param array $instance Contains 'form_id' value set in $this->update() and used in $this->widget().
+ * @return void
+ *
+ * @see WP_Widget::form()
+ * @see: http://codex.wordpress.org/Widgets_API
+ *
+ * @since 1.1.0
+ */
+ function form( $instance ) {
+ /**
+ * Check the cache and/or call the API to get the array of forms.
+ */
+ $dynamicContents = get_pardot_dynamic_content();
+ if ( ! $dynamicContents ) {
+ /**
+ * We have no forms!
+ * Create link text for the help link
+ */
+ $help_link_text = __( 'Settings', 'pardot' );
+
+ /**
+ * Merge the link and help text link into a help link.
+ */
+ $help_link = sprintf( '<a href="%s" target="_blank">%s</a>', Pardot_Settings::get_admin_page_url(), $help_link_text );
+
+ /**
+ * Create a variable for help text to be used in the HEREDOC
+ * Add the link into the help text.
+ */
+ $help_text = __( 'You have no dynamic content yet, or there is a connection issue. Please check your %s.', 'pardot' );
+ $help_text = sprintf( $help_text, $help_link );
+
+ /**
+ * Finally create the HTML containing the help message about no forms.
+ */
+ $html = "<p>{$help_text}</p>";
+
+ } else {
+ /**
+ * We DO have forms!
+ *
+ * If the instance hasn't been initialized via $this->update(), give it's 'form_id' element
+ * a value indicating no Pardot form has yet to be selected by an admin user.
+ */
+ if ( ! isset( $instance['dynamicContent_id'] ) )
+ $instance['dynamicContent_id'] = 0;
+
+ /**
+ * Create an array to capture the HTML output into.
+ */
+ $options = array();
+
+ /**
+ * Give the zero (0) value meaning no form yet selected a default value.
+ */
+ $label_option = (object) array( 'id' => 0, 'name' => __( ' Please Select Dynamic Content', 'pardot' ) );
+
+ /**
+ * Insert the 'no form yet selected' value to the beginning of the list of options.
+ */
+ array_unshift( $dynamicContents, $label_option );
+
+ /**
+ * For each Pardot form that the current account has configured
+ */
+ foreach ( $dynamicContents as $dynamicContent ) {
+ /**
+ * For the selected value, assign $selected to be ' selected="selected"' for use in the <option> tag.
+ */
+ $selected = selected( $instance['dynamicContent_id'], $dynamicContent->id, false );
+ /**
+ * Add an array element containing the HTML for each option
+ */
+ $options[] = "<option value=\"{$dynamicContent->id}\"{$selected}>{$dynamicContent->name}</option>";
+ }
+
+ /**
+ * Convert array of HTML options to a string of HTML options
+ */
+ $options = implode( '', $options );
+
+ /**
+ * Get the Form ID into a variable for HTML id that can be used in the HEREDOC
+ * This will leave dashes.
+ */
+ $html_id = $this->get_field_id( 'dynamicContent_id' );
+
+ /**
+ * Get the Form ID into a variable for HTML name that can be used in the HEREDOC
+ * This will convert dashes to underscores.
+ */
+ $html_name = $this->get_field_name( 'dynamicContent_id' );
+
+ /**
+ * Create a variable for prompting the user to be used in the HEREDOC
+ */
+ $prompt = __( 'Select Dynamic Content:', 'pardot' );
+
+ /**
+ * Create link to Settings Page
+ */
+ $pardot_settings_url = admin_url( '/options-general.php?page=pardot' );
+ $cache_text = __( '<strong>Not seeing something you added recently in Pardot?</strong> Please click the Clear Cache button on the %s.', 'pardot' );
+ $cache_link = sprintf( '<a href="%s" target="_parent">%s</a>', $pardot_settings_url, 'Pardot Settings Page' );
+ $cache_text = sprintf( $cache_text, $cache_link );
+
+ /**
+ * Create a variable for parameters helper text.
+ */
+ $param_text = __( 'Height and width should be in px or % (i.e. 250px or 90%).', 'pardot' );
+
+ /**
+ * Create the HTML for displaying the select of Pardot forms
+ */
+ $html = <<<HTML
+<p><label for="{$html_id}">{$prompt}</label><select id="{$html_id}" name="{$html_name}" style="max-width:100%">{$options}</select></p>
+HTML;
+ }
+
+ if ( isset( $instance[ 'title' ] ) ) {
+ $title = $instance[ 'title' ];
+ } else {
+ $title = __( 'New title', 'text_domain' );
+ }
+
+ $html .= '<p><label for="' . $this->get_field_id( "title" ) . '">' . __( 'Title:' ) . '</label><input class="widefat" id="' . $this->get_field_id( "title" ) . '" name="' . $this->get_field_name( "title" ) . '" type="text" value="' . esc_attr( $title ) . '" /></p>';
+
+ $html .= '<p><strong>Optional Parameters</strong><br/><small>' . $param_text . '</small></p>';
+
+ if ( isset( $instance[ 'height' ] ) ) {
+ $height = $instance[ 'height' ];
+ } else {
+ $height = __( '', 'text_domain' );
+ }
+
+ $html .= '<p><label for="' . $this->get_field_id( "height" ) . '">' . __( 'Height:' ) . '</label><input id="' . $this->get_field_id( "height" ) . '" name="' . $this->get_field_name( "height" ) . '" type="text" value="' . esc_attr( $height ) . '" size="6" />';
+
+ if ( isset( $instance[ 'width' ] ) ) {
+ $width = $instance[ 'width' ];
+ } else {
+ $width = __( '', 'text_domain' );
+ }
+
+ $html .= '<label for="' . $this->get_field_id( "width" ) . '">' . __( 'Width:' ) . '</label><input id="' . $this->get_field_id( "width" ) . '" name="' . $this->get_field_name( "width" ) . '" type="text" value="' . esc_attr( $width ) . '" size="6" /></p>';
+
+ if ( isset( $instance[ 'class' ] ) ) {
+ $class = $instance[ 'class' ];
+ } else {
+ $class = __( '', 'text_domain' );
+ }
+
+ $html .= '<p><label for="' . $this->get_field_id( "class" ) . '">' . __( 'Class:' ) . '</label><input class="widefat" id="' . $this->get_field_id( "class" ) . '" name="' . $this->get_field_name( "class" ) . '" type="text" value="' . esc_attr( $class ) . '" /></p>';
+
+ $html .= '<p><small>' . $cache_text . '</small></p>';
+
+ /**
+ * Display whatever HTML is appropriate; error message help or list of forms.
+ */
+ echo $html;
+ }
+
+}
+/**
+ * Calls startup method that add actions and filters to hook WordPress for this widget.
+ */
+Pardot_Dynamic_Content_Widget::on_load();
View
1,053 tags/1.3.7/includes/pardot-plugin-class.php
@@ -0,0 +1,1053 @@
+<?php
+/**
+ * Manages the general functionality for the Pardot Plugin that doesn't fit elsewhere.
+ *
+ * Includes:
+ * - Automatic Javascript in the theme footer
+ * - [pardot-form] Shortcode
+ * - [pardot-dynamic-content] Shortcode
+ * - Caching support
+ * - Call and retrieve values from the Pardot API
+ * - Hooks to support the Pardot Forms Shortcode Insert button for TinyMCE
+ * - AJAX support for the Pardot Forms Shortcode Insert popup
+ * - Adds 'Settings' link to the plugins admin page for this plugin.
+ * - admin_init to ensure hooks are added for admin pages.
+ *
+ * @todo Refresh the API cache on a cron task before the cache times out (default = 180 seconds) which will ensure
+ * always fast performance on Widgets page on with Shortcode Insert Popup.
+ *
+ * @author Mike Schinkel <mike@newclarity.net>
+ *
+ * @since 1.0.0
+ */
+class Pardot_Plugin {
+
+ /**
+ * @var Pardot_Plugin Capture $this so that other can remove_action() if needed.
+ */
+ private static $self;
+
+ /**
+ * @var Pardot_API Capture an $api instance since we will often use it several times in a page load.
+ */
+ private static $api;
+
+ /**
+ * @var int Set cache timeout for the API (probably 180 seconds) to cache API responses other than authenticate.
+ * Set based on a constant which can be changed in /wp-config.php
+ */
+ static $cache_timeout = PARDOT_API_CACHE_TIMEOUT;
+
+ /**
+ * Create singleton instance of the Pardot Plugin object.
+ *
+ * @since 1.0.0
+ */
+ function __construct() {
+
+ /**
+ * This class is designed to be instansiated only once.
+ * We instantiate once at end of this class definition, throw an error if someone tries a second time.
+ */
+ if ( isset( self::$self ) )
+ wp_die( __( 'Pardot_Plugin should not be created more than once.', 'pardot' ) );
+
+ /**
+ * Set self::$self so that a user can remove access to one of these actions or shortcodes if they need to.
+ */
+ self::$self = $this;
+
+ /**
+ * Hook the 'init' action where we add other actions and the shortcode.
+ */
+ add_action( 'init', array( $this, 'init' ) );
+
+ }
+ /**
+ * Return the singleton instance of this class.
+ *
+ * To be use in case someone needs to remove one of the actions or shortcodes.
+ *
+ * @static
+ * @return Pardot_Plugin
+ *
+ * @since 1.0.0
+ */
+ static function self() {
+ return self::$self;
+ }
+
+ /**
+ * Hook the 'init' action where we add other actions and the shortcode.
+ *
+ * @since 1.0.0
+ */
+ function init() {
+ /**
+ * Load the pardot text domain for language translations
+ */
+ add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
+
+ /**
+ * Add the Pardot Javascript to the form.
+ */
+ add_action( 'wp_footer', array( $this, 'wp_footer' ) );
+
+ /**
+ * Create the shortcode [pardot-form]
+ */
+ add_shortcode( 'pardot-form', array( $this, 'form_shortcode' ) );
+
+ /**
+ * Create the shortcode [pardot-dynamic-content]
+ */
+ add_shortcode( 'pardot-dynamic-content', array( $this, 'dynamic_content_shortcode' ) );
+
+ /**
+ * Add 'Settings' link on plugin list page and add TinyMCE button for post editor.
+ */
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
+
+ /**
+ * Listen for AJAX post back for the form's shortcode selector.
+ */
+ add_action( 'wp_ajax_get_pardot_forms_shortcode_select_html', array( $this, 'wp_ajax_get_pardot_forms_shortcode_select_html' ) );
+
+ /**
+ * Listen for AJAX post back for the dynamic content's shortcode selector.
+ */
+ add_action( 'wp_ajax_get_pardot_dynamicContent_shortcode_select_html', array( $this, 'wp_ajax_get_pardot_dynamicContent_shortcode_select_html' ) );
+
+ /**
+ * Listen for AJAX post back for the reload button.
+ */
+ add_action( 'wp_ajax_popup_reset_cache', array( $this, 'wp_ajax_popup_reset_cache' ) );
+ }
+
+ /**
+ * AJAX function used to return the list of Pardot forms for the current accounts selected campaign.