0f90a2a2476b42f06c97ea54fb3959fd0ddfc48f
Author: psychic
Date: 2009-01-26 12:42:38 -0800
diff --git a/app/config/routes.php b/app/config/routes.php
index 8382cf0..ab9a15e 100644
--- a/app/config/routes.php
+++ b/app/config/routes.php
@@ -1,6 +1,6 @@
<?php
- Router::connect('/', array('controller' => 'plugins', 'action' => 'index'));
+ Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
Router::mapResources('plugins');
Router::mapResources('users');
diff --git a/app/controllers/plugins_controller.php b/app/controllers/plugins_controller.php
index 4e8c9aa..ed322c4 100644
--- a/app/controllers/plugins_controller.php
+++ b/app/controllers/plugins_controller.php
@@ -139,7 +139,9 @@ class PluginsController extends AppController {
),
'contain' => false,
));
- unset($plugin['Plugin']['id']);
+ if(isset($plugin['Plugin']['id'])) {
+ unset($plugin['Plugin']['id']);
+ }
$this->set(compact('plugin'));
}
diff --git a/app/storage/9/c/497e1fb1-e910-42c2-8192-33464b77cd9c.package b/app/storage/9/c/497e1fb1-e910-42c2-8192-33464b77cd9c.package
new file mode 100644
index 0000000..d4a9186
--- /dev/null
+++ b/app/storage/9/c/497e1fb1-e910-42c2-8192-33464b77cd9c.package
@@ -0,0 +1,378 @@
+-=b4b18e13500e877f6b5c044adbb874dccdc8c0c46ea07e965e58b9de7e8e9d75cdc8c0c46ea07e96=-/manifest.xml-=952a19f4e2bb2d334653766bc78c6dc97127d9db31cdd5700dd83d7f13ce1847aa0c01a1922a0b36=-<?xml version="1.0" encoding="UTF-8" ?>
+<!-- Do not edit or delete this file. -->
+<plugin name="paypal" description="Generic PayPal component for doing immediate payments, mass payments, and profile creation and updates." major_version_number="0" minor_version_number="1" build_number="0" modified="2009-01-26 13:40:16" />-=b4b18e13500e877f6b5c044adbb874dccdc8c0c46ea07e965e58b9de7e8e9d75cdc8c0c46ea07e96=-/controllers/components/paypal.php-=952a19f4e2bb2d334653766bc78c6dc97127d9db31cdd5700dd83d7f13ce1847aa0c01a1922a0b36=-<?php
+
+App::import('HttpSocket');
+
+/**
+ * Component used for making profiles and getting data for those profiles.
+ *
+ * @package default
+ * @author John David Anderson
+ */
+class PaypalComponent extends Object
+{
+
+ /**
+ * API username.
+ *
+ * @var string
+ */
+ var $username = '';
+
+ /**
+ * API password
+ *
+ * @var string
+ */
+ var $password = '';
+
+ /**
+ * API signature.
+ *
+ * @var string
+ */
+ var $signature = '';
+
+ /**
+ * API URL
+ *
+ * @var string
+ */
+ var $apiURL = 'https://api-3t.sandbox.paypal.com/nvp';
+
+ /**
+ * API version.
+ *
+ * @var string
+ */
+ var $version = '50.0';
+
+ /**
+ * IPN secret used in notification verification.
+ *
+ * @var string
+ */
+ var $ipnSecret = 'longstringipnsecretgoeshere';
+
+ /**
+ * Reference to the calling controller.
+ *
+ * @var string
+ */
+ var $controller;
+
+ /**
+ * HttpSocket class instance used for making API calls.
+ *
+ * @var string
+ */
+ var $socket;
+
+ /**
+ * Called when controller is setup. Used for construction.
+ *
+ * @param string $controller
+ * @return void
+ * @author John David Anderson
+ */
+ function startup(&$controller)
+ {
+ $this->controller =& $controller;
+ $this->socket = new HttpSocket();
+ if(empty($this->username) || empty($this->password) || empty($this->signature))
+ {
+ trigger_error("Paypal Component not configured. Please specify username, password, and/or signature.");
+ }
+ }
+
+ /**
+ * Sends a payment amount to an email address.
+ *
+ * @param string $email
+ * @param string $amount
+ * @param string $uniqueId
+ * @return void
+ * @author John David Anderson
+ */
+ function doMassPay($email, $amount, $uniqueId)
+ {
+ $data['RECEIVERTYPE'] = 'EmailAddress';
+ $data['CURRENCYCODE'] = 'USD';
+ $data['L_EMAIL0'] = $email;
+ $data['L_AMT0'] = number_format($amount, 2);
+ $data['L_UNIQUEID0'] = $uniqueId;
+
+ return $this->__callAPI('MassPay', $data);
+ }
+
+ /**
+ * Creates a PayPal Recurring Payment profile based on CC and user information. Creates a monthly cycle until payment fails.
+ *
+ * @param string $profileReference Unique reference or invoice number
+ * @param string $amount Amount to be charged monthly.
+ * @param string $cardType Valid values: Visa, MasterCard, Discover, Amex
+ * @param string $cardNumber Credit card number.
+ * @param string $cardExpiration Expiration date. Takes array or strtotime() compatible value.
+ * @param string $cardVerification CVV number. 3 digits for most. 4 for Amex.
+ * @param string $email Email.
+ * @param string $firstName First name.
+ * @param string $lastName Last name.
+ * @return array
+ * @author John David Anderson
+ */
+ function doCreateProfile($profileReference, $amount, $cardType, $cardNumber, $cardExpiration, $cardVerification, $email, $firstName, $lastName)
+ {
+ //Massage incoming data
+ $cardNumber = preg_replace('/\D/', '', $cardNumber);
+
+ if(is_array($cardExpiration))
+ {
+ $cardExpiration = $cardExpiration['month'] . $cardExpiration['year'];
+ }
+
+ $startDate = gmdate('Y-m-d\TH:i:s\Z');
+ $amount = number_format($amount, 2);
+
+ //Create data array for API call
+ $data = array(
+ 'PROFILESTARTDATE' => $startDate,
+ 'PROFILEREFERENCE' => $profileReference,
+ 'DESC' => 'PianoMarvel Monthly Subscription',
+ 'BILLINGPERIOD' => 'Month',
+ 'BILLINGFREQUENCY' => '1',
+ 'AMT' => $amount,
+ 'CREDITCARDTYPE' => $cardType,
+ 'ACCT' => $cardNumber,
+ 'EXPDATE' => $cardExpiration,
+ 'CARDVERIFICATIONVALUE' => $cardVerification,
+ 'EMAIL' => $email,
+ 'FIRSTNAME' => substr($firstName, 0, 25),
+ 'LASTNAME' => substr($lastName, 0, 25)
+ );
+
+ return $this->__callAPI('CreateRecurringPaymentsProfile', $data);
+ }
+
+ /**
+ * Retrieves payment profile details given a specific profileID.
+ *
+ * @param string $profileId
+ * @return void
+ * @author John David Anderson
+ */
+ function doGetProfileDetails($profileId)
+ {
+ $data = array(
+ 'PROFILEID' => $profileId,
+ );
+
+ return $this->__callAPI('GetRecurringPaymentsProfileDetails', $data);
+ }
+
+ /**
+ * Manages a payment profile by cancelling, suspending, or reactivating.
+ *
+ * @param string $profileId
+ * @param string $action Valid values: Cancel, Suspend, Reactivate
+ * @param string $note
+ * @return void
+ * @author John David Anderson
+ */
+ function doManageProfile($profileId, $action, $note = '')
+ {
+ $data = array(
+ 'PROFILEID' => $profileId,
+ 'ACTION' => $action,
+ 'NOTE' => $note
+ );
+
+ return $this->__callAPI('ManageRecurringPaymentsProfileStatus', $data);
+ }
+
+ /**
+ * Updates a payment profile. Keys besides the profileID are optional and are not updated if not present.
+ *
+ * @param string $profileId
+ * @param string $note
+ * @param string $amount
+ * @param string $cardType
+ * @param string $cardNumber
+ * @param string $cardExpiration
+ * @param string $cardVerification
+ * @param string $email
+ * @param string $firstName
+ * @param string $lastName
+ * @return void
+ * @author John David Anderson
+ */
+ function doUpdateProfile($profileId, $note = '', $amount = '', $cardType = '', $cardNumber = '', $cardExpiration = '', $cardVerification = '', $email = '', $firstName = '', $lastName = '')
+ {
+ //Massage incoming data
+ $cardNumber = preg_replace('/\D/', '', $cardNumber);
+
+ if(is_array($cardExpiration))
+ {
+ $cardExpiration = $cardExpiration['month'] . $cardExpiration['year'];
+ }
+
+ if($amount != '')
+ {
+ $amount = number_format($amount, 2);
+ }
+
+ //Provent certain values from being overridden if not provided
+ $response = $this->doGetProfileDetails($profileId);
+ if($cardExpiration == '') {
+ $cardExpiration = $response['EXPDATE'];
+ }
+ if($email == '') {
+ $email = $response['EMAIL'];
+ }
+ if($firstName == '') {
+ $firstName = $response['FIRSTNAME'];
+ }
+ if($lastName == '') {
+ $lastName = $response['LASTNAME'];
+ }
+
+ //Create data array for API call
+ $data = array(
+ 'PROFILEID' => $profileId,
+ 'NOTE' => $note,
+ 'AMT' => $amount,
+ 'CREDITCARDTYPE' => $cardType,
+ 'ACCT' => $cardNumber,
+ 'EXPDATE' => $cardExpiration,
+ 'CARDVERIFICATIONVALUE' => $cardVerification,
+ 'EMAIL' => $email,
+ 'FIRSTNAME' => substr($firstName, 0, 25),
+ 'LASTNAME' => substr($lastName, 0, 25)
+ );
+
+ return $this->__callAPI('UpdateRecurringPaymentsProfile', $data);
+ }
+
+ /**
+ * Charges a credit card immediately.
+ *
+ * @param string $ccType
+ * @param string $ccNum
+ * @param string $expDateMonth
+ * @param string $expDateYear
+ * @param string $cvv
+ * @param string $amount
+ * @param string $firstName
+ * @param string $lastName
+ * @return void
+ * @author John David Anderson
+ */
+ function doDirectPayment($ccType, $ccNum, $expDateMonth, $expDateYear, $cvv, $amount, $firstName, $lastName)
+ {
+ $data = array(
+ 'CREDITCARDTYPE' => $ccType,
+ 'ACCT' => $ccNum,
+ 'EXPDATE' => str_pad($expDateMonth, 2, 0, STR_PAD_LEFT) . $expDateYear,
+ 'CVV2' => $cvv,
+ 'AMT' => $amount,
+ 'FIRSTNAME' => $firstName,
+ 'LASTNAME' => $lastName,
+ 'IPADDRESS' => getenv('REMOTE_ADDR'),
+ 'PAYMENTACTION' => 'Sale',
+ );
+
+ return $this->__callAPI('DoDirectPayment', $data);
+ }
+
+ /**
+ * Gets details about a transaction
+ *
+ * @param string $transactionId
+ * @author Heather Shelley
+ */
+ function getTransactionDetails($transactionId) {
+
+ $data = array(
+ 'TRANSACTIONID' => $transactionId
+ );
+
+ return $this->__callAPI('GetTransactionDetails', $data);
+ }
+
+ /**
+ * Bills the buyer for the outstanding balance
+ *
+ * @param string $amount
+ * @author Heather Shelley
+ */
+ function billOutstandingAmount($profileId) {
+ $data = array(
+ 'PROFILEID' => $profileId
+ );
+
+ return $this->__callAPI('BillOutstandingAmount', $data);
+ }
+
+ /**
+ * General purpose function used for tacking on required key/vals and building/parsing data.
+ *
+ * @param string $methodName
+ * @param string $data
+ * @return void
+ * @author John David Anderson
+ */
+ function __callAPI($methodName, $data)
+ {
+ $required = array(
+ 'USER' => $this->username,
+ 'PWD' => $this->password,
+ 'SIGNATURE' => $this->signature,
+ 'VERSION' => $this->version,
+ 'METHOD' => $methodName,
+ );
+
+ $nvp = $this->__buildNVP(am($required, $data));
+
+ return $this->__parseResponse($this->socket->post($this->apiURL, $nvp));
+ }
+
+ /**
+ * Turns associative arrays into a name-value string with URL encoded values.
+ *
+ * @param string $array
+ * @return void
+ * @author John David Anderson
+ */
+ function __buildNVP($array)
+ {
+ $out = '';
+ foreach($array as $key => $val)
+ {
+ if(!empty($val))
+ {
+ $out .= $key . '=' . urlencode($val) . '&';
+ }
+ }
+ return $out;
+ }
+
+ /**
+ * Explodes a name-value response into array format for easier access.
+ *
+ * @param string $socketResponse
+ * @return void
+ * @author John David Anderson
+ */
+ function __parseResponse($socketResponse)
+ {
+ $out = array();
+ $pairs = explode('&', $socketResponse);
+ foreach($pairs as $pair)
+ {
+ $parts = explode('=', $pair);
+ $out[$parts[0]] = urldecode($parts[1]);
+ }
+ return $out;
+ }
+}
+?>
\ No newline at end of file
diff --git a/app/views/pages/home.ctp b/app/views/pages/home.ctp
new file mode 100644
index 0000000..818ec4a
--- /dev/null
+++ b/app/views/pages/home.ctp
@@ -0,0 +1,9 @@
+<h1>Plugin Server (beta)</h1>
+
+<p>
+<ol>
+ <li>Download the <a href="/plugins.php.zip">plugins console application</a>.</li>
+ <li>Move the script to /app/vendors/shells/</li>
+ <li>Run <code>cake plugins</code> and follow the on-screen insructions.</li>
+</ol>
+</p>
\ No newline at end of file
diff --git a/app/webroot/plugins.php.zip b/app/webroot/plugins.php.zip
new file mode 100644
index 0000000..a602938
Binary files /dev/null and b/app/webroot/plugins.php.zip differ
