if (@txpinterface == 'admin') {
global $smd_featured_event;
$smd_featured_event = 'smd_featured';
$smd_featured_privs = get_pref('smd_featured_privs', '1,2');
add_privs($smd_featured_event, $smd_featured_privs);
register_tab("content", $smd_featured_event, smd_featured_gTxt('tab_name'));
register_callback('smd_featured_manage', $smd_featured_event);
register_callback('smd_featured_welcome', 'plugin_lifecycle.smd_featured');
}
if (!defined('SMD_FEAT')) {
define("SMD_FEAT", 'smd_featured');
}
// **********
// ADMIN SIDE
// **********
// ------------------------
function smd_featured_manage($evt, $stp) {
if ($stp == 'save_pane_state') {
smd_featured_save_pane_state();
} else {
if(!$stp or !in_array($stp, array(
'smd_featured_table_install',
'smd_featured_table_remove',
'smd_featured_save',
'smd_featured_tagit',
))) {
smd_featured_list('');
} else $stp();
}
}
// ------------------------
function smd_featured_welcome($evt, $stp) {
$msg = '';
switch ($stp) {
case 'installed':
smd_featured_table_install(0);
$msg = 'Thanks for installing smd_featured. Please read the docs :-)';
break;
case 'deleted':
smd_featured_table_remove(0);
break;
}
return $msg;
}
// ------------------------
function smd_featured_list($msg='') {
global $smd_featured_event;
pagetop(smd_featured_gTxt('tab_name'), $msg);
extract(gpsa(array('smd_feat_id', 'smd_feat_label', 'smd_feat_searchkeep', 'smd_feat_filtkeep')));
if (smd_featured_table_exist()) {
$featlist = safe_rows('*', SMD_FEAT, '1=1');
$featlist = empty($featlist) ? array() : $featlist;
$editname = $feat_label = $feat_desc = '';
$ftypes = $flist = array();
$ftypes['smd_unlabelled'] = smd_featured_gTxt('unlabelled');
foreach ($featlist as $item) {
if (isset($item['label']) && !empty($item['label'])) {
$ftypes[$item['label']] = $item['label'];
}
$flist[$item['id']] = array('label' => $item['label'], 'description' => $item['description'], 'desc_html' => $item['desc_html']);
}
$featlist = $flist;
// Get additional filtering from hidden prefs
$where = array('1=1');
$seclist = get_pref('smd_featured_section_list', '');
if ($seclist) {
$where[] = "Section IN ('".join("','", do_list($seclist))."')";
}
$where[] = "Status IN (4,5)";
$orderby = get_pref('smd_featured_sort', 'Posted desc');
$rs = safe_rows('*', 'textpattern', join(' AND ', $where). ' ORDER BY '.$orderby);
foreach ($rs as $row) {
$ftype = isset($featlist[$row['ID']]['label']) ? $featlist[$row['ID']]['label'] : '';
$out[] = array($row['ID'], $row['Title'], $ftype);
if ($smd_feat_id && $row['ID'] == $smd_feat_id) {
$editname = $row['Title'];
$feat_label = $featlist[$smd_feat_id]['label'];
$feat_desc = doStrip(str_replace('\r\n','
', $featlist[$smd_feat_id]['description']));
}
}
echo '
';
echo '';
echo '';
$edbtn = small('['.gTxt('edit').']');
if ($out) {
$sizes = do_list(get_pref('smd_featured_box_size', '150x40'), 'x');
$sizes[0] = (isset($sizes[0]) && is_numeric($sizes[0])) ? $sizes[0] : '150';
$sizes[1] = (isset($sizes[1]) && is_numeric($sizes[1])) ? $sizes[1] : '40';
$rows = count($rs);
$tblout = array();
$atts = ' class="smd_featured_table smd_clear" id="list" align="center"';
$tblout[] = hed(smd_featured_gTxt('manage_lbl', array(), 'raw'), 3, ' class="smd_clear"');
for ($idx = 0; $idx < $rows; $idx++) {
$isfeat = (isset($out[$idx]) && array_key_exists($out[$idx][0], $featlist));
$cellclass = $isfeat ? ' class="smd_featured"' : '';
$edlink = $isfeat ? ''.$edbtn.''.sp : '';
$rowdata = (isset($out[$idx])) ? ''.$out[$idx][1].'' : '';
$rowdata .= $isfeat ? '' : '';
$tblout[] = (isset($out[$idx])) ? '' : '';
}
echo tag(join("",$tblout), 'div', $atts);
echo '';
}
$qs = array(
"event" => $smd_featured_event,
);
$qsVars = "index.php".join_qs($qs);
$verifyTxt = smd_featured_gTxt('unfeature_confirm');
echo <<
function smd_featured_select(obj, id) {
obj = jQuery(obj).parent();
// N.B. Negative logic used here because we're checking the class _before_ it's been toggled
var action = ((obj).hasClass("smd_featured")) ? 'remove' : 'add';
if (action == 'remove') {
var ret = confirm('{$verifyTxt}');
if (ret == false) {
return false;
}
}
jQuery.post('{$qsVars}', { step: "smd_featured_tagit", smd_feat_id: id, smd_feat_action: action },
function(data) {
obj.toggleClass('smd_featured');
if (action == 'add') {
obj.prepend('{$edbtn} ');
obj.append('');
} else {
obj.find('a.edlink').remove();
obj.find('span.extra').remove();
if (jQuery("#smd_feat_search").val() != '') jQuery("#smd_feat_search").keyup();
if (jQuery("#smd_feat_filt").val() != '') jQuery("#smd_feat_filt").change();
}
}
);
return false;
}
function smd_featured_editkeep(id) {
jQuery("#smd_feat_editform [name='smd_feat_searchkeep']").val(jQuery("#smd_feat_search").val());
jQuery("#smd_feat_editform [name='smd_feat_filtkeep']").val(jQuery("#smd_featured_bylabel #smd_feat_filt option:selected").val());
jQuery("#smd_feat_editform [name='smd_feat_id']").val(id);
jQuery("#smd_feat_editform").submit();
}
function smd_featured_savekeep() {
jQuery("#smd_feat_saveform [name='smd_feat_searchkeep']").val(jQuery("#smd_feat_search").val());
jQuery("#smd_feat_saveform [name='smd_feat_filtkeep']").val(jQuery("#smd_featured_bylabel #smd_feat_filt option:selected").val());
}
function smd_feat_filter(selector, query, nam, csense) {
var query = jQuery.trim(query);
csense = (csense) ? "" : "i";
query = query.replace(/ /gi, '|'); // add OR for regex query
var re = new RegExp(query, csense);
jQuery(selector).each(function() {
sel = (typeof nam=="undefined" || nam=='') ? jQuery(this) : jQuery(this).find("span[name='"+nam+"']");
if (query == '') {
if (sel.length == 1 && sel.text() == '') {
jQuery(this).show();
} else {
jQuery(this).hide();
}
} else {
if (sel.text().search(re) < 0) {
jQuery(this).hide();
} else {
jQuery(this).show();
}
}
});
}
jQuery(function() {
jQuery("#smd_feat_search").keyup(function(event) {
jQuery("#smd_feat_filt").val('0'); // Clear the filter dropdown
// if esc is pressed or nothing is entered
if (event.keyCode == 27 || jQuery(this).val() == '') {
jQuery(this).val('');
jQuery(".smd_featured_table div:not(.tblhead)").show();
} else {
smd_feat_filter('.smd_featured_table div:not(.tblhead)', jQuery(this).val(), 'smd_feat_name', 0);
}
});
if ('{$smd_feat_searchkeep}' != '') {
jQuery("#smd_feat_search").keyup();
}
jQuery("#smd_feat_filt").change(function(event) {
jQuery("#smd_feat_search").val(''); // Empty the search box
if (jQuery(this).val() == '') {
jQuery('.smd_featured_table div:not(.tblhead)').show();
} else if (jQuery(this).val() == 'smd_unlabelled') {
smd_feat_filter('.smd_featured_table div:not(.tblhead)', '', 'smd_feat_label', 0);
} else {
smd_feat_filter('.smd_featured_table div:not(.tblhead)', jQuery(this).val(), 'smd_feat_label', 1);
}
});
if ('{$smd_feat_filtkeep}' != '') {
jQuery("#smd_feat_filt").change();
}
if ('{$smd_feat_id}' != '') {
jQuery("#smd_feat_label").focus();
}
});
EOS;
} else {
// Table not installed
$btnInstall = '';
$btnStyle = ' style="border:0;height:25px"';
echo startTable('list');
echo tr(tda($btnInstall, $btnStyle));
echo endTable();
}
}
// ------------------------
// Update the passed record in the featured table
function smd_featured_save() {
global $smd_featured_event;
extract(gpsa(array('smd_feat_id', 'smd_feat_label', 'smd_feat_desc')));
assert_int($smd_feat_id);
$smd_feat_desctile = $smd_feat_desc;
$smd_feat_label = doSlash($smd_feat_label);
if (smd_featured_table_exist()) {
@include_once txpath.'/lib/classTextile.php';
@include_once txpath.'/publish.php';
if (class_exists('Textile')) {
$textile = new Textile();
$smd_feat_desctile = doSlash($textile->TextileThis(parse($smd_feat_desc)));
}
$smd_feat_desc = doSlash($smd_feat_desc);
$ret = safe_upsert(SMD_FEAT, "label='$smd_feat_label', description='$smd_feat_desc', desc_html='$smd_feat_desctile'", "id='$smd_feat_id'");
unset($_POST['smd_feat_id']);
}
smd_featured_list(smd_featured_gTxt('saved'));
}
// ------------------------
// Create an empty entry in the featured table or destroy it
function smd_featured_tagit() {
global $smd_featured_event;
extract(doSlash(gpsa(array('smd_feat_id', 'smd_feat_action'))));
assert_int($smd_feat_id);
if ($smd_feat_action == 'add') {
$ret = safe_upsert(SMD_FEAT, "label=''", "id='$smd_feat_id'");
} else if ($smd_feat_action == 'remove') {
$ret = safe_delete(SMD_FEAT, "id='$smd_feat_id'");
}
}
// -------------------------------------------------------------
function smd_featured_save_pane_state() {
$panes = array('smd_featured_filters');
$pane = gps('pane');
if (in_array($pane, $panes))
{
set_pref("pane_{$pane}_visible", (gps('visible') == 'true' ? '1' : '0'), 'smd_featured', PREF_HIDDEN, 'yesnoradio', 0, PREF_PRIVATE);
send_xml_response();
} else {
send_xml_response(array('http-status' => '400 Bad Request'));
}
}
// ------------------------
// Add featured table if not already installed
function smd_featured_table_install($showpane='1') {
$GLOBALS['txp_err_count'] = 0;
$ret = '';
$sql = array();
$sql[] = "CREATE TABLE IF NOT EXISTS `".PFX.SMD_FEAT."` (
`id` int(8) NOT NULL,
`label` varchar(32) NULL default '',
`description` text NULL default '',
`desc_html` text NULL default '',
PRIMARY KEY (`id`)
) ENGINE=MyISAM";
if(gps('debug')) {
dmp($sql);
}
foreach ($sql as $qry) {
$ret = safe_query($qry);
if ($ret===false) {
$GLOBALS['txp_err_count']++;
echo "".$GLOBALS['txp_err_count'].". ".mysql_error()."
\n";
echo "\n";
}
}
if ($GLOBALS['txp_err_count'] == 0) {
$message = smd_featured_gTxt('tbl_installed');
} else {
if ($showpane) {
$message = smd_featured_gTxt('tbl_not_installed');
smd_featured_list($message);
}
}
}
// ------------------------
// Drop table if in database
function smd_featured_table_remove() {
$ret = '';
$sql = array();
$GLOBALS['txp_err_count'] = 0;
if (smd_featured_table_exist()) {
$sql[] = "DROP TABLE IF EXISTS " .PFX.SMD_FEAT. "; ";
if(gps('debug')) {
dmp($sql);
}
foreach ($sql as $qry) {
$ret = safe_query($qry);
if ($ret===false) {
$GLOBALS['txp_err_count']++;
echo "".$GLOBALS['txp_err_count'].". ".mysql_error()."
\n";
echo "\n";
}
}
}
if ($GLOBALS['txp_err_count'] == 0) {
$message = smd_featured_gTxt('tbl_removed');
} else {
$message = smd_featured_gTxt('tbl_not_removed');
smd_featured_list($message);
}
}
// ------------------------
function smd_featured_table_exist($all='') {
if ($all) {
$tbls = array(SMD_FEAT => 4);
$out = count($tbls);
foreach ($tbls as $tbl => $cols) {
if (gps('debug')) {
echo "++ TABLE ".$tbl." HAS ".count(@safe_show('columns', $tbl))." COLUMNS; REQUIRES ".$cols." ++".br;
}
if (count(@safe_show('columns', $tbl)) == $cols) {
$out--;
}
}
return ($out===0) ? 1 : 0;
} else {
if (gps('debug')) {
echo "++ TABLE ".SMD_FEAT." HAS ".count(@safe_show('columns', SMD_FEAT))." COLUMNS;";
}
return(@safe_show('columns', SMD_FEAT));
}
}
// ****************
// PUBLIC SIDE TAGS
// ****************
// ------------------------
function smd_featured($atts, $thing) {
global $smd_featured_info, $smd_prior_featured, $prefs;
extract(lAtts(array(
'label' => '',
'unlabel' => 'Featured',
'labeltag' => '',
'time' => 'past',
'status' => '4,5',
'section' => '',
'limit' => '',
'sort' => '',
'form' => '',
'wraptag' => '',
'break' => '',
'class' => '',
'html_id' => '',
),$atts));
if (isset($atts['label'])) {
if ($label) {
$where = "BINARY label REGEXP '".$atts['label']."'";
} else {
$where = "label=''";
}
unset($atts['label']);
} else {
$where = "1=1";
}
// Exclude previously seen articles
if (!empty($smd_prior_featured)) {
$where .= ' AND smdfeat.id NOT IN(' . join(',', $smd_prior_featured) . ')';
}
if ($time) {
switch ($time) {
case 'any':
break;
case 'future':
$where .= " AND Posted > now()";
break;
default:
$where .= " AND Posted <= now()";
}
if (!$prefs['publish_expired_articles']) {
$where .= " AND (now() <= Expires OR Expires = ".NULLDATETIME.")";
}
unset($atts['time']);
}
if ($status) {
$where .= ' AND Status in ('.join(',', do_list($status)).')';
unset($atts['status']);
}
if ($section) {
$where .= " AND Section in ('".join("','", do_list($section))."')";
unset($atts['section']);
}
if ($sort) {
$where .=' ORDER BY '.$sort;
unset($atts['sort']);
}
if ($limit) {
$where .=' LIMIT '.$limit;
unset($atts['limit']);
}
// Don't pass the remaining attributes we've already handled onto the article tag
unset(
$atts['label'],
$atts['unlabel'],
$atts['labeltag'],
$atts['wraptag'],
$atts['break'],
$atts['class'],
$atts['html_id']
);
$rs = getRows('SELECT *, unix_timestamp(Posted) as uPosted, unix_timestamp(Expires) as uExpires, unix_timestamp(LastMod) as uLastMod FROM '.PFX.'textpattern AS txp LEFT JOIN '.PFX.'smd_featured AS smdfeat ON txp.ID=smdfeat.id WHERE '.$where);
$out = array();
if ($rs) {
foreach ($rs as $row) {
$smd_featured_info['label'] = $row['label'];
$smd_featured_info['description'] = $row['desc_html'];
$atts['id'] = $row['ID'];
$artout = article($atts, $thing);
if ($artout) {
$smd_prior_featured[] = $row['ID'];
$out[] = $artout;
}
}
}
if ($out) {
return (($labeltag) ? doLabel( ( ($label == '') ? $unlabel : $label), $labeltag ) : '')
.doWrap($out, $wraptag, $break, $class, '', '', '', $html_id);
}
return '';
}
// ------------------------
function smd_unfeatured($atts, $thing) {
global $smd_prior_featured;
$where = "1=1";
// Exclude previously seen articles
if (!empty($smd_prior_featured)) {
$where .= ' AND id NOT IN(' . join(',', $smd_prior_featured) . ')';
}
$rs = safe_column('ID', 'textpattern', $where);
$atts['id'] = join(',', $rs);
$out = article($atts, $thing);
return $out;
}
// ------------------------
function smd_featured_info($atts) {
global $smd_featured_info;
extract(lAtts(array(
'item' => '',
),$atts));
return (isset($smd_featured_info[$item]) ? $smd_featured_info[$item] : '');
}
// ------------------------
// Plugin-specific replacement strings - localise as required
// TODO: make these into a textpack when plugin composer supports them
function smd_featured_gTxt($what, $atts = array()) {
$lang = array(
'by_label' => 'By label: ',
'by_name' => 'By name: ',
'live_search' => 'Article live search',
'manage_lbl' => 'Click to select featured articles, which will be shown highlighted.',
'saved' => 'Article info updated',
'tab_name' => 'Featured articles',
'tbl_install_lbl' => 'Install table',
'tbl_installed' => 'Table installed',
'tbl_not_installed' => 'Table not installed',
'tbl_removed' => 'Table removed',
'tbl_not_removed' => 'Table not removed',
'unfeature_confirm' => 'Sure to unfeature this article?',
'unlabelled' => '[unlabelled]',
);
return strtr($lang[$what], $atts);
}