PageRenderTime 59ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/mem_moderation/mem_moderation.php

https://bitbucket.org/Manfre/txp-plugins
PHP | 1447 lines | 1107 code | 258 blank | 82 comment | 114 complexity | d2ec2adf5df571c711293f3a8ebd65ab MD5 | raw file
  1. <?php
  2. // Copy this file to a new name like abc_myplugin.php. Edit the code, then
  3. // run this file at the command line to produce a plugin for distribution:
  4. // $ php abc_myplugin.php > abc_myplugin-0.1.txt
  5. // Plugin name is optional. If unset, it will be extracted from the current file name.
  6. // Uncomment and edit this line to override:
  7. $plugin['name'] = 'mem_moderation';
  8. $plugin['version'] = '0.7.6';
  9. $plugin['author'] = 'Michael Manfre';
  10. $plugin['author_uri'] = 'http://manfre.net/';
  11. $plugin['description'] = 'This plugin adds a generic moderation queue to Textpattern. A plugin can extend the moderation queue to support any type of content.';
  12. $plugin['type'] = 1; // 0 for regular plugin; 1 if it includes admin-side code
  13. @include_once('../zem_tpl.php');
  14. if (0) {
  15. ?>
  16. # --- BEGIN PLUGIN HELP ---
  17. h1(title). mem_moderation plugin
  18. h2(section summary). Summary
  19. p. This plugin adds a generic moderation queue to Textpattern. A plugin can extend the moderation queue to support any type of content.
  20. h2(section contact). Author Contact
  21. "Michael Manfre":mailto:mmanfre@gmail.com?subject=Textpattern%20mem_moderation%20plugin
  22. "http://manfre.net":http://manfre.net
  23. h2(section license). License
  24. p. This plugin is licensed under the "GPLv2":http://www.fsf.org/licensing/licenses/info/GPLv2.html.
  25. h2(section installation). Installation
  26. p. "Start Install Wizard":./index.php?event=moderate&step=preinstall
  27. h2(section tags). Tags
  28. * "mem_if_moderation":#mem_if_moderation
  29. * "mem_moderation_info":#mem_moderation_info
  30. * "moderate_submission_list":#moderate_submission_list
  31. * "mem_if_type":#mem_if_type
  32. * "mem_if_data":#mem_if_data
  33. * "mem_moderation_if_gps":#mem_moderation_if_gps
  34. * "mod_id":#mod_id
  35. * "mod_item_id":#mod_item_id
  36. * "mod_submitted":#mod_submitted
  37. * "mod_user":#mod_user
  38. * "mod_desc":#mod_desc
  39. * "mod_type":#mod_type
  40. * "mod_email":#mod_email
  41. * "mod_data":#mod_data
  42. * "mod_note_input":#mod_note_input
  43. h3(tag#mem_if_moderation). mem_if_moderation
  44. p(tag-summary). Conditionally parse a block of text based upon various checks.
  45. *(atts) %(atts-name)check% %(atts-type)string% Type of check to perform. Either 'type', 'data' or 'gps'
  46. * %(atts-name)name% %(atts-type)string% Name of the type, data field or GET/POST variable.
  47. * %(atts-name)value% %(atts-type)string% Value to compare against for 'data' and 'gps' checks.
  48. * %(atts-name delimiter)type% %(atts-type)string% Name of the form to identify itself to bound plugin.
  49. h3(tag#mem_moderation_info). mem_moderation_info
  50. p(tag-summary). Output information from a moderated item. Supported field names are 'id', 'item_id', 'submitted', 'user', 'desc', 'type', 'email' and 'data'.
  51. *(atts) %(atts-name)field% %(atts-type)string% Field to output.
  52. * %(atts-name)datafield% %(atts-type)string% The field from the encoded data. Field must be 'data'.
  53. * %(atts-name)format% %(atts-type)string% A time format to used to display the submitted time.
  54. h3(tag#moderate_submission_list). moderate_submission_list
  55. p(tag-summary). This will output an HTML text input field and validates the submitted value as an email address.
  56. *(atts) %(atts-name)form% %(atts-type)string% The form containing the formatting tags. If specified, tag enclosed text is ignored.
  57. * %(atts-name)type% %(atts-type)string% When set, this will restrict the list to specific types of moderated content.
  58. * %(atts-name)wraptag% %(atts-type)string% HTML tag to wrap around the output.
  59. * %(atts-name)break% %(atts-type)string% Text/HTML to separate each item in the list.
  60. * %(atts-name)breakclass% %(atts-type)string% CSS class name.
  61. * %(atts-name)class% %(atts-type)string% CSS class name.
  62. * %(atts-name)user% %(atts-type)string% Restrict the list to specified users. Defaults to logged in user.
  63. * %(atts-name)label% %(atts-type)string% Text/HTML that preceeds the list.
  64. * %(atts-name)labelwraptag% %(atts-type)string% HTML tag to wrap around the label.
  65. * %(atts-name)labelclass% %(atts-type)string% CSS class name for labelwraptag.
  66. h3(tag#mem_if_type). mem_if_type _(deprecated)_
  67. p(tag-summary). Conditionally parse a block of text based upon the current moderation type.
  68. *(atts) %(atts-name)name% %(atts-type)string% Name of the moderation to compare against.
  69. h3(tag#mem_if_data). mem_if_data _(deprecated)_
  70. p(tag-summary). Conditionally parse based upon specific moderation data.
  71. *(atts) %(atts-name)name% %(atts-type)string% Name of the data field.
  72. * %(atts-name)value% %(atts-type)string% Value to compare against. If blank, checks for existance.
  73. h3(tag#mem_moderation_if_gps). mem_moderation_if_gps _(deprecated)_
  74. p(tag-summary). Conditionally parse based upon a GET/POST variable.
  75. *(atts) %(atts-name)name% %(atts-type)string% Name of the GET/POST variable.
  76. * %(atts-name)value% %(atts-type)string% Value to compare against. If blank, checks for existance.
  77. h3(tag#mod_id). mod_id _(deprecated)_
  78. p(tag-summary). Output moderation id field.
  79. h3(tag#mod_item_id). mod_item_id _(deprecated)_
  80. p(tag-summary). Output moderation item_id field.
  81. h3(tag#mod_submitted). mod_submitted _(deprecated)_
  82. p(tag-summary). Output moderation submitted field.
  83. *(atts) %(atts-name)format% %(atts-type)string% Time format string.
  84. h3(tag#mod_user). mod_user _(deprecated)_
  85. p(tag-summary). Output moderation user field.
  86. h3(tag#mod_desc). mod_desc _(deprecated)_
  87. p(tag-summary). Output moderation desc field.
  88. h3(tag#mod_type). mod_type _(deprecated)_
  89. p(tag-summary). Output moderation type field.
  90. h3(tag#mod_email). mod_email _(deprecated)_
  91. p(tag-summary). Output moderation email field.
  92. h3(tag#mod_data). mod_data _(deprecated)_
  93. p(tag-summary). Output moderation data field.
  94. *(atts) %(atts-name)name% %(atts-type)string% Name of the moderation data field.
  95. h3(tag#mod_note_input). mod_note_input _(deprecated)_
  96. p(tag-summary). Outputs an HTML textarea to process the 'note' field.
  97. h3(tag#mem_moderation_edit_link). mem_moderation_edit_link
  98. p(tag-summary). Output a user side link to edit a specific moderation item.
  99. *(atts) %(atts-name)label% %(atts-type)string% Friendly name for the input field. If set, this will output an HTML ==<label>== tag linked to the input field.
  100. * %(atts-name)name% %(atts-type)string% Input field name.
  101. * %(atts-name)break% %(atts-type)string% Separator between label tag and input tag.
  102. * %(atts-name)delimiter% %(atts-type)string% List separator. Default ","
  103. * %(atts-name)items% %(atts-type)string% Delimited list containing a select list display values.
  104. * %(atts-name)values% %(atts-type)string% Delimited list containing a select list item values.
  105. * %(atts-name)required% %(atts-type)int% Specifies if input is required.
  106. * %(atts-name)selected% %(atts-type)string% The value of the selected item.
  107. * %(atts-name)first% %(atts-type)string% Display value of the first item in the list. E.g. "Select a Section" or "" for a blank option.
  108. * %(atts-name)class% %(atts-type)string% CSS class name.
  109. * %(atts-name)exclude% %(atts-type)string% List of item values that will not be included.
  110. * %(atts-name)sort% %(atts-type)string% How will the list values be sorted.
  111. h3(tag#mod_edit_link). mod_edit_link _(deprecated)_
  112. p(tag-summary). See mem_moderation_edit_link.
  113. h2(section). Exposed Functions
  114. h3(tag). register_moderation_type _(deprecated)_
  115. p(tag-summary). See mem_moderation_register.
  116. h3(tag). mem_moderation_register
  117. p(tag-summary). Registers a moderation type to be used in the moderation queue.
  118. *(atts) %(atts-name)type% %(atts-type)string% Moderation type name.
  119. * %(atts-name)vars% %(atts-type)array% Array of GET/POST variable used by this moderation type.
  120. * %(atts-name)presenter% %(atts-type)string% Name of the function that will construct a form to edit the plugin specific content. This is needed to allow moderators to edit submitted content.
  121. * %(atts-name)approver% %(atts-type)string% Name of callback function that will be called when an item is marked as approved.
  122. * %(atts-name)rejecter% %(atts-type)string% Name of callback function that will be called when an item is marked as rejected.
  123. h3(tag). submit_moderated_content
  124. p(tag-summary). Adds an item to the moderation queue.
  125. *(atts) %(atts-name)Return Value% %(atts-type)bool% Returns true or false, indicating whether the item was successfully added to the moderation queue.
  126. * %(atts-name)type% %(atts-type)string% Moderation type name.
  127. * %(atts-name)email% %(atts-type)string% Email of submitting user.
  128. * %(atts-name)desc% %(atts-type)string% Description of moderated item (note to moderater).
  129. * %(atts-name)data% %(atts-type)mixed% Moderation specific data to be encoded and stored with the item.
  130. * %(atts-name)item_id% %(atts-type)int% (optional) The ID of a content item not in the moderation queue. Used for when moderating edits of published content.
  131. h3(tag). update_moderated_content
  132. p(tag-summary). Updates an item in the moderation queue.
  133. *(atts) %(atts-name)Return Value% %(atts-type)bool% Returns true or false, indicating whether the item was successfully update in the moderation queue.
  134. * %(atts-name)id% %(atts-type)int% The ID of the moderated item.
  135. * %(atts-name)desc% %(atts-type)string% Description of moderated item (note to moderater).
  136. * %(atts-name)data% %(atts-type)mixed% Moderation specific data to be encoded and stored with the item.
  137. * %(atts-name)type% %(atts-type)string% (optional) Moderation type name.
  138. * %(atts-name)item_id% %(atts-type)int% (optional) The ID of a content item not in the moderation queue. Used for when moderating edits of published content.
  139. h3(tag). remove_moderated_content
  140. p(tag-summary). Remove an item from the moderation queue.
  141. *(atts) %(atts-name)Return Value% %(atts-type)bool% Returns boolean result of remove operation.
  142. * %(atts-name)id% %(atts-type%)int% ID of moderated item.
  143. h3(tag). mem_moderation_encode
  144. p(tag-summary). Serializes moderation data for storage.
  145. *(atts) %(atts-name)Return Value% %(atts-type)string% Returns a serialized string.
  146. * %(atts-name)content% %(atts-type%)mixed% The data to serialize.
  147. h3(tag). mem_moderation_decode
  148. p(tag-summary). Deserializes moderation data from storage.
  149. *(atts) %(atts-name)Return Value% %(atts-type)mixed% Returns the data.
  150. * %(atts-name)content% %(atts-type%)string% The serialized content.
  151. h2(section). Global Variables
  152. *(atts) %(atts-name)$mem_mod_info% %(atts-type)array% An array containing the moderation info. Can be used by tags inside moderate_submission_list.
  153. h2(section). Plugin Events
  154. p. This library allows other plugins to hook in to events with the @mem_moderation_register@ function. All callback functions have the structure of func($type, $data), where $type is the type name that is being processed and $data is the type specific data appended to the plugin.
  155. h3(event). presenter
  156. p(event-summary). A submitted item is being viewed by a moderator and the plugin's presenter handler should return HTML formatted form fields to enable the moderator to edit the data (no form tag or buttons).
  157. h3(event). approver
  158. p(event-summary). submitted item has been approved and the plugin's approver handler should submit $data to the appropriate place where live content resides.
  159. h3(event). rejecter
  160. p(event-summary). A submitted item has been rejected and is being removed from the queue.
  161. # --- END PLUGIN HELP ---
  162. <?php
  163. }
  164. # --- BEGIN PLUGIN CODE ---
  165. ////////////////////////////////////////////////////////////
  166. // Plugin mem_moderation
  167. // Author: Michael Manfre (http://manfre.net/)
  168. ////////////////////////////////////////////////////////////
  169. // the number of days that a newly submitted item will wait
  170. // before appearing in the moderation queue. 0 will disable
  171. //define('QUEUE_SUBMISSION_DELAY', "0");
  172. // Specify whether users with Publisher privs will have their
  173. // submitted content appear immediatly in the list without
  174. // waiting for the QUEUE_SUBMISSION_DELAY
  175. //define('PUBLISHERS_BYPASS_QUEUE_DELAY', true);
  176. ///////////////////////////////////////////////////////////
  177. // Do not modify below this line
  178. // MLP support
  179. define( 'MEM_MODERATION_PREFIX' , 'mem_moderation' );
  180. global $mem_moderation_lang;
  181. $mem_moderation_lang = array(
  182. 'id_not_found' => "Moderation ID {id} not found.",
  183. 'install_log' => "Install Log",
  184. 'invalid_arg' => "The argument {arg} is invalid.",
  185. 'missing_arg' => "The attribute {arg} is required and was not provided.",
  186. 'remove_failed' => "Failed to remove ID {id} from queue.",
  187. 'new_submission_email' => "The user {user} has submitted a request of type {type} to the moderation queue.",
  188. 'new_submission_email_subject' => "Moderation Queue",
  189. 'update_submission_email' => "The user {user} has updated their request of type {type} to the moderation queue.",
  190. 'update_submission_email_subject' => "Moderation Queue",
  191. 'table_access_failed' => "Error accessing the database table. {err}",
  192. // installation
  193. 'add_item_field' => 'Added item_id field to moderation table.',
  194. 'add_item_field_failed' => 'Failed to add field "item_id" to moderation table.',
  195. 'table_created' => "Created table {name}",
  196. 'table_create_failed' => "Failed to create moderation table. {mysql_error}",
  197. 'table_exists' => 'Moderation table already exists',
  198. 'form_found' => "Found form '{form}'. Skipping installation of default form.",
  199. 'form_created' => "Created default form '{form}'",
  200. 'form_create_fail' => "Failed to create form '{form}'. {mysql_error}",
  201. 'skipping_form_install' => "Skipping installation of default forms",
  202. 'set_pref' => 'Set preference {name}',
  203. 'set_pref_failed' => 'Failed to set preference {name}',
  204. 'set_pref_exists' => 'Preference {name} already exists.',
  205. 'mem_moderati' => 'Moderation Plugin',
  206. // prefs
  207. 'mem_mod_email_on_new' => 'Email on new content?',
  208. 'mem_mod_email_on_update' => 'Email on content update?',
  209. 'mem_mod_notify_email' => 'Notification Email Address',
  210. 'mem_mod_queue_delay' => 'Queue Delay (days)',
  211. 'mem_mod_multiedit_approve' => 'Enable Multi-edit approval?',
  212. );
  213. register_callback('fix_lang', 'prefs', '', 1);
  214. function fix_lang()
  215. {
  216. global $mem_moderation_lang, $textarray, $locale;
  217. if (strncasecmp('en', $locale, 2) != 0)
  218. return;
  219. foreach ($mem_moderation_lang as $k => $v)
  220. {
  221. $textarray[$k] = $v;
  222. }
  223. }
  224. register_callback( 'mem_moderation_enumerate_strings' , 'l10n.enumerate_strings' );
  225. function mem_moderation_enumerate_strings($event , $step='' , $pre=0)
  226. {
  227. global $mem_moderation_lang;
  228. $r = array (
  229. 'owner' => 'mem_moderation', # Change to your plugin's name
  230. 'prefix' => MEM_MODERATION_PREFIX, # Its unique string prefix
  231. 'lang' => 'en-gb', # The language of the initial strings.
  232. 'event' => 'public', # public/admin/common = which interface the strings will be loaded into
  233. 'strings' => $mem_moderation_lang, # The strings themselves.
  234. );
  235. return $r;
  236. }
  237. function mem_moderation_gTxt($what,$args = array())
  238. {
  239. global $mem_moderation_lang, $textarray;
  240. $key = strtolower( MEM_MODERATION_PREFIX . '-' . $what );
  241. if (isset($textarray[$key]))
  242. {
  243. $str = $textarray[$key];
  244. }
  245. else
  246. {
  247. $key = strtolower($what);
  248. if (isset($mem_moderation_lang[$key]))
  249. $str = $mem_moderation_lang[$key];
  250. elseif (isset($textarray[$key]))
  251. $str = $textarray[$key];
  252. else
  253. $str = $what;
  254. }
  255. if( !empty($args) )
  256. $str = strtr( $str , $args );
  257. return $str;
  258. }
  259. global $mod_event, $mem_moderation_lang, $prefs;
  260. $mod_event = 'moderate';
  261. require_plugin('mem_admin_parse');
  262. // make sure ign is loaded first, if it exists
  263. @load_plugin('ign_password_protect');
  264. // might need access to ign user table
  265. @load_plugin('mem_self_register');
  266. // -------------------------------------------------------------
  267. // Tags
  268. // -------------------------------------------------------------
  269. /** Show a submission list. User profile page. */
  270. function moderate_submission_list($atts,$thing='')
  271. {
  272. global $step,$link_list_pageby,$mod_event,$txp_user,$ign_user;
  273. // try looking for user from ign_password_protect plugin
  274. if (isset($ign_user) and empty($txp_user)) $txp_user = $ign_user;
  275. extract(lAtts(array(
  276. 'limit' => 5,
  277. 'form' => '',
  278. 'type' => '',
  279. 'wraptag' => 'div',
  280. 'break' => 'br',
  281. 'breakclass' => 'mod_listitem',
  282. 'class' => 'mod_list',
  283. 'user' => $txp_user,
  284. 'label' => '',
  285. 'labelwraptag' => '',
  286. 'labelclass' => 'moderate_list_label'
  287. ),$atts));
  288. extract(get_prefs());
  289. $Form = !empty($form) ? fetch_form($form) : $thing;
  290. $user = doSlash($user);
  291. $type = doSlash($type);
  292. $where = "`user` LIKE '{$user}'";
  293. if (!empty($type))
  294. $where .= " AND `type` LIKE '{$type}'";
  295. $where .= " ORDER BY `submitted`";
  296. $rs = safe_rows_start('*','txp_moderation',$where);
  297. if ($rs)
  298. {
  299. $out = array();
  300. while ($r = nextRow($rs))
  301. {
  302. $GLOBALS['mem_mod_info'] = $r;
  303. $out[] = admin_parse($Form);
  304. // clean up global
  305. unset($GLOBALS['mem_mod_info']);
  306. }
  307. $items = '';
  308. if (count($out) > 0 && !empty($label))
  309. {
  310. $items = doTag($label,$labelwraptag,$labelclass);
  311. }
  312. return $items . doWrap($out,$wraptag,$break,$class,$breakclass);
  313. }
  314. return '';
  315. }
  316. function mod_note_input($atts) {
  317. trigger_error(gTxt('deprecated_function_with', array('{name}' => __FUNCTION__, '{with}' => 'mem_form_textarea')), E_USER_NOTICE);
  318. global $mem_mod_info;
  319. extract(lAtts(array(
  320. 'style' => '',
  321. 'class' => __FUNCTION__
  322. ),$atts));
  323. return '<textarea name="note"'.(!empty($style)?' style="'.$style.'"':'').
  324. (!empty($class)?' class="'.$class.'"':'').'>'.
  325. htmlspecialchars(@$mem_mod_info['note']).'</textarea>';
  326. }
  327. function mem_moderation_edit_link($atts, $thing)
  328. {
  329. global $mod_event,$mem_mod_info;
  330. extract(lAtts(array(
  331. 'baseurl' => $_SERVER['REQUEST_URI']
  332. ),$atts));
  333. $elink = '<a href="'.$baseurl.'?event='.$mod_event.'&step='.$mem_mod_info['type'].'_edit&modid='.$mem_mod_info['id'].'">'.admin_parse($thing).'</a>';
  334. return $elink;
  335. }
  336. function mod_edit_link($atts,$thing)
  337. {
  338. trigger_error(gTxt('deprecated_function_with', array('{name}' => __FUNCTION__, '{with}' => 'mem_moderation_edit_link')), E_USER_NOTICE);
  339. return mem_moderation_edit_link($atts, $thing);
  340. }
  341. /** Tag to Display moderation info. */
  342. function mem_moderation_info($atts)
  343. {
  344. global $mem_mod_info, $prefs;
  345. extract(lAtts(array(
  346. 'datafield' => '',
  347. 'field' => '',
  348. 'format' => $prefs['archive_dateformat']
  349. ),$atts));
  350. if (empty($field))
  351. {
  352. trigger_error(mem_moderation_gTxt('missing_arg', array('{arg}' => 'field')), E_USER_NOTICE);
  353. }
  354. $out = '';
  355. if (isset($mem_mod_info[$field]))
  356. {
  357. if ($field == 'submitted')
  358. {
  359. $time = strtotime($mem_mod_info['submitted']);
  360. $out = safe_strftime($format, $time);
  361. }
  362. else if ($field == 'data')
  363. {
  364. $data = mem_moderation_decode($mem_mod_info['data']);
  365. if (is_array($data) and array_key_exists($datafield, $data))
  366. {
  367. $out = $data[$datafield];
  368. }
  369. else
  370. {
  371. trigger_error(mem_moderation_gTxt('invalid_arg', array('{arg}' => 'datafield')), E_USER_NOTICE);
  372. }
  373. }
  374. else
  375. {
  376. if (isset($mem_mod_info[$field]))
  377. {
  378. $out = $mem_mod_info[$field];
  379. }
  380. else
  381. {
  382. trigger_error(mem_moderation_gTxt('invalid_arg', array('{arg}' => 'field')), E_USER_NOTICE);
  383. }
  384. }
  385. }
  386. return $out;
  387. }
  388. function mem_if_moderation($atts, $thing)
  389. {
  390. global $mem_mod_info;
  391. extract(lAtts(array(
  392. 'check' => 'type',
  393. 'name' => '',
  394. 'value' => '',
  395. 'delimiter' => ',',
  396. ), $atts));
  397. if (empty($name))
  398. {
  399. trigger_error(mem_moderation_gTxt('missing_arg', array('{arg}' => 'name')), E_USER_NOTICE);
  400. return '';
  401. }
  402. switch (strtolower($check))
  403. {
  404. case 'type':
  405. // check if any of the provided types match.
  406. $types = array_flip(explode($delimiter, $name));
  407. $cond = array_key_exists($mem_mod_info['type'], $types);
  408. break;
  409. case 'gps':
  410. $g = gps($name);
  411. // true if matches value or if set when value is empty
  412. $cond = ((empty($value) && !empty($g)) or (!empty($value) && strcasecmp($g, $value) == 0));
  413. break;
  414. case 'data':
  415. $data = mem_moderation_decode($mem_mod_info['data']);
  416. // exists?
  417. $cond = is_array($data) and array_key_exists($name, $data) and !empty($data[$name]);
  418. if ($cond && !empty($value))
  419. {
  420. $cond = strcasecmp($data[$name], $value) == 0;
  421. }
  422. break;
  423. default:
  424. trigger_error(mem_moderation_gTxt('invalid_check', array('{check}' => $check)), E_USER_NOTICE);
  425. return '';
  426. }
  427. return admin_parse(EvalElse($thing, $cond));
  428. }
  429. function mod_if_type($atts,$thing) {
  430. trigger_error(gTxt('deprecated_function_with', array('{name}' => __FUNCTION__, '{with}' => 'mem_if_moderation')), E_USER_NOTICE);
  431. return mem_if_moderation(array(
  432. 'check' => 'type',
  433. 'name' => @$atts['name']
  434. ), $thing);
  435. }
  436. function mod_if_data($atts,$thing) {
  437. trigger_error(gTxt('deprecated_function_with', array('{name}' => __FUNCTION__, '{with}' => 'mem_if_moderation')), E_USER_NOTICE);
  438. return mem_if_moderation(array(
  439. 'check' => 'data',
  440. 'name' => @$atts['name'],
  441. 'value' => @$atts['value']
  442. ), $thing);
  443. }
  444. function mem_moderation_if_gps($atts,$thing) {
  445. trigger_error(gTxt('deprecated_function_with', array('{name}' => __FUNCTION__, '{with}' => 'mem_if_moderation')), E_USER_NOTICE);
  446. return mem_if_moderation(array(
  447. 'check' => 'gps',
  448. 'name' => @$atts['name'],
  449. 'value' => @$atts['value']
  450. ), $thing);
  451. }
  452. function mod_id($atts) {
  453. trigger_error(gTxt('deprecated_function_with', array('{name}' => __FUNCTION__, '{with}' => 'mem_moderation_info')), E_USER_NOTICE);
  454. return mem_moderation_info(array('field'=>'id'));
  455. }
  456. function mod_item_id($atts) {
  457. trigger_error(gTxt('deprecated_function_with', array('{name}' => __FUNCTION__, '{with}' => 'mem_moderation_info')), E_USER_NOTICE);
  458. return mem_moderation_info(array('field'=>'item_id'));
  459. }
  460. function mod_submitted($atts) {
  461. trigger_error(gTxt('deprecated_function_with', array('{name}' => __FUNCTION__, '{with}' => 'mem_moderation_info')), E_USER_NOTICE);
  462. $atts['field'] = 'submitted';
  463. return mem_moderation_info($atts);
  464. }
  465. function mod_user($atts) {
  466. trigger_error(gTxt('deprecated_function_with', array('{name}' => __FUNCTION__, '{with}' => 'mem_moderation_info')), E_USER_NOTICE);
  467. return mem_moderation_info(array('field'=>'user'));
  468. }
  469. function mod_desc($atts) {
  470. trigger_error(gTxt('deprecated_function_with', array('{name}' => __FUNCTION__, '{with}' => 'mem_moderation_info')), E_USER_NOTICE);
  471. return mem_moderation_info(array('field'=>'desc'));
  472. }
  473. function mod_type($atts) {
  474. trigger_error(gTxt('deprecated_function_with', array('{name}' => __FUNCTION__, '{with}' => 'mem_moderation_info')), E_USER_NOTICE);
  475. return mem_moderation_info(array('field'=>'type'));
  476. }
  477. function mod_email($atts) {
  478. trigger_error(gTxt('deprecated_function_with', array('{name}' => __FUNCTION__, '{with}' => 'mem_moderation_info')), E_USER_NOTICE);
  479. return mem_moderation_info(array('field'=>'email'));
  480. }
  481. function mod_data($atts) {
  482. trigger_error(gTxt('deprecated_function', array('{name}' => __FUNCTION__)), E_USER_NOTICE);
  483. $atts['field'] = 'data';
  484. $atts['datafield'] = @$atts['name'];
  485. return mem_moderation_info($atts);
  486. }
  487. /** Show the moderation queue */
  488. function mem_moderate_list($message="")
  489. {
  490. global $step, $link_list_pageby, $mod_event;
  491. // check privs
  492. if (!has_privs('moderate.list'))
  493. {
  494. return;
  495. }
  496. extract(get_prefs());
  497. $page = gps('page');
  498. $total = getCount('txp_moderation',"1");
  499. $limit = empty($link_list_pageby) ? 20 : $link_list_pageby;
  500. $numPages = $total==0 ? 1 : ceil($total/$limit);
  501. $page = (!$page) ? 1 : $page;
  502. $offset = ($page - 1) * $limit;
  503. $sort = gps('sort');
  504. $dir = gps('dir');
  505. $sort = ($sort) ? doSlash($sort) : "submitted";
  506. $dir = ($dir) ? doSlash($dir) : 'asc';
  507. // navigation links
  508. $nav[] = ($page > 1)
  509. ? PrevNextLink($mod_event,$page-1,gTxt('prev'),'prev') : '';
  510. $nav[] = sp.small($page. '/'.$numPages).sp;
  511. $nav[] = ($page != $numPages && $numPages > 1)
  512. ? PrevNextLink($mod_event,$page+1,gTxt('next'),'next') : '';
  513. $delay = isset($mem_mod_queue_delay) ? assert_int($mem_mod_queue_delay) : 0;
  514. if($mem_mod_pub_bypass_queue)
  515. {
  516. // check against user table
  517. $user_table = mem_get_user_table_name();
  518. if (empty($user_table)) $user_table = 'txp_users';
  519. $rs = safe_rows_start(
  520. "txp_moderation.*",
  521. "txp_moderation, {$user_table}",
  522. " txp_moderation.user={$user_table}.name AND (DATE_SUB( NOW(), INTERVAL ". $delay ." DAY ) > txp_moderation.submitted OR {$user_table}.privs = 1) order by txp_moderation.{$sort} $dir limit $offset,$limit"
  523. );
  524. }
  525. else
  526. {
  527. // get all queue items
  528. $rs = safe_rows_start(
  529. "*",
  530. "txp_moderation",
  531. " (DATE_SUB( NOW(), INTERVAL ". $delay ." DAY ) > submitted) order by {$sort} $dir limit $offset,$limit"
  532. );
  533. }
  534. if ($rs)
  535. {
  536. // reverse dir for links
  537. if ($dir == "desc") { $dir = "asc"; } else { $dir = "desc"; }
  538. echo '<form action="index.php" method="post" name="longform" onsubmit="return verify(\''.gTxt('are_you_sure').'\')">',
  539. startTable('list'),
  540. // column heading with sort links
  541. tr(
  542. column_head('id','id',$mod_event,1,$dir).
  543. column_head('submitted','submitted',$mod_event,1,$dir).
  544. column_head('type','type',$mod_event,1,$dir).
  545. column_head('user','user',$mod_event,1,$dir).
  546. column_head('description','description',$mod_event,0,$dir).
  547. td()
  548. );
  549. // each row
  550. $alt = false;
  551. while ($a = nextRow($rs))
  552. {
  553. extract($a);
  554. $elink = eLink($mod_event,'details','id',$id,$id);
  555. $cbox = fInput('checkbox','selected[]',$id);
  556. // no desc, use another field
  557. if (empty($desc))
  558. {
  559. $data = mem_moderation_decode($a['data']);
  560. $altfields = array('title', 'desc', 'description', 'alt');
  561. foreach ($altfields as $f)
  562. {
  563. if (isset($data[$f]) and !empty($data[$f]))
  564. {
  565. $desc = $data[$f];
  566. break;
  567. }
  568. }
  569. // ensure something is in desc column
  570. if (empty($desc))
  571. {
  572. $desc = mem_moderation_gTxt('no_desc');
  573. }
  574. }
  575. $desclink = eLink($mod_event,'details','id',$id,$desc);
  576. echo tr(
  577. td($elink,20).
  578. td($submitted,175).
  579. td($type,50).
  580. ($user!='anonymous'?td($user,130):td($email,130)).
  581. td($desclink,200).
  582. td($cbox)
  583. );
  584. }
  585. $multi_edit_options = array('reject'=>gTxt('reject'));
  586. if ($mem_mod_multiedit_approve)
  587. {
  588. $multi_edit_options['approve'] = gTxt('approve');
  589. }
  590. // list action form
  591. echo tr(tda(select_buttons().
  592. event_multiedit_form($mod_event,$multi_edit_options, $page, $sort, $dir,'',''),' colspan="6" style="text-align:right;border:0px"'));
  593. // paging
  594. echo endTable(),'</form>';
  595. echo pageby_form($mod_event,$link_list_pageby);
  596. echo graf(join('',$nav),' align="center"');
  597. }
  598. else
  599. {
  600. echo mem_moderation_gTxt('table_access_failed', array('{err}' => mysql_error()));
  601. }
  602. }
  603. /** Update an item in the queue */
  604. function mem_moderate_save()
  605. {
  606. require_privs('moderate.edit');
  607. extract(gpsa(array('id','type','moderation_description')));
  608. $vars = gpsa(mem_get_moderation_variables($type));
  609. update_moderated_content($id,$moderation_description,$vars);
  610. }
  611. /** Approve an item in the moderation queue */
  612. function mem_moderate_approve($type='',$id=false)
  613. {
  614. require_privs('moderate.approve');
  615. if ($id===false || empty($type))
  616. {
  617. extract(gpsa(array('id','type')));
  618. // save it first
  619. mem_moderate_save();
  620. }
  621. else
  622. {
  623. // Approving from the listing
  624. }
  625. $rs = safe_row("*", "txp_moderation", "id = ". doSlash($id));
  626. if ($rs)
  627. {
  628. $vars = mem_get_moderation_variables($type);
  629. extract(array_merge($rs,$vars));
  630. $decoded_data = mem_moderation_decode($rs['data']);
  631. $decoded_data['id'] = $id;
  632. // notify plugins
  633. $res = mem_moderation_approver_callback($type,$decoded_data);
  634. if ($res == '')
  635. {
  636. if (remove_moderated_content($id))
  637. {
  638. // no return on success
  639. }
  640. else
  641. {
  642. return mem_moderation_gTxt('remove_failed', array('{id}' => $id));
  643. }
  644. }
  645. return $res;
  646. }
  647. else
  648. {
  649. return mem_moderation_gTxt('id_not_found');
  650. }
  651. }
  652. /** Reject a moderated item */
  653. function mem_moderate_reject($type='', $id=false)
  654. {
  655. require_privs('moderate.approve');
  656. if ($id===false || empty($type))
  657. extract(gpsa(array('id','type')));
  658. $rs = safe_row("*", "txp_moderation", "id = $id");
  659. if ($rs)
  660. {
  661. $decoded_data = mem_moderation_decode($rs['data']);
  662. $decoded_data['id'] = $id;
  663. // notify plugins
  664. $res = mem_moderation_rejecter_callback($type, $decoded_data);
  665. if ($res == '')
  666. {
  667. if (remove_moderated_content($id))
  668. {
  669. // no return on success
  670. }
  671. else
  672. {
  673. return mem_moderation_gTxt('remove_failed', array('{id}' => $id));
  674. }
  675. }
  676. return $res;
  677. }
  678. else
  679. {
  680. return mem_moderation_gTxt('id_not_found');
  681. }
  682. }
  683. /** Add an item to the moderation queue */
  684. function submit_moderated_content($type,$email,$desc,$data,$item_id='0')
  685. {
  686. global $txp_user,$ign_user, $mem_mod_email_on_new, $mem_mod_notify_email, $sitename;
  687. // ign_user
  688. $user = isset($ign_user) ? $ign_user : $txp_user;
  689. // can this be an update instead?
  690. if ($item_id != 0)
  691. {
  692. $existing_modid = safe_field('id, item_id', 'txp_moderation', "`type` = '".doSlash($type)."' and `user` = '".doSlash($user)."' and `item_id` = ".doSlash($item_id));
  693. if ($existing_modid)
  694. {
  695. // do an update instead
  696. if (update_moderated_content($existing_modid, $desc, $data, $type, $item_id))
  697. {
  698. return $existing_modid;
  699. }
  700. return false;
  701. }
  702. }
  703. if (empty($email))
  704. {
  705. $email = safe_field('email','txp_users',"name = '".doSlash($user)."'");
  706. }
  707. // encode for insert
  708. $encoded_data = mem_moderation_encode($data);
  709. $r = safe_insert('txp_moderation',
  710. "`submitted` = now(),
  711. `type` = '".doSlash($type)."',
  712. `item_id` = '".doSlash($item_id)."',
  713. `user` = '".doSlash($user)."',
  714. `email` = '".doSlash($email)."',
  715. `ip` = '".doSlash($_SERVER['REMOTE_ADDR'])."',
  716. `desc` = '".doSlash($desc)."',
  717. `data` = '".doSlash($encoded_data)."'"
  718. );
  719. // send email notification
  720. if ($mem_mod_email_on_new && !empty($mem_mod_notify_email))
  721. {
  722. $message = mem_moderation_gTxt('new_submission_email', array('{user}'=> $user, '{type}'=> $type));
  723. $reply = $from = $to = $mem_mod_notify_email;
  724. $subject = "[$sitename] " . mem_moderation_gTxt('new_submission_email_subject');
  725. $sent = @mem_form_mail($from, $reply, $to, $subject, $message);
  726. }
  727. return $r;
  728. }
  729. /** Update an entry in the moderation queue */
  730. function update_moderated_content($id,$desc,$data,$type='',$item_id='')
  731. {
  732. global $mem_mod_email_on_update, $mem_mod_notify_email, $sitename;
  733. $encoded_data = mem_moderation_encode($data);
  734. $set = "`desc` = '". doSlash($desc)."', `data` = '$encoded_data'";
  735. if (!empty($type))
  736. {
  737. $set .= ", `type` = '".doSlash($type)."'";
  738. }
  739. if (!empty($item_id) or $item_id == '0')
  740. {
  741. $set .= ", `item_id` = ".doSlash($item_id);
  742. }
  743. $r = safe_update('txp_moderation', $set, "id='".doSlash($id)."'");
  744. if (@txpinterface != 'admin')
  745. {
  746. if ($mem_mod_email_on_update && !empty($mem_mod_notify_email))
  747. {
  748. $rs = safe_row('user,type', 'txp_moderation', "id='".doSlash($id)."'");
  749. if ($rs)
  750. extract($rs);
  751. $message = mem_moderation_gTxt('update_submission_email', array('{user}'=> $user, '{type}'=> $type));
  752. $reply = $from = $to = $mem_mod_notify_email;
  753. $subject = "[$sitename] " . mem_moderation_gTxt('update_submission_email_subject');
  754. $sent = @mem_form_mail($from, $reply, $to, $subject, $message);
  755. }
  756. }
  757. return $r;
  758. }
  759. /** Remove an item from the moderation queue */
  760. function remove_moderated_content($id)
  761. {
  762. return safe_delete('txp_moderation',"id='".doSlash($id)."'");
  763. }
  764. /** Serialize data for storage */
  765. function mem_moderation_encode($content)
  766. {
  767. return base64_encode(serialize($content));
  768. }
  769. /** Deserialize data from storage */
  770. function mem_moderation_decode($content)
  771. {
  772. return unserialize(base64_decode($content));
  773. }
  774. /** Register handlers for a content type */
  775. function mem_moderation_register($type,$vars,$presenter,$approver,$rejecter)
  776. {
  777. global $moderation_types;
  778. $moderation_types[] = array(('type') => $type,
  779. ('variables') => $vars,
  780. ('func_presenter') => $presenter,
  781. ('func_approver') => $approver,
  782. ('func_rejecter') => $rejecter);
  783. }
  784. function register_moderation_type($type, $vars, $presenter, $approver, $rejecter){
  785. //trigger_error(gTxt('deprecated_tag'), E_USER_NOTICE);
  786. mem_moderation_register($type, $vars, $presenter, $approver, $rejecter);
  787. }
  788. /** Get the registered variable names */
  789. function mem_get_moderation_variables($type)
  790. {
  791. global $moderation_types;
  792. if (!is_array($moderation_types))
  793. {
  794. return array();
  795. }
  796. $out = array();
  797. foreach ($moderation_types as $p)
  798. {
  799. if ($p[('type')]==$type)
  800. {
  801. $out = array_merge($out, $p[('variables')]);
  802. }
  803. }
  804. return $out;
  805. }
  806. /** Moderation Callback */
  807. function mem_moderation_callback($type,$callback,$data)
  808. {
  809. global $moderation_types;
  810. if (!is_array($moderation_types))
  811. {
  812. return '';
  813. }
  814. $out = '';
  815. foreach ($moderation_types as $p)
  816. {
  817. if ($p[('type')]==$type && is_callable($p[('func_'.$callback)]))
  818. {
  819. $out[] = call_user_func($p[('func_'.$callback)],$p[('type')],$data);
  820. }
  821. }
  822. return (is_array($out) ? join(' ',$out) : $out);
  823. }
  824. /** Presenter Callback */
  825. function mem_moderation_presenter_callback($type,$data) {
  826. return mem_moderation_callback($type,'presenter',$data);
  827. }
  828. /** Approver Callback */
  829. function mem_moderation_approver_callback($type,$data) {
  830. return mem_moderation_callback($type,'approver',$data);
  831. }
  832. /** Rejecter Callback */
  833. function mem_moderation_rejecter_callback($type,$data) {
  834. return mem_moderation_callback($type,'rejecter',$data);
  835. }
  836. if (!function_exists('mem_get_user_table_name')) {
  837. function mem_get_user_table_name() {
  838. global $prefs;
  839. extract($prefs);
  840. $table_name = 'txp_users';
  841. if (isset($mem_self_use_ign_db) && $mem_self_use_ign_db == '1') {
  842. if (isset($ign_use_custom) && $ign_use_custom=='1') {
  843. if (isset($ign_user_db) && !empty($ign_user_db))
  844. $table_name = $ign_user_db;
  845. }
  846. }
  847. return $table_name;
  848. }
  849. }
  850. // ----------------------------------------------------------------
  851. if (@txpinterface == 'admin')
  852. {
  853. // set up tab and event callback
  854. register_tab('extensions','moderate',$mod_event);
  855. register_callback('mem_moderate', $mod_event, '', 1);
  856. // who can access this tab
  857. add_privs($mod_event,'1,2,3');
  858. // who can view submission list
  859. add_privs($mod_event.'.list','1,2,3');
  860. // who can edit
  861. add_privs($mod_event.'.edit','1,2,3');
  862. // who can approve
  863. add_privs($mod_event.'.approve','1,2,3');
  864. /** Main step handler */
  865. function mem_moderate($event, $step)
  866. {
  867. global $txp_permissions, $mod_event;
  868. $mod_event = $event;
  869. $msg = '';
  870. pagetop('');
  871. if ($step=='details')
  872. {
  873. mem_moderate_details();
  874. }
  875. else if ($step==$mod_event.'_update')
  876. {
  877. $action = gps('action');
  878. if ($action==gTxt('save'))
  879. {
  880. mem_moderate_save();
  881. mem_moderate_details();
  882. }
  883. else
  884. {
  885. if ($action==gTxt('approve'))
  886. {
  887. $msg = mem_moderate_approve();
  888. }
  889. else if ($action==gTxt('reject'))
  890. {
  891. $msg = mem_moderate_reject();
  892. }
  893. mem_moderate_list($msg);
  894. }
  895. }
  896. else if ($step=='preinstall' or $step=='install')
  897. {
  898. echo mem_moderation_install();
  899. }
  900. else if ($step==$mod_event.'_multi_edit')
  901. {
  902. // actions from the moderation list
  903. $selected = gps('selected');
  904. $method = gps('edit_method');
  905. $success = array();
  906. $failed = array();
  907. $rs = false;
  908. if (count($selected) > 0)
  909. {
  910. $selected_ids = join(',',$selected);
  911. $rs = safe_rows("id,type",'txp_moderation',"`id` IN (". doSlash($selected_ids) .")");
  912. }
  913. if ($rs)
  914. {
  915. foreach($rs as $r)
  916. {
  917. extract($r);
  918. $result = '';
  919. if ($method=='reject')
  920. {
  921. $result = mem_moderate_reject($type,$id);
  922. }
  923. else if ($method=='approve')
  924. {
  925. $result = mem_moderate_approve($type,$id);
  926. }
  927. else
  928. {
  929. $result = 'unsupported method "'.$method."'";
  930. }
  931. if (empty($result))
  932. {
  933. $success[] = array('id'=>$id,'type'=>$type);
  934. }
  935. else
  936. {
  937. $failed[] = array('id'=>$id,'type'=>$type);
  938. }
  939. }
  940. }
  941. $msg = '';
  942. // build success list
  943. if (count($success)>0)
  944. {
  945. $msg .= "{$method} successful for: ";
  946. $slist = array();
  947. foreach($success as $s)
  948. {
  949. $slist[] = sprintf('%s %d',$s['type'],$s['id']);
  950. }
  951. $msg .= join(', ',$slist) . '; ';
  952. }
  953. // build failure list
  954. if (count($failed)>0)
  955. {
  956. $msg .= '{$method} failed for: ';
  957. $flist = array();
  958. foreach($failed as $f)
  959. {
  960. $flist[] = sprintf('%s %d',$f['type'],$f['id']);
  961. }
  962. $msg .= join(', ',$flist) . '; ';
  963. }
  964. mem_moderate_list($msg);
  965. }
  966. else
  967. {
  968. mem_moderate_list($msg);
  969. }
  970. }
  971. /** Plugin installer */
  972. function mem_moderation_install()
  973. {
  974. global $prefs;
  975. $create_default_forms = true;
  976. $log = array();
  977. ob_start();
  978. // set prefs
  979. if (!isset($prefs['mem_mod_notify_email']))
  980. {
  981. set_pref('mem_mod_notify_email', '', 'mem_moderation', 1);
  982. $log[] = mem_moderation_gTxt('set_pref', array('{name}' => 'mem_mod_notify_email'));
  983. }
  984. if (!isset($prefs['mem_mod_email_on_new']))
  985. {
  986. set_pref('mem_mod_email_on_new', '', 'mem_moderation', 1, 'yesnoradio');
  987. $log[] = mem_moderation_gTxt('set_pref', array('{name}' => 'mem_mod_email_on_new'));
  988. }
  989. if (!isset($prefs['mem_mod_email_on_update']))
  990. {
  991. set_pref('mem_mod_email_on_update', '', 'mem_moderation', 1, 'yesnoradio');
  992. $log[] = mem_moderation_gTxt('set_pref', array('{name}' => 'mem_mod_email_on_update'));
  993. }
  994. if (!isset($prefs['mem_mod_queue_delay']))
  995. {
  996. set_pref('mem_mod_queue_delay', '0', 'mem_moderation', 1);
  997. $log[] = mem_moderation_gTxt('set_pref', array('{name}' => 'mem_mod_queue_delay'));
  998. }
  999. if (!isset($prefs['mem_mod_multiedit_approve']))
  1000. {
  1001. set_pref('mem_mod_multiedit_approve', '0', 'mem_moderation', 1, 'yesnoradio');
  1002. $log[] = mem_moderation_gTxt('set_pref', array('{name}' => 'mem_mod_multiedit_approve'));
  1003. }
  1004. if (!isset($prefs['mem_mod_pub_bypass_queue']))
  1005. {
  1006. set_pref('mem_mod_pub_bypass_queue', '0', 'mem_moderation', 1, 'yesnoradio');
  1007. $log[] = mem_moderation_gTxt('set_pref', array('{name}' => 'mem_mod_pub_bypass_queue'));
  1008. }
  1009. // check for table
  1010. $rs = safe_row("id", "txp_moderation", "1=1 LIMIT 1");
  1011. if (!$rs && mysql_errno() != 0)
  1012. {
  1013. // add table
  1014. $sql = "CREATE TABLE `".PFX."txp_moderation` (
  1015. `id` int(10) unsigned NOT NULL auto_increment,
  1016. `submitted` datetime NOT NULL default '0000-00-00 00:00:00',
  1017. `type` varchar(32) NOT NULL default '',
  1018. `item_id` int(10) unsigned NOT NULL default '0',
  1019. `user` varchar(64) NOT NULL default '',
  1020. `email` varchar(100) NOT NULL default '',
  1021. `ip` varchar(16) NOT NULL default '',
  1022. `desc` text NOT NULL,
  1023. `data` longtext NOT NULL,
  1024. PRIMARY KEY (`id`),
  1025. KEY `type` (`type`)
  1026. ) Type=MyISAM PACK_KEYS=0 AUTO_INCREMENT=1 ";
  1027. if (($rs=safe_query($sql)))
  1028. {
  1029. $log[] = mem_moderation_gTxt('table_created', array('{name}' => PFX."txp_moderation"));
  1030. }
  1031. else
  1032. {
  1033. $log[] = mem_moderation_gTxt('table_create_failed', array('{mysql_error}' => mysql_error()));
  1034. }
  1035. }
  1036. else
  1037. {
  1038. $log[] = mem_moderation_gTxt('table_exists');
  1039. $rs = safe_row("item_id", "txp_moderation", "1=1 LIMIT 1");
  1040. if (!$rs && mysql_errno() != 0)
  1041. {
  1042. if (safe_alter('txp_moderation', "ADD `item_id` INT NOT NULL DEFAULT '0' AFTER `type`"))
  1043. {
  1044. $log[] = mem_moderation_gTxt('add_item_field');
  1045. }
  1046. else
  1047. {
  1048. $log[] = mem_moderation_gTxt('add_item_field_failed');
  1049. }
  1050. }
  1051. }
  1052. if ($create_default_forms)
  1053. {
  1054. $form = fetch('Form','txp_form','name','mod_submission_list');
  1055. if (!$form)
  1056. {
  1057. $form_html = <<<EOF
  1058. <txp:mem_moderation_edit_link><txp:mem_moderation_info field="type" />
  1059. #<txp:mem_moderation_info field="id" /></txp:mem_moderation_edit_link> - <txp:mem_moderation_info field="submitted" />
  1060. <div>
  1061. <txp:mem_moderation_info field="desc" />
  1062. </div>
  1063. EOF;
  1064. $form_html = doSlash($form_html);
  1065. if (safe_insert('txp_form',"name='mod_submission_list',type='misc',Form='{$form_html}'"))
  1066. {
  1067. $log[] = mem_moderation_gTxt('form_created', array('{form}' => 'mod_submission_list'));
  1068. }
  1069. else
  1070. {
  1071. $log[] = mem_moderation_gTxt('form_create_failed', array('{form}' => 'mod_submission_list', 'mysql_error' => mysql_error()));
  1072. }
  1073. }
  1074. else
  1075. {
  1076. $log[] = mem_moderation_gTxt('form_found', array('{form}' => 'mod_submission_list'));
  1077. }
  1078. }
  1079. else
  1080. {
  1081. $log[] = mem_moderation_gTxt('skipping_form_install');
  1082. }
  1083. ob_end_clean();
  1084. return tag(mem_moderation_gTxt('install_log'),'h2').doWrap($log,'ul','li');
  1085. }
  1086. /** Show item moderation details */
  1087. function mem_moderate_details()
  1088. {
  1089. global $step,$mod_event,$txp_user;
  1090. $can_approve = has_privs('moderate.approve');
  1091. $can_edit = has_privs('moderate.edit');
  1092. $id = gps('id');
  1093. if($id)
  1094. {
  1095. // fetch item
  1096. extract(safe_row("*", "txp_moderation", "id = " . doSlash($id)));
  1097. $can_edit = $can_edit or $user==$txp_user;
  1098. $textarea = '<textarea name="moderation_description" cols="40" rows="7" tabindex="4">'.
  1099. htmlspecialchars($desc).
  1100. '</textarea>';
  1101. $out = StartTable('listing');
  1102. $out .= tr( td(
  1103. hed("$type #{$id} - ".href(($user?$user:$email),'mailto:'.$email) . " ({$email})", 2) .
  1104. tag( gTxt('submitted') .' '. $submitted , 'div') .
  1105. tag( gTxt('notes'), 'div') . $textarea
  1106. )
  1107. ) .
  1108. tr( td('<hr />') );
  1109. $out .= EndTable();
  1110. $decoded_data = mem_moderation_decode($data);
  1111. $decoded_data['id'] = $id;
  1112. $decoded_data['type'] = $type;
  1113. $decoded_data['user'] = $user;
  1114. $decoded_data['email'] = $email;
  1115. $out .= mem_moderation_presenter_callback($type, $decoded_data);
  1116. $out .= eInput( $mod_event ) . sInput( $mod_event .'_update' ) . hInput( 'id', $id );
  1117. $out .= hInput('type',$type);
  1118. if ($can_edit or $can_approve)
  1119. {
  1120. $out .= StartTable('') .
  1121. tr(
  1122. ($can_edit ?
  1123. td( fInput( "submit", 'action', gTxt( 'save' ), "publish" ) )
  1124. : td()
  1125. ) .
  1126. ($can_approve ?
  1127. td( fInput( "submit", 'action', gTxt( 'approve' ), "publish" ) ) .
  1128. td( fInput( "submit", 'action', gTxt( 'reject' ), "publish",'',"return confirm('". gTxt('are_you_sure')."')" ) )
  1129. : td() . td()
  1130. )
  1131. ) .
  1132. EndTable();
  1133. }
  1134. echo form( $out );
  1135. }
  1136. }
  1137. }
  1138. else
  1139. {
  1140. $type = gps($mod_event);
  1141. if (!empty($type)) {
  1142. echo tag('Doing a moderation postback','div');
  1143. $vars = mem_get_moderation_variables($type);
  1144. $data = gpsa($vars);
  1145. exit();
  1146. }
  1147. }
  1148. # --- END PLUGIN CODE ---
  1149. ?>