View source
<?php
define('CUSTOMFILTER_API', '1.2');
function customfilter_filter_info() {
$filters = _customfilter_get_filters();
$itens = array();
foreach ($filters as $filter) {
$itens[$filter['type']] = array(
'title' => $filter['name'],
'description' => $filter['description'],
'process callback' => '_customfilter_filter_process',
'default settings' => array(
'allowed_html' => '',
'filter_html_help' => 1,
'filter_html_nofollow' => 0,
),
'tips callback' => '_customfilter_filter_tips',
);
}
return $itens;
}
function _customfilter_filter_tips($filter, $format, $long = FALSE) {
$col = $long ? 'longtip' : 'shorttip';
$filters = _customfilter_get_filters();
foreach ($filters as $item) {
if ($item['type'] == $filter->name) {
return $item[$col];
}
}
return '';
}
function _customfilter_filter_process($text, $filter, $format) {
if (empty($text)) {
return '';
}
$filters = _customfilter_get_filters();
$item = '';
foreach ($filters as $itens) {
if ($itens['type'] == $filter->name) {
$item = $itens;
}
}
if (!$item) {
return $text;
}
$globals =& _customfilter_globals('push');
$globals->text = $text;
$result = db_query("SELECT fid FROM {customfilter_filter} WHERE name = :name", array(
':name' => $item['name'],
))
->fetchField();
$rules = _customfilter_get_rules($result);
if (is_array($rules) && count($rules)) {
_customfilter_code_vars(TRUE);
$globals->stack = array();
foreach ($rules as $rule) {
if ($rule['enabled']) {
$globals->stack[] = $rule;
$globals->text = preg_replace_callback($rule['pattern'], '_customfilter_process', $globals->text);
array_pop($globals->stack);
}
}
}
$result = $globals->text;
_customfilter_globals('pop');
return $result;
}
function customfilter_flush_caches() {
return array(
'cache_customfilter',
);
}
function customfilter_help($path, $arg) {
$help = '';
switch ($path) {
case 'admin/modules#description':
$help = t('Allows the users with the right permission to create custom filters.');
break;
case 'admin/config/content/customfilter':
$help = '<p>' . t('Custom filter provides the ability for creating user defined filters using regular expressions. Instead of creating filter modules, users can create their own filter for specific site purpose.') . '</p>';
$help .= '<p>' . t('A filter is a collection of replacement rules. Each filter will appear in the input format settings page. Click on the filter name to see its replacement rules.') . '</p>';
break;
case 'admin/config/content/customfilter/%/add':
case 'admin/config/content/customfilter/%/%':
case 'admin/config/content/customfilter/%/%/edit':
case 'admin/config/content/customfilter/%/%/add':
$help = '<p>' . t('For more information about the regular expressions syntax, see <a href="http://www.php.net/manual/en/regexp.reference.php">Regular expression details</a>.') . '</p>';
break;
}
return $help;
}
function customfilter_menu() {
$access = array(
'administer customfilter',
);
$items = array();
$items['admin/config/content/customfilter'] = array(
'title' => 'Custom filters',
'description' => 'Allow the users to define custom filters.',
'page callback' => 'customfilter_settings',
'access arguments' => $access,
);
$items['admin/config/content/customfilter/list'] = array(
'title' => 'Filters',
'access arguments' => $access,
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -1,
);
$items['admin/config/content/customfilter/add'] = array(
'title' => 'Add filter',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'customfilter_filter_add',
),
'access arguments' => $access,
'type' => MENU_LOCAL_TASK,
);
$items['admin/config/content/customfilter/tools'] = array(
'title' => 'Tools',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'customfilter_export_form',
),
'access arguments' => $access,
'type' => MENU_LOCAL_TASK,
);
$items['admin/config/content/customfilter/tools/export'] = array(
'title' => 'Export',
'access arguments' => $access,
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/config/content/customfilter/tools/import'] = array(
'title' => 'Import',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'customfilter_import_form',
),
'access arguments' => $access,
'type' => MENU_LOCAL_TASK,
);
$items['admin/config/content/customfilter/%'] = array(
'title' => 'Rules',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'customfilter_rules_form',
4,
),
'access arguments' => $access,
'type' => MENU_CALLBACK,
);
$items['admin/config/content/customfilter/%/list'] = array(
'title' => 'List rules',
'access arguments' => $access,
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -1,
);
$items['admin/config/content/customfilter/%/edit'] = array(
'title' => 'Edit filter',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'customfilter_filter_edit',
4,
),
'access arguments' => $access,
'type' => MENU_CALLBACK,
);
$items['admin/config/content/customfilter/%/delete'] = array(
'title' => 'Delete filter',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'customfilter_filter_delete',
4,
),
'access arguments' => $access,
'type' => MENU_CALLBACK,
'weight' => 2,
);
$items['admin/config/content/customfilter/%/add'] = array(
'title' => 'Add rule',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'customfilter_rule_edit',
'add',
4,
),
'access arguments' => $access,
'type' => MENU_LOCAL_TASK,
'weight' => 4,
);
$items['admin/config/content/customfilter/%/%'] = array(
'title' => 'Edit rule',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'customfilter_rule_edit',
'edit',
4,
5,
),
'access arguments' => $access,
'type' => MENU_CALLBACK,
);
$items['admin/config/content/customfilter/%/%/edit'] = array(
'title' => 'Edit rule',
'access arguments' => $access,
'type' => MENU_CALLBACK,
'weight' => -1,
);
$items['admin/config/content/customfilter/%/%/delete'] = array(
'title' => 'Delete rule',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'customfilter_rule_delete',
5,
),
'access arguments' => $access,
'type' => MENU_CALLBACK,
);
$items['admin/config/content/customfilter/%/%/add'] = array(
'title' => 'Add subrule',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'customfilter_rule_edit',
'add',
4,
5,
),
'access arguments' => $access,
'type' => MENU_CALLBACK,
);
return $items;
}
function customfilter_permission() {
$perm = array(
'administer customfilter' => array(
'title' => t('administer customfilter'),
'description' => t('Administer the module customfilter, which allows the
creation of custom filters'),
'restrict access' => TRUE,
),
);
return $perm;
}
function customfilter_theme($existing, $type, $theme, $path) {
return array(
'customfilter_rules_form' => array(
'arguments' => array(
'form',
),
'render element' => 'form',
),
);
}
function customfilter_cache_clear($fid = NULL) {
cache_clear_all('filters', 'cache_customfilter');
cache_clear_all(isset($fid) ? "rules:{$fid}" : 'rules', 'cache_customfilter', TRUE);
}
function _customfilter_breadcrumb($page_breadcrumb = array()) {
$base = array(
l(t('Home'), NULL),
l(t('Administer'), 'admin'),
l(t('Site configuration'), 'admin/config'),
l(t('Content'), 'admin/config/content'),
l(t('Custom filters'), 'admin/config/content/customfilter'),
);
if (count($page_breadcrumb)) {
drupal_set_breadcrumb(array_merge($base, $page_breadcrumb));
}
else {
drupal_set_breadcrumb($base);
}
}
function _customfilter_delete_rule($rid) {
$result = db_query("SELECT * FROM {customfilter_rule} where prid = :rid", array(
':rid' => $rid,
));
foreach ($result as $rule) {
_customfilter_delete_rule($rule->rid);
}
db_delete('customfilter_rule')
->condition('rid', $rid)
->execute();
}
function _customfilter_get_filters() {
if ($cache = cache_get('filters', 'cache_customfilter')) {
$filters = $cache->data;
}
else {
$filters = array();
$result = db_query("SELECT * FROM {customfilter_filter} ORDER BY name");
while ($filter = $result
->fetchAssoc()) {
$filters[$filter['fid']] = $filter;
}
cache_set('filters', $filters, 'cache_customfilter');
}
return $filters;
}
function _customfilter_get_rules($fid, $root = 0, $nocache = FALSE) {
if (!$nocache && ($cache = cache_get("rules:{$fid}:{$root}", 'cache_customfilter'))) {
$rules = $cache->data;
}
else {
$rules = array();
$result = db_query("SELECT * FROM {customfilter_rule} WHERE fid = :fid and prid = :prid ORDER BY weight", array(
':fid' => $fid,
':prid' => $root,
));
while ($rule = $result
->fetchAssoc()) {
$rule['sub'] = _customfilter_get_rules($fid, $rule['rid'], TRUE);
$rules[$rule['rid']] = $rule;
}
if (!$nocache) {
cache_set("rules:{$fid}:{$root}", $rules, 'cache_customfilter');
}
}
return $rules;
}
function &_customfilter_code_vars($reset = FALSE) {
static $vars;
if (!isset($vars) || $reset) {
$vars = new stdClass();
}
return $vars;
}
function &_customfilter_globals($op = '') {
static $globals = array(), $index = 0;
if ($op == 'push') {
$globals[++$index] = new stdClass();
}
elseif ($op == 'pop' && $index) {
unset($globals[$index--]);
}
return $globals[$index];
}
function _customfilter_process($matches) {
$globals =& _customfilter_globals();
$result = $matches[0];
$rule = end($globals->stack);
$code = $rule['code'];
$pattern = $rule['pattern'];
$replacement = $rule['replacement'];
if (is_array($sub = $rule['sub']) && count($sub)) {
foreach ($sub as $subrule) {
if ($subrule['enabled']) {
$globals->stack[] = $subrule;
$substr =& $matches[$subrule['matches']];
$substr = preg_replace_callback($subrule['pattern'], '_customfilter_process', $substr);
array_pop($globals->stack);
}
}
if ($code) {
_customfilter_replace_callback($replacement, TRUE);
$result = _customfilter_replace_callback($matches);
}
else {
$result = $replacement;
$rmatches = array();
$reps = array();
preg_match_all('/([^\\\\]|^)(\\$([0-9]{1,2}|\\{([0-9]{1,2})\\}))/', $replacement, $rmatches, PREG_OFFSET_CAPTURE);
foreach ($rmatches[4] as $key => $val) {
if ($val == '') {
$index = $rmatches[3][$key][0];
}
else {
$index = $rmatches[4][$key][0];
}
$offset = $rmatches[2][$key][1];
$length = strlen($rmatches[2][$key][0]);
$reps[] = array(
'index' => $index,
'offset' => $offset,
'length' => $length,
);
}
krsort($reps);
foreach ($reps as $rep) {
$result = substr_replace($result, $matches[$rep['index']], $rep['offset'], $rep['length']);
}
}
}
elseif ($code) {
_customfilter_replace_callback($replacement, TRUE);
$result = preg_replace_callback($pattern, '_customfilter_replace_callback', $result);
}
else {
$result = preg_replace($pattern, $replacement, $result);
}
return $result;
}
function _customfilter_replace_callback($matches, $init = FALSE) {
static $code;
if ($init) {
$code = $matches;
return;
}
$vars =& _customfilter_code_vars();
@eval($code);
return isset($result) ? $result : '';
}
function customfilter_export_form($variables, &$form_state) {
$form = array();
$filters = _customfilter_get_filters();
if (isset($_SESSION['customfilter_storage'])) {
$form_state['storage'] = $_SESSION['customfilter_storage'];
}
else {
$form_state['storage'] = NULL;
}
$step = isset($form_state['storage']['step']) ? $form_state['storage']['step'] : 1;
switch ($step) {
case 1:
if ($filters) {
foreach ($filters as $filter) {
$opt[$filter['fid']] = check_plain($filter['name']);
}
$form['#filters'] = $filters;
$form['filters'] = array(
'#type' => 'radios',
'#title' => t('Filters'),
'#description' => 'Choose the filter to export.',
'#options' => $opt,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Export',
);
}
else {
$form['filters'] = array(
'#value' => '<p>' . t('There are no custom filters defined.') . '</p>',
);
}
break;
case 2:
if ($form_state['storage']['export_data']) {
$form['export'] = array(
'#type' => 'textarea',
'#title' => t('Export data'),
'#description' => t('Copy the export text and paste it into the import form.'),
'#cols' => 60,
'#default_value' => $form_state['storage']['export_data'],
'#rows' => 40,
);
}
else {
$form['export'] = array(
'#value' => '<p>' . t('The selected filter has not been found in the database table.') . '</p>',
);
}
$form_state['storage']['step'] = 1;
break;
}
$_SESSION['customfilter_storage'] = $form_state['storage'];
return $form;
}
function customfilter_export_form_submit($form, &$form_state) {
$form_state['storage'] = $_SESSION['customfilter_storage'];
$step = isset($form_state['storage']['step']) ? $form_state['storage']['step'] : 1;
if ($step == 1) {
$export_data = array();
$fid = $form_state['values']['filters'];
$filters = $form['#filters'];
if ($filter = $filters[$fid]) {
$export_data[] = '$filter = array(';
$export_data[] = " 'fid' => _customfilter_map_filter_id('" . $filter['fid'] . "'),";
$export_data[] = " 'type' => base64_decode('" . base64_encode($filter['type']) . "'),";
$export_data[] = " 'name' => base64_decode('" . base64_encode($filter['name']) . "'),";
$export_data[] = " 'cache' => {$filter['cache']},";
$export_data[] = " 'description' => base64_decode('" . base64_encode($filter['description']) . "'),";
$export_data[] = " 'shorttip' => base64_decode('" . base64_encode($filter['shorttip']) . "'),";
$export_data[] = " 'longtip' => base64_decode('" . base64_encode($filter['longtip']) . "'),";
$export_data[] = ");";
$export_data[] = '';
$rules = array();
_customfilter_rules_tree($rules, $fid, 0);
foreach ($rules as $rule) {
$export_data[] = '$rules[] = array(';
$export_data[] = " 'rid' => _customfilter_map_rule_id('" . $rule['rid'] . "'),";
$export_data[] = " 'fid' => _customfilter_map_filter_id('" . $filter['fid'] . "'),";
$export_data[] = " 'prid' => _customfilter_map_rule_id('" . $rule['prid'] . "'),";
$export_data[] = " 'name' => base64_decode('" . base64_encode($rule['name']) . "'),";
$export_data[] = " 'description' => base64_decode('" . base64_encode($rule['description']) . "'),";
$export_data[] = " 'enabled' => {$rule['enabled']},";
$export_data[] = " 'matches' => base64_decode('" . base64_encode($rule['matches']) . "'),";
$export_data[] = " 'pattern' => base64_decode('" . base64_encode($rule['pattern']) . "'),";
$export_data[] = " 'replacement' => base64_decode('" . base64_encode($rule['replacement']) . "'),";
$export_data[] = " 'code' => {$rule['code']},";
$export_data[] = " 'weight' => {$rule['weight']},";
$export_data[] = ");";
}
}
$form_state['storage']['step'] = 2;
$form_state['storage']['export_data'] = count($export_data) ? implode("\n", $export_data) : '';
$_SESSION['customfilter_storage'] = $form_state['storage'];
}
}
function customfilter_filter_add() {
$fid = (int) db_query("SELECT MAX(fid) FROM {customfilter_filter}")
->fetchField() + 1;
if ($fid > 128) {
drupal_set_message(t('It is not possible to add further filters; the limit of 128 filters has been reached.'), 'error');
return $form;
}
$item = array(
'fid' => $fid,
'type' => "filter_{$fid}",
'name' => t('Filter #!fid', array(
'!fid' => $fid,
)),
'cache' => 1,
'description' => '',
'shorttip' => '',
'longtip' => '',
);
_customfilter_filter_add_edit_fields($form, $item);
return $form;
}
function customfilter_filter_add_validate($form, &$form_state) {
if (!empty($form_state['values']['type'])) {
$type[] = trim($form_state['values']['type']);
if (!preg_match('!^[a-z0-9_]+$!', $type[0])) {
form_set_error('type', t('The machine-readable name must contain only lowercase letters, numbers, and underscores.'));
}
elseif (db_query("SELECT count(*) FROM {customfilter_filter} WHERE type = ':type'", array(
':type' => $type,
))
->fetchField()) {
form_set_error('type', t('The machine-readable name must be unique.'));
}
}
}
function customfilter_filter_add_submit($form, &$form_state) {
drupal_write_record('customfilter_filter', $form_state['values']);
customfilter_cache_clear('filters', $form_state['values']['fid']);
$form_state['redirect'] = 'admin/config/content/customfilter';
}
function customfilter_filter_delete($variables, $form_state, $fid) {
$filters = _customfilter_get_filters();
$form = array();
_customfilter_breadcrumb();
if (!$fid || !isset($filters[$fid])) {
drupal_set_message(t('The filter data have not been found, or the menu callback received a wrong parameter.'), 'error');
watchdog('customfilter', 'The filter data have not been found, or the menu callback received a wrong parameter.', NULL, WATCHDOG_ERROR);
return $form;
}
$form['#fid'] = $fid;
return confirm_form($form, t('Are you sure you want to delete %name?', array(
'%name' => $filters[$fid]['name'],
)), 'admin/config/content/customfilter', NULL, t('Delete'));
}
function customfilter_filter_delete_submit($form, $form_state) {
$fid = $form['#fid'];
db_delete('customfilter_rule')
->condition('fid', $fid)
->execute();
db_delete('customfilter_filter')
->condition('fid', $fid)
->execute();
customfilter_cache_clear($fid);
drupal_goto('admin/config/content/customfilter');
}
function customfilter_filter_edit($vars, $form_state, $fid) {
$form = array();
$filters = _customfilter_get_filters();
$item = $filters[$fid];
_customfilter_breadcrumb();
if (!$fid || !isset($filters[$fid])) {
drupal_set_message(t('The filter data have not been found, or the menu callback received a wrong parameter.'), 'error');
watchdog('customfilter', 'The filter data have not been found, or the menu callback received a wrong parameter.', NULL, WATCHDOG_ERROR);
return $form;
}
_customfilter_filter_add_edit_fields($form, $item);
return $form;
}
function customfilter_filter_edit_validate($form, &$form_state) {
if (!empty($form_state['values']['type'])) {
$type = trim($form_state['values']['type']);
if (!preg_match('!^[a-z0-9_]+$!', $type)) {
form_set_error('type', t('The machine-readable name must contain only lowercase letters, numbers, and underscores.'));
}
elseif (db_query("SELECT count(*) FROM {customfilter_filter} WHERE type = :type AND fid <> :fid", array(
':type' => $type,
':fid' => $form_state['values']['fid'],
))
->fetchField()) {
form_set_error('type', t('The machine-readable name must be unique.'));
}
}
}
function customfilter_filter_edit_submit($form, &$form_state) {
drupal_write_record('customfilter_filter', $form_state['values'], 'fid');
customfilter_cache_clear($form_state['values']['fid']);
$form_state['redirect'] = 'admin/config/content/customfilter';
}
function customfilter_import_form() {
$form = array();
$form['import'] = array(
'#type' => 'textarea',
'#title' => t('Import data'),
'#description' => t('Paste the text you obtained from the export form.'),
'#cols' => 60,
'#default_value' => '',
'#rows' => 40,
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Import'),
);
return $form;
}
function customfilter_import_form_validate($form, &$form_state) {
@eval($form_state['values']['import']);
if (!isset($filter) || !isset($rules) || !is_array($filter) || !is_array($rules)) {
form_set_error('import', t('The imported data is not valid.'));
return;
}
$form_state['filter'] = $filter;
$form_state['rules'] = $rules;
}
function customfilter_import_form_submit($form, &$form_state) {
drupal_write_record('customfilter_filter', $form_state['filter']);
foreach ($form_state['rules'] as $rule) {
drupal_write_record('customfilter_rule', $rule);
}
customfilter_cache_clear();
drupal_set_message(format_plural(count($form_state['rules']), '1 replacement rule has been imported.', '@count replacement rules have been imported.'));
$form_state['redirect'] = 'admin/config/content/customfilter';
}
function customfilter_rules_form($variables, &$form_state, $fid, $rid = 0) {
$form = array(
'#tree' => TRUE,
);
$rules = _customfilter_get_rules($fid, $rid);
_customfilter_breadcrumb();
if (count($rules)) {
$form['fid'] = array(
'#type' => 'hidden',
'#value' => $fid,
);
$form['rules'] = _customfilter_rules_tree_form($rules, 0);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
}
return $form;
}
function customfilter_rules_form_submit($form, &$form_state) {
foreach ($form_state['values']['rules'] as $rule) {
drupal_write_record('customfilter_rule', $rule, 'rid');
}
customfilter_cache_clear($form_state['values']['fid']);
$form_state['redirect'] = "admin/config/content/customfilter/{$form_state['values']['fid']}";
}
function customfilter_rule_delete($vars, $form_state, $rid) {
$filters = _customfilter_get_filters();
$rule = db_query("SELECT * FROM {customfilter_rule} WHERE rid = :rid", array(
':rid' => $rid,
))
->fetchObject();
$rules_count = db_query("SELECT COUNT(*) FROM {customfilter_rule} WHERE prid = :rid", array(
':rid' => $rid,
))
->fetchField();
if ($rule === FALSE) {
drupal_set_message(t('The replacement rule has been deleted.'));
drupal_goto(isset($_REQUEST['destination']) ? $_REQUEST['destination'] : 'admin/config/content/customfilter');
}
if (isset($filters[$rule->fid])) {
_customfilter_breadcrumb(array(
l($filters[$rule->fid]['name'], "admin/config/content/customfilter/{$rule->fid}"),
));
}
$form = array(
'#fid' => $rule->fid,
'#rid' => $rid,
);
$msg_text = t('This action cannot be undone.');
if ($rules_count) {
$msg_text .= " <p>" . t('This rule has subrules. If you delete this rule, they will be deleted too.') . "</p>";
}
return confirm_form($form, t('Are you sure you want to delete the replacement rule %name?', array(
'%name' => $rule->name,
)), "admin/config/content/customfilter/{$rule->fid}", $msg_text, t('Delete'));
}
function customfilter_rule_delete_submit($form, &$form_state) {
_customfilter_delete_rule($form['#rid']);
customfilter_cache_clear($form_state['values']['fid']);
$form_state['redirect'] = 'admin/config/content/customfilter/' . $form['#fid'];
}
function customfilter_rules_form_edit($variables, $form_state, $op, $fid, $rid = 0) {
$filters = _customfilter_get_filters();
$form = array();
if (isset($filters[$fid])) {
_customfilter_breadcrumb(array(
l($filters[$fid]['name'], "admin/config/content/customfilter/{$fid}"),
));
}
if ($op == 'edit') {
$item = db_fetch_array(db_query("SELECT * FROM {customfilter_rule} WHERE rid = %d", $rid));
}
elseif ($op == 'add') {
$item = array(
'rid' => (int) db_query("SELECT MAX(rid) FROM {customfilter_rule}")
->fetchField() + 1,
'prid' => $rid,
'fid' => $fid,
'name' => '$1',
'description' => '',
'enabled' => 1,
'matches' => 1,
'pattern' => '/regex/i',
'replacement' => 'Regular Expressions',
'code' => 0,
'weight' => 0,
);
}
$matchopt = drupal_map_assoc(range(0, 99));
$form['rid'] = array(
'#type' => 'value',
'#value' => $item['rid'],
);
$form['fid'] = array(
'#type' => 'value',
'#value' => $fid,
);
$form['prid'] = array(
'#type' => 'value',
'#value' => $item['prid'],
);
$form['operation'] = array(
'#type' => 'value',
'#value' => $op,
);
if ($item['prid'] != 0) {
$form['matches'] = array(
'#type' => 'select',
'#title' => t('# Match'),
'#description' => t('n-th matched substring in parent rule. This replacement rule will replace only for that substring.'),
'#options' => $matchopt,
'#default_value' => $item['matches'],
);
}
$form['name'] = array(
'#type' => 'textfield',
'#description' => t('The name of this replacement rule.'),
'#title' => t('Name'),
'#default_value' => $item['name'],
'#required' => TRUE,
);
$form['weight'] = array(
'#title' => t('Weight'),
'#default_value' => $item['weight'],
);
$form['enabled'] = array(
'#type' => 'checkbox',
'#title' => t('Enabled'),
'#description' => t('If selected, the rule is used.'),
'#default_value' => $item['enabled'],
);
$form['description'] = array(
'#type' => 'textarea',
'#title' => t('Description'),
'#description' => t('The description of this rule.'),
'#default_value' => $item['description'],
);
$form['pattern'] = array(
'#type' => 'textarea',
'#title' => t('Pattern'),
'#description' => t('The regular expression to use. Look at <a href="http://www.php.net/manual/en/regexp.reference.php">Regular Expression Details</a> for more help.'),
'#default_value' => $item['pattern'],
'#rows' => 3,
);
$form['code'] = array(
'#type' => 'checkbox',
'#title' => t('PHP Code'),
'#description' => t('If selected, the replacement text is PHP code.'),
'#default_value' => $item['code'],
);
$form['replacement']['replacement'] = array(
'#type' => 'textarea',
'#title' => t('Replacement text'),
'#description' => t('The replacement text that will replace the matched string. Use $n (i.e. $1, $25) or ${n} (i.e. ${1}, ${25}), with n range from 0 to 99, to get the n-th original strings matched ($0 represents the entire matched string). If you select <strong>PHP Code</strong>, you can enter PHP code that will be executed during the elaboration of the rules. n-th matched string is provided in <code>$matches[n]</code>, and there is a global variable <code>$vars</code> you can use to store values that will be kept during the execution of different rules of the same filter. PHP code must set a value for <code>$result</code>, and must not be entered between <code><</code><code>?php ?></code>. Note that executing incorrect PHP-code can break your Drupal site.'),
'#default_value' => $item['replacement'],
'#rows' => 16,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
function customfilter_rule_edit($vars, $form_state, $op, $fid, $rid = 0) {
$filters = _customfilter_get_filters();
$form = array();
if (isset($filters[$fid])) {
_customfilter_breadcrumb(array(
l($filters[$fid]['name'], "admin/config/content/customfilter/{$fid}"),
));
}
if ($op == 'edit') {
$item = db_query("SELECT * FROM {customfilter_rule} WHERE rid = :rid", array(
':rid' => $rid,
))
->fetchAssoc();
}
elseif ($op == 'add') {
$item = array(
'rid' => (int) db_query("SELECT MAX(rid) FROM {customfilter_rule}")
->fetchField() + 1,
'prid' => $rid,
'fid' => $fid,
'name' => '$1',
'description' => '',
'enabled' => 1,
'matches' => 1,
'pattern' => '/regex/i',
'replacement' => 'Regular Expressions',
'code' => 0,
'weight' => 0,
);
}
$matchopt = drupal_map_assoc(range(0, 99));
$form['rid'] = array(
'#type' => 'value',
'#value' => $item['rid'],
);
$form['fid'] = array(
'#type' => 'value',
'#value' => $fid,
);
$form['prid'] = array(
'#type' => 'value',
'#value' => $item['prid'],
);
$form['operation'] = array(
'#type' => 'value',
'#value' => $op,
);
if ($item['prid'] != 0) {
$form['matches'] = array(
'#type' => 'select',
'#title' => t('# Match'),
'#description' => t('n-th matched substring in parent rule. This replacement rule will replace only for that substring.'),
'#options' => $matchopt,
'#default_value' => $item['matches'],
);
}
$form['name'] = array(
'#type' => 'textfield',
'#description' => t('The name of this replacement rule.'),
'#title' => t('Name'),
'#default_value' => $item['name'],
'#required' => TRUE,
);
$form['weight'] = array(
'#title' => t('Weight'),
'#default_value' => $item['weight'],
);
$form['enabled'] = array(
'#type' => 'checkbox',
'#title' => t('Enabled'),
'#description' => t('If selected, the rule is used.'),
'#default_value' => $item['enabled'],
);
$form['description'] = array(
'#type' => 'textarea',
'#title' => t('Description'),
'#description' => t('The description of this rule.'),
'#default_value' => $item['description'],
);
$form['pattern'] = array(
'#type' => 'textarea',
'#title' => t('Pattern'),
'#description' => t('The regular expression to use. Look at <a href="http://www.php.net/manual/en/regexp.reference.php">Regular Expression Details</a> for more help.'),
'#default_value' => $item['pattern'],
'#rows' => 3,
);
$form['code'] = array(
'#type' => 'checkbox',
'#title' => t('PHP Code'),
'#description' => t('If selected, the replacement text is PHP code.'),
'#default_value' => $item['code'],
);
$form['replacement']['replacement'] = array(
'#type' => 'textarea',
'#title' => t('Replacement text'),
'#description' => t('The replacement text that will replace the matched string. Use $n (i.e. $1, $25) or ${n} (i.e. ${1}, ${25}), with n range from 0 to 99, to get the n-th original strings matched ($0 represents the entire matched string). If you select <strong>PHP Code</strong>, you can enter PHP code that will be executed during the elaboration of the rules. n-th matched string is provided in <code>$matches[n]</code>, and there is a global variable <code>$vars</code> you can use to store values that will be kept during the execution of different rules of the same filter. PHP code must set a value for <code>$result</code>, and must not be entered between <code><</code><code>?php ?></code>. Note that executing incorrect PHP-code can break your Drupal site.'),
'#default_value' => $item['replacement'],
'#rows' => 16,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
function customfilter_rule_edit_submit($form, &$form_state) {
switch ($form_state['values']['operation']) {
case 'edit':
drupal_write_record('customfilter_rule', $form_state['values'], array(
'rid',
));
break;
case 'add':
drupal_write_record('customfilter_rule', $form_state['values']);
break;
}
customfilter_cache_clear($form_state['values']['fid']);
$form_state['redirect'] = "admin/config/content/customfilter/{$form_state['values']['fid']}";
}
function customfilter_settings() {
$rows = array();
foreach (_customfilter_get_filters() as $id => $filter) {
$row = array();
$row[] = l($filter['name'], "admin/config/content/customfilter/{$id}");
$row[] = l(t('edit'), "admin/config/content/customfilter/{$id}/edit");
$row[] = l(t('delete'), "admin/config/content/customfilter/{$id}/delete");
$rows[] = $row;
}
if (!count($rows)) {
$rows[] = array(
array(
'data' => t('No filters have been defined.'),
'colspan' => 3,
),
);
}
$header[] = t('Name');
$header[] = array(
'data' => t('Operations'),
'colspan' => '2',
);
$variables["rows"] = $rows;
$variables["header"] = $header;
return theme('table', $variables);
}
function theme_customfilter_rules_form($vars) {
$form = $vars['form'];
$rows = array();
if (isset($form['rules'])) {
foreach (element_children($form['rules']) as $rid) {
$row = array();
$element =& $form['rules'][$rid];
$element['prid']['#attributes']['class'] = array(
'rule-prid',
);
$element['rid']['#attributes']['class'] = array(
'rule-rid',
);
$element['weight']['#attributes']['class'] = array(
'rule-weight',
);
$row[] = theme('indentation', array(
'size' => $element['level']['#value'],
)) . $element['name']['#value'];
$row[] = drupal_render($element['rid']) . drupal_render($element['prid']) . drupal_render($element['weight']);
$row[] = drupal_render($element['enabled']);
$row[] = $element['operations']['add']['#value'];
$row[] = $element['operations']['edit']['#value'];
$row[] = $element['operations']['delete']['#value'];
$rows[] = array(
'data' => $row,
'class' => array(
'draggable',
),
);
}
}
if (!count($rows)) {
$rows[] = array(
array(
'data' => t('There are no replacement rules currently defined.'),
'colspan' => '6',
),
);
}
$header[] = t('Name');
$header[] = t('Weight');
$header[] = t('Enabled');
$header[] = array(
'data' => t('Operations'),
'colspan' => '3',
);
drupal_add_tabledrag('customfilter-rules-tree', 'order', 'sibling', 'rule-weight', NULL, NULL, TRUE);
drupal_add_tabledrag('customfilter-rules-tree', 'match', 'parent', 'rule-prid', 'rule-prid', 'rule-rid', TRUE);
$args['header'] = $header;
$args['rows'] = $rows;
$args['attributes'] = array(
'id' => 'customfilter-rules-tree',
);
$args['caption'] = null;
$args['colgroups'] = array();
$args['sticky'] = false;
$args['empty'] = null;
return theme('table', $args) . drupal_render_children($form);
}
function _customfilter_filter_add_edit_fields(&$form, $item) {
$form['fid'] = array(
'#type' => 'value',
'#value' => $item['fid'],
);
$form['type'] = array(
'#type' => 'textfield',
'#title' => t('Type'),
'#description' => t('The machine-readable name of the filter. This name must contain only lowercase letters, numbers, and underscores.'),
'#default_value' => $item['type'],
'#maxlength' => 32,
'#required' => TRUE,
);
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#description' => t('The human-readable name of the filter. It is recommended that this name begin with a capital letter and contain only letters, numbers, and <em>spaces</em>.'),
'#default_value' => $item['name'],
'#maxlength' => 64,
'#required' => TRUE,
);
$form['cache'] = array(
'#type' => 'checkbox',
'#title' => t('Cache'),
'#description' => t('If checked, the content will be cached.'),
'#default_value' => $item['cache'],
);
$form['description'] = array(
'#type' => 'textarea',
'#title' => t('Description'),
'#description' => t('A description of the purpose of this filter.'),
'#default_value' => $item['description'],
);
$form['shorttip'] = array(
'#type' => 'textarea',
'#title' => t('Tips (short)'),
'#default_value' => $item['shorttip'],
'#rows' => 5,
);
$form['longtip'] = array(
'#type' => 'textarea',
'#title' => t('Tips (full)'),
'#default_value' => $item['longtip'],
'#rows' => 20,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
}
function _customfilter_map_filter_id($id) {
static $base = 0, $fids = array();
if (!$base) {
$base = (int) db_query("SELECT MAX(fid) FROM {customfilter_filter}")
->fetchField() + 1;
}
if (!isset($fids[$id])) {
$fids[$id] = $base++;
}
return $fids[$id];
}
function _customfilter_map_rule_id($id) {
static $base = 0, $rids = array();
if (!$id) {
return 0;
}
if (!$base) {
$base = (int) db_query("SELECT MAX(rid) FROM {customfilter_rule}")
->fetchField() + 1;
}
if (!isset($rids[$id])) {
$rids[$id] = $base++;
}
return $rids[$id];
}
function _customfilter_rules_tree(&$rules, $fid, $prid = 0) {
$result = db_query("SELECT * FROM {customfilter_rule} WHERE fid = :fid and prid = :prid ORDER BY weight", array(
':fid' => $fid,
':prid' => $prid,
));
while ($rule = $result
->fetchAssoc()) {
$rules[] = $rule;
_customfilter_rules_tree($rules, $fid, $rule['rid']);
}
}
function _customfilter_rules_tree_form($rules, $level = 0) {
$base = 'admin/config/content/customfilter';
$form = array();
foreach ($rules as $rule) {
$fid = $rule['fid'];
$rid = $rule['rid'];
$form[$rid] = array(
'name' => array(
'#value' => l($rule['name'], "{$base}/{$fid}/{$rid}/edit"),
),
'enabled' => array(
'#type' => 'checkbox',
'#default_value' => $rule['enabled'],
),
'weight' => array(
'#type' => 'weight',
'#default_value' => $rule['weight'],
),
'rid' => array(
'#type' => 'hidden',
'#value' => $rid,
),
'prid' => array(
'#type' => 'textfield',
'#default_value' => $rule['prid'],
'#size' => 4,
),
'level' => array(
'#type' => 'value',
'#value' => $level,
),
);
$form[$rid]['operations'] = array(
'add' => array(
'#value' => l(t('add'), "{$base}/{$fid}/{$rid}/add"),
),
'edit' => array(
'#value' => l(t('edit'), "{$base}/{$fid}/{$rid}/edit"),
),
'delete' => array(
'#value' => l(t('delete'), "{$base}/{$fid}/{$rid}/delete"),
),
);
if ($rule['sub']) {
$form += _customfilter_rules_tree_form($rule['sub'], $level + 1);
}
}
return $form;
}