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

/assets/snippets/jot/jot.class.inc.php

https://github.com/good-web-master/modx.evo.custom
PHP | 914 lines | 884 code | 19 blank | 11 comment | 32 complexity | 248db22780cbd39adf08f23a8d468f16 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-1.0, GPL-2.0, MIT, BSD-3-Clause
  1. <?php
  2. class CJot {
  3. var $name;
  4. var $config = array();
  5. var $parameters = array();
  6. var $_ctime;
  7. var $_provider;
  8. var $_instance;
  9. var $templates = array();
  10. var $_link = array();
  11. var $output;
  12. var $event;
  13. function CJot() {
  14. global $modx;
  15. $path = strtr(realpath(dirname(__FILE__)), '\\', '/');
  16. include_once($path . '/includes/jot.db.class.inc.php');
  17. if (!class_exists('CChunkie'))
  18. include_once($path . '/includes/chunkie.class.inc.php');
  19. $this->name = $this->config["snippet"]["name"] = "Jot";
  20. $this->client = $modx->getUserData();
  21. $this->_ctime = time();
  22. $this->_check = 0;
  23. $this->provider = new CJotDataDb;
  24. $this->form = array();
  25. }
  26. function Get($field) {
  27. return $this->parameters[$field];
  28. }
  29. function Set($field, $value) {
  30. $this->parameters[$field] = $value;
  31. }
  32. function UniqueId($docid = 0,$tagid = '') {
  33. // Creates a unique hash / id
  34. $id[] = $docid."&".$tagid."&";
  35. foreach ($this->parameters as $n => $v) { $id[] = $n.'='.($v); }
  36. return md5(join('&',$id));
  37. }
  38. function Run() {
  39. global $modx;
  40. $this->config["path"] = $this->Get("path");
  41. $this->provider->path = $this->Get("path");
  42. //onBeforeConfiguration event
  43. $this->doEvent("onBeforeConfiguration");
  44. //DB events
  45. $this->provider->events["onBeforeFirstRun"] = $this->Get("onBeforeFirstRun");
  46. $this->provider->events["onFirstRun"] = $this->Get("onFirstRun");
  47. $this->provider->events["onDeleteComment"] = $this->Get("onDeleteComment");
  48. $this->provider->events["onGetCommentFields"] = $this->Get("onGetCommentFields");
  49. $this->provider->events["onBeforeSaveComment"] = $this->Get("onBeforeSaveComment");
  50. $this->provider->events["onSaveComment"] = $this->Get("onSaveComment");
  51. $this->provider->events["onSubscriptionCheck"] = $this->Get("onSubscriptionCheck");
  52. $this->provider->events["onGetSubscriptions"] = $this->Get("onGetSubscriptions");
  53. $this->provider->events["onBeforeSubscribe"] = $this->Get("onBeforeSubscribe");
  54. $this->provider->events["onBeforeUnsubscribe"] = $this->Get("onBeforeUnsubscribe");
  55. $this->provider->events["onBeforeGetUserPostCount"] = $this->Get("onBeforeGetUserPostCount");
  56. $this->provider->events["onBeforeGetCommentCount"] = $this->Get("onBeforeGetCommentCount");
  57. $this->provider->events["onBeforeGetComments"] = $this->Get("onBeforeGetComments");
  58. $this->provider->events["onGetComments"] = $this->Get("onGetComments");
  59. // Add input parameters (just for debugging purposes)
  60. $this->config["snippet"]["input"] = $this->parameters;
  61. // General settings
  62. $this->config["docid"] = !is_null($this->Get("docid")) ? intval($this->Get("docid")):$modx->documentIdentifier;
  63. $this->config["tagid"] = !is_null($this->Get("tagid")) ? preg_replace("/[^A-z0-9_\-]/",'',$this->Get("tagid")):'';
  64. $this->config["docids"] = !is_null($this->Get("docids")) ? $this->processDocs($this->Get("docids")) : $this->config["docid"];
  65. $this->config["tagids"] = !is_null($this->Get("tagids")) ? $this->processTags($this->Get("tagids")) : $this->config["tagid"];
  66. $this->config["userids"] = !is_null($this->Get("userids")) ? $this->processUsers($this->Get("userids")) : '*';
  67. $this->config["pagination"] = !is_null($this->Get("pagination")) ? $this->Get("pagination") : 10; // Set pagination (0 = disabled, # = comments per page)
  68. $this->config["captcha"] = !is_null($this->Get("captcha")) ? intval($this->Get("captcha")) : 0; // Set captcha (0 = disabled, 1 = enabled, 2 = enabled for not logged in users)
  69. $this->config["postdelay"] = !is_null($this->Get("postdelay")) ? $this->Get("postdelay") : 15; // Set post delay in seconds
  70. $this->config["guestname"] = !is_null($this->Get("guestname")) ? $this->Get("guestname") : "Гость"; // Set guestname if none is specified
  71. $this->config["subscriber"] = !is_null($this->Get("subscriber")) ? $this->Get("subscriber") : "подписчик";
  72. $this->config["subscribe"] = !is_null($this->Get("subscribe")) ? intval($this->Get("subscribe")) : 0;
  73. $this->config["numdir"] = !is_null($this->Get("numdir")) ? intval($this->Get("numdir")) : 1;
  74. $this->config["placeholders"] = !is_null($this->Get("placeholders")) ? intval($this->Get("placeholders")) : 0;
  75. $this->config["authorid"] = !is_null($this->Get("authorid")) ? intval($this->Get("authorid")) : intval($modx->documentObject["createdby"]);
  76. $this->config["title"] = !is_null($this->Get("title")) ? $this->Get("title") : '';
  77. $this->config["subject"]["subscribe"] = !is_null($this->Get("subjectSubscribe")) ? $this->Get("subjectSubscribe") : "Новый комментарий";
  78. $this->config["subject"]["moderate"] = !is_null($this->Get("subjectModerate")) ? $this->Get("subjectModerate") : "Новый комментрий в модерируемом разделе";
  79. $this->config["subject"]["author"] = !is_null($this->Get("subjectAuthor")) ? $this->Get("subjectAuthor") : "Новый комментарий на ваш материал";
  80. $this->config["subject"]["emails"] = !is_null($this->Get("subjectEmails")) ? $this->Get("subjectEmails") : $this->config["subject"]["subscribe"];
  81. $this->config["debug"] = !is_null($this->Get("debug")) ? intval($this->Get("debug")) : 0;
  82. $this->config["output"] = !is_null($this->Get("output")) ? intval($this->Get("output")) : 1;
  83. $this->config["validate"] = !is_null($this->Get("validate")) ? $this->Get("validate") : "content:Вы не заполнили поле сообщения";
  84. $this->config["upc"] = !is_null($this->Get("upc")) ? intval($this->Get("upc")) : 1;
  85. $this->config["limit"] = !is_null($this->Get("limit")) ? intval($this->Get("limit")) : 0;
  86. $this->config["depth"] = !is_null($this->Get("depth")) ? intval($this->Get("depth")) : 10;
  87. $notifyEmails = !is_null($this->Get("notifyEmails")) ? explode(",",$this->Get("notifyEmails")) : array();
  88. foreach($notifyEmails as $notifyEmail) {
  89. $notifyProp = explode(":",$notifyEmail,2);
  90. $notifyProp[0] = trim($notifyProp[0]);
  91. $this->config["notifyEmails"][] = $notifyProp[0];
  92. $this->config["notifyNames"][$notifyProp[0]] = isset($notifyProp[1]) ? $notifyProp[1] : $this->config["subscriber"];
  93. }
  94. // CSS Settings (basic)
  95. $this->config["css"]["include"] = !is_null($this->Get("css")) ? intval($this->Get("css")) : 1;
  96. $this->config["css"]["file"] = !is_null($this->Get("cssFile")) ? $this->Get("cssFile") : "assets/snippets/jot/css/jot.css";
  97. $this->config["css"]["rowalt"] = !is_null($this->Get("cssRowAlt")) ? $this->Get("cssAltRow") : "jot-row-alt";
  98. $this->config["css"]["rowme"] = !is_null($this->Get("cssRowMe")) ? $this->Get("cssRowMe") : "jot-row-me";
  99. $this->config["css"]["rowauthor"] = !is_null($this->Get("cssRowAuthor")) ? $this->Get("cssRowAuthor") : "jot-row-author";
  100. // JS Settings
  101. $this->config["js"]["include"] = !is_null($this->Get("js")) ? intval($this->Get("js")) : 0;
  102. $this->config["js"]["file"] = !is_null($this->Get("jsFile")) ? $this->Get("jsFile") : "";
  103. // Security
  104. $this->config["user"]["mgrid"] = intval($_SESSION['mgrInternalKey']);
  105. $this->config["user"]["usrid"] = intval($_SESSION['webInternalKey']);
  106. $this->config["user"]["id"] = ( $this->config["user"]["usrid"] > 0 ) ? (-$this->config["user"]["usrid"]) : $this->config["user"]["mgrid"];
  107. $this->config["user"]["host"] = $this->client['ip'];
  108. $this->config["user"]["ip"] = $this->client['ip'];
  109. $this->config["user"]["agent"] = $this->client['ua'];
  110. $this->config["user"]["sechash"] = md5($this->config["user"]["id"].$this->config["user"]["host"].$this->config["user"]["ip"].$this->config["user"]["agent"]);
  111. // Automatic settings
  112. $this->_instance = $this->config["id"] = $this->UniqueId($this->config["docid"],$this->config["tagid"]);
  113. $this->_idshort = substr($this->_instance,0,8);
  114. if($this->config["captcha"] == 2) { if ($this->config["user"]["id"]) { $this->config["captcha"] = 0;} else { $this->config["captcha"] = 1;} }
  115. $this->config["seed"] = rand(1000,10000);
  116. $this->config["doc.pagetitle"] = $modx->documentObject["pagetitle"];
  117. $this->config["customfields"] = $this->Get("customfields") ? explode(",",$this->Get("customfields")):array("name","email"); // Set names of custom fields
  118. $this->config["sortby"] = !is_null($this->Get("sortby")) ? strtolower($this->Get("sortby")) : "createdon:d";
  119. if ($this->config["sortby"] != 'rand()') $this->config["sortby"] = $this->validateSortString($this->config["sortby"]);
  120. // Set access groups
  121. $this->config["permissions"]["post"] = !is_null($this->Get("canpost")) ? explode(",",$this->Get("canpost")):array();
  122. $this->config["permissions"]["view"] = !is_null($this->Get("canview")) ? explode(",",$this->Get("canview")):array();
  123. $this->config["permissions"]["edit"] = !is_null($this->Get("canedit")) ? explode(",",$this->Get("canedit")):array();
  124. $this->config["permissions"]["moderate"] = !is_null($this->Get("canmoderate")) ? explode(",",$this->Get("canmoderate")):array();
  125. $this->config["permissions"]["trusted"] = !is_null($this->Get("trusted")) ? explode(",",$this->Get("trusted")):array();
  126. // Moderation
  127. $this->config["moderation"]["type"] = !is_null($this->Get("moderated")) ? intval($this->Get("moderated")) : 0;
  128. $this->config["moderation"]["notify"] = !is_null($this->Get("notify")) ? intval($this->Get("notify")) : 1;
  129. $this->config["moderation"]["notifyAuthor"] = !is_null($this->Get("notifyAuthor")) ? intval($this->Get("notifyAuthor")) : 0;
  130. // Access Booleans
  131. // TODO Add logic for manager groups
  132. $this->isModerator = $this->config["moderation"]["enabled"] = intval($modx->isMemberOfWebGroup($this->config["permissions"]["moderate"] ) || $modx->checkSession());
  133. $this->isTrusted = $this->config["moderation"]["trusted"] = intval($modx->isMemberOfWebGroup($this->config["permissions"]["trusted"] ) || $this->isModerator);
  134. $this->canPost = $this->config["user"]["canpost"] = ((count($this->config["permissions"]["post"])==0) || $modx->isMemberOfWebGroup($this->config["permissions"]["post"]) || $this->isModerator) ? 1 : 0;
  135. $this->canView = $this->config["user"]["canview"] = ((count($this->config["permissions"]["view"])==0) || $modx->isMemberOfWebGroup($this->config["permissions"]["view"]) || $this->isModerator) ? 1 : 0;
  136. $this->canEdit = $this->config["user"]["canedit"] = intval($modx->isMemberOfWebGroup($this->config["permissions"]["edit"]) || $this->isModerator);
  137. // Templates
  138. $this->templates["form"] = !is_null($this->Get("tplForm")) ? $this->Get("tplForm") : $this->config["path"]."/templates/chunk.form.inc.html";
  139. $this->templates["comments"] = !is_null($this->Get("tplComments")) ? $this->Get("tplComments") : $this->config["path"]."/templates/chunk.comment.inc.html";
  140. $this->templates["navigation"] = !is_null($this->Get("tplNav")) ? $this->Get("tplNav") : $this->config["path"]."/templates/chunk.navigation.inc.html";
  141. $this->templates["moderate"] = !is_null($this->Get("tplModerate")) ? $this->Get("tplModerate") : $this->config["path"]."/templates/chunk.moderate.inc.html";
  142. $this->templates["subscribe"] = !is_null($this->Get("tplSubscribe")) ? $this->Get("tplSubscribe") : $this->config["path"]."/templates/chunk.subscribe.inc.html";
  143. $this->templates["notify"] = !is_null($this->Get("tplNotify")) ? $this->Get("tplNotify") : $this->config["path"]."/templates/chunk.notify.inc.txt";
  144. $this->templates["notifymoderator"] = !is_null($this->Get("tplNotifyModerator")) ? $this->Get("tplNotifyModerator") : $this->config["path"]."/templates/chunk.notify.moderator.inc.txt";
  145. $this->templates["notifyauthor"] = !is_null($this->Get("tplNotifyAuthor")) ? $this->Get("tplNotifyAuthor") : $this->config["path"]."/templates/chunk.notify.author.inc.txt";
  146. $this->templates["notifyemails"] = !is_null($this->Get("tplNotifyEmails")) ? $this->Get("tplNotifyEmails") : $this->templates["notify"];
  147. $this->templates["navPage"] = !is_null($this->Get("tplNavPage")) ? $this->Get("tplNavPage") : $this->config["path"]."/templates/chunk.nav.page.inc.html";
  148. $this->templates["navPageCur"] = !is_null($this->Get("tplNavPageCur")) ? $this->Get("tplNavPageCur") : $this->config["path"]."/templates/chunk.nav.pagecur.inc.html";
  149. $this->templates["navPageSpl"] = !is_null($this->Get("tplNavPageSpl")) ? $this->Get("tplNavPageSpl") : '';
  150. // Querystring keys
  151. $this->config["querykey"]["action"] = "jot".$this->_idshort;
  152. $this->config["querykey"]["navigation"] = "jn".$this->_idshort;
  153. $this->config["querykey"]["id"] = "jid".$this->_idshort;
  154. $this->config["querykey"]["view"] = "jv".$this->_idshort;
  155. // Querystring values
  156. $this->config["query"]["action"] = $_GET[$this->config["querykey"]["action"]];
  157. $this->config["query"]["navigation"] = intval($_GET[$this->config["querykey"]["navigation"]]);
  158. $this->config["query"]["id"] = intval($_GET[$this->config["querykey"]["id"]]);
  159. $this->config["query"]["view"] = intval($_GET[$this->config["querykey"]["view"]]);
  160. // Form options
  161. $this->isPostback = $this->config["form"]["postback"] = ($_POST["JotForm"] == $this->_instance) ? 1 : 0;
  162. // Field validation array
  163. $valStrings = explode(",",$this->config["validate"]);
  164. $valFields = array();
  165. foreach($valStrings as $valString) {
  166. $valProp = explode(":",$valString,3);
  167. $valField = array();
  168. $valField["validation"] = "required";
  169. foreach($valProp as $i => $v) {
  170. if ($i==1) $valField["msg"] = $v;
  171. if ($i==2) $valField["validation"] = $v;
  172. }
  173. $valFields[$valProp[0]][] = $valField;
  174. }
  175. $this->config["form"]["validation"] = $valFields;
  176. //onConfiguration event
  177. $this->doEvent("onConfiguration");
  178. //-- Initialize form array()
  179. $this->form = array();
  180. $this->form["source"] = $this->config["query"]["id"];
  181. $this->form["guest"] = ($this->config["user"]["id"]) ? 0 : 1;
  182. $this->form["field"] = array("custom" => array());
  183. $this->form["error"] = 0;
  184. $this->form["confirm"] = 0;
  185. $this->form["published"] = 0;
  186. $this->form["badwords"] = 0;
  187. $this->form["edit"] = 0;
  188. $this->form["save"] = 0;
  189. $this->form["field"]["parent"] = intval($_GET['parent']);
  190. // Modes
  191. $this->config["mode"]["type"] = "comments";
  192. $this->config["mode"]["active"] = $this->config["query"]["action"];
  193. $this->config["mode"]["passive"] = str_replace('-','',$this->Get("action"));
  194. // Generated links
  195. $this->_link = array($this->config["querykey"]["action"]=>NULL,$this->config["querykey"]["id"]=>NULL);
  196. $this->config["link"]["id"] = $this->_idshort;
  197. $this->config["link"]["current"] = $this->preserveUrl($modx->documentIdentifier,'',$this->_link);
  198. $this->config["link"]["navigation"] = $this->preserveUrl($modx->documentIdentifier,'',array_merge($this->_link,array($this->config["querykey"]["navigation"]=>NULL)),true);
  199. $this->config["link"]["subscribe"] = $this->preserveUrl($modx->documentIdentifier,'',array_merge($this->_link,array($this->config["querykey"]["action"]=>'subscribe')));
  200. $this->config["link"]["unsubscribe"] = $this->preserveUrl($modx->documentIdentifier,'',array_merge($this->_link,array($this->config["querykey"]["action"]=>'unsubscribe')));
  201. $this->config["link"]["save"] = $this->preserveUrl($modx->documentIdentifier,'',array_merge($this->_link,array($this->config["querykey"]["action"]=>'save',$this->config["querykey"]["id"]=>$this->config["query"]["id"])));
  202. $this->config["link"]["edit"] = $this->preserveUrl($modx->documentIdentifier,'',array_merge($this->_link,array($this->config["querykey"]["action"]=>'edit')),true);
  203. $this->config["link"]["delete"] = $this->preserveUrl($modx->documentIdentifier,'',array_merge($this->_link,array($this->config["querykey"]["action"]=>'delete')),true);
  204. $this->config["link"]["view"] = $this->preserveUrl($modx->documentIdentifier,'',array_merge($this->_link,array($this->config["querykey"]["view"]=>NULL)),true);
  205. $this->config["link"]["publish"] = $this->preserveUrl($modx->documentIdentifier,'',array_merge($this->_link,array($this->config["querykey"]["action"]=>'publish')),true);
  206. $this->config["link"]["unpublish"] = $this->preserveUrl($modx->documentIdentifier,'',array_merge($this->_link,array($this->config["querykey"]["action"]=>'unpublish')),true);
  207. $this->provider->FirstRun($this->config["path"]); // Check for first run
  208. // Badwords
  209. $this->config["badwords"]["enabled"] = !is_null($this->Get("badwords")) ? 1 : 0;
  210. $this->config["badwords"]["type"] = !is_null($this->Get("bw")) ? intval($this->Get("bw")) : 1;
  211. if($this->config["badwords"]["enabled"]) {
  212. $badwords = $this->Get("badwords");
  213. $badwords = preg_replace("~([\n\r\t\s]+)~","",$badwords);
  214. $this->config["badwords"]["words"] = explode(",",$badwords);
  215. $this->config["badwords"]["regexp"] = "~" . implode("|",$this->config["badwords"]["words"]) . "~iu";
  216. }
  217. // Moderation
  218. if ($this->isModerator) {
  219. $this->config["moderation"]["view"] = $view = isset($_GET[$this->config["querykey"]["view"]]) ? $this->config["query"]["view"]: 2;
  220. }
  221. // Subscription
  222. $this->config["subscription"]["enabled"] = 0;
  223. $this->config["subscription"]["status"] = 0;
  224. if ($this->config["user"]["id"] && $this->config["subscribe"]) {
  225. $this->config["subscription"]["enabled"] = 1;
  226. $isSubscribed = $this->provider->hasSubscription($this->config["docid"],$this->config["tagid"], $this->config["user"]);
  227. if ($isSubscribed) $this->config["subscription"]["status"] = 1;
  228. }
  229. $commentId = $this->config["query"]["id"];
  230. //onBeforeRunActions event
  231. $this->doEvent("onBeforeRunActions");
  232. // Active action
  233. switch ($this->config["mode"]["active"]) {
  234. case "delete":
  235. $this->doModerate('delete',$commentId);
  236. break;
  237. case "publish":
  238. $this->doModerate('publish',$commentId);
  239. break;
  240. case "unpublish":
  241. $this->doModerate('unpublish',$commentId);
  242. break;
  243. case "edit":
  244. if ($this->isModerator) {
  245. $this->doModerate('edit',$commentId);
  246. break;
  247. } else {
  248. $this->form["edit"] = 1;
  249. }
  250. case "save":
  251. if ($this->isModerator) {
  252. $this->doModerate('save',$commentId);
  253. break;
  254. } else {
  255. $this->form["edit"] = 1;
  256. $this->form["save"] = 1;
  257. }
  258. case "move":
  259. break;
  260. case "subscribe":
  261. if ($this->config["subscription"]["enabled"] == 1) {
  262. if ($this->config["subscription"]["status"] == 0) {
  263. $this->provider->Subscribe($this->config["docid"],$this->config["tagid"],$this->config["user"]);
  264. $this->config["subscription"]["status"] = 1;
  265. }
  266. }
  267. break;
  268. case "unsubscribe":
  269. if ($this->config["subscription"]["enabled"] == 1) {
  270. if ($this->config["subscription"]["status"] == 1) {
  271. $this->provider->Unsubscribe($this->config["docid"],$this->config["tagid"],$this->config["user"]);
  272. $this->config["subscription"]["status"] = 0;
  273. }
  274. }
  275. break;
  276. }
  277. //onRunActions event
  278. $this->doEvent("onRunActions");
  279. // Form Processing
  280. $frmCommentId = ($this->form["edit"]) ? $commentId : 0;
  281. $this->processForm($frmCommentId);
  282. //onBeforeProcessPassiveActions event
  283. $this->doEvent("onBeforeProcessPassiveActions");
  284. // Passive Action
  285. $actionPath = $this->config["path"].'actions/' . $this->config["mode"]["passive"] . '.inc.php';
  286. $object = & $this;
  287. if(is_file($actionPath)) {
  288. include_once $actionPath;
  289. $modeName = $this->config["mode"]["passive"] . '_mode';
  290. if(function_exists($modeName)) $this->output = $modeName($object);
  291. }
  292. //onProcessPassiveActions event
  293. $this->doEvent("onProcessPassiveActions");
  294. if ($this->config["debug"]) {
  295. $this->output .= '<br /><hr /><b>'.$this->name.' : Debug</b><hr /><pre style="overflow: auto;background-color: white;font-weight: bold;">';
  296. $this->output .= $this->getOutputDebug($this->config,"jot");
  297. $this->output .= '</pre><hr />';
  298. }
  299. // Dump config into placeholders?
  300. if ($this->config["placeholders"]) $this->setPlaceholders($this->config,"jot");
  301. // Include stylesheet if needed
  302. if ($this->config["css"]["include"]) $modx->regClientCSS($modx->config["base_url"].$this->config["css"]["file"]);
  303. // Include JS if needed
  304. if ($this->config["js"]["include"]) $modx->regClientStartupScript($modx->config["base_url"].$this->config["js"]["file"]);
  305. //onReturnOutput event
  306. $this->doEvent("onReturnOutput");
  307. return $this->output;
  308. }
  309. // Output snippet values in debug format
  310. function getOutputDebug($value = '', $key = '', $path = '') {
  311. $keypath = !empty($path) ? $path . "." . $key : $key;
  312. $output = array();
  313. if (is_array($value)) {
  314. foreach ($value as $subkey => $subval) {
  315. $output[] = $this->getOutputDebug($subval, $subkey, $keypath);
  316. }
  317. } else {
  318. $output[] = '<span style="color: navy;">'.$keypath.'</span> = <span style="color: maroon;">'.htmlspecialchars($value).'</span><br />';
  319. }
  320. return implode("",$output);
  321. }
  322. // Create placeholders in MODx from arrays
  323. function setPlaceholders($value = '', $key = '', $path = '') {
  324. global $modx;
  325. $keypath = !empty($path) ? $path . "." . $key : $key;
  326. $output = array();
  327. if (is_array($value)) {
  328. foreach ($value as $subkey => $subval) {
  329. $this->setPlaceholders($subval, $subkey, $keypath);
  330. }
  331. } else {
  332. if (strlen($this->config["tagid"]) > 0) {$keypath .= ".".$this->config["tagid"]; }
  333. $modx->setPlaceholder($keypath,$value);
  334. }
  335. }
  336. function processForm($id=0) {
  337. global $modx;
  338. // Comment
  339. $id = intval($id);
  340. $pObj = $this->provider;
  341. $formMode = $this->config["mode"]["passive"];
  342. $saveComment = 1;
  343. $this->form["action"] = $this->config["link"]["current"];
  344. if ($id && $pObj->isValidComment($this->config["docid"],$this->config["tagid"],$id) && $this->canEdit) {
  345. $pObj->Comment($id);
  346. if (($pObj->Get("createdby") == $this->config["user"]["id"]) || $this->isModerator) {
  347. $this->form["action"] = $this->config["link"]["save"];
  348. $this->form['guest'] = ($pObj->Get("createdby") == 0 && $this->form["save"] != 1) ? 1 : 0;
  349. $this->form["field"] = $pObj->getFields();
  350. $this->config["mode"]["passive"] = "form";
  351. } else {
  352. $this->form['edit'] = 0;
  353. $this->form['save'] = 0;
  354. $saveComment = 0;
  355. }
  356. } else {
  357. $pObj->Comment(0); // fix for update/new problem
  358. }
  359. // If this is not a postback or a false edit then return.
  360. if (!$this->isPostback || !$saveComment) return;
  361. // If we get here switch passive mode back and let the save option decide the final passive mode
  362. $this->config["mode"]["passive"] = $formMode;
  363. //-- Get Post Objects
  364. $chkPost = array();
  365. $valFields = array();
  366. //onBeforePOSTProcess event
  367. if (null !== ($output = $this->doEvent("onBeforePOSTProcess",array("id"=>$id,"pObj"=>&$pObj,"saveComment"=>&$saveComment)))) return;
  368. // For every field posted loop
  369. foreach($_POST as $n=>$v) {
  370. // Stripslashes if needed
  371. if (get_magic_quotes_gpc()) { $v = stripslashes($v); }
  372. // Validate fields and store error level + msg in array
  373. $valFields[] = $this->validateFormField($n,$v);
  374. // Store field data
  375. switch($n) {
  376. case 'title': // Title field
  377. if ($v == '' && $this->config["title"]) $v = "Re: " . $this->config["title"];
  378. $this->form["field"]["title"] = $v;
  379. $pObj->Set("title",$v);
  380. break;
  381. case 'content': // Content field
  382. $this->form["field"]["content"] = $v;
  383. $pObj->Set("content",$v);
  384. break;
  385. case 'parent': // Parent field
  386. $this->form["field"]["parent"] = intval($v);
  387. $pObj->Set("parent",intval($v));
  388. break;
  389. default: // Custom fields
  390. if (in_array($n, $this->config["customfields"])) {
  391. $this->form["field"]["custom"][$n] = $v;
  392. $pObj->SetCustom($n,$v);
  393. } else {
  394. $this->form["field"][$n] = $v;
  395. }
  396. }
  397. //-- Detect bad words
  398. if ($this->config["badwords"]["enabled"]) $this->form['badwords'] = $this->form['badwords'] + preg_match_all($this->config["badwords"]["regexp"],$v,$matches);
  399. //--
  400. $chkPost[] = $n.'='.($v);
  401. } // --
  402. //-- Double Post Capture
  403. $chkPost = md5(join('&',$chkPost));
  404. if ($_SESSION['JotLastPost'] == $chkPost) {
  405. $this->form['error'] = 1;
  406. $this->form['confirm'] = 0;
  407. $saveComment = 0;
  408. } else {
  409. $_SESSION['JotLastPost'] = $chkPost;
  410. }
  411. //-- Security check (Post Delay?)
  412. if ($saveComment && $this->form['error'] == 0 && $this->config["postdelay"] != 0 && $pObj->hasPosted($this->config["postdelay"],$this->config["user"])) {
  413. $this->form['error'] = 3; // Post to fast (within delay)
  414. return;
  415. };
  416. //-- Captcha/Veriword
  417. if ($saveComment && !(($this->config["captcha"] == 0 || isset($_POST['vericode']) && isset($_SESSION['veriword']) && $_SESSION['veriword'] == $_POST['vericode']))) {
  418. $this->form['error'] = 2; // Veriword / Captcha incorrect
  419. unset($pObj);
  420. return;
  421. } else {
  422. $_SESSION['veriword'] = md5($this->config["seed"]);
  423. }
  424. //-- Validate fields
  425. if ($saveComment) {
  426. foreach($valFields as $valid) {
  427. if (!$valid[0]) {
  428. $this->form['error'] = 5;
  429. $this->form['errormsg'] = $valid[1];
  430. $this->form['confirm'] = 0;
  431. $saveComment = 0;
  432. return;
  433. }
  434. }
  435. }
  436. // Everything OK so far
  437. if ($saveComment) {
  438. $this->form['confirm'] = 1;
  439. $this->form['published'] = 1;
  440. }
  441. //-- Check publish settings (moderations)
  442. if ($saveComment && $this->config["moderation"]["type"] && !$this->isTrusted) {
  443. $this->form['confirm'] = 2;
  444. $this->form['published'] = 0;
  445. }
  446. // Badwords detection logic
  447. if ($saveComment && $this->form["badwords"] && $this->config["badwords"]["enabled"] && !$this->isTrusted) {
  448. switch($this->config["badwords"]["type"]) {
  449. case 2: // Post Rejected
  450. $this->form['error'] = 4;
  451. $this->form['confirm'] = 0;
  452. $saveComment = 0;
  453. break;
  454. case 1: // Post Not Published
  455. $this->form['published'] = 0;
  456. $this->form['confirm'] = 2; // Post Not Published
  457. break;
  458. }
  459. }
  460. // If published or unpublished save the comment, else do nothing.
  461. if (!$id) {
  462. // this is a new post
  463. $pObj->Set("createdon",$this->_ctime);
  464. $pObj->Set("createdby",$this->config["user"]["id"]);
  465. $pObj->Set("secip",$this->config["user"]["ip"]);
  466. $pObj->Set("sechash",$this->config["user"]["sechash"]);
  467. $pObj->Set("uparent",$this->config["docid"]);
  468. $pObj->Set("tagid",$this->config["tagid"]);
  469. } else {
  470. // edit/save
  471. $pObj->Set("editedon",$this->_ctime);
  472. $pObj->Set("editedby",$this->config["user"]["id"]);
  473. }
  474. $pObj->Set("published",$this->form['published']);
  475. if ($saveComment) $pObj->Save();
  476. // Edit mode logic
  477. if ($saveComment && $this->form["save"]) {
  478. $this->form["moderation"] = 0;
  479. $this->form["edit"] = 0;
  480. if($this->form["confirm"]==1) $this->form["confirm"] = 3;
  481. $this->form["action"] = $this->config["link"]["current"];
  482. }
  483. if ($this->form["edit"]) { $this->config["mode"]["passive"] = "form"; }
  484. // Notify Subscribers
  485. if ($saveComment && $this->form['published']>0 && $this->config["subscription"]["enabled"]) $this->doNotify($pObj->Get("id"),"notify");
  486. // Notify Moderators
  487. if ($saveComment && (($this->form['published']==0 && $this->config["moderation"]["notify"]==1) || ($this->form['published'] >0 && $this->config["moderation"]["notify"]==2)))
  488. $this->doNotify($pObj->Get("id"),"notifymoderator");
  489. // Notify Author
  490. if ($saveComment && $this->config["moderation"]["notifyAuthor"]) $this->doNotify($pObj->Get("id"),"notifyauthor");
  491. // Notify Emails
  492. if ($saveComment && !empty($this->config["notifyEmails"])) $this->doNotify($pObj->Get("id"),"notifyemails");
  493. // If no error occured clear fields.
  494. if ($this->form['error'] <= 0 ) $this->form["field"] = array();
  495. //onProcessForm event
  496. if (null !== ($output = $this->doEvent("onProcessForm",array("id"=>$id,"pObj"=>&$pObj,"saveComment"=>$saveComment)))) return;
  497. // Destroy Comment Object and return form array()
  498. unset($pObj);
  499. return;
  500. }
  501. // Notifications
  502. function doNotify($commentid=0,$action="notify") {
  503. global $modx;
  504. // Get comment fields
  505. $cObj = $this->provider;
  506. $cObj->Comment($commentid);
  507. $comment = $cObj->getFields();
  508. unset($cObj);
  509. switch ($action) {
  510. case "notify":
  511. $user_ids = $this->provider->getSubscriptions($this->config["docid"],$this->config["tagid"]);
  512. $subject = $this->config["subject"]["subscribe"];
  513. break;
  514. case "notifymoderator":
  515. $user_ids = $this->getMembersOfWebGroup($this->config["permissions"]["moderate"]);
  516. $subject = $this->config["subject"]["moderate"];
  517. break;
  518. case "notifyauthor":
  519. $user_ids = array($this->config["authorid"]);
  520. $subject = $this->config["subject"]["author"];
  521. break;
  522. case "notifyemails":
  523. $user_ids = $this->config["notifyEmails"];
  524. $subject = $this->config["subject"]["emails"];
  525. break;
  526. }
  527. include_once MODX_BASE_PATH . "manager/includes/controls/class.phpmailer.php";
  528. foreach ($user_ids as $user_id){
  529. if ($this->config["user"]["id"] !== $user_id) {
  530. if ($action == "notifyemails") {
  531. $user = array();
  532. $user["email"] = $user_id;
  533. $user["username"] = $this->config["notifyNames"][$user_id];
  534. } else {
  535. $user = $this->getUserInfo($user_id);
  536. }
  537. $tpl = new CChunkie($this->templates[$action]);
  538. $tpl->AddVar("siteurl","http://".$_SERVER["SERVER_NAME"]);
  539. //onBeforeNotify event
  540. if (null === $this->doEvent("onBeforeNotify",array("commentid"=>$commentid,"action"=>$action,"tpl"=>&$tpl,"subject"=>&$subject,"comment"=>&$comment,"user"=>&$user))) {
  541. $tpl->AddVar("jot",$this->config);
  542. $tpl->AddVar("comment",$comment);
  543. $tpl->AddVar("recipient",$user);
  544. $mail = new PHPMailer();
  545. $mail->IsMail();
  546. $mail->CharSet = $modx->config["modx_charset"];
  547. $mail->IsHTML(false);
  548. $mail->From = $modx->config["emailsender"];
  549. $mail->FromName = $modx->config["site_name"];
  550. $mail->Subject = $subject;
  551. $mail->Body = $tpl->Render();
  552. $mail->AddAddress($user["email"]);
  553. $mail->Send();
  554. }
  555. }
  556. }
  557. }
  558. // Moderation
  559. function doModerate($action = '',$id = 0) {
  560. $output = NULL;
  561. $pObj = $this->provider;
  562. if ($this->isModerator && $pObj->isValidComment($this->config["docid"],$this->config["tagid"],$id)) {
  563. switch ($action) {
  564. case "delete":
  565. $pObj->Comment($id);
  566. $pObj->Delete();
  567. break;
  568. case "publish":
  569. $pObj->Comment($id);
  570. $pObj->Set("publishedon",$this->_ctime);
  571. $pObj->Set("publishedby",$this->config["user"]["id"]);
  572. $pObj->Set("published",1);
  573. $pObj->Save();
  574. if ($this->config["subscription"]["enabled"]) $this->doNotify($id,"notify");
  575. break;
  576. case "edit":
  577. $this->form["moderation"] = 1;
  578. $this->form["edit"] = 1;
  579. break;
  580. case "save":
  581. $this->form["moderation"] = 1;
  582. $this->form["edit"] = 1;
  583. $this->form["save"] = 1;
  584. break;
  585. case "unpublish":
  586. $pObj->Comment($id);
  587. $pObj->Set("publishedon",$this->_ctime);
  588. $pObj->Set("publishedby",$this->config["user"]["id"]);
  589. $pObj->Set("published",0);
  590. $pObj->Save();
  591. break;
  592. }
  593. }
  594. unset($pObj);
  595. return $output;
  596. }
  597. // Templating
  598. function getChunkRowClass($count,$userid) {
  599. $rowstyle = ($count%2) ? "jot-row-alt" : "";
  600. if ( $this->config["user"]["id"] == $userid && ($userid != 0)) {
  601. $rowstyle .= " jot-row-me";
  602. } elseif ( $this->config["authorid"] == $userid && ($userid != 0) ) {
  603. $rowstyle .= " jot-row-author";
  604. }
  605. return $rowstyle;
  606. }
  607. // Validate a field
  608. function validateFormField($name = '', $value = '') {
  609. $returnValue = array(1,"");
  610. $validateFields = $this->config["form"]["validation"];
  611. //onBeforeValidateFormField event
  612. if (null !== ($output = $this->doEvent("onBeforeValidateFormField",array("name"=>$name,"value"=>$value)))) return $output;
  613. // Validation Exists?
  614. if (!array_key_exists($name, $validateFields))
  615. return $returnValue;
  616. // Load field validation array
  617. $validations = $validateFields[$name];
  618. // Loop validation array
  619. foreach($validations as $validation) {
  620. switch ($validation["validation"]) {
  621. // email validation
  622. case "email": $re = "~^(?:[a-z0-9_-]+?\.)*?[a-z0-9_-]+?@(?:[a-z0-9_-]+?\.)*?[a-z0-9_-]+?\.[a-z0-9]{2,5}$~i"; break;
  623. // simple required field validation
  624. case "required": $re = "~.+~s";break;
  625. // simple number validation
  626. case "number": $re = "~^\d+$~";break;
  627. // custom regexp pattern
  628. default: $re = $validation["validation"]; break;
  629. }
  630. // if not a match return error msg
  631. if (!preg_match($re,$value)) {
  632. //onValidateFormFieldFail event
  633. if (null !== ($output = $this->doEvent("onValidateFormFieldFail",array("name"=>$name,"value"=>$value,"validation"=>$validation)))) return $output;
  634. return array(0,$validation["msg"]);
  635. }
  636. }
  637. return $returnValue;
  638. }
  639. // Validates and returns a special sort string so the data provider can handle this.
  640. function validateSortString($strSort = '') {
  641. $z = array();
  642. $xObj = $this->provider;
  643. $xObj->Comment();
  644. $y = explode(",",$strSort); // suggested sort fields
  645. $x = $xObj->getFields(); // actual available sort fields
  646. $x2 = $this->config["customfields"]; // actual available custom sort fields
  647. unset($xObj);
  648. // for each suggested sort
  649. foreach ($y as $i) {
  650. $i = trim($i);
  651. if(strlen($i)>2) {
  652. // get direction
  653. $dir = substr($i, -2);
  654. // get fieldname
  655. $name = substr($i,0,(strlen($i)-2));
  656. // if this is a custom field prefix with '#' so data provider can detect it.
  657. if (in_array($name, $x2)) { $z[] = "#".$name.$dir; }
  658. // if normal field
  659. elseif (array_key_exists($name, $x)) { $z[] = $name.$dir; }
  660. }
  661. }
  662. return implode(",",$z);
  663. }
  664. // Returns an array containing webusers which are a member of the specified group(s).
  665. function getMembersOfWebGroup($groupNames=array()) {
  666. global $modx;
  667. $usrIDs = array();
  668. $tbl = $modx->getFullTableName("webgroup_names");
  669. $tbl2 = $modx->getFullTableName("web_groups");
  670. $sql = "SELECT distinct wg.webuser
  671. FROM $tbl wgn
  672. INNER JOIN $tbl2 wg ON wg.webgroup=wgn.id AND wgn.name IN ('" . implode("','",$groupNames) . "')";
  673. $usrRows = $modx->db->getColumn("webuser", $sql);
  674. foreach ($usrRows as $v) $usrIDs[] = -intval($v);
  675. return $usrIDs;
  676. }
  677. // MODx UserInfo enhanced
  678. function getUserInfo($userid = 0,$field = NULL) {
  679. global $modx;
  680. //onBeforeGetUserInfo event
  681. if (null !== ($output = $this->doEvent("onBeforeGetUserInfo",array("userid"=>$userid,"field"=>$field)))) return $output;
  682. if (intval($userid) < 0) {
  683. $user = $modx->getWebUserInfo(-($userid));
  684. } else {
  685. $user = $modx->getUserInfo($userid);
  686. }
  687. if ($field) { return $user[$field]; }
  688. return $user;
  689. }
  690. // MODx makeUrl enhanced: preserves querystring.
  691. function preserveUrl($docid = '', $alias = '', $array_values = array(), $suffix = false) {
  692. global $modx;
  693. $array_get = $_GET;
  694. $urlstring = array();
  695. unset($array_get["id"]);
  696. unset($array_get["q"]);
  697. $array_url = array_merge($array_get, $array_values);
  698. foreach ($array_url as $name => $value) {
  699. if (!is_null($value)) {
  700. $urlstring[] = $name . '=' . urlencode($value);
  701. }
  702. }
  703. $url = join('&',$urlstring);
  704. if ($suffix) {
  705. if (empty($url)) { $url = "?"; }
  706. else { $url .= "&"; }
  707. }
  708. return $modx->makeUrl($docid, $alias, $url);
  709. }
  710. // invoke events
  711. function doEvent($event,$params=array()) {
  712. global $modx;
  713. $this->event = $event;
  714. $event = $this->Get($event);
  715. if (!$event) return null;
  716. $plugins=explode(',',$event);
  717. $object = & $this;
  718. $result = null;
  719. foreach ($plugins as $plugin) {
  720. if(function_exists($plugin)) {
  721. if (null !== ($output = $plugin($object,$params))) $result = $output;
  722. } else {
  723. $pluginPath = $this->config["path"].'plugins/' . $plugin . '.inc.php';
  724. if(is_file($pluginPath)) {
  725. include $pluginPath;
  726. if(function_exists($plugin)) {
  727. if (null !== ($output = $plugin($object,$params))) $result = $output;
  728. }
  729. }
  730. }
  731. }
  732. $this->event = '';
  733. return $result;
  734. }
  735. function processDocs($docids) {
  736. global $modx;
  737. $idarray = array();
  738. if ($docids != '*') $values = explode(',',$docids);
  739. else return $docids;
  740. /* parse values, and check for invalid entries */
  741. foreach ($values as $value) {
  742. /* value is a range */
  743. if (preg_match('/^[\d]+\-[\d]+$/', trim($value))) {
  744. $match = explode('-', $value);
  745. $loop = $match[1] - $match[0];
  746. for ($i = 0; $i <= $loop; $i++) {
  747. $idarray[] = $i + intval($match[0]);
  748. }
  749. }
  750. /* value is a group for immediate children */
  751. elseif (preg_match('/^[\d]+\*$/', trim($value), $match)) {
  752. $match = rtrim($match[0], '*');
  753. $idarray[] = intval($match);
  754. $children = $modx->getChildIds($match,1);
  755. foreach ($children as $v) $idarray[] = intval($v);
  756. }
  757. /* value is a group for ALL children */
  758. elseif (preg_match('/^[\d]+\*\*$/', trim($value), $match)) {
  759. $match = rtrim($match[0], '**');
  760. $idarray[] = intval($match);
  761. $children = $modx->getChildIds($match);
  762. foreach ($children as $v) $idarray[] = intval($v);
  763. }
  764. /* value is a single document */
  765. elseif (preg_match('/^[\d]+$/', trim($value), $match)) {
  766. $idarray[] = intval($match[0]);
  767. }
  768. }
  769. if (empty($idarray)) return $modx->documentIdentifier;
  770. return $idarray;
  771. }
  772. function processTags($tagids) {
  773. global $modx;
  774. $idarray = array();
  775. if ($tagids != '*') $values = explode(',',$tagids);
  776. else return $tagids;
  777. foreach ($values as $value) {
  778. $value = preg_replace('/[^A-z0-9_\-]/','',$value);
  779. if (!empty($value)) $idarray[] = $value;
  780. }
  781. if (empty($idarray)) return '';
  782. return $idarray;
  783. }
  784. function processUsers($userids) {
  785. global $modx;
  786. $idarray = array();
  787. if ($userids != '*') $values = explode(',',$userids);
  788. else return $userids;
  789. foreach ($values as $value) {
  790. $value = preg_replace('/[^0-9\-]/','',$value);
  791. if (!empty($value)) $idarray[] = $value;
  792. }
  793. if (empty($idarray)) return '*';
  794. return $idarray;
  795. }
  796. }
  797. ?>