summaryrefslogtreecommitdiff
path: root/includes/actions.inc
diff options
context:
space:
mode:
authorGábor Hojtsy <gabor@hojtsy.hu>2007-08-29 14:57:50 +0000
committerGábor Hojtsy <gabor@hojtsy.hu>2007-08-29 14:57:50 +0000
commit118e91cc4048905446ee46fa87af60a96c996c8e (patch)
tree711299f43ce8fb8e9a872910bc8bb146944c7c9b /includes/actions.inc
parent89aef5b74f6eff31f80427e246a7a81fe52feb42 (diff)
downloadbrdo-118e91cc4048905446ee46fa87af60a96c996c8e.tar.gz
brdo-118e91cc4048905446ee46fa87af60a96c996c8e.tar.bz2
#155828 by Eaton, pwolanin and jvandyk: let actions live even if actions.module is not turned on
Diffstat (limited to 'includes/actions.inc')
-rw-r--r--includes/actions.inc158
1 files changed, 149 insertions, 9 deletions
diff --git a/includes/actions.inc b/includes/actions.inc
index 28ec1078a..2c2e41afd 100644
--- a/includes/actions.inc
+++ b/includes/actions.inc
@@ -7,6 +7,8 @@
*/
/**
+ * Perform a given list of actions by executing their callback functions.
+ *
* Given the IDs of actions to perform, find out what the callbacks
* for the actions are by querying the database. Then call each callback
* using the function call $function('do', $object, $context, $a1, $2)
@@ -116,8 +118,8 @@ function actions_do($action_ids, $object = NULL, $context = NULL, $a1 = NULL, $a
* 'description' => t('Save node'),
* 'configurable' => FALSE,
* 'hooks' => array(
- * 'nodeapi' => array('delete','insert','update', 'view'),
- * 'comment' => array('delete','insert','update', 'view'),
+ * 'nodeapi' => array('delete', 'insert', 'update', 'view'),
+ * 'comment' => array('delete', 'insert', 'update', 'view'),
* )
* )
* );
@@ -130,26 +132,40 @@ function actions_do($action_ids, $object = NULL, $context = NULL, $a1 = NULL, $a
* validation and submission functions. The hooks the action supports
* are declared in the 'hooks' array.
*
+ * @param $reset
+ * Reset the action info static cache.
+ *
* @return
* An associative array keyed on function name. The value of each key is
* an array containing information about the action, such as type of
* action and description of the action, e.g.,
*
- * $actions['actions_node_publish'] = ('description' => 'Publish a node' ... )
+ * @code
+ * $actions['node_publish_action'] = array(
+ * 'type' => 'node',
+ * 'description' => t('Publish post'),
+ * 'configurable' => FALSE,
+ * 'hooks' => array(
+ * 'nodeapi' => array('presave', 'insert', 'update', 'view'),
+ * 'comment' => array('delete', 'insert', 'update', 'view'),
+ * ),
+ * );
+ * @endcode
*/
-function actions_list() {
+function actions_list($reset = FALSE) {
static $actions;
- if (isset($actions)) {
- return $actions;
+ if (!isset($actions) || $reset) {
+ $actions = module_invoke_all('action_info');
+ drupal_alter('action_info', $actions);
}
- $actions = module_invoke_all('action_info');
- drupal_alter('action_info', $actions);
- return $actions;
+ // See module_implements for explanations of this cast.
+ return (array)$actions;
}
/**
* Retrieve all action instances from the database.
+ *
* Compare with actions_list() which gathers actions by
* invoking hook_action_info(). The two are synchronized
* by visiting /admin/build/actions (when actions.module is
@@ -176,6 +192,7 @@ function actions_get_all_actions() {
/**
* Create an associative array keyed by md5 hashes of function names.
+ *
* Hashes are used to prevent actual function names from going out into
* HTML forms and coming back.
*
@@ -204,6 +221,7 @@ function actions_actions_map($actions) {
/**
* Given an md5 hash of a function name, return the function name.
+ *
* Faster than actions_actions_map() when you only need the function name.
*
* @param $hash
@@ -224,3 +242,125 @@ function actions_function_lookup($hash) {
$aid = db_result(db_query("SELECT aid FROM {actions} WHERE MD5(aid) = '%s' AND parameters != ''", $hash));
return $aid;
}
+
+/**
+ * Synchronize actions that are provided by modules.
+ *
+ * They are synchronized with actions that are stored in the actions table.
+ * This is necessary so that actions that do not require configuration can
+ * receive action IDs. This is not necessarily the best approach,
+ * but it is the most straightforward.
+ */
+function actions_synchronize($actions_in_code = array(), $delete_orphans = FALSE) {
+ if (!$actions_in_code) {
+ $actions_in_code = actions_list();
+ }
+ $actions_in_db = array();
+ $result = db_query("SELECT * FROM {actions} WHERE parameters = ''");
+ while ($action = db_fetch_object($result)) {
+ $actions_in_db[$action->callback] = array('aid' => $action->aid, 'description' => $action->description);
+ }
+
+ // Go through all the actions provided by modules.
+ foreach ($actions_in_code as $callback => $array) {
+ // Ignore configurable actions since their instances get put in
+ // when the user adds the action.
+ if (!$array['configurable']) {
+ // If we already have an action ID for this action, no need to assign aid.
+ if (array_key_exists($callback, $actions_in_db)) {
+ unset($actions_in_db[$callback]);
+ }
+ else {
+ // This is a new singleton that we don't have an aid for; assign one.
+ db_query("INSERT INTO {actions} (aid, type, callback, parameters, description) VALUES ('%s', '%s', '%s', '%s', '%s')", $callback, $array['type'], $callback, '', $array['description']);
+ watchdog('actions', t("Action '%action' added.", array('%action' => filter_xss_admin($array['description']))));
+ }
+ }
+ }
+
+ // Any actions that we have left in $actions_in_db are orphaned.
+ if ($actions_in_db) {
+ $orphaned = array();
+ $placeholder = array();
+
+ foreach ($actions_in_db as $callback => $array) {
+ $orphaned[] = $callback;
+ $placeholder[] = "'%s'";
+ }
+
+ $orphans = implode(', ', $orphaned);
+
+ if ($delete_orphans) {
+ $placeholders = implode(', ', $placeholder);
+ $results = db_query("SELECT a.aid, a.description FROM {actions} a WHERE callback IN ($placeholders)", $orphaned);
+ while ($action = db_fetch_object($results)) {
+ actions_delete($action->aid);
+ watchdog('actions', t("Removed orphaned action '%action' from database.", array('%action' => filter_xss_admin($action->description))));
+ }
+ }
+ else {
+ $link = l(t('Remove orphaned actions'), 'admin/build/actions/orphan');
+ $count = count($actions_in_db);
+ watchdog('actions', format_plural($count, 'One orphaned action (%orphans) exists in the actions table. !link', '@count orphaned actions (%orphans) exist in the actions table. !link', array('@count' => $count, '%orphans' => $orphans, '!link' => $link), 'warning'));
+ }
+ }
+}
+
+/**
+ * Save an action and its associated user-supplied parameter values to the database.
+ *
+ * @param $function
+ * The name of the function to be called when this action is performed.
+ * @param $params
+ * An associative array with parameter names as keys and parameter values
+ * as values.
+ * @param $desc
+ * A user-supplied description of this particular action, e.g., 'Send
+ * e-mail to Jim'.
+ * @param $aid
+ * The ID of this action. If omitted, a new action is created.
+ *
+ * @return
+ * The ID of the action.
+ */
+function actions_save($function, $type, $params, $desc, $aid = NULL) {
+ $serialized = serialize($params);
+ if ($aid) {
+ db_query("UPDATE {actions} SET callback = '%s', type = '%s', parameters = '%s', description = '%s' WHERE aid = %d", $function, $type, $serialized, $desc, $aid);
+ watchdog('actions', 'Action %action saved.', array('%action' => $desc));
+ }
+ else {
+ // aid is the callback for singleton actions so we need to keep a
+ // separate table for numeric aids.
+ db_query('INSERT INTO {actions_aid} () VALUES ()');
+ $aid = db_last_insert_id('actions_aid', 'aid');
+ db_query("INSERT INTO {actions} (aid, callback, type, parameters, description) VALUES (%d, '%s', '%s', '%s', '%s')", $aid, $function, $type, $serialized, $desc);
+ watchdog('actions', 'Action %action created.', array('%action' => $desc));
+ }
+
+ return $aid;
+}
+
+/**
+ * Retrieve a single action from the database.
+ *
+ * @param $aid
+ * integer The ID of the action to retrieve.
+ *
+ * @return
+ * The appropriate action row from the database as an object.
+ */
+function actions_load($aid) {
+ return db_fetch_object(db_query("SELECT * FROM {actions} WHERE aid = %d", $aid));
+}
+
+/**
+ * Delete a single action from the database.
+ *
+ * @param $aid
+ * integer The ID of the action to delete.
+ */
+function actions_delete($aid) {
+ db_query("DELETE FROM {actions} WHERE aid = %d", $aid);
+ module_invoke_all('actions_delete', $aid);
+}