regcode_api.inc.php in Registration codes 5.3
regcode_api.inc.php contains general low-level functions for the registration-code module, for tasks like
- data handling
- internal field info
- import
File
regcode_api.inc.phpView source
<?php
/**
* @file
* regcode_api.inc.php contains general low-level
* functions for the registration-code module, for tasks like
* - data handling
* - internal field info
* - import
*/
// ===========================
// = common helper functions =
// ===========================
/**
* Return text message requested by given identifier/constant
*
* @param $id1
* The primary section-identifier (string) for the message
* @param $id2
* The secondary sub-identifier (constant) for the message
* @return
* The text of the message.
*/
function regcode_message($id1, $id2 = NULL) {
switch ($id1) {
case 'VALIDITY_ERROR':
switch ($id2) {
case REGCODE_VALIDITY_NOTEXISTING:
return 'This registration code does not exist.';
case REGCODE_VALIDITY_NOTAVAILABLE:
return 'This registration code is not available.';
case REGCODE_VALIDITY_TAKEN:
return 'This registration code has already been used.';
case REGCODE_VALIDITY_EXPIRED:
return 'This registration code has expired.';
}
}
}
// ===================================
// = registration code data handling =
// ===================================
/**
* Retrieve a particular registration code identified by given code id,
* or assign it to a given user
*
* @param $code
* The code identifiert string
* @param $assign_to_uid
* Optional user id to assign the given code to
* @return
* The data array of the code to retrieve, or a boolean result (TRUE=successfully assigned to given uid) if assign_to_uid has been given.
*/
function regcode_get_code($code, $assign_to_uid = FALSE) {
// look up and retrieve code record from DB
$code = db_fetch_array(db_query("SELECT * FROM {regcode} WHERE code = '%s'", $code));
// check validity
if (!is_array($code)) {
return REGCODE_VALIDITY_NOTEXISTING;
}
if ($code['uid']) {
return REGCODE_VALIDITY_TAKEN;
}
if (!$code['available']) {
return REGCODE_VALIDITY_NOTAVAILABLE;
}
if ($code['expire'] && $code['expire'] < $_SERVER["REQUEST_TIME"]) {
return REGCODE_VALIDITY_EXPIRED;
}
// optionally mark this code as taken for the given user uid
if ($assign_to_uid) {
if ($code['reuse']) {
$result = db_query("UPDATE {regcode} SET used_count = (used_count + 1), used = UNIX_TIMESTAMP() WHERE code = '%s'", $code['code']);
}
else {
$result = db_query("UPDATE {regcode} SET available = 0, used_count = 1, used = UNIX_TIMESTAMP(), uid = %d WHERE code = '%s'", $assign_to_uid, $code['code']);
}
}
return $code;
}
/**
* Return the database query result for the given options to list codes
*
* @param $options
* An array of options for retrieving registration codes:
* filter_field - registration code field to filter the results by (see regcode_get_fields)
* filter_operand - The filter operand: contains / equals / not / greater / smaller (see regcode_get_filter_operands)
* filter_data - The data to filter on, string or number
* start - db result sequence number of first code to retrieve, see regcode_get_fields
* limit - number of codes to retrieve
* order - registration code field to order the results by (see regcode_get_fields)
* sort - sort order to order the results by: ASC / DESC
* pager - the pager identifier if a paging mechanism should be used
*
* @return
* An array list of code data arrays
*/
function regcode_get_codes($options = array()) {
$o = array_merge(array(
'filter_operand' => 'equals',
'start' => 0,
'limit' => 100,
'order' => 'code',
'sort' => 'asc',
'pager' => NULL,
), $options);
$fields = regcode_get_fields(TRUE);
if (isset($o['filter_field']) && isset($o['filter_data'])) {
if ($fields[$o['filter_field']]) {
$filter = $o['filter_field'];
}
$operand = regcode_get_filter_operands('sql', $o['filter_operand']);
$sql_where = "WHERE {$filter} {$operand} ";
}
$order = isset($fields[$o['order']]) ? $o['order'] : 'code';
$sort = drupal_strtoupper($o['sort']) == 'DESC' ? 'DESC' : 'ASC';
foreach (array_keys($fields) as $f) {
$sql_fields[] = $f . ' as ' . str_replace('.', '___', $f);
}
$sql = "SELECT " . implode(', ', $sql_fields) . "\n FROM {regcode} c\n LEFT JOIN {users} u ON (u.uid = c.uid)\n LEFT JOIN {role} r ON (r.rid = c.rid)\n {$sql_where}\n ORDER BY {$order} {$sort}\n ";
$args = array(
$o['filter_data'],
);
if (isset($o['pager'])) {
$result = pager_query($sql, $o['limit'], $o['pager'], NULL, $args);
}
else {
$result = db_query_range($sql, $args, $o['start'], $o['limit']);
}
while ($row = db_fetch_object($result)) {
foreach ((array) $row as $key => $data) {
$row_temp[str_replace('___', '.', $key)] = $data;
}
$rows[] = $row_temp;
}
return $rows;
}
/**
* Save given code array to a record in the db
*
* @param $code
* An array of code data fields, containing the fields:
* code - code identifier string (unique)
* available - is code available for user registration? ('1' = available)
* reuse - is code re-usable for many user registrations? ('1' = re-use)
* uid - user id to assign this code to a particular user (and thus mark is as "taken" by that user)
* rid - role id of the role this code will grant to the user that registers with it
* created - unix timestamp of the date this code has been created/added
* used - unix timestamp of the date this code has been used for registration
* revoke - unix timestamp of the date this code and its granted role will be revoked from the user that used it (not implemented)
* expire - unix timestamp of the date this code's availability for registration will expire (not touching already used codes)
* info - string (up to 255 characters) for any arbitrary information data
* @param $action
* Action to perform when saving the code:
* overwrite - overwrite any existing code with same code identifier
* skip - skip and do not save code if there is any existing code with same code identifier
* * - "
*
* @return
* An array list of code data arrays
*/
function regcode_save_code($code, $action = 'overwrite') {
if (empty($code)) {
return FALSE;
}
if (empty($code['code'])) {
return FALSE;
}
// empty template
$row = array(
'code' => '',
'available' => 1,
'reuse' => 0,
'uid' => 'NULL',
'rid' => 'NULL',
'created' => $_SERVER['REQUEST_TIME'],
'used' => 0,
'revoke' => 0,
'expire' => 0,
'info' => 'NULL',
);
// fill row template with filtered and escaped input for fields which actually exist
foreach ($code as $key => $value) {
if (isset($row[$key])) {
$row[$key] = "'" . db_escape_string(check_plain($value)) . "'";
}
}
// optionally delete old record
if ($action == 'overwrite') {
db_query("DELETE FROM {regcode} WHERE code = '%s' LIMIT 1", $code['code']);
}
// insert record into db
$sql = "INSERT INTO {regcode} (`" . implode('`, `', array_keys($row)) . "`) VALUES (" . implode(", ", $row) . ")";
// implode(',', $placeholders)
$result = db_query($sql);
// , $row);
return $result;
}
/**
* Clean all codes from the db
*
* @param $action
* Action to perform when cleaning the code:
* clean - clean codes from db
* * - do nothing
*/
function regcode_clean_codes($action = 'clean') {
if ($action == 'clean') {
db_query("TRUNCATE {regcode}");
}
}
// =========================
// = backend API functions =
// =========================
/**
* Get the list of regcode db fields as key/title pairs
*
* @param $include_related
* Whether to include foreign key field from related tables used by regcode queries
* @param $translated
* Whether to return translated titles
* @return
* An array list of field name/title pairs
*/
function regcode_get_fields($include_related = FALSE, $translated = FALSE) {
$fields = array(
'c.code' => 'Code',
'c.available' => 'Available',
'c.reuse' => 'Reuse',
'c.uid' => 'User ID',
'c.rid' => 'Role ID',
'c.created' => 'Created',
'c.used' => 'Used',
'c.expire' => 'Expire',
'c.revoke' => 'Revoke',
'c.info' => 'Info',
);
// optionally include related fields from other tables for db filtering etc.
if ($include_related) {
$fields['r.name'] = 'Role';
$fields['u.name'] = 'User';
}
if ($translated) {
foreach ($fields as $field_name => $field_title) {
$fields[$field_name] = t($field_title);
}
}
return $fields;
}
/**
* Get the key of a given field name (redundant) or title
* This function is quite stupid, but is necessary to compensate a bug in Drupal
* for correctly retrieving a column key from table sorting querystring-argument "order",
* which is wrongfully set to the table column's header NAME (=title) instead of FIELD,
* - see http://drupal.org/comment/reply/61931 -
* which has to be taken into account by searching for the fieldname (array key)
* by array search by column name
*
* @param $field_key_or_title
* The field key (redundant) or title to look up
* @param $fields
* Optionally a field/title array to use for lookup
* @param $translated
* Whether to compare translated field titles
*
* @return
* An array list of code data arrays
*/
function regcode_get_field_key($field_key_or_title, $fields = NULL, $translated = TRUE) {
if ($fields == NULL) {
$fields = regcode_get_fields($include_related = TRUE);
}
// if argument found as field array key, return it
if (isset($fields['field_key_or_title'])) {
return $field_key_or_title;
}
// else, look for first matching (opt. localized) field array title matching the argument, and return its key
foreach ($fields as $key => $title) {
if ($translated) {
$title = t($title);
}
if ($field_key_or_title == $title) {
return $key;
}
}
}
/**
* Get the list of available filter operands for code retrieval
*
* @param $part
* Which part data of the operand(s) to return: title / sql
* title - return the operand(s) titles
* sql - return the operand(s) sql filter code
* @param $operand
* Specific operand to look up
*
* @return
* Either an array of operand/title or operand/sql pairs, or the title resp. sql for one operand if the operand argument has been given
*/
function regcode_get_filter_operands($part = 'title', $operand = NULL) {
$operands = array(
'contains' => array(
'title' => 'contains',
'sql' => "LIKE '%%%s%%'",
),
'equals' => array(
'title' => 'equals',
'sql' => "= '%s'",
),
'not' => array(
'title' => 'not equals',
'sql' => "<> '%s'",
),
'greater' => array(
'title' => 'is greater than',
'sql' => "> '%s'",
),
'smaller' => array(
'title' => 'is smaller than',
'sql' => "< '%s'",
),
);
foreach (array_keys(next($operands)) as $part_key) {
foreach ($operands as $operand_key => $operand_value) {
$operand_parts[$part_key][$operand_key] = $operand_value[$part_key];
}
}
if ($operand != NULL) {
return $operands[$operand][$part];
}
return $operand_parts[$part];
}
// ====================
// = import functions =
// ====================
/**
* Import codes from a file (plain list or CSV)
*
* @param $filepath
* File system path of the file to import from
* @param $action
* Import action:
* overwrite - overwrite any existing codes with same code identifiers as the imported ones
* skip - skip any import of a codes, if any code with same code identifier exists
* clean - completely wipe the code database befor importing all codes
* @param $code_template
* Optional code data template to use as default data setting for each imported code (key/value pairs for any applicable code field, see regcode_save_code)
*
* @return
* Whether the import operation has been successful (TRUE) or not (FALSE)
*/
function regcode_import_file($filepath, $action = NULL, $code_template = NULL) {
// open file as stream and delegate to regcode_import_stream
$handle = fopen($filepath, "r");
$result = regcode_import_stream($handle, $action, $code_template);
fclose($handle);
return $result;
}
/**
* Import codes from a multi-line string (plain list or CSV)
*
* @param $text
* Multi-line string to import from
* @param $action
* Import action:
* overwrite - overwrite any existing codes with same code identifiers as the imported ones
* skip - skip any import of a codes, if any code with same code identifier exists
* clean - completely wipe the code database befor importing all codes
* @param $code_template
* Optional code data template to use as default data setting for each imported code (key/value pairs for any applicable code field, see regcode_save_code)
*
* @return
* Whether the import operation has been successful (TRUE) or not (FALSE)
*/
function regcode_import_text(&$text, $action = NULL, $code_template = NULL) {
// open string as memory stream and delegate to regcode_import_stream
$handle = fopen("php://temp/maxmemory:" . 5 * 1024 * 1024, 'rw');
fputs($handle, $text);
rewind($handle);
$result = regcode_import_stream($handle, $action, $code_template);
fclose($handle);
return $result;
}
/**
* Import codes from a stream (plain list or CSV text data)
*
* @param $stream
* Stream handle of the stream to import from
* @param $action
* Import action:
* overwrite - overwrite any existing codes with same code identifiers as the imported ones
* skip - skip any import of a codes, if any code with same code identifier exists
* clean - completely wipe the code database befor importing all codes
* @param $code_template
* Optional code data template to use as default data setting for each imported code (key/value pairs for any applicable code field, see regcode_save_code)
*
* @return
* Whether the import operation has been successful (TRUE) or not (FALSE)
*/
function regcode_import_stream($stream, $action = NULL, $code_template = NULL) {
if (!$stream) {
return FALSE;
}
if (!$action) {
$action = variable_get('regcode_import_action', 'skip');
}
$delimiter = variable_get('regcode_import_csv_delimiter', ',');
$enclosure = variable_get('regcode_import_csv_text_enclosure', '"');
$fieldorder = variable_get('regcode_import_csv_fieldorder', 'code');
// clean codes when needed (depending on action)
regcode_clean_codes($action);
// iterate through stream line by line
while (($row = fgetcsv($stream, 9999, $delimiter, $enclosure)) !== FALSE) {
if (empty($fieldorder)) {
$fieldorder = $row;
}
else {
if (regcode_import_code($row, $action, $fieldorder, $code_template)) {
$count++;
}
}
}
drupal_set_message(t('!count registration codes imported.', array(
'!count' => intval($count),
)));
watchdog('RegistrationCode', t('!count registration codes imported.', array(
'!count' => intval($count),
)));
return $count > 0;
}
/**
* Import a single codes from a single ine string (plain one-field or CSV)
*
* @param $data
* The single-line string containing the code data to import (a single field or CSV)
* @param $action
* Import action:
* overwrite - overwrite any existing code with same code identifier as the imported one
* skip - skip import of code, if any code with same code identifier exists
* * - "^
* @param $fieldorder
* List of field keys indicating the order of field to expect in the $data string (array or delimiter-seperated string of keys)
* @param $code
* Optional code data template to use as default data setting for each imported code (key/value pairs for any applicable code field, see regcode_save_code)
*
* @return
* Whether the import operation has been successful (TRUE) or not (FALSE)
*/
function regcode_import_code($data, $action, $fieldorder = NULL, $code = array()) {
if (empty($fieldorder)) {
$fieldorder = variable_get('regcode_import_csv_fieldorder', 'code');
}
if (!is_array($fieldorder)) {
$fieldorder = explode(variable_get('regcode_import_csv_delimiter', ','), $fieldorder);
}
foreach ($data as $key => $value) {
$code[$fieldorder[$key]] = $value;
}
return regcode_save_code($code, $action);
}
Functions
Name | Description |
---|---|
regcode_clean_codes | Clean all codes from the db |
regcode_get_code | Retrieve a particular registration code identified by given code id, or assign it to a given user |
regcode_get_codes | Return the database query result for the given options to list codes |
regcode_get_fields | Get the list of regcode db fields as key/title pairs |
regcode_get_field_key | Get the key of a given field name (redundant) or title This function is quite stupid, but is necessary to compensate a bug in Drupal for correctly retrieving a column key from table sorting querystring-argument "order", which is wrongfully… |
regcode_get_filter_operands | Get the list of available filter operands for code retrieval |
regcode_import_code | Import a single codes from a single ine string (plain one-field or CSV) |
regcode_import_file | Import codes from a file (plain list or CSV) |
regcode_import_stream | Import codes from a stream (plain list or CSV text data) |
regcode_import_text | Import codes from a multi-line string (plain list or CSV) |
regcode_message | Return text message requested by given identifier/constant |
regcode_save_code | Save given code array to a record in the db |