Developer Documentation

Introduction

The CASH Music platform gives all musicians access to tools that let them manage, promote, and sell their music online — all owned and controlled themselves.

Everything is modular. We built up around a PHP core. The admin app, API, and each element are separate applications that work together to form a full platform. We've built around the concept of cooperation, so we've abstracted all third party services so artists can easily change mailing providers, payment processors, etc. And we've kept dependencies as lightweight as possible so functionality can play well with other apps like WordPress, Drupal, etc.

We host a free (now and forever) version of the CASH Music platform at cashmusic.org or the whole thing can be downloaded and installed on your own server. A few simple changes to settings switch the platform from single-user mode to mutli-user (hosted) mode.

In short: the CASH Music platform was built to create possibilies for artists on the open web.

In these docs we'll cover:

  • Working directly with the PHP Core
  • Our APIs (verbose and RESTful)
  • Defining connections to third party services
  • Building elements (custom workflow for embeds)
  • Working with our admin app

Useful Links

Github / Twitter / Facebook / Development Group


Introduction: Setup

One of our goals is for this to run in as many places as possible, so we've worked hard to keep the requirements minimal:

  • PHP 5.4+
  • PDO (a default) and MySQL OR SQLite
  • mod_rewrite (for admin app)
  • fopen wrappers OR cURL

For local testing and development all you need to get started is VirtualBox, Vagrant 1.4+, and this repo. Just fork, install VirtualBox and Vagrant, then open a terminal window and in the repo directory type:

vagrant up

Vagrant will fire up a VM, set up Apache, install the platform, and start serving a special dev website with tools, docs, and a live instance of the platform — all mapped right to http://localhost:8888.

Dev site included in repo

If you want to go beyond the basic setup included wth our vagrant scripts, you'll nbeed to edit the /framework/settings/cashmusic.ini.php file. We include a template (cashmusic_template.ini.php) and the settings are pretty straightforward. You can change database settings, modify default system salt for password security, set timezone and email settings, and switch between single or multi-user mode.

Introduction: Code Standards

When in doubt, code for legibility and easy adoption. Capitalization and CamelCase should be used for class names, camelCase starting with lowercase for function names, and variable names in snake_case (lowercase and underscores.) Indentation has been kept simple — a single hard tab for each level, with curly brackets on the same line as the control statement.

So a simplified file will look something like:

Each class should have a file of it's own.

No class is final without formatted comments.

PHP Core

All functionality of the platform is accessed through a consistent request/response model at the heart of the PHP Core. No direct function calls should be made — instead data should be accessed and set through a secure and standard request/response model.

The request/response model lets us build consistency from PHP to API and into elements and connections. It mimics a REST-style API and standardizes calls and responses across the methods.

Every request is made with a specific type and action, plus any required or optional parameters. It's response will contain an http-esque status code, a uid containing type/action/code, a human-readable status message, a more detailed contextual message, an echo of the request type and action, a payload with the full response data or false if the request failed, the api version, and a timestamp.

Initiating a PHP Request looks like this:

An example of a failed response object:

Or on success:

The payload is returned as an associative array. Most basic data requests will include creation and modification dates which are standard and automated in the system. Requests to create new resources will return an id number on success.

All core files are located in the repo at /framework/classes/core with requests divided by type and organized into individual plant classes at /framework/classes/plants. Most new functionality is defined at the plant level, with the core classes used to route requests, to plants, abstract database connections, etc.

Each plant includes a routing table for requests that points to internal functions and defines the authentication context under which they're allowed. See below for a complete list of requests exposed by the core.

PHP Core: System requests

All actions defined for 'system' type requests:

system / addbulklockcodes

Allowed methods:
Parameters:
  • scope_table_alias (REQUIRED)
  • scope_table_id (REQUIRED)
  • user_id (REQUIRED)
  • count (REQUIRED)

system / addlogin

Allowed methods:
Parameters:
  • address (REQUIRED)
  • password (REQUIRED)
  • is_admin (default: 0)
  • username (default: '')
  • display_name (default: 'Anonymous')
  • first_name (default: '')
  • last_name (default: '')
  • organization (default: '')
  • address_country (default: '')
  • force52compatibility (default: false)
  • data (default: '')
  • address_postalcode (default: '')

system / addlockcode

Allowed methods:
Parameters:
  • scope_table_alias (REQUIRED)
  • scope_table_id (REQUIRED)
  • user_id (default: 0)

system / deletelogin

Allowed methods:
Parameters:
  • address (REQUIRED)

system / deletesettings

Allowed methods:
Parameters:
  • user_id (REQUIRED)
  • type (REQUIRED)

system / deletetemplate

Allowed methods:
Parameters:
  • template_id (REQUIRED)
  • user_id (default: false)

system / getapicredentials

Allowed methods:
Parameters:
  • user_id (REQUIRED)

system / getlockcodes

