View source
<?php
define('CUSTOMFILTER_CODE_DECLARE', 'global $_customfilter_code_vars; $vars = & $_customfilter_code_vars;');
global $_customfilter_code_vars;
global $_customfilter_globals;
function customfilter_filter($op, $delta = 0, $format = -1, $text = '') {
switch ($op) {
case 'list':
return _customfilter_filter_list();
case 'no cache':
return !_customfilter_filter_cache($delta);
case 'description':
return _customfilter_filter_desc($delta);
case 'prepare':
return $text;
case 'process':
return _customfilter_process($delta, $format, $text);
default:
return $text;
}
}
function customfilter_filter_tips($delta, $format, $long = FALSE) {
$col = $long ? 'longtips' : 'shorttips';
$tips = customfilter_get_set($delta, array(
'sid',
$col,
));
return isset($tips[$col]) ? $tips[$col] : '';
}
function customfilter_help($section) {
$arg3 = arg(3);
$arg4 = arg(4);
$help = '';
$sid = isset($arg3) && is_numeric($arg3) ? $arg3 : '';
$fid = isset($arg4) && is_numeric($arg4) ? $arg4 : '';
switch ($section) {
case "admin/modules#description":
$help = t('Custom Filter');
break;
case "admin/settings/customfilter":
$help = '<p>' . t('Custom Filter provides an 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>';
if (count(customfilter_get_sets()) > 0) {
$help .= '<p>' . t('Below are the filter sets. ');
}
else {
$help .= '<p>' . t('Before you can use custom filters, you must have at least one filter set. ');
}
$help .= t('Filter set is a container of filters. Each will appear in Input Format configuration. Click at their name to see what filter they have.') . '</p>';
break;
case "admin/settings/customfilter/export":
$help = '<p>' . t('You can export your custom filters as XML document. Just check filters you want to export below, and click the button Export.') . '</p>';
break;
case "admin/settings/customfilter/import":
$help = '<p>' . t('You can import custom filters from an XML file.') . '</p>';
break;
case "admin/settings/customfilter/{$sid}":
$help = '<p>' . t('This filterset has filters listed below. Each filter can have subfilters.') . '</p>';
break;
case "admin/settings/customfilter/add":
case "admin/settings/customfilter/{$sid}/edit":
$help = '<p>' . t('Give this filter set some name and description.') . '</p>';
break;
case "admin/settings/customfilter/{$sid}/add":
case "admin/settings/customfilter/{$sid}/{$fid}":
case "admin/settings/customfilter/{$sid}/{$fid}/edit":
case "admin/settings/customfilter/{$sid}/{$fid}/add":
$help = '<p>' . t('Here you can define your own filters using regular expressions. For some information about regular expressions, please look at ') . l('http://www.regular-expressions.info', 'http://www.regular-expressions.info') . '</p>';
break;
}
return $help;
}
function customfilter_menu($may_cache) {
$access = user_access('administer customfilter');
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'admin/settings/customfilter',
'title' => t('Custom Filter'),
'description' => t('User defined filters.'),
'callback' => 'customfilter_settings',
'access' => $access,
'type' => MENU_NORMAL_ITEM,
);
$items[] = array(
'path' => 'admin/settings/customfilter/list',
'title' => t('List'),
'access' => $access,
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 1,
);
$items[] = array(
'path' => 'admin/settings/customfilter/add',
'title' => t('Add filter set'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'customfilter_set_edit',
'add',
),
'access' => $access,
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
$items[] = array(
'path' => 'admin/settings/customfilter/export',
'title' => t('Export'),
'callback' => 'drupal_get_form',
'access' => $access,
'callback arguments' => array(
'customfilter_export_form',
),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
$items[] = array(
'path' => 'admin/settings/customfilter/import',
'title' => t('Import'),
'callback' => 'drupal_get_form',
'access' => $access,
'callback arguments' => array(
'customfilter_import_form',
),
'type' => MENU_LOCAL_TASK,
'weight' => 4,
);
$items[] = array(
'path' => 'admin/settings/customfilter/export/xml',
'title' => t('XML'),
'callback' => 'customfilter_xml_export',
'access' => $access,
'type' => MENU_CALLBACK,
);
}
else {
$arg0 = arg(0);
$arg1 = arg(1);
$arg2 = arg(2);
$arg3 = arg(3);
$arg4 = arg(4);
$bool = isset($arg0) && $arg0 == 'admin' && isset($arg1) && $arg1 == 'settings' && isset($arg2) && $arg2 == 'customfilter' && isset($arg3) && is_numeric($arg3);
if ($bool) {
$sid = $arg3;
$set = customfilter_get_set($sid, 'name');
if ($set) {
$items[] = array(
'path' => "admin/settings/customfilter/{$sid}",
'title' => t("Custom filter: {$set['name']}"),
'callback' => 'customfilter_filters',
'callback arguments' => array(
arg(3),
),
'access' => $access,
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => "admin/settings/customfilter/{$sid}/list",
'title' => t('List'),
'access' => $access,
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 1,
);
$items[] = array(
'path' => "admin/settings/customfilter/{$sid}/edit",
'title' => t('Edit'),
'callback' => 'drupal_get_form',
'access' => $access,
'callback arguments' => array(
'customfilter_set_edit',
'edit',
$sid,
),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
$items[] = array(
'path' => "admin/settings/customfilter/{$sid}/delete",
'title' => t('Delete'),
'callback' => 'drupal_get_form',
'access' => $access,
'callback arguments' => array(
'customfilter_set_delete',
$sid,
),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
$items[] = array(
'path' => "admin/settings/customfilter/{$sid}/add",
'title' => t('Add filter'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'customfilter_filter_edit',
'add',
$sid,
),
'access' => $access,
'type' => MENU_LOCAL_TASK,
'weight' => 4,
);
if (isset($arg4) && is_numeric($arg4)) {
$fid = $arg4;
$filter = customfilter_get_filter($fid, '*');
$items[] = array(
'path' => "admin/settings/customfilter/{$sid}/{$fid}",
'title' => t("Filter: {$filter['name']}"),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'customfilter_filter_edit',
'edit',
$sid,
$fid,
),
'access' => $access,
'type' => MENU_CALLBACK,
);
$items[] = array(
'path' => "admin/settings/customfilter/{$sid}/{$fid}/edit",
'title' => t('Edit'),
'access' => $access,
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 1,
);
$items[] = array(
'path' => "admin/settings/customfilter/{$sid}/{$fid}/delete",
'title' => t('Delete filter'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'customfilter_filter_delete',
$fid,
),
'access' => $access,
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
$items[] = array(
'path' => "admin/settings/customfilter/{$sid}/{$fid}/add",
'title' => t('Add subfilter'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'customfilter_filter_edit',
'add',
$sid,
$fid,
),
'access' => $access,
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
}
}
}
}
return $items;
}
function customfilter_perm() {
return array(
'administer customfilter',
);
}
function customfilter_export_form() {
$form = array();
$sets = customfilter_get_sets();
foreach ($sets as $set) {
$opt[$set['sid']] = $set['name'];
}
$form['sets'] = array(
'#type' => 'checkboxes',
'#title' => t('Filter sets'),
'#options' => $opt,
'#description' => 'Choose filter sets.',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Export',
);
return $form;
}
function customfilter_export_form_submit($form_id, $form_values) {
$sids = array();
foreach ($form_values['sets'] as $sid) {
if ($sid > 0) {
$sids[] = $sid;
}
}
$arg = join('.', $sids);
return "admin/settings/customfilter/export/xml/{$arg}";
}
function customfilter_filters($sid) {
return customfilter_filter_render_table($sid, 0);
}
function customfilter_import_form() {
$form = array();
$form['xml'] = array(
'#type' => 'file',
'#title' => t('Import from file'),
'#description' => t('The XML file to be imported.'),
);
$form[] = array(
'#type' => 'submit',
'#value' => t('Import'),
);
$form['#attributes'] = array(
'enctype' => 'multipart/form-data',
);
return $form;
}
function customfilter_import_form_submit($form_id, $form_values) {
global $_customfilter_globals;
if (!isset($_customfilter_globals)) {
$_customfilter_globals = new stdClass();
}
$cg =& $_customfilter_globals;
if ($file = file_check_upload('xml')) {
if ($thefile = fopen($file->filepath, "rb")) {
$fstat = fstat($thefile);
$xml = fread($thefile, $fstat['size']);
fclose($thefile);
drupal_set_message(t('XML file %f imported.', array(
'%f' => $file->filename,
)));
customfilter_xml_read($xml);
_customfilter_xml_sql($cg->sets, $cg->filters);
}
}
}
function customfilter_set_delete($sid) {
$filters = customfilter_get_filters($sid);
$set = customfilter_get_set($sid, '*');
$form['sid'] = array(
'#type' => 'value',
'#value' => $sid,
);
$message = t('Are you sure you want to delete this filter set?');
$msg_text = "<h3>" . $set['name'] . "</h3>" . "<p>" . $set->description . "</p>";
if (count($filters) > 0) {
$msg_text .= "<p>" . t('This set has filters. If you delete this, they will be deleted too.') . "</p>" . customfilter_filter_render_table($sid, $fid, FALSE);
}
$msg_text .= "<p>" . t('This action cannot be undone.') . "</p>";
return confirm_form($form, $message, 'admin/settings/customfilter', $msg_text, t('Delete'));
}
function customfilter_set_delete_submit($form_id, $form_values) {
customfilter_delete_set($form_values['sid']);
return 'admin/settings/customfilter';
}
function customfilter_set_edit($op, $sid = 0) {
switch ($op) {
case 'edit':
$item = customfilter_get_set($sid, '*');
break;
case 'add':
$item = array(
'sid' => 0,
'name' => 'Filter set #',
'cache' => 1,
'description' => '',
'shorttips' => '',
'longtips' => '',
);
break;
}
$form['sid'] = array(
'#type' => 'value',
'#value' => $item['sid'],
);
$form['operation'] = array(
'#type' => 'value',
'#value' => $op,
);
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#default_value' => $item['name'],
'#description' => t('The name of the filter set.'),
'#required' => TRUE,
);
$form['cache'] = array(
'#type' => 'checkbox',
'#title' => t('Cache'),
'#default_value' => $item['cache'],
'#description' => t('If checked, the content will be cached (i.e. this filter will be executed once per content edit).'),
);
$form['description'] = array(
'#type' => 'textarea',
'#title' => t('Description'),
'#default_value' => $item['description'],
'#description' => t('Some text to describe this filter set.'),
);
$form['shorttips'] = array(
'#type' => 'textarea',
'#title' => t('Tips (short)'),
'#default_value' => $item['shorttips'],
'#description' => '',
);
$form['longtips'] = array(
'#type' => 'textarea',
'#title' => t('Tips (full)'),
'#default_value' => $item['longtips'],
'#description' => '',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
function customfilter_set_edit_submit($form_id, $form_values) {
switch ($form_values['operation']) {
case 'edit':
db_query("UPDATE {customfilter_set}\n SET name = '%s', cache = %d, description = '%s', shorttips = '%s', longtips = '%s'\n WHERE sid = %d", $form_values['name'], $form_values['cache'], $form_values['description'], $form_values['shorttips'], $form_values['longtips'], $form_values['sid']);
break;
case 'add':
$nextid = db_next_id('{customfilter_set}_sid');
db_query("INSERT INTO {customfilter_set} (sid, name, cache, description, shorttips, longtips) VALUES (%d, '%s', %d, '%s', '%s', '%s');", $nextid, $form_values['name'], $form_values['cache'], $form_values['description'], $form_values['shorttips'], $form_values['longtips']);
break;
}
return 'admin/settings/customfilter';
}
function customfilter_settings() {
$header = array(
t('Name'),
t('Description'),
array(
'data' => t('Operations'),
'colspan' => '2',
),
);
$rows = customfilter_set_get_rows();
$table = theme('table', $header, $rows ? $rows : array(
array(
array(
'data' => t('No custom filter defined.'),
'colspan' => 5,
),
),
));
return $table;
}
function customfilter_filter_delete($fid) {
$filter = db_fetch_object(db_query("SELECT * FROM {customfilter_filter} WHERE fid = %d", $fid));
$subfilter = db_fetch_object(db_query("SELECT * FROM {customfilter_filter} WHERE parentid = %d", $fid));
$form['fid'] = array(
'#type' => 'value',
'#value' => $fid,
);
$form['sid'] = array(
'#type' => 'value',
'#value' => $filter->sid,
);
$message = t('Are you sure you want to delete this custom filter?');
$msg_text = ($filter->parentid == 0 ? "<h3>{$filter->name}</h3>" : "") . "<p>{$filter->description}</p>" . "<h3>Pattern</h3>" . "<pre>{$filter->pattern}</pre>" . "<h3>Replacer</h3>" . "<pre>{$filter->replacer}</pre>";
if ($subfilter) {
$msg_text .= "<p>" . t('This filter has subfilters. If you delete this, they will be deleted too.') . "</p>" . customfilter_filter_render_table($filter->sid, $fid, FALSE);
}
$msg_text .= "<p>" . t('This action cannot be undone.') . "</p>";
return confirm_form($form, $message, "admin/settings/customfilter/{$filter->sid}", $msg_text, t('Delete'));
}
function customfilter_filter_delete_submit($form_id, $form_values) {
customfilter_delete_filter($form_values['fid']);
return "admin/settings/customfilter/{$form_values['sid']}";
}
function customfilter_filter_edit($op, $sid, $fid = 0) {
if ($op == 'edit') {
$item = customfilter_get_filter($fid, '*');
}
elseif ($op == 'add') {
$item = array(
'fid' => 0,
'parentid' => $fid,
'sid' => $sid,
'name' => '$1',
'description' => '',
'matches' => 1,
'pattern' => '/regex/i',
'replacement' => 'Regular Expressions',
'func' => 0,
'weight' => 0,
);
}
$matchopt = array();
for ($i = 0; $i <= 99; $i++) {
$matchopt[$i] = $i;
}
$form['fid'] = array(
'#type' => 'value',
'#value' => $item['fid'],
);
$form['sid'] = array(
'#type' => 'value',
'#value' => $sid,
);
$form['parentid'] = array(
'#type' => 'value',
'#value' => $item['parentid'],
);
$form['operation'] = array(
'#type' => 'value',
'#value' => $op,
);
if ($item['parentid'] != 0) {
$form['matches'] = array(
'#type' => 'select',
'#title' => t('# Match'),
'#options' => $matchopt,
'#default_value' => $item['matches'],
'#description' => t('Matches.'),
);
}
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Name'),
'#default_value' => $item['name'],
'#description' => t('The name of the filter.'),
'#required' => TRUE,
);
$form['pattern'] = array(
'#type' => 'textarea',
'#title' => t('Pattern'),
'#default_value' => $item['pattern'],
'#description' => t('Regular expression. Look at <a href="http://www.regular-expressions.info">http://www.regular-expressions.info</a> for more help.'),
);
$form['replacement'] = array(
'#type' => 'textarea',
'#title' => t('Replacement text'),
'#default_value' => $item['replacement'],
'#description' => t('Replacement Text. Matched string will be replaced with text supplied here. Use $n (e.g. $1, $25) or ${n} (e.g. ${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 set the <strong>PHP Code</strong> below, you can enter replaced text with some PHP Code. n-th matched string will be provided in $matches[n], and there will be a global variable named $vars you can use it for your own purpose. Don\'t forget to write the return statement.'),
);
$form['func'] = array(
'#type' => 'checkbox',
'#title' => t('PHP Code'),
'#default_value' => $item['func'],
'#description' => t('Check to allow using PHP code to replace the text.'),
);
$form['weight'] = array(
'#type' => 'weight',
'#title' => t('Weight'),
'#default_value' => $item['weight'],
'#description' => t('Filter weight.'),
);
$form['description'] = array(
'#type' => 'textarea',
'#title' => t('Description'),
'#default_value' => $item['description'],
'#description' => t('Some text to describe this filter.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save Configuration'),
);
return $form;
}
function customfilter_filter_edit_submit($form_id, $form_values) {
switch ($form_values['operation']) {
case 'edit':
db_query("UPDATE {customfilter_filter} SET sid = %d, parentid = %d, name = '%s', description = '%s', matches = %d, pattern = '%s', replacement = '%s', func = %d, weight = %d\n WHERE fid = %d", $form_values['sid'], $form_values['parentid'], $form_values['name'], $form_values['description'], $form_values['matches'], $form_values['pattern'], $form_values['replacement'], $form_values['func'], $form_values['weight'], $form_values['fid']);
break;
case 'add':
$nextid = db_next_id('{customfilter_filter}_fid');
db_query("INSERT INTO {customfilter_filter} (fid, sid, parentid, name, description, matches, pattern, replacement, func, weight) VALUES (%d, %d, %d, '%s', '%s', %d, '%s', '%s', %d, %d);", $nextid, $form_values['sid'], $form_values['parentid'], $form_values['name'], $form_values['description'], $form_values['matches'], $form_values['pattern'], $form_values['replacement'], $form_values['func'], $form_values['weight']);
break;
}
return "admin/settings/customfilter/{$form_values['sid']}";
}
function customfilter_delete_filter($fid) {
$result = db_query("SELECT * FROM {customfilter_filter} where parentid = %d", $fid);
while ($filter = db_fetch_object($result)) {
customfilter_delete_filter($filter->fid);
}
db_query("DELETE FROM {customfilter_filter} WHERE fid = %d", $fid);
}
function customfilter_delete_set($sid) {
$filters = customfilter_get_filters($sid);
foreach ($filters as $filter) {
customfilter_delete_filter($filter['fid']);
}
db_query('DELETE FROM {customfilter_set} WHERE sid = %d', $sid);
}
function customfilter_filter_get_rows($filters, $depth, &$rows, $op = TRUE) {
$rows = array();
foreach ($filters as $filter) {
$format = $depth == 0 ? "strong" : "em";
$row = array(
str_repeat('» ', $depth) . '<' . $format . '>' . $filter['name'] . '</' . $format . '>',
'<em>' . $filter['description'] . '</em>',
htmlspecialchars($filter['pattern']),
$filter['parentid'] == 0 ? "" : $filter['matches'],
$filter['weight'],
);
if ($op) {
$row[] = l(t('add'), "admin/settings/customfilter/{$filter['sid']}/{$filter['fid']}/add");
$row[] = l(t('edit'), "admin/settings/customfilter/{$filter['sid']}/{$filter['fid']}/edit");
$row[] = l(t('delete'), "admin/settings/customfilter/{$filter['sid']}/{$filter['fid']}/delete");
}
$rows[] = $row;
if (!empty($filter['sub']) && is_array($filter['sub'])) {
customfilter_filter_get_rows($filter['sub'], $depth + 1, $rows, $op);
}
}
}
function customfilter_filter_render_table($sid = 0, $fid = 0, $op = TRUE) {
$filters = customfilter_get_filters($sid, $fid);
$header = array(
t('Name'),
t('Description'),
t('Pattern'),
t('Match'),
t('Weight'),
);
$rows = array();
if ($op) {
$header[] = array(
'data' => t('Operations'),
'colspan' => '3',
);
}
if (count($filters) > 0) {
customfilter_filter_get_rows($filters, 0, $rows, $op);
}
else {
$rows[] = array(
0 => array(
'data' => t('No custom filter defined.'),
'colspan' => 5,
),
);
}
$table = theme('table', $header, $rows);
return $table;
}
function customfilter_get_descriptions($filter) {
$desc = "<em>" . $filter['description'] . "</em>";
if (is_array($filter['sub']) && count($filter['sub']) > 0) {
$desc .= "<ul>";
foreach ($filter['sub'] as $subfilter) {
$desc .= "<li>";
$desc .= customfilter_get_descriptions($subfilter);
$desc .= "</li>";
}
$desc .= "</ul>";
}
return $desc;
}
function customfilter_get_filter($fid, $cols = '*') {
static $filters;
if (!is_array($filters)) {
$filters = array();
}
if (!isset($filters[$fid])) {
if (!is_array($cols)) {
$cols = array(
$cols,
);
}
$columns = join(', ', $cols);
$filter = db_fetch_array(db_query("SELECT {$columns} FROM {customfilter_filter} WHERE fid = %d", $fid));
$filters[$fid] = $filter;
}
return $filters[$fid];
}
function customfilter_get_filters($sid, $root = 0, $sortby = 'weight', $cols = '*') {
static $filters;
if (!is_array($filters)) {
$filters = array();
}
if (!isset($filters[$sid]) || $root > 0) {
if (!is_array($cols)) {
$cols = array(
$cols,
);
}
$columns = join(', ', $cols);
$nodes = array();
if (is_array($root)) {
$nodes = $root;
}
else {
$nodes = array(
$root,
);
}
foreach ($nodes as $node) {
$result = db_query("SELECT {$columns} FROM {customfilter_filter} WHERE sid = %d and parentid = %d ORDER BY {$sortby}", $sid, $node);
while ($filter = db_fetch_array($result)) {
$filter['sub'] = customfilter_get_filters($sid, $filter['fid'], $sortby, $cols);
$filters[$sid][$filter['fid']] = $filter;
}
}
}
return $filters[$sid];
}
function customfilter_get_set($sid, $cols = array(
'sid',
'name',
'description',
)) {
static $sets;
if (!is_array($sets)) {
$sets = array();
}
if (!$sets[$sid]) {
if (!is_array($cols)) {
$cols = array(
$cols,
);
}
$columns = join(', ', $cols);
$set = db_fetch_array(db_query("SELECT {$columns} FROM {customfilter_set} WHERE sid = %d", $sid));
$sets[$sid] = $set;
}
return $sets[$sid];
}
function customfilter_get_sets($cols = array(
'sid',
'name',
'description',
), $cond = '1=1') {
static $sets;
if (!isset($sets)) {
$sets = array();
if (!is_array($cols)) {
$cols = array(
$cols,
);
}
$columns = join(', ', $cols);
$result = db_query("SELECT {$columns} FROM {customfilter_set} WHERE {$cond} ORDER BY name");
while ($set = db_fetch_array($result)) {
$sets[] = $set;
}
}
return $sets;
}
function customfilter_set_get_rows() {
$sets = customfilter_get_sets();
foreach ($sets as $set) {
$rows[] = array(
l($set['name'], "admin/settings/customfilter/{$set['sid']}"),
'<em>' . $set['description'] . '</em>',
l(t('edit'), "admin/settings/customfilter/{$set['sid']}/edit"),
l(t('delete'), "admin/settings/customfilter/{$set['sid']}/delete"),
);
}
return $rows;
}
function customfilter_xml_create($sids) {
$xml = "<?xml version=\"1.0\" standalone=\"yes\"?>\n";
$xml .= "<customfilter>\n";
foreach ($sids as $sid) {
$xml .= customfilter_xml_filterset($sid);
}
$xml .= "</customfilter>";
return $xml;
}
function customfilter_xml_export($sets) {
$sids = explode('.', $sets);
$xml = customfilter_xml_create($sids);
header('Content-Type: application/octet-stream');
header('Content-Length: ' . strlen($xml));
header("Content-Disposition: attachment; filename=customfilter.xml");
echo $xml;
}
function customfilter_xml_filter($filter, $level = 0) {
$indent = str_repeat(' ', $level + 3);
$xml = $indent . "<filter name=\"{$filter['name']}\" matches=\"{$filter['matches']}\" func=\"{$filter['func']}\" weight=\"{$filter['weight']}\">\n";
$xml .= $indent . " <description><![CDATA[{$filter['description']}]]></description>\n";
$xml .= $indent . " <pattern><![CDATA[{$filter['pattern']}]]></pattern>\n";
$xml .= $indent . " <replacement><![CDATA[{$filter['replacement']}]]></replacement>\n";
$subfilters = $filter['sub'];
if (is_array($subfilters) && count($subfilters) > 0) {
$xml .= $indent . " <subfilters>\n";
foreach ($subfilters as $subfilter) {
$xml .= customfilter_xml_filter($subfilter, $level + 2);
}
$xml .= $indent . " </subfilters>\n";
}
$xml .= $indent . "</filter>\n";
return $xml;
}
function customfilter_xml_filterset($sid) {
$filters = customfilter_get_filters($sid, 0);
$set = customfilter_get_set($sid, '*');
$xml = " <filterset name=\"{$set['name']}\" cache=\"{$set['cache']}\">\n";
$xml .= " <description>{$set['description']}</description>\n";
$xml .= " <tips>\n";
$xml .= " <short><![CDATA[{$set['shorttips']}]]></short>\n";
$xml .= " <long><![CDATA[{$set['longtips']}]]></long>\n";
$xml .= " </tips>\n";
$xml .= " <filters>\n";
foreach ($filters as $filter) {
$xml .= customfilter_xml_filter($filter);
}
$xml .= " </filters>\n";
$xml .= " </filterset>\n";
return $xml;
}
function customfilter_xml_read(&$xml) {
global $_customfilter_globals;
$cg =& $_customfilter_globals;
$cg->elements = array();
$cg->sets = array();
$cg->filters = array();
$cg->set = array();
$cg->filter = array();
$cg->parents = array();
$parser = drupal_xml_parser_create($xml);
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
xml_set_element_handler($parser, '_customfilter_xml_element_start', '_customfilter_xml_element_end');
xml_set_character_data_handler($parser, '_customfilter_xml_element_cdata');
xml_parse($parser, $xml, TRUE);
xml_parser_free($parser);
}
function _customfilter_filter_cache($delta) {
$set = customfilter_get_set($delta, array(
'sid',
'cache',
));
return $set['cache'];
}
function _customfilter_filter_desc($delta) {
$set = customfilter_get_set($delta, array(
'sid',
'description',
));
return $set['description'];
}
function _customfilter_filter_list() {
$s = array();
$sets = customfilter_get_sets('sid, name');
foreach ($sets as $set) {
$s[$set['sid']] = $set['name'];
}
return $s;
}
function _customfilter_process($delta, $format, $text) {
global $_customfilter_globals;
if (!isset($_customfilter_globals)) {
$_customfilter_globals = new stdClass();
}
$_customfilter_globals->text = $text;
if ($set = customfilter_get_set($delta, 'sid')) {
$filters = customfilter_get_filters($delta);
if (count($filters) > 0) {
$_customfilter_globals->stack = array();
foreach ($filters as $filter) {
$_customfilter_globals->stack[] = $filter;
$_customfilter_globals->text = preg_replace_callback($filter['pattern'], '_customfilter_process_filter', $_customfilter_globals->text);
array_pop($_customfilter_globals->stack);
}
}
}
return $_customfilter_globals->text;
}
function _customfilter_process_extract_rep($replacement) {
$arr = array();
$reps = array();
preg_match_all('/([^\\\\]|^)(\\$([0-9]{1,2}|\\{([0-9]{1,2})\\}))/', $replacement, $reps, PREG_OFFSET_CAPTURE);
foreach ($reps[4] as $key => $val) {
if ($val == '') {
$str = $reps[3][$key][0];
}
else {
$str = $reps[4][$key][0];
}
$offset = $reps[2][$key][1];
$length = strlen($reps[2][$key][0]);
$arr[] = array(
'index' => $str,
'offset' => $offset,
'length' => $length,
);
}
return $arr;
}
function _customfilter_process_filter($matches) {
global $_customfilter_globals;
$result = $matches[0];
$filter = end($_customfilter_globals->stack);
if (is_array($filter['sub']) && count($filter['sub']) > 0) {
foreach ($filter['sub'] as $subfilter) {
$_customfilter_globals->stack[] = $subfilter;
$substr =& $matches[$subfilter['matches']];
$substr = preg_replace_callback($subfilter['pattern'], '_customfilter_process_filter', $substr);
array_pop($_customfilter_globals->stack);
}
$result = _customfilter_process_replace_sub($filter['replacement'], $matches, $filter['func']);
}
elseif ($filter['func'] == 1) {
$result = preg_replace_callback($filter['pattern'], create_function('$matches', CUSTOMFILTER_CODE_DECLARE . $filter['replacement']), $result);
}
else {
$result = preg_replace($filter['pattern'], $filter['replacement'], $result);
}
return $result;
}
function _customfilter_process_replace_sub($replacement, $sub, $func = 0) {
if ($func == 1) {
$code = create_function('$matches', CUSTOMFILTER_CODE_DECLARE . $replacement);
$text = $code($sub);
}
else {
$text = $replacement;
$reps = _customfilter_process_extract_rep($replacement);
krsort($reps);
foreach ($reps as $rep) {
$text = substr_replace($text, $sub[$rep['index']], $rep['offset'], $rep['length']);
}
}
return $text;
}
function _customfilter_xml_element_cdata($parser, $data) {
global $_customfilter_globals;
$cg =& $_customfilter_globals;
$element = end($cg->elements);
$context = prev($cg->elements);
switch ($element) {
case 'DESCRIPTION':
if ($context == 'FILTERSET') {
$cg->set['description'] = $data;
}
elseif ($context == 'FILTER') {
$cg->filter['description'] = $data;
}
break;
case 'SHORT':
case 'LONG':
$cg->set[strtolower($element) . 'tips'] = $data;
break;
case 'PATTERN':
case 'REPLACEMENT':
$cg->filter[strtolower($element)] = $data;
break;
}
}
function _customfilter_xml_element_end($parser, $name) {
global $_customfilter_globals;
$cg =& $_customfilter_globals;
switch ($name) {
case 'FILTERSET':
$cg->sets[$cg->set['sid']] = $cg->set;
$cg->set = array();
break;
case 'FILTER':
$cg->filters[$cg->filter['fid']] = $cg->filter;
$cg->filter = array();
break;
case 'SUBFILTERS':
$cg->filter = array_pop($cg->parents);
break;
}
array_pop($cg->elements);
}
function _customfilter_xml_element_start($parser, $name, $attr) {
global $_customfilter_globals;
$cg =& $_customfilter_globals;
$cg->elements[] = $name;
switch ($name) {
case 'FILTERSET':
$cg->set['sid'] = db_next_id('{customfilter_set}_sid');
$cg->set['name'] = $attr['NAME'];
$cg->set['cache'] = $attr['CACHE'];
$cg->set['description'] = '';
$cg->set['shorttips'] = '';
$cg->set['longtips'] = '';
break;
case 'FILTER':
$cg->filter['fid'] = db_next_id('{customfilter_filter}_fid');
$cg->filter['sid'] = $cg->set['sid'];
$cg->filter['name'] = $attr['NAME'];
$cg->filter['matches'] = $attr['MATCHES'];
$cg->filter['func'] = $attr['FUNC'];
$cg->filter['weight'] = $attr['WEIGHT'];
$cg->filter['description'] = '';
$cg->filter['pattern'] = '';
$cg->filter['replacement'] = '';
if (count($cg->parents) > 0) {
$parent = end($cg->parents);
$cg->filter['parentid'] = $parent['fid'];
}
else {
$cg->filter['parentid'] = 0;
}
break;
case 'SUBFILTERS':
$cg->parents[] = $cg->filter;
$cg->filter = array();
break;
case 'FILTERS':
$cg->parents = array();
$cg->filter = array();
break;
}
}
function _customfilter_xml_sql($sets, $filters) {
foreach ($sets as $set) {
db_query("INSERT INTO {customfilter_set} (sid, name, cache, description, shorttips, longtips) VALUES (%d, '%s', %d, '%s', '%s', '%s');", $set['sid'], $set['name'], $set['cache'], $set['description'], $set['shorttips'], $set['longtips']);
}
foreach ($filters as $filter) {
db_query("INSERT INTO {customfilter_filter} (fid, sid, parentid, name, description, matches, pattern, replacement, func, weight) VALUES (%d, %d, %d, '%s', '%s', %d, '%s', '%s', %d, %d);", $filter['fid'], $filter['sid'], $filter['parentid'], $filter['name'], $filter['description'], $filter['matches'], $filter['pattern'], $filter['replacement'], $filter['func'], $filter['weight']);
}
}