rules_link.module in Rules Link 7
Same filename and directory in other branches
Rules Link - module file.
File
rules_link.moduleView source
<?php
/**
* @file
* Rules Link - module file.
*/
/**
* Implements hook_entity_info().
*/
function rules_link_entity_info() {
return array(
'rules_link' => array(
'label' => t('Rules Link'),
'entity class' => 'RulesLink',
'controller class' => 'EntityAPIControllerExportable',
'base table' => 'rules_link',
'fieldable' => TRUE,
'entity keys' => array(
'id' => 'id',
'name' => 'name',
'label' => 'label',
),
'exportable' => TRUE,
'module' => 'rules_link',
'access callback' => 'rules_link_access',
// Enable the entity API's admin UI.
'admin ui' => array(
'path' => 'admin/config/workflow/rules_links',
'file' => 'rules_link.admin.inc',
'controller class' => 'RulesLinkUIController',
),
),
);
}
/**
* Access callback for the entity API.
*/
function rules_link_access($op, $type = NULL, $account = NULL) {
return user_access('administer rules links', $account);
}
/**
* Menu argument loader; Load a rules link by string.
*
* @param $name
* The machine-readable name of a rules link to load.
* @return
* A rules link array or FALSE if $name does not exist.
*/
function rules_link_load($name) {
return rules_link_get_links($name);
}
/**
* Implements hook_permission().
*/
function rules_link_permission() {
$permissions = array(
'administer rules links' => array(
'title' => t('Administer rules links'),
'description' => t('Create and delete rules links and set their permissions.'),
),
);
foreach (rules_link_get_links() as $link) {
$name = check_plain($link->name);
$permissions += array(
"access rules link {$name}" => array(
'title' => t('%link_label: Execute rules link', array(
'%link_label' => $link->label,
)),
),
);
}
return $permissions;
}
/**
* Gets an array of all rules links, keyed by the type name.
*
* @param $link_names
* If set, the function will return the link with the given name.
* @return RuleLinks[]
* Depending on isset $link_names, a name single or an array of rules links.
*/
function rules_link_get_links($link_names = NULL) {
$links = entity_load_multiple_by_name('rules_link', isset($link_names) ? array(
$link_names,
) : FALSE);
return isset($link_names) ? reset($links) : $links;
}
/**
* Returns the name condition set to a rules link.
*/
function rules_link_get_condition_set_name($rules_link) {
return 'rules_link_condition_' . $rules_link->name;
}
/**
* Returns the name condition set to a rules link.
*/
function rules_link_get_rules_set_name($rules_link) {
return 'rules_link_set_' . $rules_link->name;
}
/**
* Loads and returns the condition to a link. If it
* doesn't exist, a new one will be created.
*
* @param $rules_link
* The rules link to which the condition should be loaded.
*/
function rules_link_load_condition_set($rules_link) {
$condition_set = rules_config_load(rules_link_get_condition_set_name($rules_link));
if ($condition_set != FALSE) {
return $condition_set;
}
else {
$conditions = rules_and(array(
$rules_link->entity_type => array(
'type' => $rules_link->entity_type,
'label' => $rules_link->entity_type,
),
));
$conditions->label = 'Rules link: ' . $rules_link->label . ' condition';
$conditions
->save(rules_link_get_condition_set_name($rules_link), 'rules_link');
return $conditions;
}
}
/**
* Loads and returns the rules set to a link. If it
* doesn't exist, a new one will be created.
*
* @param $rules_link
* The rules link to which the condition or rules set should be loaded.
*/
function rules_link_load_rules_set($rules_link) {
$rule_set = rules_config_load(rules_link_get_rules_set_name($rules_link));
if ($rule_set != FALSE) {
return $rule_set;
}
else {
$rule_set = rules_rule_set(array(
$rules_link->entity_type => array(
'type' => $rules_link->entity_type,
'label' => $rules_link->entity_type,
),
));
$rule_set->label = 'Rules link: ' . $rules_link->label . ' rules set';
$rule_set
->save(rules_link_get_rules_set_name($rules_link), 'rules_link');
return $rule_set;
}
}
/**
* Renders a link using the name of the rules_link and the entity id.
*
* @param $rules_link_name
* The name the link which should be rendered.
* @param $entity_id
* The entity id of entity on which the rule should be triggered.
* @param $destination
* The destination to which the Rules Module should redirect the user after
* triggering the link.
* @param $parameters
* Additional parameters for the Rules components of the link.
*
* @return
* A renderable array.
*/
function rules_link_render($rules_link_name, $entity_id, $destination = NULL, $parameters = array()) {
$rules_link = rules_link_load($rules_link_name);
return rules_link_render_link($rules_link, $entity_id, $destination, $parameters);
}
/**
* Renders a link.
*
* @param $rules_link
* The link which should be rendered.
* @param $entity_id
* The entity id of entity on which the rule should be triggered.
* @param $destination
* The destination to which the Rules Module should redirect the user after
* triggering the link.
* @param $parameters
* Additional parameters for the Rules components of the link.
*
* @return
* A renderable array.
*/
function rules_link_render_link($rules_link, $entity_id, $destination = NULL, $parameters = array()) {
if (rules_link_check_visibility($rules_link, array_merge(array(
$entity_id,
), $parameters))) {
$path = $rules_link->path . '/' . $entity_id;
if (count($parameters) > 0) {
$path .= '/' . implode('/', $parameters);
}
$path .= $rules_link->settings['link_type'] == 'confirm' ? '' : '/' . rules_link_get_token($entity_id);
$link = array(
'#title' => $rules_link
->getSettingTranslation('text'),
'#href' => $path,
'#attr' => array(
'class' => array(
'rules-link',
),
'rel' => 'nofollow',
),
'#rules_link' => $rules_link,
'#theme' => 'rules_link',
);
if ($rules_link->settings['link_type'] == 'javascript') {
$link['#attr']['class'][] = 'rules-link-js';
drupal_add_js(drupal_get_path('module', 'rules_link') . '/rules_link.js', 'file');
drupal_add_css(drupal_get_path('module', 'rules_link') . '/rules_link.css', 'file');
}
else {
$link['#options'] = array(
'query' => $destination,
);
}
return $link;
}
return array();
}
/**
* Trims a whitespaces from a parameter.
*/
function rules_link_trim_parameters(&$value) {
$value = trim($value);
}
/**
* Custom Entity class.
*/
class RulesLink extends Entity {
public $settings = array();
public function __construct($values = array()) {
parent::__construct($values, 'rules_link');
}
/**
* Gets the i18n translation of a setting.
*
* @param $name
* The setting name.
* @param $langcode
* The optional language code. Defaults to the current display language.
*
* @see Entity::getTranslation()
*/
public function getSettingTranslation($name, $langcode = NULL) {
$value = isset($this->settings[$name]) ? $this->settings[$name] : NULL;
$i18n_name = 'rules_link:rules_link:' . $this
->identifier() . ':' . $name;
return entity_i18n_string($i18n_name, $value, $langcode);
}
}
/**
* Implements hook_rules_link_insert().
*/
function rules_link_rules_link_insert($link) {
// Do not directly issue menu rebuilds here to avoid potentially multiple
// rebuilds. Instead, let menu_get_item() issue the rebuild on the next page.
variable_set('menu_rebuild_needed', TRUE);
}
/**
* Implements hook_rules_link_update().
*/
function rules_link_rules_link_update($link) {
// Make sure to only issue menu rebuilds if necessary.
// @see rules_link_rules_link_insert()
if (!empty($link->original) && ($link->path != $link->original->path || $link->settings['link_type'] != $link->original->settings['link_type'])) {
variable_set('menu_rebuild_needed', TRUE);
}
}
/**
* Implements hook_rules_link_delete().
*/
function rules_link_rules_link_delete($link) {
// @see rules_link_rules_link_insert()
variable_set('menu_rebuild_needed', TRUE);
// Delete associate rule configs.
rules_link_load_condition_set($link)
->delete();
rules_link_load_rules_set($link)
->delete();
}
/**
* Generates a token used to protect links from spoofing.
*/
function rules_link_get_token($content_id) {
// Anonymous users get a less secure token, since it must be the same for all
// anonymous users on the entire site to work with page caching.
return $GLOBALS['user']->uid ? drupal_get_token($content_id) : drupal_hmac_base64($content_id, drupal_get_private_key() . drupal_get_hash_salt());
}
/**
* Checks if the given token is correct.
*/
function rules_link_check_token($token, $content_id) {
return rules_link_get_token($content_id) === $token;
}
function rules_link_get_paramters($rules_link) {
$args = arg();
// Remove the first arguments, that represent the url of the link.
$path_args = explode('/', $rules_link->path);
$args = array_slice($args, count($path_args));
return $args;
}
function rules_link_invoke_component($name, $args) {
if ($component = rules_get_cache('comp_' . $name)) {
return $component
->executeByArgs($args);
}
}
function rules_link_check_visibility($rules_link, $args) {
$rule_set = rules_link_load_rules_set($rules_link);
$paramInfo = $rule_set
->parameterInfo();
return count($args) >= count($paramInfo) && user_access("access rules link " . $rules_link->name) && rules_link_invoke_component(rules_link_get_condition_set_name($rules_link), $args);
}
/**
* Triggers a rule set from a rules link.
*/
function rules_link_trigger($rules_link, $entity_id) {
rules_link_invoke_component(rules_link_get_rules_set_name($rules_link), rules_link_get_paramters($rules_link));
}
/**
* Menu callback for javascript links.
*/
function rules_link_trigger_js($rules_link, $entity_id) {
rules_link_trigger($rules_link, $entity_id);
$json = array(
'message' => drupal_get_messages(),
);
drupal_json_output($json);
}
/**
* Menu callback for token links.
*/
function rules_link_trigger_token($rules_link, $entity_id) {
rules_link_trigger($rules_link, $entity_id);
drupal_goto();
}
/**
* Form generator for the menu callback for the confirm form links.
*/
function rules_link_trigger_form($form, &$form_state, $rules_link, $entity_id) {
$form['link'] = array(
'#type' => 'hidden',
'#value' => $rules_link->name,
);
$form['entity_id'] = array(
'#type' => 'hidden',
'#value' => $entity_id,
);
return confirm_form($form, filter_xss_admin($rules_link
->getSettingTranslation('confirm_question')), '', filter_xss_admin($rules_link
->getSettingTranslation('confirm_description')));
}
/**
* Submit function for the confirm form links.
*/
function rules_link_trigger_form_submit($form, &$form_state) {
$rules_link = rules_link_load($form_state['values']['link']);
rules_link_trigger($rules_link, $form_state['values']['entity_id']);
}
/**
* Access callback function for confirm type links.
*/
function rules_link_access_link_confirm($rules_link, $entity_id) {
if (rules_link_check_visibility($rules_link, rules_link_get_paramters($rules_link))) {
return TRUE;
}
return FALSE;
}
/**
* Access callback function for the token and javascript links.
*/
function rules_link_access_link($rules_link, $entity_id) {
// The token is always the last element of the argument array.
$params = rules_link_get_paramters($rules_link);
$token = array_pop($params);
return rules_link_check_token($token, $entity_id) && rules_link_access_link_confirm($rules_link, $entity_id);
}
/**
* Implements hook_menu().
*/
function rules_link_menu() {
$item = array();
foreach (rules_link_get_links() as $name => $link) {
$first_arg = count(explode('/', $link->path));
switch ($link->settings['link_type']) {
case 'javascript':
$item[$link->path . '/%/%'] = array(
'page callback' => 'rules_link_trigger_js',
'page arguments' => array(
$link,
$first_arg,
),
'access arguments' => array(
$link,
$first_arg,
$first_arg + 1,
),
'access callback' => 'rules_link_access_link',
'type' => MENU_CALLBACK,
);
break;
case 'token':
$item[$link->path . '/%/%'] = array(
'page callback' => 'rules_link_trigger_token',
'page arguments' => array(
$link,
$first_arg,
),
'access arguments' => array(
$link,
$first_arg,
$first_arg + 1,
),
'access callback' => 'rules_link_access_link',
'type' => MENU_CALLBACK,
);
break;
case 'confirm':
$item[$link->path . '/%'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array(
'rules_link_trigger_form',
$link,
$first_arg,
),
'access arguments' => array(
$link,
$first_arg,
),
'access callback' => 'rules_link_access_link_confirm',
'type' => MENU_CALLBACK,
);
break;
}
}
return $item;
}
/**
* Implements hook_theme().
*/
function rules_link_theme() {
return array(
'rules_link' => array(
'template' => 'rules-link',
'variables' => array(
'title' => NULL,
'href' => NULL,
'attr' => NULL,
'options' => NULL,
'rules_link' => NULL,
),
'pattern' => 'rules-link__',
),
);
}
/**
* Implements hook_theme_registry_alter().
*/
function rules_link_theme_registry_alter(&$theme_registry) {
// Override the base hook so that we do not overlay with the default entity
// theme hook defined in entity_theme().
// Directly changing this setting in rules_link_theme() did not work.
$theme_registry['rules_link']['base hook'] = 'rules_link';
}
/**
* Implements hook_views_api().
*/
function rules_link_views_api() {
return array(
'api' => '3.0',
);
}
function template_preprocess_rules_link(&$variables) {
if (!isset($variables['options'])) {
$variables['options'] = array();
}
$variables['options'] += array(
'html' => FALSE,
);
$variables['title'] = $variables['options']['html'] ? $variables['title'] : check_plain($variables['title']);
if (isset($options['attr']['title']) && strpos($options['attr']['title'], '<') !== FALSE) {
$variables['attr']['title'] = strip_tags($options['attr']['title']);
}
else {
if (!isset($options['attr']['title'])) {
$variables['attr']['title'] = $variables['title'];
}
}
$variables['href'] = check_plain(url($variables['href'], $variables['options']));
$variables['attr'] = drupal_attributes($variables['attr']);
}
/**
* Implement hook_entity_view().
*/
function rules_link_entity_view($entity, $type, $view_mode, $langcode) {
$links = array();
$rules_links = rules_link_get_links();
foreach ($rules_links as $name => $rules_link) {
if ($rules_link->entity_type == $type && $rules_link->settings['entity_link']) {
list($id, $rev, $bundle) = entity_extract_ids($type, $entity);
// If the link is restricted to some bundles, verify the bundle.
// If it should be only shown on certain view modes, check the view modes.
if ($id && (empty($rules_link->settings['bundles']) || in_array($bundle, $rules_link->settings['bundles'])) && (empty($rules_link->settings['view_mode']) || in_array($view_mode, $rules_link->settings['view_mode']))) {
$rendered_link = rules_link_render_link($rules_link, $id, drupal_get_destination());
if (!empty($rendered_link)) {
$links[$name] = drupal_render($rendered_link);
}
}
}
}
foreach ($links as $name => $link) {
$entity->content['rules_links_' . $name] = array(
'#markup' => $link,
);
}
}
/**
* Implements hook_features_pipe_component_alter() for fields.
*/
function rules_link_features_pipe_rules_link_alter(&$pipe, $data, $export) {
foreach ($data as $id) {
$rules_link = entity_load_single('rules_link', $id);
$pipe['rules_config'][] = rules_link_get_condition_set_name($rules_link);
$pipe['rules_config'][] = rules_link_get_rules_set_name($rules_link);
}
}
/**
* Alter the breadcrumb trail of the rules components.
*/
function rules_link_menu_breadcrumb_alter(&$active_trail, $item) {
if (substr($item['href'], 22, 34) == 'rules/components/manage/rules_link') {
// Parse the name out of the link.
if (substr($item['href'], 57, 3) == 'set') {
$start = 61;
}
elseif (substr($item['href'], 57, 3) == 'con') {
$start = 67;
}
$link_name = substr($item['href'], $start, strlen($item['href']));
$pos = strpos($link_name, '/');
if ($pos !== FALSE) {
$link_name = substr($link_name, 0, $pos);
}
$rules_link = rules_link_load($link_name);
if ($rules_link) {
// Replace the link to Rules with a link to Rules Link.
$active_trail[4]['title'] = 'Rules Links';
$active_trail[4]['href'] = 'admin/config/workflow/rules_links';
$active_trail[4]['options']['attributes']['title'] = 'Manage links that triggers rules.';
$active_trail[4]['localized_options'] = array();
// Replace component link with link to the current rules link.
$active_trail[5]['title'] = $rules_link->label;
$active_trail[5]['href'] = "admin/config/workflow/rules_links/manage/{$link_name}/components";
$active_trail[5]['options']['attributes']['title'] = 'Edit the current link.';
$active_trail[5]['localized_options'] = array();
}
}
}
/**
* Implements hook_field_extra_fields().
*/
function rules_link_field_extra_fields() {
$return = array();
$rules_links = rules_link_get_links();
foreach ($rules_links as $rules_link) {
if ($rules_link->settings['entity_link']) {
$entity_info = entity_get_info($rules_link->entity_type);
$bundles = empty($rules_link->settings['bundles']) ? array_keys($entity_info['bundles']) : $rules_link->settings['bundles'];
foreach ($bundles as $bundle) {
$return[$rules_link->entity_type][$bundle]['display']['rules_links_' . $rules_link->name]['label'] = $rules_link->label;
$return[$rules_link->entity_type][$bundle]['display']['rules_links_' . $rules_link->name]['description'] = '';
$return[$rules_link->entity_type][$bundle]['display']['rules_links_' . $rules_link->name]['weight'] = 0;
}
}
}
return $return;
}
/**
* Implements hook_token_info().
*/
function rules_link_token_info() {
$type = array(
'name' => t('Rules link access token'),
'description' => t('Tokens related to rules link access token.'),
);
$rules_link = array();
return array(
'types' => array(
'rules_link_token' => $type,
),
'tokens' => array(
'rules_link_token' => $rules_link,
),
);
}
/**
* Implements hook_token_info_alter().
*/
function rules_link_token_info_alter(&$data) {
$entities = entity_get_info();
foreach (array_keys($entities) as $entity) {
$entity = str_replace('_', '-', $entity);
if (isset($data['tokens'][$entity])) {
$data['tokens'][$entity]['rules_link_token'] = array(
'name' => t('Rules link token'),
'description' => t('The rules link access token for this entity.'),
'type' => 'rules_link_token',
);
}
}
}
/**
* Implements hook_tokens().
*/
function rules_link_tokens($type, $tokens, array $data = array(), array $options = array()) {
$url_options = array(
'absolute' => TRUE,
);
if (isset($options['language'])) {
$url_options['language'] = $options['language'];
$language_code = $options['language']->language;
}
else {
$language_code = NULL;
}
$sanitize = !empty($options['sanitize']);
$replacements = array();
$entities = entity_get_info();
if (isset($entities[$type]) && !empty($data[$type])) {
$entity = $data[$type];
list($id, $vid, $bundle) = entity_extract_ids($type, $entity);
foreach ($tokens as $name => $original) {
switch ($name) {
case 'rules_link_token':
$replacements[$original] = rules_link_get_token($id);
break;
}
}
}
return $replacements;
}
Functions
Name | Description |
---|---|
rules_link_access | Access callback for the entity API. |
rules_link_access_link | Access callback function for the token and javascript links. |
rules_link_access_link_confirm | Access callback function for confirm type links. |
rules_link_check_token | Checks if the given token is correct. |
rules_link_check_visibility | |
rules_link_entity_info | Implements hook_entity_info(). |
rules_link_entity_view | Implement hook_entity_view(). |
rules_link_features_pipe_rules_link_alter | Implements hook_features_pipe_component_alter() for fields. |
rules_link_field_extra_fields | Implements hook_field_extra_fields(). |
rules_link_get_condition_set_name | Returns the name condition set to a rules link. |
rules_link_get_links | Gets an array of all rules links, keyed by the type name. |
rules_link_get_paramters | |
rules_link_get_rules_set_name | Returns the name condition set to a rules link. |
rules_link_get_token | Generates a token used to protect links from spoofing. |
rules_link_invoke_component | |
rules_link_load | Menu argument loader; Load a rules link by string. |
rules_link_load_condition_set | Loads and returns the condition to a link. If it doesn't exist, a new one will be created. |
rules_link_load_rules_set | Loads and returns the rules set to a link. If it doesn't exist, a new one will be created. |
rules_link_menu | Implements hook_menu(). |
rules_link_menu_breadcrumb_alter | Alter the breadcrumb trail of the rules components. |
rules_link_permission | Implements hook_permission(). |
rules_link_render | Renders a link using the name of the rules_link and the entity id. |
rules_link_render_link | Renders a link. |
rules_link_rules_link_delete | Implements hook_rules_link_delete(). |
rules_link_rules_link_insert | Implements hook_rules_link_insert(). |
rules_link_rules_link_update | Implements hook_rules_link_update(). |
rules_link_theme | Implements hook_theme(). |
rules_link_theme_registry_alter | Implements hook_theme_registry_alter(). |
rules_link_tokens | Implements hook_tokens(). |
rules_link_token_info | Implements hook_token_info(). |
rules_link_token_info_alter | Implements hook_token_info_alter(). |
rules_link_trigger | Triggers a rule set from a rules link. |
rules_link_trigger_form | Form generator for the menu callback for the confirm form links. |
rules_link_trigger_form_submit | Submit function for the confirm form links. |
rules_link_trigger_js | Menu callback for javascript links. |
rules_link_trigger_token | Menu callback for token links. |
rules_link_trim_parameters | Trims a whitespaces from a parameter. |
rules_link_views_api | Implements hook_views_api(). |
template_preprocess_rules_link |