Allowed methods:
Parameters:
  • scope_table_alias (REQUIRED)
  • scope_table_id (REQUIRED)
  • user_id (default: false)

system / getnewesttemplate

Allowed methods:
Parameters:
  • user_id (REQUIRED)
  • type (default: 'page')
  • all_details (default: false)

system / getsettings

Allowed methods:
Parameters:
  • user_id (REQUIRED)
  • type (REQUIRED)
  • return_json (default: false)

system / gettemplate

Allowed methods:
Parameters:
  • template_id (REQUIRED)
  • user_id (default: false)
  • all_details (default: false)

system / gettemplatesforuser

Allowed methods:
Parameters:
  • user_id (REQUIRED)
  • type (default: false)

system / migratedb

Allowed methods:
Parameters:
  • todriver (REQUIRED)
  • tosettings (REQUIRED)

system / redeemlockcode

Allowed methods:
Parameters:
  • code (REQUIRED)
  • scope_table_alias (default: false)
  • scope_table_id (default: false)
  • user_id (default: false)

system / setapicredentials

Allowed methods:
Parameters:
  • user_id (REQUIRED)

system / setlogincredentials

Allowed methods:
Parameters:
  • user_id (REQUIRED)
  • address (default: false)
  • password (default: false)
  • username (default: false)
  • is_admin (default: false)
  • display_name (default: false)
  • url (default: false)

system / setresetflag

Allowed methods:
Parameters:
  • address (REQUIRED)

system / setsettings

Allowed methods:
Parameters:
  • user_id (REQUIRED)
  • type (REQUIRED)
  • value (REQUIRED)

system / settemplate

Allowed methods:
Parameters:
  • user_id (REQUIRED)
  • type (default: false)
  • name (default: false)
  • template (default: false)
  • template_id (default: false)

system / startjssession

