Skip to content
Snippets Groups Projects
Tony Freixas's avatar
Bug #56839 by Daniel Glucksman: Fixed a problem with product key access for some users.
freixas authored
80378360
History
			UBERCART PRODUCT KEYS

This is a quick intro to the uc_product_keys module.

TERMINOLOGY
-----------

  Product key		- A string of text used to unlock or activate a
			  software product.

  Product key sequence	- A collection of product keys, any of which
			  can be used to unlock or activate a specific
			  software product.

  Dynamic sequences	- A product key sequence where all keys are
			  generated dynamically by some external code.

  Activation		- The process by which the sofware becomes
			  operational. It usually involves having the
			  software communicate with an activation
			  server.

  Revokation		- If a license is revoked, any attempt to
			  activate it the software will be denied.
			  This may not shut down any activated
			  programs, but will prevent the product key
			  from being used to activate any more
			  products.

CONCEPTUAL MODEL
----------------

  1. Create a software product.
  2. Create a mechanism for generating product keys.
  3. Place code in the software which prevents the software from
     working without a valid product key.
  4. Create a product sequence for the product.
  5. Create the Ubercart product that sells the product key.
  6. Tell the product to use the sequence you created.
  7. If product keys are generated off-line, generate a batch of keys,
     encrypt them if necessary and import them into the database.
  8. User downloads software.
  9. User purchases product key. If product keys are dynamically
     generated, uc_product_keys will ask your code to generate the
     keys and will send them to the customer. A non-dynamic key is
     taken from the database. If uc_stock is used, the stock count
     will be decremented.
 10. User enters product key into the software and software becomes
     operational.

Alternatively,

  10. User enters product key and software communicates with the Web
      site (using code you create). The software sends an installation
      ID and the server returns an activation ID. This makes the
      program operational.
  11. The code can increment the activation count in the database. It
      can also check for the revokation flag and avoid sending the
      activatioon code.

			     PLEASE NOTE!
			     ------------

If an administrator creates an order and the product is associated
with a product key sequence, a product key is not generated unless
the order is enters the 'payment_received' or 'completed' states.

Once an order is completed, you should not add or remove products
associated with product keys to the order. Create a new order if you
want to issue a new product key to a customer. If you add products to
a completed order, no product keys will be generated. If you remove
products from an order, the product keys are not deleted.

			     ------------


USER INTERFACE
--------------

Permissions:
  administer product keys
  view everyone's product keys

  Everyone can always view the product keys they have purchased.

Where to find things:

  Home » Administer » Store administration » Products » Product keys
	  Administer product keys

  Home » <Product> » Edit (fieldset "Product key")
	  Associate a product with a product key sequence

  Home » <Product> » Edit » Product keys
	  Lists all product keys associated with this product

  Home » My account » Product keys
	  Lets users view their product keys

Product key sequence features:

  You can create, rename, edit and delete product sequences. If you
  delete a sequence, any assigned product keys stay in the database.
  Unassigned keys are deleted.

Product key features:

  You can import product keys using one of two formats:

	1. sequence name<tab>key<eol>
	2. sequence name<eol>
	   key<eol>
	   more of same key<eol>
	   .<eol>

  The first format has one key per line. You create this in a
  spreadsheet and output it as a tab-separated-values file.

  The second format allows for multi-line keys. The key ends when the
  software finds a line containing only a specific string ("." by
  default).

  Once imported, you can view all keys, delete unassigned keys and
  revoke (or unrevoke) assigned keys.

Table variations

  Tables are used to display sequences and keys. If you have admin
  access, the tables will display all fields and some fields may be
  editable.

  If you have "view everyone's keys" access, you can view all fields,
  but none will be editable.

  If you have neither, you can obly view keys you have purchased and
  you get to see only a few fields.

  To view all product keys, go to
	Home » Administer » Store administration » Products » Product keys
  To view all product keys associated with one product, go to
	Home » <Product> » Edit » Product keys
  To view all product keys associated with one customer, go to
	<User's account page> » Product keys

EXTENDING THE MODULE
--------------------

Sample module

  There is a sample extension module in the uc_product_keys_sample
  sub-directory that demonstrates how to extend uc_product_keys. You
  can also use this module as a starting point for your own
  extensions.

  If you don't plan to use uc_product_keys_sample, delete it, zip it
  or move it out of the Drupal tree. Unfortunately, Drupal.org does
  not allow me to check in the file in ZIP or GZ format.

  To view the module in action, enable it on the Module page.

Extending the database

  You will often want to add your own data fields to the product keys
  and product key sequences. To do so, create your own module. In the
  module.install file, in hook_install(), use db_add_field() to add
  your own fields to uc_product_keys and uc_product_key_sequences (you
  may want to namespace the field names to avoid collisions with
  future enhancements I make to the tables). Your fields will be
  automatically loaded and saved along with the standard fields. You
  will also benefit from the cache.

