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