Allowed methods:
Parameters:

    system / validateapicredentials

    Allowed methods:
    Parameters:
    • api_key (REQUIRED)
    • api_secret (default: false)

    system / validatelogin

    Allowed methods:
    Parameters:
    • address (REQUIRED)
    • password (REQUIRED)
    • require_admin (default: false)
    • verified_address (default: false)
    • browserid_assertion (default: false)
    • element_id (default: NULL)
    • keep_session (default: false)

    system / validateresetflag

    Allowed methods:
    Parameters:
    • address (REQUIRED)
    • key (REQUIRED)

    PHP Core: Asset requests

    All actions defined for 'asset' type requests:

    asset / addasset

    Allowed methods:
    Parameters:
    • title (REQUIRED)
    • description (REQUIRED)
    • user_id (REQUIRED)
    • location (default: '')
    • connection_id (default: 0)
    • hash (default: '')
    • size (default: 0)
    • public_url (default: '')
    • type (default: 'file')
    • tags (default: false)
    • metadata (default: false)
    • parent_id (default: 0)
    • public_status (default: 0)

    asset / addlockcode

    Allowed methods:
    Parameters:
    • asset_id (REQUIRED)

    asset / claim

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • element_id (default: 0)
    • session_id (default: false)

    asset / deleteasset

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)
    • connection_id (default: false)

    asset / editasset

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • hash (default: false)
    • size (default: false)
    • location (default: false)
    • title (default: false)
    • description (default: false)
    • public_url (default: false)
    • connection_id (default: false)
    • type (default: false)
    • parent_id (default: false)
    • public_status (default: false)
    • user_id (default: false)
    • tags (default: false)
    • metadata (default: false)

    asset / finalizeupload

    Allowed methods:
    Parameters:
    • connection_id (REQUIRED)
    • filename (REQUIRED)

    asset / findassets

    Allowed methods:
    Parameters:
    • query (REQUIRED)
    • user_id (REQUIRED)
    • page (default: 1)
    • max_returned (default: 10)

    asset / getanalytics

    Allowed methods:
    Parameters:
    • analtyics_type (REQUIRED)
    • user_id (REQUIRED)

    asset / getasset

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)

    asset / getassetsforconnection

    Allowed methods:
    Parameters:
    • connection_id (REQUIRED)

    asset / getassetsforparent

    Allowed methods:
    Parameters:
    • parent_id (REQUIRED)

    asset / getassetsforuser

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • type (default: false)
    • parent_id (default: false)

    asset / getassetfromunlockcode

    Allowed methods:
    Parameters:
    • scope_table_alias (REQUIRED)
    • scope_table_id (REQUIRED)

    asset / getasseturl

    Allowed methods:
    Parameters:
    • connection_id (REQUIRED)
    • user_id (REQUIRED)
    • asset_location (REQUIRED)
    • params (default: false)

    asset / getfulfillmentassets

    Allowed methods:
    Parameters:
    • asset_details (REQUIRED)
    • type (default: 'fulfillment')
    • session_id (default: false)

    asset / getuploadparameters

    Allowed methods:
    Parameters:
    • connection_id (REQUIRED)
    • user_id (REQUIRED)
    • acl (default: false)

    asset / getpublicurl

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)

    asset / makepublic

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)
    • commit (default: false)

    asset / redeemcode

    Allowed methods:
    Parameters:
    • code (REQUIRED)
    • user_id (default: false)
    • element_id (default: false)

    asset / unlock

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • session_id (default: false)

    PHP Core: People requests

    All actions defined for 'people' type requests:

    people / addaddresstolist

    Allowed methods:
    Parameters:
    • address (REQUIRED)
    • list_id (REQUIRED)
    • do_not_verify (default: false)
    • initial_comment (default: '')
    • additional_data (default: '')
    • name (default: 'Anonymous')
    • force_verification_url (default: false)
    • request_from_service (default: false)
    • service_opt_in (default: true)
    • extra_querystring (default: '')
    • element_id (default: false)
    • first_name (default: '')
    • last_name (default: '')
    • postal_code (default: '')

    people / addbulkaddresses

    Allowed methods:
    Parameters:
    • addresses (REQUIRED)

    people / addbulklistmembers

    Allowed methods:
    Parameters:
    • user_ids (REQUIRED)
    • list_id (REQUIRED)

    people / addcontact

    Allowed methods:
    Parameters:
    • email_address (REQUIRED)
    • user_id (REQUIRED)
    • first_name (default: '')
    • last_name (default: '')
    • organization (default: '')
    • address_line1 (default: '')
    • address_line2 (default: '')
    • address_city (default: '')
    • address_region (default: '')
    • address_postalcode (default: '')
    • address_country (default: '')
    • phone (default: '')
    • notes (default: '')
    • links (default: '')

    people / addmailing

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • list_id (REQUIRED)
    • connection_id (REQUIRED)
    • subject (REQUIRED)
    • template_id (default: 0)
    • html_content (default: '')
    • text_content (default: '')
    • from_name (default: '')
    • asset (default: false)

    people / addlist

    Allowed methods:
    Parameters:
    • name (REQUIRED)
    • user_id (REQUIRED)
    • description (default: '')
    • connection_id (default: 0)

    people / buildmailingcontent

    Allowed methods:
    Parameters:
    • template_id (REQUIRED)
    • html_content (REQUIRED)
    • title (REQUIRED)
    • subject (REQUIRED)
    • template (default: 'user_email')
    • asset (default: false)

    people / checkverification

    Allowed methods:
    Parameters:
    • address (REQUIRED)
    • list_id (REQUIRED)

    people / deletelist

    Allowed methods:
    Parameters:
    • list_id (REQUIRED)
    • user_id (default: false)

    people / editcontact

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • email_address (default: false)
    • first_name (default: false)
    • last_name (default: false)
    • organization (default: false)
    • address_line1 (default: false)
    • address_line2 (default: false)
    • address_city (default: false)
    • address_region (default: false)
    • address_postalcode (default: false)
    • address_country (default: false)
    • phone (default: false)
    • notes (default: false)
    • links (default: false)
    • user_id (default: false)

    people / editlist

    Allowed methods:
    Parameters:
    • list_id (REQUIRED)
    • name (default: false)
    • description (default: false)
    • connection_id (default: false)
    • user_id (default: false)

    people / editmailing

    Allowed methods:
    Parameters:
    • mailing_id (REQUIRED)
    • send_date (default: false)
    • subject (default: false)
    • html_content (default: false)
    • text_content (default: false)
    • user_id (default: false)
    • from_name (default: false)

    people / getaddresslistinfo

    Allowed methods:
    Parameters:
    • address (REQUIRED)
    • list_id (REQUIRED)

    people / getanalytics

    Allowed methods:
    Parameters:
    • analtyics_type (REQUIRED)
    • user_id (default: 0)
    • list_id (default: false)

    people / getcontact

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)

    people / getcontactsbyinitials

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • initial (REQUIRED)

    people / getcontactinitials

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)

    people / getlistsforuser

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)

    people / getlist

    Allowed methods:
    Parameters:
    • list_id (REQUIRED)
    • user_id (default: false)

    people / getmailing

    Allowed methods:
    Parameters:
    • mailing_id (REQUIRED)
    • user_id (default: false)

    people / getmailingmetadata

    Allowed methods:
    Parameters:
    • mailing_id (REQUIRED)
    • user_id (default: false)

    people / getmailinganalytics

    Allowed methods:
    Parameters:
    • mailing_id (REQUIRED)
    • user_id (default: false)

    people / getrecentactivity

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • since_date (default: 0)

    people / getuser

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)

    people / getuseridforaddress

    Allowed methods:
    Parameters:
    • address (REQUIRED)
    • with_security_credentials (default: false)

    people / getuseridforusername

    Allowed methods:
    Parameters:
    • username (REQUIRED)

    people / processwebhook

    Allowed methods:
    Parameters:
    • origin (REQUIRED)
    • user_id (REQUIRED)
    • list_id (default: 0)
    • type (default: false)
    • data (default: false)
    • mandrill_events (default: false)

    people / recordmailinganalytics

    Allowed methods:
    Parameters:
    • mailing_id (REQUIRED)
    • sends (default: 0)
    • opens_total (default: 0)
    • opens_mobile (default: 0)
    • opens_country (default: false)
    • opens_id (default: false)
    • click_url (default: false)
    • failures (default: 0)
    • user_id (default: false)

    people / removeaddress

    Allowed methods:
    Parameters:
    • address (REQUIRED)
    • list_id (REQUIRED)

    people / sendmailing

    Allowed methods:
    Parameters:
    • mailing_id (REQUIRED)
    • user_id (default: false)
    • asset (default: false)

    people / signintolist

    Allowed methods:
    Parameters:
    • address (REQUIRED)
    • password (REQUIRED)
    • list_id (REQUIRED)
    • browserid_assertion (default: false)
    • element_id (default: NULL)

    people / signup

    Allowed methods:
    Parameters:
    • list_id (REQUIRED)
    • address (REQUIRED)
    • user_id (default: false)
    • comment (default: '')
    • name (default: 'Anonymous')
    • element_id (default: false)
    • first_name (default: '')
    • last_name (default: '')
    • additional_data (default: '')
    • postal_code (default: '')

    people / storeuserdata

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • key (REQUIRED)
    • value (REQUIRED)

    people / verifyaddress

    Allowed methods:
    Parameters:
    • address (REQUIRED)
    • list_id (REQUIRED)
    • verification_code (REQUIRED)

    people / viewlist

    Allowed methods:
    Parameters:
    • list_id (REQUIRED)
    • unlimited (default: false)
    • user_id (default: false)

    PHP Core: Commerce requests

    All actions defined for 'commerce' type requests:

    commerce / additem

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • name (REQUIRED)
    • description (default: '')
    • sku (default: '')
    • price (default: 0)
    • flexible_price (default: 0)
    • available_units (default: -1)
    • digital_fulfillment (default: 0)
    • physical_fulfillment (default: 0)
    • physical_weight (default: 0)
    • physical_width (default: 0)
    • physical_height (default: 0)
    • physical_depth (default: 0)
    • variable_pricing (default: 0)
    • fulfillment_asset (default: 0)
    • descriptive_asset (default: 0)
    • shipping (default: '')

    commerce / additemvariants

    Allowed methods:
    Parameters:
    • item_id (REQUIRED)
    • variants (REQUIRED)

    commerce / addorder

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • order_contents (REQUIRED)
    • transaction_id (default: -1)
    • physical (default: 0)
    • digital (default: 0)
    • cash_session_id (default: '')
    • element_id (default: 0)
    • customer_user_id (default: 0)
    • fulfilled (default: 0)
    • canceled (default: 0)
    • notes (default: '')
    • country_code (default: '')
    • currency (default: 'USD')
    • data (default: '')

    commerce / addtocart

    Allowed methods:
    Parameters:
    • item_id (REQUIRED)
    • element_id (REQUIRED)
    • item_variant (default: false)
    • price (default: false)
    • session_id (default: false)

    commerce / addtransaction

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • connection_id (REQUIRED)
    • connection_type (REQUIRED)
    • service_timestamp (default: '')
    • service_transaction_id (default: '')
    • data_sent (default: '')
    • data_returned (default: '')
    • successful (default: -1)
    • gross_price (default: 0)
    • service_fee (default: 0)
    • status (default: 'abandoned')
    • currency (default: 'USD')
    • parent (default: 'order')
    • parent_id (default: '0')

    commerce / cancelorder

    Allowed methods:
    Parameters:
    • order_id (REQUIRED)
    • user_id (default: false)

    commerce / cancelsubscription

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • connection_id (REQUIRED)
    • id (REQUIRED)

    commerce / createsubscriptionplan

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • connection_id (REQUIRED)
    • plan_name (REQUIRED)
    • description (REQUIRED)
    • sku (REQUIRED)
    • amount (default: 0)
    • flexible_price (default: false)
    • recurring (default: true)
    • suggested_price (default: false)
    • physical (default: false)
    • interval (default: 'month')
    • interval_count (default: 12)
    • currency (default: 'usd')

    commerce / createcompedsubscription

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • plan_id (REQUIRED)
    • first_name (REQUIRED)
    • last_name (REQUIRED)
    • email_address (REQUIRED)

    commerce / deleteitem

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)

    commerce / deleteitemvariant

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)

    commerce / deleteitemvariants

    Allowed methods:
    Parameters:
    • item_id (REQUIRED)
    • user_id (default: false)

    commerce / deletesubscription

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • subscription_id (REQUIRED)

    commerce / deletesubscriptionplan

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • id (REQUIRED)

    commerce / editcartquantity

    Allowed methods:
    Parameters:
    • item_id (REQUIRED)
    • element_id (REQUIRED)
    • qty (REQUIRED)
    • item_variant (default: '')
    • session_id (default: false)

    commerce / editcartshipping

    Allowed methods:
    Parameters:
    • element_id (REQUIRED)
    • region (default: 'r1')
    • session_id (default: false)

    commerce / editfulfillmentorder

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • name (default: false)
    • email (default: false)
    • shipping_address_1 (default: false)
    • shipping_address_2 (default: false)
    • shipping_city (default: false)
    • shipping_province (default: false)
    • shipping_postal (default: false)
    • shipping_country (default: false)
    • complete (default: false)
    • fulfilled (default: false)
    • price (default: false)
    • tier_id (default: false)
    • order_data (default: false)
    • notes (default: false)
    • data_sent (default: false)

    commerce / edititem

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • name (default: false)
    • description (default: false)
    • sku (default: false)
    • price (default: false)
    • flexible_price (default: false)
    • available_units (default: false)
    • digital_fulfillment (default: false)
    • physical_fulfillment (default: false)
    • physical_weight (default: false)
    • physical_width (default: false)
    • physical_height (default: false)
    • physical_depth (default: false)
    • variable_pricing (default: false)
    • fulfillment_asset (default: false)
    • descriptive_asset (default: false)
    • user_id (default: false)
    • shipping (default: false)

    commerce / edititemvariant

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • quantity (REQUIRED)
    • item_id (REQUIRED)
    • user_id (default: false)

    commerce / editorder

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • fulfilled (default: false)
    • canceled (default: false)
    • notes (default: false)
    • country_code (default: false)
    • customer_user_id (default: false)
    • order_contents (default: false)
    • transaction_id (default: false)
    • physical (default: false)
    • digital (default: false)
    • user_id (default: false)
    • data (default: '')

    commerce / edittransaction

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • service_timestamp (default: false)
    • service_transaction_id (default: false)
    • data_sent (default: false)
    • data_returned (default: false)
    • successful (default: false)
    • gross_price (default: false)
    • service_fee (default: false)
    • status (default: false)

    commerce / emailbuyersbyitem

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • connection_id (REQUIRED)
    • item_id (REQUIRED)
    • subject (REQUIRED)
    • message (REQUIRED)
    • include_download (default: false)

    commerce / emptycart

    Allowed methods:
    Parameters:
    • element_id (REQUIRED)
    • session_id (default: false)

    commerce / formatvariantname

    Allowed methods:
    Parameters:
    • name (REQUIRED)

    commerce / getanalytics

    Allowed methods:
    Parameters:
    • analtyics_type (REQUIRED)
    • user_id (REQUIRED)
    • date_low (default: false)
    • date_high (default: false)

    commerce / getcart

    Allowed methods:
    Parameters:
    • element_id (REQUIRED)
    • session_id (default: false)

    commerce / getfulfillmentjobbytier

    Allowed methods:
    Parameters:
    • tier_id (REQUIRED)

    commerce / getfulfillmentorder

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)

    commerce / getitem

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)
    • with_variants (default: true)

    commerce / getitemvariants

    Allowed methods:
    Parameters:
    • item_id (REQUIRED)
    • exclude_empties (default: false)
    • user_id (default: false)

    commerce / getitemsforuser

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • with_variants (default: true)

    commerce / getorder

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • deep (default: false)
    • user_id (default: false)

    commerce / getordersforuser

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • include_abandoned (default: false)
    • max_returned (default: false)
    • since_date (default: 0)
    • unfulfilled_only (default: 0)
    • deep (default: false)
    • skip (default: 0)

    commerce / getordersbycustomer

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • customer_email (REQUIRED)

    commerce / getordersbyitem

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • item_id (REQUIRED)
    • max_returned (default: false)
    • skip (default: 0)

    commerce / getordertotals

    Allowed methods:
    Parameters:
    • order_contents (REQUIRED)

    commerce / getsubscriptiondetails

    Allowed methods:
    Parameters:
    • id (REQUIRED)

    commerce / getsubscriptionplan

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)

    commerce / getsubscriptionplanbysku

    Allowed methods:
    Parameters:
    • sku (REQUIRED)

    commerce / getallsubscriptionsbyplan

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • limit (default: false)

    commerce / getsubscriptionplans

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • limit (default: false)

    commerce / getsubscriptionstats

    Allowed methods:
    Parameters:
    • plan_id (REQUIRED)

    commerce / getsubscribercount

    Allowed methods:
    Parameters:
    • plan_id (REQUIRED)

    commerce / getsubscriptiontransactions

    Allowed methods:
    Parameters:
    • id (REQUIRED)

    commerce / gettransaction

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)

    commerce / finalizepayment

    Allowed methods:
    Parameters:
    • order_id (REQUIRED)
    • token (REQUIRED)
    • email_address (default: false)
    • customer_name (default: false)
    • shipping_info (default: false)
    • session_id (default: false)
    • total_price (default: false)
    • description (default: false)
    • finalize_url (default: false)

    commerce / initiatecheckout

    Allowed methods:
    Parameters:
    • element_id (default: false)
    • shipping_info (default: false)
    • paypal (default: false)
    • stripe (default: false)
    • origin (default: false)
    • email_address (default: false)
    • customer_name (default: false)
    • session_id (default: false)
    • geo (default: false)
    • finalize_url (default: false)

    commerce / initiatesubscription

    Allowed methods:
    Parameters:
    • element_id (default: false)
    • price (default: false)
    • stripe (default: false)
    • origin (default: false)
    • email_address (default: false)
    • subscription_plan (default: false)
    • customer_name (default: false)
    • session_id (default: false)
    • geo (default: false)
    • shipping_info (default: false)
    • finalize_url (default: false)

    commerce / loginsubscriber

    Allowed methods:
    Parameters:
    • email (default: false)
    • password (default: false)
    • plans (default: false)

    commerce / processwebhook

    Allowed methods:
    Parameters:
    • origin (REQUIRED)
    • type (default: false)
    • data (default: false)

    commerce / sendorderreceipt

    Allowed methods:
    Parameters:
    • id (default: false)
    • order_details (default: false)
    • finalize_url (default: false)

    commerce / updatesubscriptionplan

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • connection_id (REQUIRED)
    • id (REQUIRED)
    • sku (REQUIRED)
    • name (REQUIRED)
    • description (REQUIRED)
    • flexible_price (default: false)
    • suggested_price (default: false)
    • physical (default: false)

    commerce / updatesubscription

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • status (default: false)
    • total (default: false)
    • start_date (default: false)
    • update_plan_id (default: false)

    commerce / validatesubscription

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • plans (REQUIRED)

    PHP Core: Calendar requests

    All actions defined for 'calendar' type requests:

    calendar / addevent

    Allowed methods:
    Parameters:
    • date (REQUIRED)
    • user_id (REQUIRED)
    • venue_id (REQUIRED)
    • purchase_url (default: '')
    • comment (default: '')
    • published (default: 0)
    • cancelled (default: 0)

    calendar / addvenue

    Allowed methods:
    Parameters:
    • name (REQUIRED)
    • city (REQUIRED)
    • address1 (REQUIRED)
    • address2 (REQUIRED)
    • region (REQUIRED)
    • country (REQUIRED)
    • postalcode (REQUIRED)
    • url (REQUIRED)
    • phone (REQUIRED)
    • user_id (REQUIRED)

    calendar / deleteevent

    Allowed methods:
    Parameters:
    • event_id (REQUIRED)

    calendar / deletevenue

    Allowed methods:
    Parameters:
    • venue_id (REQUIRED)

    calendar / editevent

    Allowed methods:
    Parameters:
    • event_id (REQUIRED)
    • date (default: false)
    • venue_id (default: false)
    • purchase_url (default: false)
    • comment (default: false)
    • published (default: false)
    • cancelled (default: false)
    • user_id (default: false)

    calendar / editvenue

    Allowed methods:
    Parameters:
    • venue_id (REQUIRED)
    • name (default: false)
    • address1 (default: false)
    • address2 (default: false)
    • city (default: false)
    • region (default: false)
    • country (default: false)
    • postalcode (default: false)
    • url (default: false)
    • phone (default: false)

    calendar / findvenues

    Allowed methods:
    Parameters:
    • query (REQUIRED)
    • user_id (REQUIRED)
    • page (default: 1)
    • max_returned (default: 12)

    calendar / getallvenues

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • visible_event_types (REQUIRED)

    calendar / getevent

    Allowed methods:
    Parameters:
    • event_id (REQUIRED)

    calendar / getevents

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • offset (default: 0)
    • published_status (default: 1)
    • cancelled_status (default: 0)
    • cutoff_date_low (default: false)
    • cutoff_date_high (default: false)
    • visible_event_types (default: 'upcoming')

    calendar / geteventsnostatus

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • visible_event_types (default: 'upcoming')
    • cutoff_date_low (default: false)
    • cutoff_date_high (default: false)

    calendar / getvenue

    Allowed methods:
    Parameters:
    • venue_id (REQUIRED)

    PHP Core: Element requests

    All actions defined for 'element' type requests:

    element / addelementtocampaign

    Allowed methods:
    Parameters:
    • element_id (REQUIRED)
    • campaign_id (REQUIRED)

    element / addcampaign

    Allowed methods:
    Parameters:
    • title (REQUIRED)
    • description (REQUIRED)
    • user_id (REQUIRED)
    • elements (default: '[]')
    • metadata (default: '{}')

    element / addelement

    Allowed methods:
    Parameters:
    • name (REQUIRED)
    • type (REQUIRED)
    • options_data (REQUIRED)
    • user_id (REQUIRED)

    element / addlockcode

    Allowed methods:
    Parameters:
    • element_id (REQUIRED)

    element / checkuserrequirements

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)
    • element_type (REQUIRED)

    element / deletecampaign

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)

    element / deleteelement

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)

    element / editelement

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • name (REQUIRED)
    • options_data (REQUIRED)
    • user_id (default: false)

    element / editcampaign

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)
    • title (default: false)
    • description (default: false)
    • elements (default: false)
    • metadata (default: false)
    • template_id (default: false)

    element / getanalytics

    Allowed methods:
    Parameters:
    • analtyics_type (REQUIRED)
    • user_id (REQUIRED)
    • element_id (default: 0)

    element / getanalyticsforcampaign

    Allowed methods:
    Parameters:
    • id (REQUIRED)

    element / getcampaign

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)

    element / getelement

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • user_id (default: false)

    element / getcampaignsforuser

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)

    element / getcampaignforelement

    Allowed methods:
    Parameters:
    • id (REQUIRED)

    element / getelementsforcampaign

    Allowed methods:
    Parameters:
    • id (REQUIRED)

    element / getelementsforuser

    Allowed methods:
    Parameters:
    • user_id (REQUIRED)

    element / getelementtemplate

    Allowed methods:
    Parameters:
    • element_id (REQUIRED)
    • return_template (default: false)

    element / getmarkup

    Allowed methods:
    Parameters:
    • id (REQUIRED)
    • status_uid (REQUIRED)
    • original_request (default: false)
    • original_response (default: false)
    • access_method (default: 'direct')
    • location (default: false)
    • geo (default: false)
    • donottrack (default: false)

    element / getsupportedtypes

    Allowed methods:
    Parameters:
    • force_all (default: false)

    element / redeemcode

    Allowed methods:
    Parameters:
    • code (REQUIRED)
    • element_id (REQUIRED)

    element / removeelementfromcampaign

    Allowed methods:
    Parameters:
    • element_id (REQUIRED)
    • campaign_id (REQUIRED)

    element / setelementtemplate

    Allowed methods:
    Parameters:
    • element_id (REQUIRED)
    • template_id (REQUIRED)
    • user_id (default: false)

    API

    Our API is a standalone app located in the repo at /interfaces/api/ and available at the /api/ URL at cashmusic.org and locally for testing. Like the admin app, all configuration is handled by the constants.php file located in the app root, and all requests are routed through the controller.php script via mod_rewrite.

    The main API functionality is handled by the APICore class, located at /interfaces/api/classes/APICore.php.

    The API returns JSON objects for any request. Simply requesting / at the /api gives a basic hello with version number:

    A bad request returns a more standard format with status code and messages:

    We'll detail succesful requests in the verbose and RESTful docs below.

    API: Verbose API

    The verbose API is a direct wrapper for all requests that allow the apipublic or apikey access methods. At the moment those are mostly limited to list signups and initiating new transactions, but we're working on a full authorization scheme to expand scope.

    The response object and payload are nearly identical to the return from the PHP core, except returned as JSON. Making a request that doesn't allow API access will give you a forbidden status, but here's an example endpoint:

    /api/verbose/asset/getasset/id/2
    

    The format is simple: /verbose/plant/request/{parameter name}/{parameter value} — it'll parse as many parameters as you throw at it and respond:

    More about authorization methods coming soon.

    API: RESTful API

    The RESTful version of the API is still a work in progress.

    Connections

    Connections are basically API wrappers — an abstracted way for us to connect to third party services, categorize their offering, and define the data we need to store to make each one work. (Tokens, settings, etc.)

    Defining a connection happens in two different files:

    1. A definition JSON in /framework/settings/connections
    2. A Seed Class in /framework/classes/seeds

    The connection is defined in JSON and should look something like this:

    It needs a name, description, unique type, and you must define the classname of the seed used with the connection. There's an option for scope. This lets us narrow the connection type so we can show connections contextually in the admin app and beyond. (Currently, the scope types have been chosen fairly arbitrarily, though we need to define them better going forward.) Lastly, there's an array listing compatibility — does the connection work in single-user mode, multi-user mode, or both?

    Note that you can define different data needed for single-user and multi-user versions of the connection. (We frown on storing keys/secrets in multi-user mode.)

    The Seed class

    In the larger scheme of the platform, Plants handle requests while Seeds handle specific functionality — mostly in the form of connecting to third party APIs. Because seeds are supposed to be flexible, they're pretty arbitrary in structure, but you'll notice a bunch of common functions between similar seeds — check seeds for S3 and Google Drive.

    We'll be defining this more concretely on a scope-by-scope basis soon, but for now please look for similar services and pattern after them. We want as much uniformity as we can get at the seed level so we can abstract as much as possible at the plant level.

    Any connection supporting an OAuth style redirect (generally in multi-user mode) will need to have these two functions defined:

    • getRedirectMarkup($data=false)
    • handleRedirectReturn($data=false)

    The getRedirectMarkup will handle any logic needed to present the user with a redirect link, and the handleRedirectReturn will deal with the returned token and complete the connection process.

    Any data like application-level keys that need to be stored to initiate OAuth requests can be stored in /framework/settings/connections.json. See template at /framework/settings/_connections.json for a quick example.

    Elements

    Elements bundle unique workflows in the CASH Music platform. Think of them as apps accessing the core the same way apps access APIs on a phone. We took inspiration from app stores in the idea of creating a simple bundle that's easy to use and configure.

    Each element has a PHP class that follows a set pattern, mustache templates for markup, an image for thumbs, a LICENSE, and an accompanying JSON definition file. The rest is handled automatically. All settings forms are generated by the admin app itself (and could even be set manually from PHP if you feel like going gusto.)

    The main element class defines and responds to various states — usually triggered by GET or POST request via embed. The element listens for its own id and reacts to all matching CASH Responses.

    An element is embedded with a single function call, and will respond automatically when interacted with. The whole idea being that it's a simple to use structure that can be powerful and flexible enough to innovate on top of the PHP core.

    Elements: Structure

    Each element is essentially a bundle all to itself, with three main parts:

    1. An app.json definition file that defines element messages and data to be stored
    2. A Class file with logic and states for the element
    3. A folder of mustache templates (markup views for every state)

    Data and settings for each instance of an element are stored as encrypted JSON in the database, and defined in an element's app.json file. The app.json file defines all details like title and description of the element, instructions, and the data structure along with labels, messages, etc. A detailed sample file is better than a description here:

    The options define what can be set in the element admin, what options will be present and expected, and provide default values, etc.

    The allowed types for options are:

    • select
      • values (required)
    • boolean
    • number
    • text
    • markup

    And every option can also contain:

    • required
    • default
    • displaysize
    • helptext
    • placeholder

    The main element class

    The main element class file extends the ElementBase class, automating most of the state management and template selection you'll need. The logic can be as complex as necessary,
    but in the end the goal is to define some data into $this->element_data and return it as the output of the getData() function. Whatever you define will be added to the stored data and accessible in your mustache templates.

    In the example below, note that we use the $this->setTemplate() function to choose a template other than the (required) default.mustache file. This is based on filenames in the template folder, and controlled by state — the CASH Response UID returned the the last request. So if the element contains a form that triggers a CASH Request via GET or POST the element responds, sets its internal state, and your getData() function does some magic based on state before returning the data needed to render your embed.

    By separating the getData from rendering output we allow elements to work at all states on a purely data level — leaving room in the future for mobile app support, etc. But for now the data is combined with the mustache template you choose to render HTML in the browser.

    This is just a starting point. For more examples see the /framework/classes/elements directory in the main platform repo.

    Elements: Embedding

    We use our (tiny) custom javascript library, cashmusic.js, to create iframe embeds for elements. They can be styled to match any site with full user control over CSS and markup. Embedding is pretty straightforward and happens with a single copy and paste code.

    In a basic example, an element is embedded in place by id only:

    Endpoint and id are always required, but you can also choose to have the element appear in an overlay (lightboxed.) A lightboxed element will create a link inline with the caption passed in to the window.cashmusic.embed function. You can also pass in an object specifying size and position of the element inside the overlay.

    For embed calls after page load, provide a target element as the final argument to window.cashmusic.embed. This will place the embed, iframe or lightbox link, inside the first matching element. The target should be a string that will work with document.querySelector, like "#id", "#id .class", or similar.

    For styling, all iframe embeds are placed in a <div> classed with "cashmusic embed" and lightboxed embed links are placed in a <span> classed "cashmusic embed".

    An example with all options:

    We're also working on a new JSON object based embed call. It's mostly for clear formatting, but you'll notice a new CSS override option not available by the standard method. More on that soon...

    Admin app

    The admin app for the platform (/interfaces/admin) is a fairly straight-forward MVC-style webapp built with a front controller, individual controllers for each route, mustache views, and using the framework for the model instead of a traditional database layer. Basically it's dog-fooding the PHP core but building a much more complex app than a simple element.

    In terms of structure, it's fairly simple:

    • Settings are stored in the constants.php file
    • The .htaccess pushes all traffic through the controller.php file
    • Each route has a controller in /components/pages/controllers and after doing any logic the controller calls a mustache template view from /components/pages/views
    • The main page UI is stored in mustache templates in /ui/default

    It shouldn't be lost that the admin app is structured to mirror the CASH Request/Response types — this is very much on purpose with the goal of getting musicians and developers speaking the same language.