PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/mem_public_article/mem_public_article.php

https://bitbucket.org/Manfre/txp-plugins
PHP | 511 lines | 382 code | 108 blank | 21 comment | 80 complexity | 7d63183528cad530d47a9cf390faa6db MD5 | raw file
  1. <?php
  2. // This is a PLUGIN TEMPLATE.
  3. // Copy this file to a new name like abc_myplugin.php. Edit the code, then
  4. // run this file at the command line to produce a plugin for distribution:
  5. // $ php abc_myplugin.php > abc_myplugin-0.1.txt
  6. // Plugin name is optional. If unset, it will be extracted from the current
  7. // file name. Uncomment and edit this line to override:
  8. $plugin['name'] = 'mem_public_article';
  9. // 0 = Plugin help is in Textile format, no raw HTML allowed (default).
  10. // 1 = Plugin help is in raw HTML. Not recommended.
  11. // $plugin['allow_html_help'] = 1;
  12. $plugin['version'] = '0.1';
  13. $plugin['author'] = 'Michael Manfre';
  14. $plugin['author_uri'] = 'http://manfre.net/';
  15. $plugin['description'] = 'Create/edit articles from the public side of a site.';
  16. // Plugin types:
  17. // 0 = regular plugin; loaded on the public web side only
  18. // 1 = admin plugin; loaded on both the public and admin side
  19. // 2 = library; loaded only when include_plugin() or require_plugin() is called
  20. $plugin['type'] = 0;
  21. if (!defined('txpinterface'))
  22. @include_once('../zem_tpl.php');
  23. if (0) {
  24. ?>
  25. # --- BEGIN PLUGIN HELP ---
  26. h1(title). mem_public_article plugin
  27. h2(section summary). Summary
  28. p. This plugin allows for a site owner to create an article edit form on the public side of their site.
  29. p. Note: There are no security checks. Anyone who can see the form will be able to submit an article. I strongly suggest that you only let the user modify fields that you want them to modify. All other import fields should be passed through with mem_form_secret. It is recommended that you use ign_password_protect to reduce spam.
  30. p. This plugin requires mem_form.
  31. p. This plugin has MLP support.
  32. p. This plugin has been tested with 4.0.7 and 4.0.8
  33. h2(section contact). Author Contact
  34. "Michael Manfre":mailto:mmanfre@gmail.com?subject=Textpattern%20mem_public_article%20plugin
  35. "http://manfre.net":http://manfre.net
  36. h2(section license). License
  37. p. This plugin is licensed under the "GPLv2":http://www.fsf.org/licensing/licenses/info/GPLv2.html.
  38. h2(section installation). Installation
  39. p. No extra installation steps
  40. h2(section tags). Tags
  41. * "mem_public_article":#mem_
  42. * "mem_public_article_if_ps":#mem_public_article_if_ps
  43. * "mem_public_article_ps":#mem_public_article_ps
  44. h3(tag#mem_public_article). mem_public_article
  45. p(tag-summary). This tag will output an HTML form. You must specify each of the article input fields that you want to display to the author.
  46. *(atts) %(atts-name)form% %(atts-type)string% Name of form that contains the mem_simple_form form tags.
  47. *(atts) %(atts-name)success_form% %(atts-type)string% Name of the form that will be shown after a successful post.
  48. *(atts) %(atts-name)do_pings% %(atts-type)boolean% Set to "1" if you want to ping the services that are normally pinged using the admin edit form.
  49. h4. HTML Field Names
  50. p. Title, Body, Body_html, Excerpt, Excerpt_html, Image, Keywords, Status, Author, Section, Category1, Category2, textile_body, textile_excerpt, Annotate, override_form, url_title, AnnotateInvite, custom_1, custom_2, ..., custom_10
  51. p. Expires Time: expires, exp_year, exp_month, exp_day, exp_hour, exp_minute, exp_second
  52. p. Posted Time: publish_now, year, month, day, hour, minute, exp_second
  53. h3(tag#mem_simple_if_ps). mem_public_article_if_ps
  54. p(tag-summary). Conditional tag that checks to see if a HTML field was posted, or if it has a specific value.
  55. *(atts) %(atts-name)name% %(atts-type)string% HTML field name posted with the form.
  56. *(atts) %(atts-name)equal% %(atts-type)string% Value to compare against the value of name. If not specified, tag checks to see if form posted variable HTML field name.
  57. h3(tag#mem_simple_ps). mem_public_article_ps
  58. p(tag-summary). This tag will output the value of the posted HTML form field.
  59. *(atts) %(atts-name)name% %(atts-type)string% HTML field name posted with the form.
  60. # --- END PLUGIN HELP ---
  61. <?php
  62. }
  63. # --- BEGIN PLUGIN CODE ---
  64. // needed for MLP
  65. define( 'MEM_PUBLIC_ARTICLE_PREFIX' , 'mem_public_article' );
  66. global $mem_public_article_lang;
  67. if (!is_array($mem_public_article_lang))
  68. {
  69. $mem_public_article_lang = array(
  70. 'author_missing' => 'Author not provided.',
  71. 'url_title_is_multiple' => 'The url_title must be unique.',
  72. );
  73. }
  74. register_callback( 'mem_public_article_enumerate_strings' , 'l10n.enumerate_strings' );
  75. function mem_public_article_enumerate_strings($event , $step='' , $pre=0)
  76. {
  77. global $mem_public_article_lang;
  78. $r = array (
  79. 'owner' => 'mem_public_article', # Change to your plugin's name
  80. 'prefix' => MEM_PUBLIC_ARTICLE_PREFIX, # Its unique string prefix
  81. 'lang' => 'en-gb', # The language of the initial strings.
  82. 'event' => 'public', # public/admin/common = which interface the strings will be loaded into
  83. 'strings' => $mem_public_article_lang, # The strings themselves.
  84. );
  85. return $r;
  86. }
  87. function mem_pa_gtxt($what,$args = array())
  88. {
  89. global $mem_public_article_lang, $textarray;
  90. $key = strtolower( MEM_PUBLIC_ARTICLE_PREFIX . '-' . $what );
  91. if (isset($textarray[$key]))
  92. {
  93. $str = $textarray[$key];
  94. }
  95. else
  96. {
  97. $key = strtolower($what);
  98. if (isset($mem_public_article_lang[$key]))
  99. $str = $mem_public_article_lang[$key];
  100. elseif (isset($textarray[$key]))
  101. $str = $textarray[$key];
  102. else
  103. $str = $what;
  104. }
  105. if( !empty($args) )
  106. $str = strtr( $str , $args );
  107. return $str;
  108. }
  109. require_plugin('mem_form');
  110. function mem_public_article($atts, $thing='')
  111. {
  112. global $mem_public_article_id;
  113. $atts = lAtts(array(
  114. 'form' => '',
  115. 'success_form' => false,
  116. 'do_pings' => false,
  117. 'article_id' => false,
  118. ),$atts,0);
  119. $atts['type'] = 'mem_article_public';
  120. if (!empty($atts['form'])) {
  121. $thing = fetch_form($atts['form']);
  122. unset($atts['form']);
  123. }
  124. $mem_public_article_id = $atts['article_id'];
  125. foreach(array('do_pings','success_form', 'article_id') as $a) {
  126. $thing .= '<txp:mem_form_secret name="mem_public_article_'.$a.'" value="'.$atts[$a].'" />';
  127. unset($atts[$a]);
  128. }
  129. return mem_form($atts, $thing);
  130. }
  131. register_callback('mem_public_article_defaults', 'mem_form.defaults');
  132. function mem_public_article_defaults()
  133. {
  134. global $mem_form_type, $mem_form_default, $thisarticle, $mem_public_article_id;
  135. if ($mem_form_type != 'mem_article_public')
  136. return;
  137. if (isset($mem_public_article_id))
  138. {
  139. if (!is_numeric($mem_public_article_id) && strpos($mem_public_article_id, '<txp:')==0 )
  140. $mem_public_article_id = parse($mem_public_article_id);
  141. if (is_numeric($mem_public_article_id))
  142. $article = safe_row('*', 'textpattern', "ID = ".doSlash($mem_public_article_id));
  143. }
  144. if (!$article && isset($thisarticle))
  145. {
  146. $article = $thisarticle;
  147. }
  148. if ($article)
  149. {
  150. foreach($article as $k => $v)
  151. {
  152. $mem_form_default[$k] = $v;
  153. }
  154. }
  155. }
  156. register_callback('mem_public_article_submit', 'mem_form.submit');
  157. function mem_public_article_submit()
  158. {
  159. global $mem_form_type, $mem_form_values, $prefs, $vars, $txp_user, $ign_user;
  160. if ($mem_form_type !== 'mem_article_public')
  161. return;
  162. $user = doSlash(!empty($ign_user) ? $ign_user : $txp_user);
  163. if (isset($mem_form_values['Author']))
  164. $user = doSlash($mem_form_values['Author']);
  165. if (empty($user))
  166. {
  167. return mem_form_error( mem_pa_gtxt('author_missing') );
  168. }
  169. require_once(txpath.'/include/txp_article.php');
  170. $int_vars = array('Status','textile_body','textile_excerpt');
  171. $incoming = textile_main_fields($mem_form_values, $prefs['use_textile']);
  172. if (empty($mem_form_values['ID']))
  173. {
  174. foreach ($vars as $v)
  175. {
  176. if (!isset($mem_form_values[$v]))
  177. $mem_form_values[$v] = in_array($v, $int_vars) ? 0 : '';
  178. }
  179. extract(doSlash($incoming));
  180. extract(array_map('assert_int', array( $incoming['Status'], $incoming['textile_body'], $incoming['textile_excerpt'])));
  181. $Annotate = (int) $Annotate;
  182. $Keywords = doSlash(trim(preg_replace('/( ?[\r\n\t,])+ ?/s', ',', preg_replace('/ +/', ' ', $Keywords)), ', '));
  183. if (!empty($expires_date))
  184. {
  185. $expires = strtotime($expires_date);
  186. $whenexpires = $expires_date;
  187. }
  188. else
  189. {
  190. if (empty($exp_year)) {
  191. $expires = 0;
  192. $whenexpires = NULLDATETIME;
  193. }
  194. else {
  195. if(empty($exp_month)) $exp_month=1;
  196. if(empty($exp_day)) $exp_day=1;
  197. if(empty($exp_hour)) $exp_hour=0;
  198. if(empty($exp_minute)) $exp_minute=0;
  199. if(empty($exp_second)) $exp_second=0;
  200. $expires = strtotime($exp_year.'-'.$exp_month.'-'.$exp_day.' '.$exp_hour.':'.$exp_minute.':'.$exp_second)-tz_offset();
  201. $whenexpires = "from_unixtime($expires)";
  202. }
  203. }
  204. if ($publish_now==1) {
  205. $when = 'now()';
  206. $when_ts = time();
  207. } else {
  208. if(empty($month)) $month=1;
  209. if(empty($day)) $day=1;
  210. if(empty($hour)) $hour=0;
  211. if(empty($minute)) $minute=0;
  212. if(empty($second)) $second=0;
  213. $when = $when_ts = strtotime($year.'-'.$month.'-'.$day.' '.$hour.':'.$minute.':'.$second)-tz_offset();
  214. $when = "from_unixtime($when)";
  215. }
  216. if ($Title or $Body or $Excerpt)
  217. {
  218. if (empty($url_title)) $url_title = stripSpace($Title_plain, 1);
  219. $url_title_count = safe_count('textpattern', "url_title = '$url_title'");
  220. if ($url_title_count > 0)
  221. return mem_form_error( mem_pa_gtxt('url_title_is_multiple', array('{count}' => $url_title_count, '{value}' => $url_title)) );
  222. $rs = safe_insert(
  223. "textpattern",
  224. "Title = '$Title',
  225. Body = '$Body',
  226. Body_html = '$Body_html',
  227. Excerpt = '$Excerpt',
  228. Excerpt_html = '$Excerpt_html',
  229. Image = '$Image',
  230. Keywords = '$Keywords',
  231. Status = $Status,
  232. Posted = $when,
  233. Expires = $whenexpires,
  234. LastMod = now(),
  235. AuthorID = '$user',
  236. Section = '$Section',
  237. Category1 = '$Category1',
  238. Category2 = '$Category2',
  239. textile_body = $textile_body,
  240. textile_excerpt = $textile_excerpt,
  241. Annotate = $Annotate,
  242. override_form = '$override_form',
  243. url_title = '$url_title',
  244. AnnotateInvite = '$AnnotateInvite',
  245. custom_1 = '$custom_1',
  246. custom_2 = '$custom_2',
  247. custom_3 = '$custom_3',
  248. custom_4 = '$custom_4',
  249. custom_5 = '$custom_5',
  250. custom_6 = '$custom_6',
  251. custom_7 = '$custom_7',
  252. custom_8 = '$custom_8',
  253. custom_9 = '$custom_9',
  254. custom_10 = '$custom_10',
  255. uid = '".md5(uniqid(rand(),true))."',
  256. feed_time = now()"
  257. );
  258. $GLOBALS['ID'] = mysql_insert_id();
  259. if ($Status>=4) {
  260. if (!empty($mem_form_values['mem_public_article_do_pings']))
  261. do_pings();
  262. update_lastmod();
  263. }
  264. }
  265. }
  266. else
  267. {
  268. // update
  269. $oldArticle = safe_row('*, unix_timestamp(LastMod) as sLastMod','textpattern','ID = '.(int)$incoming['ID']);
  270. $incoming = lAtts($oldArticle, $incoming, 0);
  271. $incoming['Annotate'] = empty($incoming['Annotate']) ? 0 : $incoming['Annotate'];
  272. if (!empty($incoming['sLastMod']) && $oldArticle['sLastMod'] != $incoming['sLastMod'])
  273. {
  274. //concurrent edit
  275. return mem_form_error( gTxt('concurrent_edit_by', array('{author}' => htmlspecialchars($oldArticle['LastModID']))) );
  276. }
  277. extract($incoming);
  278. $LastModID = $user;
  279. if (!empty($expires_date))
  280. {
  281. $expires = strtotime($expires_date);
  282. $whenexpires = "Expires=from_unixtime($expires)";
  283. }
  284. else
  285. {
  286. if (!empty($exp_year)) {
  287. if(empty($exp_month)) $exp_month=1;
  288. if(empty($exp_day)) $exp_day=1;
  289. if(empty($exp_hour)) $exp_hour=0;
  290. if(empty($exp_minute)) $exp_minute=0;
  291. if(empty($exp_second)) $exp_second=0;
  292. $expires = strtotime($exp_year.'-'.$exp_month.'-'.$exp_day.' '.$exp_hour.':'.$exp_minute.':'.$exp_second)-tz_offset();
  293. $whenexpires = "Expires=from_unixtime($expires)";
  294. }
  295. else
  296. $whenexpires = '';
  297. }
  298. if(@$reset_time) {
  299. $whenposted = ",Posted=now()";
  300. $when_ts = time();
  301. } else {
  302. if (!empty($year))
  303. {
  304. $when = $when_ts = strtotime($year.'-'.$month.'-'.$day.' '.$hour.':'.$minute.':'.$second)-tz_offset();
  305. $whenposted = ",Posted=from_unixtime($when)";
  306. }
  307. else
  308. $whenposted = '';
  309. }
  310. //Auto-Update custom-titles according to Title, as long as unpublished and NOT customized
  311. if ( empty($url_title)
  312. || ( ($oldArticle['Status'] < 4)
  313. && ($oldArticle['url_title'] == $url_title )
  314. && ($oldArticle['url_title'] == stripSpace($oldArticle['Title'],1))
  315. && ($oldArticle['Title'] != $Title)
  316. )
  317. )
  318. {
  319. $url_title = stripSpace($Title_plain, 1);
  320. $url_title_count = safe_count('textpattern', "url_title = '$url_title' and ID != $ID");
  321. if ($url_title_count > 0)
  322. return mem_form_error( mem_pa_gtxt('url_title_is_multiple', array('{count}' => $url_title_count, '{value}' => $url_title) ));
  323. }
  324. $rs = safe_update("textpattern",
  325. "Title = '$Title',
  326. Body = '$Body',
  327. Body_html = '$Body_html',
  328. Excerpt = '$Excerpt',
  329. Excerpt_html = '$Excerpt_html',
  330. Keywords = '$Keywords',
  331. Image = '$Image',
  332. Status = $Status,
  333. LastMod = now(),
  334. LastModID = '$LastModID',
  335. Section = '$Section',
  336. Category1 = '$Category1',
  337. Category2 = '$Category2',
  338. Annotate = $Annotate,
  339. textile_body = $textile_body,
  340. textile_excerpt = $textile_excerpt,
  341. override_form = '$override_form',
  342. url_title = '$url_title',
  343. AnnotateInvite = '$AnnotateInvite',
  344. custom_1 = '$custom_1',
  345. custom_2 = '$custom_2',
  346. custom_3 = '$custom_3',
  347. custom_4 = '$custom_4',
  348. custom_5 = '$custom_5',
  349. custom_6 = '$custom_6',
  350. custom_7 = '$custom_7',
  351. custom_8 = '$custom_8',
  352. custom_9 = '$custom_9',
  353. custom_10 = '$custom_10'
  354. $whenposted
  355. $whenexpires",
  356. "ID = $ID"
  357. );
  358. if($Status >= 4) {
  359. if ($oldArticle['Status'] < 4 && !empty($mem_form_values['mem_public_article_do_pings']) ) {
  360. do_pings();
  361. }
  362. update_lastmod();
  363. }
  364. }
  365. if (isset($rs) && $rs)
  366. {
  367. $success_form = @$mem_form_values['mem_public_article_success_form'];
  368. if (!empty($success_form))
  369. {
  370. return parse(fetch_form($success_form));
  371. }
  372. }
  373. }
  374. function mem_public_article_ps($atts,$thing='')
  375. {
  376. extract(lAtts(array(
  377. 'name' => false,
  378. ),$atts));
  379. if (!empty($name))
  380. {
  381. $n = gps($name);
  382. if (!empty($n))
  383. return $n;
  384. }
  385. return '';
  386. }
  387. function mem_public_article_if_ps($atts, $thing='')
  388. {
  389. extract(lAtts(array(
  390. 'name' => false,
  391. 'equal' => false,
  392. ),$atts));
  393. if ($name === false)
  394. trigger_error(gTxt('attribute_missing', array('{name}' => $name)));
  395. if ($equal === false)
  396. $condition = isset($_POST[$name]);
  397. else
  398. $condition = (gps('name') == $equal);
  399. $thing = EvalElse($thing, $condition);
  400. return parse($thing);
  401. }
  402. # --- END PLUGIN CODE ---
  403. ?>