// -------------------------------------------------------------
if (@txpinterface == 'admin') {
add_privs('smd_wu','1,2');
// Extensions tab
register_tab('extensions', 'smd_wu', smd_wu_gTxt('smd_wu'));
register_callback('smd_wu', 'smd_wu');
}
// -------------------------------------------------------------
function smd_wu($event, $step) {
if(!$step or !in_array($step, array(
'smd_wu_search',
))) {
smd_wu_showform('');
} else $step();
}
// -------------------------------------------------------------
function smd_wu_showform($message, $term='', $sel=array(), $incl=0, $whole=0) {
pagetop(smd_wu_gTxt('smd_wu'),$message);
$btnSearch = fInput('submit', 'smd_wu_search', gTxt('search'), 'smallerbox').sInput('smd_wu_search');
$btnStyle = ' style="border:0;height:25px"';
$place = array('sections','pages','forms','articles');
$sel = (empty($sel)) ? $place : $sel;
echo '
';
}
// -------------------------------------------------------------
function smd_wu_search() {
extract(doSlash(gpsa(array('search_for'))));
$whole = gps('whole');
$meth = gps('meth'); // 0 = include, 1 = exclude
$joinme = ($meth == 0) ? " OR " : " AND ";
$places = gps('places');
$places = is_array($places) ? $places : array();
smd_wu_showform('', $search_for, $places, $meth, $whole);
// Entries in the placeTable array are:
// 0: Table to search
// 1: Column to search
// 2: Column to return
// 3: Heading to display if results found
// 4: Event of destination URL
// 5: Step of destination URL
// 6: Additional URL var
// 7: Additional URL var replacement (used in strtr)
$placeTable = array(
'pages' => array('txp_page', 'user_html', 'name', gTxt('pages'), 'page', '', 'name', '{name}'),
'forms' => array('txp_form', 'form', 'name', gTxt('forms'), 'form', 'form_edit', 'name', '{name}'),
'articles' => array('textpattern', 'Body,Excerpt,override_form,section', 'ID,title', gTxt('articles'), 'article', 'edit', 'ID', '{ID}'),
'sections' => array('txp_section', 'page,css', 'name', gTxt('sections'), 'section', '', '#', 'section-{name}'),
);
$rs = array();
echo n.'
';
echo startTable('list');
$colHead = array();
$colBody = array();
if ($search_for) {
echo tr(tdcs(tag(gTxt('search_results'), 'h2'), 4));
foreach ($places as $place) {
$crow = $placeTable[$place];
$where = array();
$witems = do_list($crow[1]);
$list = do_list($crow[2]);
foreach ($witems as $item) {
$where[] = $item . (($meth==1) ? ' NOT' : '') . (($whole==1) ? ' REGEXP \'[[:<:]]'.$search_for.'[[:>:]]\'' : " LIKE '%$search_for%'");
}
$rs = safe_rows($crow[2], $crow[0], '('.join($joinme, $where).') ORDER BY '.$list[0]);
$colHead[] = td(strong($crow[3]));
if ($rs) {
$out = '';
foreach ($rs as $row) {
$op = '';
foreach ($list as $col) {
$from = '{'.$col.'}';
if (strpos($crow[7], $from) !== false) {
if ($crow[6] == "#") {
$vars = join_qs(array("event" => $crow[4], "step" => $crow[5])).$crow[6].strtr($crow[7], array($from => $row[$col]));
} else {
$vars = join_qs(array("event" => $crow[4], "step" => $crow[5], $crow[6] => strtr($crow[7], array($from => $row[$col]))));
}
$op .= ''.$row[$col].' ';
} else {
$op .= $row[$col]." ";
}
}
$out .= '- '.$op.'
';
}
$out .= '
';
$colBody[] = td($out);
} else {
$colBody[] = td(gTxt('no_results_found'));
}
}
echo tr(join(" ", $colHead));
echo tr(join(" ", $colBody));
} else {
// No search criteria, so show orphans
echo tr(tdcs(tag(smd_wu_gTxt('orphan_results'), 'h2'), 5));
// Reprogram the places/placeTable
$artkey = array_search('articles', $places);
if ($artkey !== false) {
unset($places[$artkey]);
}
// pages/forms/sections to ignore because they are static and cannot be deleted
$essentials = array(
'sections' => array('default'),
'pages' => array('error_default'),
'forms' => array('comments','comments_display','comment_form','default','Links','files'), // copied from txp_forms
);
$places[] = 'plugins';
$places[] = 'stylesheets';
$placeTable['plugins'] = array('txp_plugin', 'name', 'name', gTxt('plugins'), 'plugin', '', '#', '{name}');
$placeTable['stylesheets'] = array('txp_css', 'name', 'name', smd_wu_gTxt('stylesheets'), 'css', '', 'name', '{name}');
$placeTable['forms'][0] = "SELECT tf.name FROM " .safe_pfx('txp_form'). " AS tf WHERE tf.name NOT IN (" .doQuote(implode("','",$essentials['forms'])). ") ORDER BY tf.name"; // Would be nice to exclude forms that reference forms here instead of iterating through them later
$placeTable['pages'][0] = "SELECT tp.name FROM " .safe_pfx('txp_section'). " AS ts RIGHT JOIN " .safe_pfx('txp_page'). " AS tp ON ts.page = tp.name WHERE ts.page IS NULL AND tp.name NOT IN (" .doQuote(implode("','",$essentials['pages'])). ") ORDER BY tp.name";
$placeTable['plugins'][0] = "SELECT tg.name, tg.code FROM " .safe_pfx('txp_plugin'). " AS tg WHERE type = 0 ORDER BY tg.name";
$placeTable['sections'][0] = "SELECT ts.name FROM " .safe_pfx('txp_section'). " AS ts LEFT JOIN " .safe_pfx('textpattern'). " AS txp ON ts.name = txp.section WHERE ID IS NULL AND ts.name NOT IN (" .doQuote(implode("','",$essentials['sections'])). ") ORDER BY ts.name";
$placeTable['stylesheets'][0] = "SELECT tc.name FROM " .safe_pfx('txp_section'). " AS ts RIGHT JOIN " .safe_pfx('txp_css'). " AS tc ON ts.css = tc.name WHERE ts.page IS NULL ORDER BY tc.name";
// For "awkward" queries that can't be done in one shot, there are three things required per $place:
// 1: txp table name
// 2: list of columns to compare
// 3: method of comparison per column (0 = "direct match", 1 = "like")
$cTable = array(
'plugins' => array(
'txp_form' => array('form' => 1),
'txp_page' => array('user_html' => 1),
'textpattern' => array('Body' => 1, 'Excerpt' => 1),
),
'forms' => array(
'txp_form' => array('form' => 1),
'txp_page' => array('user_html' => 1),
'textpattern' => array('Body' => 1, 'Excerpt' => 1, 'override_form' => 0),
),
);
// Work on a column at a time
foreach ($places as $place) {
$crow = $placeTable[$place];
$colRefs = do_list($crow[2]);
$colHead[] = td(strong($crow[3]));
$rs = startRows($crow[0]);
if ($rs) {
$out = '';
while ($row = nextRow($rs)) {
// Count the no of records matching this name in each table.
// Any time this goes above zero, the item is used and it can be ignored
$op = '';
$fnaliases = array();
if (array_key_exists($place, $cTable)) {
// Plugin functions are not necessarily the name of the plugin itself.
// Find all function definitions and build a list of aliases
if ($place == 'plugins') {
$re = '/function\s+([A-Za-z0-9_]+)\s*\(/';
$num = preg_match_all($re, $row['code'], $fnaliases);
}
$recs = 0;
foreach ($cTable[$place] as $tbl => $colInfo) {
if ($recs == 0) {
$where = array();
foreach ($colInfo as $colName => $qryType) {
$where[] = $colName . (($qryType==0) ? " = '" .$row[$colRefs[0]]. "'" : " LIKE '%" .$row[$colRefs[0]]. "%'");
if (count($fnaliases) > 1) {
foreach ($fnaliases[1] as $fnalias) {
$where[] = $colName . (($qryType==0) ? " = '" .$fnalias. "'" : " LIKE '%" .$fnalias. "%'");
}
}
}
$where = join(" OR ", $where);
$recs += safe_count($tbl, $where);
}
}
// If the item has not been found, flag it
if ($recs == 0) {
$colNames = $colRefs;
} else {
$colNames = array();
}
} else {
$colNames = $colRefs;
}
// Make up the string to display, and hyperlink it if directed
foreach ($colNames as $col) {
$from = '{'.$col.'}';
if (strpos($crow[7], $from) !== false) {
if ($crow[6] == "#") {
$vars = join_qs(array("event" => $crow[4], "step" => $crow[5])).$crow[6].strtr($crow[7], array($from => $row[$col]));
} else {
$vars = join_qs(array("event" => $crow[4], "step" => $crow[5], $crow[6] => strtr($crow[7], array($from => $row[$col]))));
}
$op .= ''.$row[$col].' ';
} else {
$op .= $row[$col]." ";
}
}
$out .= '- '.$op.'
';
}
$out .= '
';
$colBody[] = td($out);
} else {
$colBody[] = td(smd_wu_gTxt('no_orphans_found'));
}
}
echo tr(join(" ", $colHead));
echo tr(join(" ", $colBody));
}
echo endTable();
}
// -------------------------------------------------------------
// Plugin-specific replacement strings - localise as required
// -------------------------------------------------------------
function smd_wu_gTxt($what, $atts = array()) {
$lang = array(
'exclusion' => 'Exclude',
'inclusion' => 'Include',
'filter' => 'Filter:',
'no_orphans_found' => 'No orphans found.',
'orphan_results' => 'Possible orphans',
'search_lbl' => 'Find:',
'search_where_lbl' => 'Look in:',
'stylesheets' => 'Stylesheets',
'smd_wu' => 'Where used',
'whole_word' => 'Whole words',
);
return strtr($lang[$what], $atts);
}