# PLUGIN PREVIEW BY TEXTPATTERN.INFO
/*
adi_recent_tab - Recent Items Tab
Written by Adi Gilbert
Released under the GNU General Public License
Version history:
0.6 - refixed for critical, admin interface killing, bug in TXP 4.6
- responsive layout & styling for recent items tab
- fix: recognises "upload file from existing"
- enhancement: pref for image alt text (for Uli)
0.5 - change: IDs display switched on by default
- change: articles heading link now goes to Articles (list) tab rather than Write
- fix: error when reordering images/files in list
- fix: error when changing number of items per page
- fix: error when file upload failed (e.g. file too big/file already exists)
- fix: article titles etc that are blank with multiple spaces are treated as Untitled
- fix: unslashed quotes in DB queries
- fix: tabs no longer listed if user lacks privs
- fix: upload thumbnail now ignored
- fix: all new section names sanitised & recognised
- enhancement: plugin privs
- code tidy up (thanks gocom)
- TXP 4.5+
- tested & fixed for TXP 4.6
0.4 - TXP 4.5-ified (particularly to cope with new Sections tab & new-style Links tab)
- fix: record new links properly
- fix: losing image (file) name if both alt & caption blank
0.3 - style improvements to cope with long titles
- fix: style for latest version of Hive theme (thanks Uli)
- fix: error message in images & files search result page (thanks Uli)
0.2 - fix: cope with image replace & file replace properly
- fix: cope with style create/save/delete properly
- new pref: include article/image/link/file IDs
0.1 - initial release
*/
if (@txpinterface == 'admin') {
global $adi_recent_tab_debug;
$adi_recent_tab_debug = 0;
if (!version_compare(txp_version,'4.5.0','>=')) return;
adi_recent_tab_init();
}
function adi_recent_tab_init() {
global $event,$step,$textarray,$txp_user,$prefs,$adi_recent_tab_outlaws,$adi_recent_tab_url,$adi_recent_tab_plugin_status,$adi_recent_tab_event_gtxt,$adi_recent_tab_include,$adi_recent_tab_exclude_combo,$adi_recent_tab_include_combo,$adi_recent_tab_prefs,$adi_recent_tab_debug,$adi_recent_tab_txp460;
// meet the new boss?
$adi_recent_tab_txp460 = (version_compare(txp_version,'4.6-dev','>='));
// plugin lifecycle
register_callback('adi_recent_tab_lifecycle','plugin_lifecycle.adi_recent_tab');
// Textpack
$adi_recent_tab_url = array(
'textpack' => 'http://www.greatoceanmedia.com.au/files/adi_textpack.txt',
'textpack_download' => 'http://www.greatoceanmedia.com.au/textpack/download',
'textpack_feedback' => 'http://www.greatoceanmedia.com.au/textpack/?plugin=adi_recent_tab',
);
if (strpos($prefs['plugin_cache_dir'],'adi') !== FALSE) // use Adi's local version
$adi_recent_tab_url['textpack'] = $prefs['plugin_cache_dir'].'/adi_textpack.txt';
# --- BEGIN PLUGIN TEXTPACK ---
$adi_recent_tab_gtxt = array(
'adi_include' => 'Include:',
'adi_include_ids' => 'Include IDs',
'adi_install_fail' => 'Unable to install',
'adi_installed' => 'Installed',
'adi_pref_update_fail' => 'Preference update failed',
'adi_recent_items' => 'Recent items',
'adi_recent_tab' => 'Recent',
'adi_recent_tab_max_items' => 'Maximum number of items',
'adi_tab' => 'Tab',
'adi_textpack' => 'Textpack',
'adi_textpack_fail' => 'Textpack installation failed',
'adi_textpack_feedback' => 'Textpack feedback',
'adi_textpack_online' => 'Textpack also available online',
'adi_uninstall' => 'Uninstall',
'adi_uninstall_fail' => 'Unable to uninstall',
'adi_uninstalled' => 'Uninstalled',
'adi_update_prefs' => 'Update preferences',
);
# --- END PLUGIN TEXTPACK ---
// update $textarray
$textarray += $adi_recent_tab_gtxt;
/*
Events & Steps - A minefield of inconsistencies ...
Step other vars
Event=article
Write create - (empty create tab)
Edit edit ID
Save edit ID
Publish create -> edit $GLOBALS['ID']
Event=image
Images list -
(search) image_list
(sort) list
(paging) image_change_pageby
Image upload image_insert $GLOBALS['ID']
Image edit image_edit id
Image save image_edit id
Image replace image_replace id
Thumbnail upld thumbnail_insert
Event=page
Pages/default -
Page edit - name
Save page_save name
Copy page_save name, newname
Create page page_save newname
Event=form
Forms/default -
Form edit form_edit name
Form save form_save
Event=link
Links list - -> link_edit
(search) link_list
(sort) list
(paging) link_change_pageby
Link edit link_edit id
Link save link_save id
Link create link_post $GLOBALS['ID'] (pre-4.5.0)
Link create link_save $GLOBALS['ID'] (post-4.5.0)
Event=file
Files list -
(search) file_list
(sort) list
(paging) file_change_pageby
Upload file_insert $GLOBALS['ID']
Save file_save ?
File edit file_edit id
File replace file_replace id
From existing file_create name
Event=css
Style/default -
Style edit - name
Save css_save name
New style pour newname
Copy style css_save name
Event=section
Section list -
(search) sec_section_list
(sort) list
(paging) section_change_pageby
Section edit section_edit name
Section create section_edit - (empty create tab)
Section save section_save name
Section create section_save newname (post-4.5.0)
*/
// the privileged few ...
$adi_recent_tab_include = array('article','image','page','form','link','file','css','section'); // if you're not on the list, you're not getting in
// privileges for the privileged
$adi_recent_tab_include_privs = array(
'article' => 'list',
'image' => 'image',
'page' => 'page',
'form' => 'form',
'link' => 'link',
'file' => 'file',
'css' => 'css',
'section' => 'section',
);
if ($adi_recent_tab_debug)
foreach ($adi_recent_tab_include as $index => $tab)
if (has_privs($adi_recent_tab_include_privs[$tab]))
echo $tab.sp.'- has privs'.br;
else
echo $tab.sp.'- no privs'.br;
// weed out the unworthy
foreach ($adi_recent_tab_include as $index => $tab)
if (!has_privs($adi_recent_tab_include_privs[$tab]))
unset($adi_recent_tab_include[$index]);
// it's what we call 'em
$adi_recent_tab_event_gtxt = array(
'article' => 'tab_list',
'css' => 'tab_style',
'file' => 'tab_file',
'form' => 'tab_forms',
'image' => 'tab_image',
'link' => 'tab_link',
'page' => 'tab_pages',
'section' => 'tab_sections',
);
// not so fast ...
$adi_recent_tab_exclude_combo[] = array('event' => '^article$', 'step' => '^$'); // empty create article tab - event="article", step=blank
$adi_recent_tab_exclude_combo[] = array('event' => '^image$', 'step' => '^$'); // image list tab - event="image", step=blank
$adi_recent_tab_exclude_combo[] = array('event' => '^image$', 'step' => 'image_multi_edit'); // image list multi-edit - event="image", step contains image_multi_edit
$adi_recent_tab_exclude_combo[] = array('event' => '^image$', 'step' => 'image_replace'); // image replace - event="image", step contains image_multi_edit
$adi_recent_tab_exclude_combo[] = array('event' => '^image$', 'step' => 'list'); // image list - event="image", step contains list (search results=image_list,sort=list)
$adi_recent_tab_exclude_combo[] = array('event' => '^image$', 'step' => '^thumbnail_insert$'); // thumbnail upload - event="image", step=thumbnail_insert
$adi_recent_tab_exclude_combo[] = array('event' => '^page$', 'step' => 'page_new'); // new page tab - event="page", step contains page_new
$adi_recent_tab_exclude_combo[] = array('event' => '^form$', 'step' => 'form_multi_edit'); // form list multi-edit - event="form", step contains form_multi_edit
$adi_recent_tab_exclude_combo[] = array('event' => '^link$', 'step' => 'link_edit', 'id' => '^$'); // link list tab
$adi_recent_tab_exclude_combo[] = array('event' => '^link$', 'id' => '^$'); // TXP 4.5 link list tab
$adi_recent_tab_exclude_combo[] = array('event' => '^link$', 'step' => 'link_multi_edit'); // link list tab - event="link", step contains link_multi_edit
$adi_recent_tab_exclude_combo[] = array('event' => '^file$', 'step' => '^$'); // file list tab - event="file", step=blank
$adi_recent_tab_exclude_combo[] = array('event' => '^file$', 'step' => 'file_replace'); // file replace - event="file", step contains file_replace
$adi_recent_tab_exclude_combo[] = array('event' => '^file$', 'step' => 'list'); // file list - event="file", step contains list (search results=file_list,sort=list)
$adi_recent_tab_exclude_combo[] = array('event' => '^css$', 'step' => 'pour'); // style list tab - event="css", step=pour (create style)
$adi_recent_tab_exclude_combo[] = array('event' => '^section$', 'step' => 'section_edit', 'name' => '^$'); // empty section create tab (TXP 4.5.0)
$adi_recent_tab_exclude_combo[] = array('event' => '^section$', 'step' => 'list'); // section list - event="section", step contains list (search results=sec_section_list,sort=list)
$adi_recent_tab_exclude_combo[] = array('event' => '.*', 'step' => 'save'); // any step containing "save" (e.g. page_save, form_save, link_save)
$adi_recent_tab_exclude_combo[] = array('event' => '.*', 'step' => 'create'); // any step containing "create" (e.g. new article create, form create)
$adi_recent_tab_exclude_combo[] = array('event' => '.*', 'step' => 'apply'); // any step containing "apply" - just in case!
$adi_recent_tab_exclude_combo[] = array('event' => '.*', 'step' => 'update'); // any step containing "update" - just in case!
$adi_recent_tab_exclude_combo[] = array('event' => '.*', 'step' => 'delete'); // any step containing "delete" - just in case!
$adi_recent_tab_exclude_combo[] = array('event' => '.*', 'step' => 'change_pageby'); // any step containing "change_pageby", e.g. image_change_pageby, when changing # per page
// don't log initial page/form/style tab visit (i.e. default by default)
$adi_recent_tab_exclude_combo[] = array('event' => '^page$', 'step' => '^$', 'name' => '^$'); // default page tab (i.e. edit default)
$adi_recent_tab_exclude_combo[] = array('event' => '^form$', 'step' => '^$', 'name' => '^$'); // default form tab (i.e. edit default)
$adi_recent_tab_exclude_combo[] = array('event' => '^css$', 'step' => '^$', 'name' => '^$'); // default style tab (i.e. edit default)
$adi_recent_tab_exclude_combo[] = array('event' => '^section$', 'step' => '^$', 'name' => '^$'); // default section list tab (TXP 4.5.0)
// oh, go on then ...
$adi_recent_tab_include_combo[] = array('event' => 'page', 'step' => 'page_save'); // create new page
$adi_recent_tab_include_combo[] = array('event' => 'form', 'step' => 'form_save'); // create new form
$adi_recent_tab_include_combo[] = array('event' => 'css', 'step' => 'css_save'); // create new form
$adi_recent_tab_include_combo[] = array('event' => 'file', 'step' => 'file_create'); // create file from existing
$adi_recent_tab_include_combo[] = array('event' => 'link', 'step' => 'link_post'); // create new link (pre-4.5.0)
$adi_recent_tab_include_combo[] = array('event' => 'link', 'step' => 'link_save'); // create new link (post-4.5.0)
$adi_recent_tab_include_combo[] = array('event' => 'section', 'step' => 'section_save'); // create new section (TXP 4.5.0+)
// preferences & defaults
$adi_recent_tab_prefs = array(
'adi_recent_tab_privs' => array('value' => '1,2,3,4,5,6', 'blank' => 1, 'private' => 0, 'input' => 'custom', 'label' => 'adi_plugin_privs', 'tab' => 'options'), // allowed to use plugin
'adi_recent_tab_list' => array('value' => implode(',',$adi_recent_tab_include), 'blank' => 0, 'private' => 1, 'input' => 'custom', 'label' => 'adi_include', 'tab' => 'admin'),
'adi_recent_tab_max_items' => array('value' => '5', 'blank' => 0, 'private' => 1, 'input' => 'text_input', 'label' => 'adi_recent_tab_max_items', 'tab' => 'admin'),
'adi_recent_tab_ids' => array('value' => '1', 'blank' => 1, 'private' => 1, 'input' => 'yesnoradio', 'label' => 'adi_include_ids', 'tab' => 'admin'),
'adi_recent_tab_img_alt' => array('value' => '1', 'blank' => 1, 'private' => 1, 'input' => 'yesnoradio', 'label' => 'alt_text', 'tab' => 'admin'),
);
// plugin privs to be excluded
$adi_recent_tab_outlaws = array(0);
// who's playing today?
add_privs('adi_recent_tab',adi_recent_tab_pref('adi_recent_tab_privs')); // recent items tab
add_privs('tab.recent',adi_recent_tab_pref('adi_recent_tab_privs')); // recent items menu
// do the business
if (adi_recent_tab_installed() && has_privs('adi_recent_tab')) {
// menu style for all
register_callback('adi_recent_tab_menu_style','admin_side','head_end');
// tab style for tab only
if ($event == "adi_recent_tab")
register_callback('adi_recent_tab_style','admin_side','head_end');
// adi_recent_tab tab
register_callback("adi_recent_tab","adi_recent_tab");
$textarray['tab_recent'] = gTxt('adi_recent_tab'); // to get something meaningful into tab
// put logger in the footer - to catch the elusive newly created article/image IDs etc
register_callback('adi_recent_tab_logger','admin_side','footer');
// TXP 4.5: recent tab under recent items menu; TXP 4.6: recent tab under extensions menu (due to lack of top-level click-through)
if ($adi_recent_tab_txp460) {
// recent items tab under extensions
register_tab('extensions','adi_recent_tab',gTxt('adi_recent_items'));
// separate recent items menu
add_privs('adi_recent_tab_menu',adi_recent_tab_pref('adi_recent_tab_privs')); // recent items tab
register_tab('recent','adi_recent_tab_menu',gTxt('adi_recent_items'));
register_callback('adi_recent_tab_menu','adi_recent_tab_menu');
// inject markup to create recent items menu
register_callback('adi_recent_tab_menu_markup_mega','admin_side','footer'); // markup in the footer, shifted by jQuery
}
else {
// recent items tab under separate recent items menu
register_tab('recent','adi_recent_tab',gTxt('adi_recent_items'));
// inject markup to create recent items menu
adi_recent_tab_menu_ob();
}
}
// script
if ($adi_recent_tab_txp460)
register_callback('adi_recent_tab_script','admin_side','head_end');
// plugin options
$adi_recent_tab_plugin_status = fetch('status','txp_plugin','name','adi_recent_tab');
if ($adi_recent_tab_plugin_status) { // proper install - options under Plugins tab
add_privs('plugin_prefs.adi_recent_tab','1,2,6');
register_callback('adi_recent_tab_options','plugin_prefs.adi_recent_tab');
}
else { // txpdev - options under Extensions tab
add_privs('adi_recent_tab_options','1,2,6');
register_tab('extensions','adi_recent_tab_options','adi_recent_tab options');
register_callback('adi_recent_tab_options','adi_recent_tab_options');
}
}
function adi_recent_tab_style() {
// style for tab
echo
'<style type="text/css">
/* adi_recent_tab */
#adi_recent_tab_tab, #adi_recent_tab_tab ul { overflow:hidden; list-style:none; margin:0; padding:0 }
#adi_recent_tab_tab li { list-style:none; margin:0; padding:0 }
#adi_recent_tab_tab > li { float:left; width:47%; margin:0 6% 1% 0 }
#adi_recent_tab_tab > li:nth-child(2n) { margin-right:0 }
#adi_recent_tab .adi_recent_tab_prefs { margin:4em 0 2em; border-top:1px solid #ccc }
#adi_recent_tab input.adi_recent_tab_max_items { width:3em }
/* responsive */
@media (max-width: 47em) {
#adi_recent_tab_tab > li { float:none; width:100% }
.adi_recent_tab_prefs p.adi_recent_tab_list label { display:block; margin-top:0.5em }
}
/* TXP 4.5 */
div.txp-body h1, div.txp-body h2 { font-weight:bold }
div.txp-body .adi_recent_tab_prefs h2 { margin-top:0.5em }
/* Hive TXP 4.5 adjustments - recent tab page given class="recent" which is Hive styling for Recent Articles! */
.txp-nav li { margin-left:0 }
</style>';
}
function adi_recent_tab_menu_style() {
// style for dropdown menu
echo
'<style type="text/css">
/* adi_recent_tab */
/* TXP 4.5 Remora */
#nav .adi_recent_tab_menu_title { font-weight:bold }
#nav a[href="?event=adi_recent_tab"] + ul { width:25em; padding-top:0.5em; padding-bottom:0.5em }
#nav a[href="?event=adi_recent_tab"] + ul li { width:auto; height:auto }
#nav a[href="?event=adi_recent_tab"] + ul li:first-child { display:none }
#nav a[href="?event=adi_recent_tab"] + ul li a { width:23em; height:auto; line-height:1.2; padding-top:0.3em; padding-bottom:0.3em }
#nav a[href="?event=adi_recent_tab"] + ul li a span { font-weight:bold }
.txp-header #nav a[href="?event=adi_recent_tab"] + ul { z-index:9999 }
/* TXP 4.5 Hive */
div.txp-nav .adi_recent_tab_menu_title { font-weight:bold }
div.txp-nav a[href="?event=adi_recent_tab"] + ul { padding-bottom:0.5em }
div.txp-nav a[href="?event=adi_recent_tab"] + ul { width:25em }
div.txp-nav a[href="?event=adi_recent_tab"] + ul > li { float:none; width:auto }
div.txp-nav a[href="?event=adi_recent_tab"] + ul > li:hover { background-color:#ffefaf }
/* TXP 4.6 Hive */
nav.txp-nav a[href="?event=adi_recent_tab"] + ul > li:first-child { display:none }
nav.txp-nav a[href="?event=adi_recent_tab"] + ul { width:50em }
nav.txp-nav a[href="?event=adi_recent_tab"] + ul > li { float:left; width:50% }
nav.txp-nav a[href="?event=adi_recent_tab"] + ul > li:hover { background-color:transparent }
nav.txp-nav a[href="?event=adi_recent_tab"] + ul > li:nth-child(2n) { clear:left }
nav.txp-nav a[href="?event=adi_recent_tab"] + ul li h2 { margin:0.5em 0 0; font-size:1em }
nav.txp-nav a[href="?event=adi_recent_tab"] + ul li h2:hover { background-color:#ffefaf }
nav.txp-nav a[href="?event=adi_recent_tab"] + ul li a { width:auto; padding-top:0.3em; padding-bottom:0.3em; word-wrap:break-word }
nav.txp-nav a[href="?event=adi_recent_tab"] + ul ul { width:auto }
nav.txp-nav a[href="?event=adi_recent_tab"] + ul { left:-20em; border-radius:0.5em }
nav.txp-nav a[href="?event=adi_recent_tab"] + ul:before { left:18em } /* the pointy bit */
/* bot_write_tab_customize tab overrides */
body#page-bot_wtc_tab .txp-nav a[href="?event=adi_recent_tab"] + ul li h2 { margin:0.5em 0 0; padding:0; text-align:left }
/* responsive */
@media (max-width: 47em) {
nav.txp-nav a[href="?event=adi_recent_tab"] + ul { width:auto }
nav.txp-nav a[href="?event=adi_recent_tab"] + ul li a { width:auto; padding-top:0.5em; padding-bottom:0.5em }
}
</style>';
}
function adi_recent_tab_script() {
// scriptimus
echo <<<END_SCRIPT
<script type="text/javascript">
$(function() {
// adi_recent_tab menu
var closest_ul = $('a[href="?event=adi_recent_tab_menu"]').closest("ul"); // find (grand)parent ul
var menu_id = $(closest_ul).attr('id'); // i.e. "#txp-nav-dropX-menu"
$("ul#adi_recent_tab_inject > li").insertAfter($("ul#" + menu_id + " li")); // shift recent menu items from footer
$("ul#adi_recent_tab_inject").remove(); // footer housekeeping
var top_link = $(closest_ul).prev(); // get top level menu item link
$(top_link).attr("href","?event=adi_recent_tab"); // restore click-through to recent_tab tab (also allows some styles to kick in)
});
</script>
END_SCRIPT;
}
function adi_recent_tab_logger() {
// monitor each TXP admin page visit & decide what's to be recorded by adi_recent_tab
global $DB,$adi_recent_tab_debug,$event,$step,$txp_user,$adi_recent_tab_include,$adi_recent_tab_exclude_combo,$adi_recent_tab_include_combo,$adi_recent_tab_txp460;
if (!adi_recent_tab_installed()) // in case it's just been uninstalled
return;
$id = gps('id'); // image id
$name = gps('name'); // section/page/form/image name
if ($adi_recent_tab_debug) {
echo 'Event='.$event.', Final Step='.$step.', supplied id='.$id.', supplied name='.$name.'<br/>';
echo 'Include event list:';
dmp($adi_recent_tab_include);
echo 'Exclude combo list:';
dmp($adi_recent_tab_exclude_combo);
echo 'Include combo list:';
dmp($adi_recent_tab_include_combo);
}
// process included & excluded events/steps
// events of interest
$exclude = array_search($event,$adi_recent_tab_include) === FALSE;
if ($adi_recent_tab_debug && $exclude)
echo '($adi_recent_tab_include) EXCLUDE EVENT: '.$event.'<br/>';
// sort the men from the boys
if (!$exclude) {
// event/step combos to be discounted
$exclude = adi_recent_tab_filter($adi_recent_tab_exclude_combo,$event,$step,$id,$name);
if ($adi_recent_tab_debug && $exclude)
echo '($adi_recent_tab_exclude_combo) '."EXCLUDED EVENT/STEP/ID/NAME: $event,$step,$id,$name<br/>";
// explicitly include these combos
$include = adi_recent_tab_filter($adi_recent_tab_include_combo,$event,$step,$id,$name);
if ($adi_recent_tab_debug && $include)
echo '($adi_recent_tab_include_combo) '."INCLUDED EVENT/STEP/ID/NAME: $event,$step,$id,$name<br/>";
if ($include)
$exclude = FALSE;
}
if (!$exclude) { // massage stuff
// ID
if (empty($id)) // try finding an article ID
$id = gps('ID');
if (isset($GLOBALS['ID'])) // set the "newly created" ID to something
$globals_id = $GLOBALS['ID'];
else
$globals_id = '';
if (empty($id) && ($event == 'article')) // i.e. a newly created article
$id = $globals_id;
if (empty($id) && ($event == 'image')) // i.e. a newly created image
$id = $globals_id;
if (empty($id) && ($event == 'link')) // i.e. a newly created link
$id = $globals_id;
if (empty($id) && ($event == 'file')) // i.e. a newly uploaded file
$id = $globals_id;
// NAME
if (($event == 'section') && ($step == 'section_save'))
$name = strtolower(sanitizeForUrl($name)); // sanitise (create/edit) section name (from txp_section.php)
if ((($event == 'page') || ($event == 'form')) && empty($name)) // fill in the "default" blank - needed if logging initial page/form tab visit
$name = 'default';
if ($event == 'image') // don't want to store image name coz we've got the ID (& the name might change)
$name = '';
$newname = sanitizeForPage(gps('newname')); // sanitise (create/copy) page name
if ($newname)
$name = $newname;
// STEP
$this_step = $step;
if (($event== 'image') && ($step == 'image_insert')) // tweak step - new image
$this_step = 'image_edit';
if (($event== 'page') && ($step == 'page_save')) // new/save page
$this_step = '';
if (($event== 'form') && ($step == 'form_save')) // new/save form
$this_step = 'form_edit';
if (($event== 'css') && ($step == 'css_save')) // new style/save style
$this_step = '';
if (($event== 'form') && ($step == '')) // tweak step - click between forms
$this_step = 'form_edit';
if (($event== 'link') && ($step == 'link_post')) // new link (pre-4.5.0)
$this_step = 'link_edit';
if (($event== 'link') && ($step == 'link_save')) // new link (post-4.5.0)
$this_step = 'link_edit';
if (($event== 'section') && ($step == 'section_save')) // new section (post-4.5.0)
$this_step = 'section_edit';
if (($event== 'file') && ($step == 'file_insert')) // new file
$this_step = 'file_edit';
if (($event== 'file') && ($step == 'file_create')) // new file from existing
$this_step = 'file_edit';
if ($adi_recent_tab_debug)
echo 'Event='.$event.', this_step='.$this_step.', massaged id='.$id.', massaged name='.$name.'<br/>';
if ($id == '' && (($event == 'article') || ($event == 'image') || ($event == 'link') || ($event == 'file'))) {
if ($adi_recent_tab_debug)
echo 'No ID, no update!';
}
else {
// update adi_recent_tab DB table
$table = 'adi_recent_tab';
$set = 'timestamp=now(), user="'.doSlash($txp_user).'", event="'.doSlash($event).'", step="'.doSlash($this_step).'", id="'.doSlash($id).'", name="'.doSlash($name).'"';
$where = 'user="'.$txp_user.'" AND event="'.$event.'" AND step="'.$this_step.'" AND id="'.$id.'" AND name="'.$name.'"';
// it's me own safe_upsert ...
$r = safe_update($table,$set,$where,$adi_recent_tab_debug);
if ($adi_recent_tab_txp460) {
if (!($r and (mysqli_affected_rows($DB->link) or safe_count($table,$where,$adi_recent_tab_debug))))
safe_insert($table,$set,$adi_recent_tab_debug);
}
else {
if (!($r and (mysql_affected_rows() or safe_count($table,$where,$adi_recent_tab_debug))))
safe_insert($table,$set,$adi_recent_tab_debug);
}
}
}
// tidy up
adi_recent_tab_housekeeping();
}
function adi_recent_tab_filter($pattern_list,$event,$step,$id='',$name='') {
// look for combination matches
$match = FALSE;
foreach ($pattern_list as $pair) {
$this_match = TRUE;
foreach ($pair as $var => $pattern)
$this_match = $this_match && preg_match('/'.$pattern.'/',$$var);
$match = $match || $this_match;
}
return $match;
}
function adi_recent_tab_installed($table='adi_recent_tab') {
// test if table is present
$rs = safe_query("SHOW TABLES LIKE '".safe_pfx($table)."'");
$a = nextRow($rs);
if ($a)
return TRUE;
else
return FALSE;
}
function adi_recent_tab_install() {
// install adi_recent_tab table in database
global $adi_recent_tab_debug;
$res = safe_query(
// 'id' is a VARCHAR (rather than an INT) coz I need it to be blank sometimes
"CREATE TABLE IF NOT EXISTS ".safe_pfx('adi_recent_tab')
."( `timestamp` datetime NOT NULL default '0000-00-00 00:00:00',
`user` VARCHAR(64) NOT NULL DEFAULT '',
`event` VARCHAR(64) NOT NULL DEFAULT '',
`step` VARCHAR(64) NOT NULL DEFAULT '',
`id` VARCHAR(12) NOT NULL DEFAULT '',
`name` VARCHAR(64) NOT NULL DEFAULT ''
);"
,$adi_recent_tab_debug);
return $res;
}
function adi_recent_tab_uninstall() {
// uninstall adi_recent_tab
global $adi_recent_tab_debug,$adi_recent_tab_prefs;
// delete table
$res = safe_query("DROP TABLE ".safe_pfx('adi_recent_tab').";",$adi_recent_tab_debug);
// delete preferences
foreach ($adi_recent_tab_prefs as $this_pref => $value)
$res = $res && safe_delete('txp_prefs',"name = '$this_pref'",$adi_recent_tab_debug);
return $res;
}
function adi_recent_tab_lifecycle($event,$step) {
// a matter of life & death
// $event: "plugin_lifecycle.adi_recent_tab"
// $step: "installed", "enabled", disabled", "deleted"
// install/reinstall: "installed"; make active: "enabled"; make inactive: "disabled"; delete: "disabled" then "deleted"
// (as of TXP 4.5, reinstall only triggers "installed" event)
// adi_lifecycle: "installed" -> install() regardless, upgrade() if required; "deleted" -> uninstall(); "enabled" & disabled" -> do nothing
global $adi_recent_tab_debug;
$result = $upgrade_required = '?';
if ($step == 'installed') {
$result = adi_recent_tab_install();
// $upgrade_required = adi_recent_tab_upgrade();
// if ($upgrade_required)
// $result &= adi_recent_tab_upgrade(TRUE);
}
if ($step == 'deleted')
$result = adi_recent_tab_uninstall();
if ($adi_recent_tab_debug)
echo "event=$event,step=$step,result=$result,upgrade_required=$upgrade_required";
}
function adi_recent_tab_housekeeping() {
// delete oldest recents that exceed max count; make sure items still exist in DB
global $adi_recent_tab_debug,$txp_user,$adi_recent_tab_include,$adi_recent_tab_prefs;
$max_recent = adi_recent_tab_pref('adi_recent_tab_max_items');
$sort = ' ORDER BY timestamp desc';
$default_where = " AND user='$txp_user'";
if ($adi_recent_tab_debug)
echo '<br/>Housekeeping (deceased entries):<br/>';
// delete entries that don't exist ... the recently deceased
foreach ($adi_recent_tab_include as $recent) {
$table = 'txp_'.$recent;
if ($recent == 'article')
$table = 'textpattern';
$rs = safe_rows('*','adi_recent_tab',"event='".$recent."'".$default_where.$sort,$adi_recent_tab_debug);
foreach ($rs as $index => $row) {
extract($row);
// "id" entries
if (($recent == 'article') || ($recent == 'image') || ($recent == 'link') || ($recent == 'file')) {
$row = safe_row('*',$table,"id='$id'",$adi_recent_tab_debug);
if (empty($row)) {
$where = 'user="'.$txp_user.'" AND event="'.$event.'" AND step="'.$step.'" AND id="'.$id.'" AND name="'.doSlash($name).'"';
safe_delete('adi_recent_tab',$where,$adi_recent_tab_debug);
}
}
// "name" entries
if (($recent == 'page') || ($recent == 'form') || ($recent == 'css') || ($recent == 'section')) {
$row = safe_row('*',$table,"name='".doSlash($name)."'",$adi_recent_tab_debug);
if (empty($row)) {
$where = 'user="'.$txp_user.'" AND event="'.$event.'" AND step="'.$step.'" AND id="'.$id.'" AND name="'.doSlash($name).'"';
safe_delete('adi_recent_tab',$where,$adi_recent_tab_debug);
}
}
}
}
if ($adi_recent_tab_debug)
echo 'Housekeeping (remove surplus):<br/>';
// lose the surplus
foreach ($adi_recent_tab_include as $recent) {
$rs = safe_rows('*','adi_recent_tab',"event='".$recent."'".$default_where.$sort,$adi_recent_tab_debug);
if (count($rs) > $max_recent)
foreach ($rs as $index => $row) {
extract($row);
if (!($index < $max_recent)) {
$where = 'user="'.$txp_user.'" AND event="'.$event.'" AND step="'.$step.'" AND id="'.$id.'" AND name="'.doSlash($name).'"'; // BIG GLOBAL FOR THIS WHERE???
safe_delete('adi_recent_tab',$where,$adi_recent_tab_debug);
}
}
}
}
function adi_recent_tab_links($event,$wrap=TRUE) {
// return a <ul><li> or <li> of all the "recent" links
global $adi_recent_tab_debug,$adi_recent_tab_prefs,$txp_user;
// $sort_method = 'timestamp';
$sort_method = 'alphanumeric';
$default_where = " AND user = '$txp_user'";
if ($sort_method == 'timestamp') {
$sort = ' ORDER BY timestamp desc';
$rs = safe_rows('*','adi_recent_tab',"event = '$event'".$default_where.$sort,$adi_recent_tab_debug);
}
else if ($sort_method == 'alphanumeric') {
if ($event == 'article') {
$sort = ' ORDER BY Title';
$rs = safe_rows('Title,textpattern.ID,adi_recent_tab.*','textpattern, adi_recent_tab',"event = '$event' AND textpattern.ID = adi_recent_tab.id".$default_where.$sort,$adi_recent_tab_debug);
}
else if ($event == 'image') {
$sort = ' ORDER BY alt,txp_image.name';
// note that actual name is last in list of fields - image name not stored by adi_recent_tab, so don't want blank to override proper name
$rs = safe_rows('adi_recent_tab.*,alt,txp_image.name','txp_image, adi_recent_tab',"event = '$event' AND txp_image.id = adi_recent_tab.id".$default_where.$sort,$adi_recent_tab_debug);
}
else if ($event == 'file') {
$sort = ' ORDER BY title,filename';
$rs = safe_rows('title,filename,adi_recent_tab.*','txp_file, adi_recent_tab',"event = '$event' AND txp_file.id = adi_recent_tab.id".$default_where.$sort,$adi_recent_tab_debug);
}
else if ($event == 'link') {
$sort = ' ORDER BY linkname,url';
$rs = safe_rows('linkname,url,adi_recent_tab.*','txp_link, adi_recent_tab',"event = '$event' AND txp_link.id = adi_recent_tab.id".$default_where.$sort,$adi_recent_tab_debug);
}
else { // page, form, style, section
$sort = ' ORDER BY name';
$rs = safe_rows('*','adi_recent_tab',"event='$event'".$default_where.$sort,$adi_recent_tab_debug);
}
}
if ($adi_recent_tab_debug)
dmp($rs);
$out = '';
foreach ($rs as $index => $row) {
$item = '';
extract($row);
// link text fiddling
if ($event == 'article') { // use article title, or Untitled if empty
$Title = trim($Title);
if (empty($Title))
$link_text = gTxt('untitled');
else
$link_text = $Title;
}
else if ($event == 'image') { // use alt text, or name if blank
$alt = trim($alt);
if (empty($alt) || !adi_recent_tab_pref('adi_recent_tab_img_alt'))
$link_text = $name;
else
$link_text = $alt;
}
else if ($event == 'link') { // use link name, or url if blank
$linkname = trim($linkname);
if (empty($linkname))
$link_text = $url;
else
$link_text = $linkname;
}
else if ($event == 'file') { // use title, or filename if blank
$title = trim($title);
if (empty($title))
$link_text = $filename;
else
$link_text = $title;
}
else if ($event == 'section') // use name
$link_text = $name;
// include IDs?
if (adi_recent_tab_pref('adi_recent_tab_ids') && ($id != ''))
$link_text .= ' ('.tag($id,'span').')';
// links to items
if ($event == 'article')
$item .= '<a href="?event='.$event.a.'step='.$step.a.'ID='.$id.'">'.$link_text.'</a>';
else if (($event == 'image') || ($event == 'link') || ($event == 'file'))
$item .= '<a href="?event='.$event.a.'step='.$step.a.'id='.$id.'">'.$link_text.'</a>';
else if ($event == 'section')
$item .= '<a href="?event='.$event.a.'step='.$step.a.'name='.$name.'">'.$link_text.'</a>';
else
$item .= '<a href="?event='.$event.a.'name='.$name.'">'.$name.'</a>';
$out .= tag($item,'li',' class="adi_recent_tab_menu_item"').n;
}
if ($wrap)
return tag($out,'ul');
else
return $out;
}
function adi_recent_tab($event,$step) {
// the page that displays all the "recent" links
global $adi_recent_tab_debug,$adi_recent_tab_event_gtxt,$adi_recent_tab_include,$adi_recent_tab_prefs,$adi_recent_tab_txp460;
$message= '';
if ($step == 'update_prefs') {
$result = adi_recent_tab_update_prefs('admin');
$result ? $message = gTxt('preferences_saved') : $message = array(gTxt('adi_pref_update_fail'),E_ERROR);
adi_recent_tab_housekeeping(); // do extra housekeeping to reflect possible change in max items (habitually done at bottom of page)
}
// generate page
pagetop('adi_recent_tab '.gTxt('adi_recent_tab'),$message);
echo '<div id="adi_recent_tab">';
echo tag(gTxt('adi_recent_items'),'h1');
// generate list of recents
echo tag(implode(n,adi_recent_tab_list_markup()),'ul',' id="adi_recent_tab_tab"');
// preferences
echo adi_recent_tab_pref_inputs($event,'admin');
echo '</div>';
if ($adi_recent_tab_debug)
echo adi_recent_tab_db_dump();
}
function adi_recent_tab_menu_ob() {
// the old-fashioned magic that gets the recent items into adi_recent_tab's menu - TXP 4.5
ob_start('adi_recent_tab_menu_inject');
}
function adi_recent_tab_menu_inject($buffer) {
// another bit of arcane magic - TXP 4.5
global $DB, $adi_recent_tab_txp460;
if(!isset($DB)) $DB = new db;
$pattern = '#'.gTxt('adi_recent_items').'</a></li>#sU';
$insert = 'adi_recent_tab_menu_markup';
$buffer = preg_replace_callback($pattern, $insert, $buffer); // this causes grief in 4.6 (seemingly just for me!)
return $buffer;
}
function adi_recent_tab_menu_markup($matches) {
// generate markup for adi_recent_tab recent item lists - TXP 4.5
global $adi_recent_tab_event_gtxt,$adi_recent_tab_include,$adi_recent_tab_prefs;
$out = '';
$tab_list = do_list(adi_recent_tab_pref('adi_recent_tab_list'));
foreach ($tab_list as $this_event) {
$link_event = $this_event;
if ($this_event == 'article')
$link_event = 'list';
$out .=
'<li><a class="adi_recent_tab_menu_title" href="?event='.$link_event.'">'
.gTxt($adi_recent_tab_event_gtxt[$this_event])
.'</a></li>'
.adi_recent_tab_links($this_event,FALSE);
}
return $matches[0].$out;
}
function adi_recent_tab_list_markup() {
// generate markup for dropdown or tab
// <ul>
// <li>
// <h2><a>TAB</a></h2>
// <a>RECENT LINK 1</a>
// <a>RECENT LINK 2</a> etc
// </li>
global $adi_recent_tab_event_gtxt,$adi_recent_tab_include,$adi_recent_tab_prefs;
$out = array();
$tab_list = do_list(adi_recent_tab_pref('adi_recent_tab_list'));
foreach ($tab_list as $index => $this_event) {
$tab_event = $this_event;
if ($this_event == 'article')
$tab_event = 'list';
$out[] =
tag(
tag(
'<a href="?event='.$tab_event.'">'.gTxt($adi_recent_tab_event_gtxt[$this_event]).'</a>'
,'h2'
)
.adi_recent_tab_links($this_event)
,'li'
);
}
return $out;
}
function adi_recent_tab_menu_markup_mega() {
// generate mega menu markup - TXP 4.6
echo tag(implode(n,adi_recent_tab_list_markup()),'ul',' id="adi_recent_tab_inject"');
}
function adi_recent_tab_db_dump($table='adi_recent_tab') {
// print out contents of database table
$result = mysql_query("SELECT * FROM {$table}");
$fields_num = mysql_num_fields($result);
$out = "<br/><table><tr>";
// table headers
for ($i = 0; $i < $fields_num; $i++) {
$field = mysql_fetch_field($result);
$out .= "<td><b>{$field->name}</b> </td>";
}
$out .= "</tr>";
// table rows
while ($row = mysql_fetch_row($result)) {
$out .= "<tr>";
foreach($row as $cell)
$out .= "<td>$cell </td>";
$out .= "</tr>";
}
$out .= '</table><br/>';
return $out;
}
function adi_recent_tab_pref($name,$value=NULL,$private=FALSE) {
// read or set pref
global $prefs,$adi_recent_tab_prefs;
if ($value === NULL)
return get_pref($name,$adi_recent_tab_prefs[$name]['value']);
else {
if (array_key_exists($name,$adi_recent_tab_prefs))
$html = $adi_recent_tab_prefs[$name]['input'];
else
$html = 'text_input';
$res = set_pref($name,$value,'adi_recent_tab_admin',2,$html,0,$private);
$prefs[$name] = get_pref($name,$adi_recent_tab_prefs[$name]['value'],TRUE);
return $res;
}
}
function adi_recent_tab_pref_inputs($event,$tab=NULL) {
// output preference input fields accoring to options/admin setting
global $txp_groups,$adi_recent_tab_prefs,$adi_recent_tab_outlaws,$adi_recent_tab_admin_outlaws,$adi_recent_tab_include,$adi_recent_tab_event_gtxt;
if ($tab === NULL) return;
$out = '';
foreach ($adi_recent_tab_prefs as $pref_name => $pref_info) {
if ($pref_info['tab'] == $tab) {
switch ($pref_info['input']) {
case 'yesnoradio':
$out .=
graf(
tag(gTxt($pref_info['label']),'label')
.sp.sp
.tag(radio($pref_name,'0',(adi_recent_tab_pref($pref_name) == '0')).sp.gTxt('no'),'label')
.sp.sp
.tag(radio($pref_name,'1',(adi_recent_tab_pref($pref_name) == '1')).sp.gTxt('yes'),'label')
,' class="'.$pref_name.'"'
);
break;
case 'custom':
// admin privs
if ($pref_name == 'adi_recent_tab_admin_privs') {
$priv_out = gTxt($pref_info['label']);
$admin_privs = do_list(adi_recent_tab_pref('adi_recent_tab_admin_privs'));
foreach ($txp_groups as $index => $group)
if (array_search($index,$adi_recent_tab_admin_outlaws) === FALSE) // ignore the outlaws
$priv_out .= tag(sp.sp.checkbox2("adi_recent_tab_admin_privs[$index]",(array_search($index,$admin_privs) !== FALSE),'','adi_recent_tab_admin_privs').sp.gTxt($group),'label');
$out .= graf($priv_out,' class="'.$pref_name.'"');
}
// plugin privs
if ($pref_name == 'adi_recent_tab_privs') {
$priv_out = gTxt($pref_info['label']);
$plugin_privs = do_list(adi_recent_tab_pref('adi_recent_tab_privs'));
foreach ($txp_groups as $index => $group)
if (array_search($index,$adi_recent_tab_outlaws) === FALSE) // ignore the outlaws
$priv_out .= tag(sp.sp.checkbox2("adi_recent_tab_privs[$index]",(array_search($index,$plugin_privs) !== FALSE),'','adi_recent_tab_privs').sp.gTxt($group),'label');
$out .= graf($priv_out,' class="'.$pref_name.'"');
}
// tab visibility
if ($pref_name == 'adi_recent_tab_list') {
$checkboxes = gTxt($pref_info['label']);
$tab_list = do_list(adi_recent_tab_pref('adi_recent_tab_list'));
foreach ($adi_recent_tab_include as $tab_name) {
$checked = array_search($tab_name,$tab_list) !== FALSE;
$checkboxes .=
tag(
sp.sp
.checkbox("adi_recent_tab_list[$tab_name]",TRUE,$checked)
.sp
.gTxt($adi_recent_tab_event_gtxt[$tab_name])
,'label'
);
}
$out .= graf($checkboxes,' class="'.$pref_name.'"');
}
break;
default: // text_input
$out .=
graf(
tag(gTxt($pref_info['label']),'label')
.sp.sp
.finput('text',$pref_name,stripslashes(adi_recent_tab_pref($pref_name)),$pref_name)
,' class="'.$pref_name.'"'
);
break;
}
}
}
if ($out)
return form(
tag(
tag(gTxt('edit_preferences'),'h2')
.$out
.fInput('submit','do_something',gTxt('adi_update_prefs'),'smallerbox')
.eInput($event)
.sInput('update_prefs')
,'div'
,' class="adi_recent_tab_prefs"'
)
);
}
function adi_recent_tab_update_prefs($tab=NULL) {
// update prefs
global $txp_user,$adi_recent_tab_prefs;
if ($tab === NULL)
return FALSE;
else {
$result = TRUE;
foreach ($adi_recent_tab_prefs as $pref_name => $pref_info) {
if ($pref_info['tab'] == $tab) { // tab match?
if (array_key_exists($pref_name,$_POST))
$value = $_POST[$pref_name];
else if ($pref_info['input'] == 'yesnoradio')
$value = '0';
else
$value = $pref_info['value'];
if (is_array($value)) { // string-ify arrays
$values = array_keys($value); // need index values not 1s
if ($pref_name == 'adi_recent_tab_admin_privs') {
$user_priv = safe_field('privs','txp_users',"name='".doSlash($txp_user)."'");
$values = array_unique(array_merge($values,array(1,$user_priv))); // can't kill off Publisher or self
}
$value = implode(',',$values);
}
// some values not allowed to be blank, reset to default
if ((!$pref_info['blank']) && (trim($value) == ''))
$value = $adi_recent_tab_prefs[$pref_name]['value'];
// update pref
$private = ($pref_info['tab'] == 'options' ? FALSE : $pref_info['private']); // "options" prefs can't be private
$result &= adi_recent_tab_pref($pref_name,$value,$private);
}
}
return $result;
}
}
function adi_recent_tab_options($event,$step) {
// plugin options page
global $adi_recent_tab_debug,$adi_recent_tab_url,$textarray,$adi_recent_tab_prefs,$adi_recent_tab_include,$adi_recent_tab_event_gtxt,$adi_recent_tab_plugin_status;
$message = '';
// step-tastic
if ($step == 'textpack') {
if (function_exists('install_textpack')) {
$adi_textpack = file_get_contents($adi_recent_tab_url['textpack']);
if ($adi_textpack) {
$result = install_textpack($adi_textpack);
$message = gTxt('textpack_strings_installed', array('{count}' => $result));
$textarray = load_lang(LANG); // load in new strings
}
else
$message = array(gTxt('adi_textpack_fail'),E_ERROR);
}
}
else if ($step == 'install') {
$result = adi_recent_tab_install();
$result ? $message = gTxt('adi_installed') : $message = array(gTxt('adi_install_fail'),E_ERROR);
}
else if ($step == 'uninstall') {
$result = adi_recent_tab_uninstall();
$result ? $message = gTxt('adi_uninstalled') : $message = array(gTxt('adi_uninstall_fail'),E_ERROR);
}
else if ($step == 'update_prefs') {
$result = adi_recent_tab_update_prefs('options');
$result ? $message = gTxt('preferences_saved') : $message = array(gTxt('adi_pref_update_fail'),E_ERROR);
}
// generate page
pagetop('adi_recent_tab - '.gTxt('plugin_prefs'),$message);
// *nstall buttons
$install_button =
form(
fInput('submit','do_something',gTxt('install'),'publish','',"return verify('".gTxt('are_you_sure')."')")
.eInput($event).sInput('install')
);
$uninstall_button =
form(
fInput('submit','do_something',gTxt('adi_uninstall'),'publish','',"return verify('".gTxt('are_you_sure')."')")
.eInput($event).sInput('uninstall')
,'margin-top:3em'
);
if ($adi_recent_tab_plugin_status) // proper plugin install, so lifecycle takes care of install/uninstall
$install_button = $uninstall_button = '';
$installed = adi_recent_tab_installed();
// options
echo tag(
tag('adi_recent_tab '.gTxt('plugin_prefs'),'h2')
.( $installed ?
// link to plugin admin tab
graf(href(gTxt('adi_recent_items'),'?event=adi_recent_tab'))
// prefs
.adi_recent_tab_pref_inputs($event,'options')
// textpack links
.graf(href(gTxt('install_textpack'),'?event='.$event.a.'step=textpack'),' style="margin-top:3em"')
.graf(href(gTxt('adi_textpack_online'),$adi_recent_tab_url['textpack_download']))
.graf(href(gTxt('adi_textpack_feedback'),$adi_recent_tab_url['textpack_feedback']))
.$uninstall_button
: $install_button
)
,'div'
,' style="text-align:center; margin-bottom:3em"'
);
if ($adi_recent_tab_debug) {
echo '<b>$adi_textpack ('.$adi_recent_tab_url['textpack'].'):</b>';
$adi_textpack = file_get_contents($adi_recent_tab_url['textpack']);
dmp($adi_textpack);
}
}