Hooks

  hook_uc_product_keys_sequence_api()

  This hook allows you to extend product key sequences.

  $arg1		- If $op is 'load_multiple', then $arg1 is an array of
		  product key sequence objects. Otherwise, it is a
		  single product key sequence object.
  $op		- The operation being performed. Possible values:

    load		- A product key sequence has been loaded. You
			  may add extra data to the sequence.

    load_all		- All product key sequences have been loaded.
			  You may add extra data to the sequences.

    insert		- A product key sequence has been inserted
			  into the database.

    update		- An existing product key sequence has been
		          updated.

   delete		- An existing product key sequence has been
			  deleted.
  </ul>

  Returns true if the operation succeeded; false otherwise.

  **********

  hook_uc_product_keys_api()

  This hook allows you to extend product keys.

  $arg1		- If $op is 'create_multiple' or 'load_multiple', then $arg1
		  is an array of product key objects. Otherwise, it is a
		  single product key object.
  $op		- The operation being performed. Possible values:

    create_multiple	- For dynamically created keys, you will need
			  to at least fill in the product_key field.
			  You may also add extra data to the keys. The
			  $other parameter is an associative array
			  containing references to:

			product		- The product node associated with this key.
			user		- The user who is purchasing the key.
		 	order		- The order associated with this key.
			order_product	- The specific line item on
					  the order associated with
					  this key.
    load		- A product key has been loaded. You may add
			  extra data to the key.

    load_multiple	- A set of product keys have been loaded. You
			  may add extra data to the keys. The
			  $sequence parameter will be null and the
			  keys may belong to different sequences.

    insert		- A product key has been inserted into the
			  database.

    update		- An existing product key has been updated.

    delete		- An existing product key has been deleted.

  $sequence	- The sequence object associated with the key. In some
		  cases, this may be null.

  $other	- An array containing additional information. See $op.

  Returns true if the operation succeeded; false otherwise.

  **********

  hook_uc_product_keys_theme_list_api()

  This hook makes it easier to theme new values added to the sequence or
  product key list displays.

  $op		- The operation being performed. Possible values are:

    sequence_header	- Supply a array of header names for any new
			  items added to the sequence listing.

    sequence_row	- Supply the matching row values for the new
			  items added to the sequence listing.

    key_header		- Supply a array of header names for any new
			  items added to the key listing.

    key_row		- Supply the matching row values for the new
			  items added to the key listing.

    key_long_header	- Supply a array of header names for any new
			  items added to the key listing whose values
			  may be very long.

    key_long_row	- Supply the matching row values for the new
			  long items added to the key listing.

  $a1		- The header or row array in which to place names or
		  values.

  $form		- The form (only present for rows; otherwise, an empty
		  array is passed).

  $obj		- The sequence or key associated with a particular row
		  (only present for rows; otherwise, null is passed).

  **********

  hook_uc_product_keys_decrypt($product_key)

  If you want to encrypt the product keys in the database, you will
  need to implement this hook in order to decrypt the keys. The keys
  will always be displayed in their decrypted form.

  $product_key	- An encrypted product key

  Returns the decrypted product key

  There needs to be a hook for reading extra fields when importing
  keys. This is on my TO-DO list and I'm not sure how best to
  implement it.

  **********

  hook_uc_product_keys_order_ready($order, $status)

  This hook allows you to specify the whether an order is ready to
  have the product keys delivered to the customer. It is only called
  when the order is being updated.

  You will need to decide if the order is ready to have product keys
  issued to the customer (return TRUE) or is not ready (return FALSE)
  or you don't know (return NULL).

  If any module returns FALSE, the keys are not issued. If one or
  more modules return TRUE (and none return FALSE), the keys are
  issued. If all modules return NULL or if there are no hook methods
  implemented, a default test is used: the order has transitioned to
  the payment_received or completed states.

  You will need this hook in case you are using a payment module
  where you don't want the keys issued on one or the other or both
  states. Typically, you will check the payment type. If it is one
  you want to control, you will return TRUE or FALSE. Otherwise, you
  will return NULL.

  Even if all hooks report that the order is ready, keys are never
  issued for any order that already has keys. (We perform the hook
  check first to avoid the database access needed for the second
  check).

  $order	- The order (with the old order status).
  $status	- The new order status (note: *not* the order state).

  Returns TRUE if the product keys should be assigned; FALSE if it
  should not be assigned and NULL if the hook method doesn't know the
  right answer.


Utility Functions

  These functions allow you to hook your activation and revokation
  code to the database.

  Get a product key from the database by name.

  uc_product_keys_get_key($product_key)
    $product_key	- The (encrypted) product key string to use to
			  find a product key in the database.
    Returns		- The product key object.

  Increment the number of activations of a product_key.

  uc_product_keys_increment_activation($product_key)
    $product_key	- The (encrypted) product key string to use to
			  find a product key in the database.

  Sets the revoke flag for this key. You will need to check the flag
  in your product activation code in order to make this be meaningful.

  uc_product_keys_revoke_key($product_key)
    $product_key	- The (encrypted) product key string to use to
			  find a product key in the database.