Platform documentation

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.

The whole thing is designed to work as a freestanding API or integrated with
publishing and CMS systems like Wordpress or Drupal. The standard repo contains the core
framework, installers, an admin webapp, APIs, demos, and a full suite of tests.

Setup and requirements

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

PHP 5.2.7+

PDO and MySQL OR SQLite

mod_rewrite (for admin)

fopen wrappers OR cURL

Installation: Just fork/clone this repo, cd into the new /DIY folder, and run:

make install

choosing SQLite will get you up and running fastest. Next just point Apache or MAMP
at the /DIY directory and view http://localhost/ in a browser.

There's a web installer for non-coders here.
The idea is that we make it easy to deploy on any shared server.

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.

Core framework PHP API

All functionality of the core platform is accessed through a single and consistent PHP-based API.
No direct function calls should be made — instead data should be accessed and set through a secure
and standard request / response model consistent with any HTTP GET/POST requests.

Request / response format

For developers looking to build custom functionality we've built a request/response
process as the primary interface to the PHP framework. It mimics a REST-style API
and standardizes calls and responses across the methods...so the PHP interaction
will be nearly identical to future REST or verbose interactions.

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.

system / gettemplatesforuser

system / migratedb

Wrapper for CASHData migrateDB call. Currently used for SQLite -> MySQL migrations but any
from/to should be possible. More tests need to be written for full support.

@return bool

Allowed methods: direct

Parameterstodriver (REQUIRED)tosettings (REQUIRED)

system / redeemlockcode

Attempts to redeem a given lock code, returning all details for the code on success or false
on failure. The code is tied to a scope_table_alias and scope_table_id pointing to a specific
asset, element, etc.

Pass a specific scope_table_alias, scope_table_id, or user_id to limit results to only matching
returns.

This will continue to return true for four hours after initial redemption — in the case of a
failed download this will give a user a second try without risking any long-term breach.

system / validatelogin

Logins are validated using the email address given with a salted sha256 hash of the given
password. Blowfish is unavailable to PHP 5.2 (reliably) so we're limited in hashing. The
system salt is stored in /framework/settings/cashmusic.ini.php outside the database for
additional security.

In addition to the standard email/pass we also validate against Mozilla's Browser ID standard
using the browserid_assetion which can be passed in. This works with the CASHSystem Browser ID
calls to determine a positive login status for the user, get the email address, and compare it
to the system to return the correct user and login status.

Pass require_admin to only return true for admin-level users. Pass an element_id if you want
the login analytics to be tied to a specific element.

asset / unlock

People requests

All actions defined for 'people' type requests:

people / addaddresstolist

Adds a user to a list. If no user exists for the email address passed, a
new user will be created then added to the list.

@param {string} $address - the email address in question@param {int} $list_id - the id of the list@param {bool} $verified - 0 for unverified, 1 to skip verification and mark ok@param {string} $initial_comment - a comment passed with the list signup@param {string} $additional_data - any extra data (JSON, etc) a dev might pass with signup for later use@param {string} $name - if the user doesn't exist in the system this will be used as their display name@return bool

people / addlist

Adds a new list to the system

@param {int} $list_id - the list@param {int} $name - a name given to the list for easy recognition@param {int} $description - a description, in case the name is terrible and offers no help@param {int} $connection_id - a third party connection with which the list should sync@return id|false

people / editlist

Edits the details of a given list

@param {int} $list_id - the list@param {int} $name - a name given to the list for easy recognition@param {int} $description - a description, in case the name is terrible and offers no help@param {int} $connection_id - a third party connection with which the list should sync@return id|false

element / setelementtemplate

Elements

Elements are like a plugin, or functional bundle, for the CASH platform. Each one is a standalone
package containing descriptive metadata, a controller class, view templates, and forms to plug into
the admin app. Specifically, each element consists of:

A main controller class file

A support directory containing:

templates directory for mustache template views for every state (plus admin)

Data for each instance of an element is stored as a JSON string in the database, so the data itself
can be pretty flexible for each element type.

The public-facing code in the element is designed to respond to targeted POST and/or GET requests —
so a CASH Request is made and the element responds to the CASH Response if the correct element_id
was set along with the request. So 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 API.

As a starting point, look at the StaticContent element.

Admin app

The admin app for the platform (/interfaces/php/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
API but building a much more complex app than a simple element.

Like the framework, the admin app is built with minimal requirements, not using any more robust PHP
app frameworks. The reason for this decision was the distributed version of the platform — what we
lose in functionality we gain in portability, which is a major concern.

In terms of structure, it's fairly simple:

At the root there's an .htaccess redirect pointing all incoming traffic at controller.php, which
pulls in settings from constants.php

A page is rendered based on pieces found in the /components directory

Each page/route has a controller in /components/pages/controllers and the controller calls a
mustache template from /components/pages/templates

We're in the process of moving localized text to the /components/text directory, and similarly
menus are pulled out by language in the /components/menu directory

Two simple helper classes are found in the /classes directory

The main page UI is a simple mustache-based template found in /ui/default — there's not currently
a setting in the admin to allow theming but it's essentially just a path change away

Currently the admin is more of a code-wrapper than an application with elegant UI/UX. Our prime
focus is improving that, making each section of the admin feel intuitive and easy as well as adding
more help infrastructure.

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