// -------------------------------------------------------------
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, $mode=0, $plugtype=0) {
pagetop(smd_wu_gTxt('smd_wu'),$message);
$btnSearch = fInput('submit', 'smd_wu_search', gTxt('search'), 'smallerbox').sInput('smd_wu_search').hInput('plugtype', (($plugtype==1) ? 0 : 1));
$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
$plugtype = gps('plugtype'); // 0 = client, 1 = 0+admin, 2 = 1+library
$plugtype = (is_numeric($plugtype) && $plugtype < 3) ? $plugtype : 0;
$joinme = ($meth == 0) ? " OR " : " AND ";
$places = gps('places');
$places = is_array($places) ? $places : array();
$mode = ($search_for) ? 0 : 1;
smd_wu_showform('', $search_for, $places, $meth, $whole, $mode, $plugtype);
// 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,Title,keywords', '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) {
$hlink = '';
$vars = '';
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]))));
}
}
$hlink .= $row[$col]." ";
}
$out .= ($hlink) ? '- ' . (($vars) ? ''.$hlink.' ' : $hlink) . '
': '';
}
$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 < " .($plugtype+1). " AND tg.name != 'smd_where_used' 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] . (($place == 'plugins') ? (($plugtype==0) ? smd_wu_gTxt('client_plugins') : smd_wu_gTxt('admin_plugins') ) : '') ));
$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
$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
$hlink = '';
$vars = '';
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]))));
}
}
$hlink .= $row[$col]." ";
}
$out .= ($hlink) ? '- ' . (($vars) ? ''.$hlink.' ' : $hlink) . '
': '';
}
$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(
'admin_plugins' => ' [ A+C ]',
'client_plugins' => ' [ C ]',
'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);
}