1 <?php
2 3 4 5 6 7 8 9 10 11 12
13 class EUserFlash extends CWidget
14 {
15 const LOG_CATEGORY = 'userflash';
16
17 18 19 20 21
22 public $errorLogVars = array('_GET','_POST');
23
24 25 26 27 28 29 30 31 32 33 34
35 public $context;
36
37 38 39 40 41
42 public $deleteMessages = true;
43
44 45 46 47 48
49 public $tag = 'div';
50
51 52 53 54 55
56 public $cssClassDefault = 'flash-default';
57
58 59 60 61 62
63 public $cssClassNotice = 'flash-notice';
64
65 66 67 68 69
70 public $cssClassError = 'flash-error';
71
72 73 74 75 76
77 public $cssClassWarning = 'flash-warning';
78
79 80 81 82 83
84 public $cssClassSuccess = 'flash-success';
85
86 87 88 89 90 91 92 93 94
95 public $initScript;
96
97 98 99 100 101
102 public $htmlOptions = array();
103
104 105 106 107 108
109 public $loggingEnabled = true;
110
111 112 113 114 115
116 private $_registerJQuery;
117
118 119 120 121 122
123 public function renderMessages()
124 {
125 $this->_registerJQuery = !empty($this->initScript) && is_string($this->initScript);
126
127 if (isset($this->context))
128 $this->context = self::contextToArray($this->context);
129
130 $renderedCount = 0;
131 $flashMessages = Yii::app()->user->getFlashes(false);
132
133 if (!empty($flashMessages))
134 {
135 $id = $this->getId();
136
137 foreach ($flashMessages as $key=>$message)
138 if ($this->decodeFlashKey($key,$messageType,$context,$cssClass,$logLevel))
139 {
140 $logContext = $context;
141 $htmlOptions = $this->htmlOptions;
142 $displayMessage = false;
143
144 if ($this->context === null)
145 $displayMessage = true;
146 else
147 if (empty($this->context) && empty($context))
148 $displayMessage = true;
149 else
150 if (!empty($context))
151 {
152 $logContext = array_intersect($this->context,$context);
153 $displayMessage = !empty($logContext);
154 }
155
156 if ($displayMessage)
157 {
158 if(!empty($cssClass))
159 $htmlOptions['class'] = isset($htmlOptions['class'])
160 ? $htmlOptions['class'] .' ' . $cssClass
161 : $cssClass;
162
163 $htmlOptions['class'] = !empty($htmlOptions['class'])
164 ? $htmlOptions['class'] .' userflash userflash_'.$messageType
165 : 'userflash userflash_'.$messageType;
166
167 $htmlOptions['id'] = isset($htmlOptions['id'])
168 ? $htmlOptions['id'] .'_' . $renderedCount
169 : $id .'_' . $renderedCount;
170
171 $this->renderMessage($messageType,$message,$htmlOptions);
172
173 $this->logFlashMessage($messageType,$logContext,$message,$logLevel);
174
175 if ($this->deleteMessages)
176 Yii::app()->user->setFlash($key,null);
177
178 $renderedCount++;
179 }
180 }
181 }
182
183 return $renderedCount;
184 }
185
186 187 188
189 protected function renderMessage($messageType,$message,$htmlOptions)
190 {
191
192 if ($messageType=='js_alert')
193 {
194 $script = "alert('$message');";
195 Yii::app()->clientScript->registerScript(__CLASS__.'#'.$htmlOptions['id'],$script);
196 }
197 else
198
199 if($messageType=='jq_ajax')
200 {
201 $this->_registerJQuery = true;
202
203 echo CHtml::tag($this->tag,$htmlOptions,'');
204 $script = CHtml::ajax(array(
205 'url'=>$message,
206 'type'=>'get',
207 'update'=>'#'.$htmlOptions['id'],
208 ));
209 Yii::app()->clientScript->registerScript(__CLASS__.'#'.$htmlOptions['id'],$script);
210 }
211
212 else
213 echo CHtml::tag($this->tag,$htmlOptions,$message);
214 }
215
216 217 218 219 220 221 222
223 public static function setNoticeMessage($message,$context='',$logLevel='')
224 {
225 self::setMessage($message,$context,'',$logLevel,'notice');
226 }
227
228 229 230 231 232 233 234
235 public static function setSuccessMessage($message,$context='',$logLevel='')
236 {
237 self::setMessage($message,$context,'',$logLevel,'success');
238 }
239
240 241 242 243 244 245 246
247 public static function setErrorMessage($message,$context='',$logLevel=CLogger::LEVEL_ERROR)
248 {
249 self::setMessage($message,$context,'',$logLevel,'error');
250 }
251
252 253 254 255 256 257 258
259 public static function setWarningMessage($message,$context='',$logLevel=CLogger::LEVEL_WARNING)
260 {
261 self::setMessage($message,$context,'',$logLevel,'warning');
262 }
263
264 265 266 267 268 269 270
271 public static function setAlertMessage($message,$context='',$logLevel='')
272 {
273 self::setMessage($message,$context,'',$logLevel,'js_alert');
274 }
275
276 277 278 279 280 281 282
283 public static function setAjaxMessage($url,$context='',$logLevel='')
284 {
285 self::setMessage($url,$context,'',$logLevel,'jq_ajax');
286 }
287
288 289 290 291 292 293 294 295
296 public static function setMessage($message,$context='',$cssClass='',$logLevel='',$messageType='default')
297 {
298 $key = self::encodeFlashKey($messageType,$context,$cssClass,$logLevel);
299 Yii::app()->user->setFlash($key,$message);
300 }
301
302 303 304 305 306 307
308 protected static function contextToArray($configString)
309 {
310 if (is_array($configString))
311 return $configString;
312
313 $result = array();
314
315 if (is_string($configString) && !empty($configString))
316 {
317 if (strpos($configString,','))
318 {
319 $parts = explode(',',$configString);
320 foreach ($parts as $part)
321 {
322 $part = trim($part);
323 if (!empty($part))
324 $result[] = trim($part);
325 }
326 }
327 else
328 $result[] = trim($configString);
329 }
330
331 return $result;
332 }
333
334 335 336 337 338 339 340 341
342 protected static function encodeFlashKey($messageType,$context,$cssClass,$logLevel)
343 {
344 $id = uniqid(rand(),true);
345
346 $context = self::contextToArray($context);
347
348 if (empty($cssClass))
349 $cssClass = '';
350
351 return 'euserflash__' . $id . '__' . $messageType . '__' . $cssClass . '__' . $logLevel . '__' . implode('__',$context);
352 }
353
354 355 356 357 358 359 360 361
362 protected function decodeFlashKey($key,&$messageType='',&$context=null,&$cssClass='',&$logLevel='')
363 {
364 if (strpos($key,'euserflash__') !== 0)
365 return false;
366
367 list($marker,$id,$messageType,$cssClass,$logLevel,$context) = explode('__',$key,6);
368
369 if (empty($cssClass))
370 $cssClass = $this->getCssClass($messageType);
371
372 if (!empty($context))
373 if(strpos($context,'__'))
374 $context = explode('__',$context);
375 else
376 $context = array($context);
377
378 return true;
379 }
380
381 382 383 384 385 386
387 protected function getCssClass($messageType)
388 {
389 $result = '';
390
391 $properties = get_object_vars($this);
392
393 foreach ($properties as $name => $value)
394 if ($name == 'cssClass'.ucfirst($messageType))
395 {
396 $result = $value;
397 break;
398 }
399
400 if (empty($result))
401 $result = $this->cssClassDefault;
402
403 return $result;
404 }
405
406 407 408 409 410 411 412 413 414 415 416
417 protected function logFlashMessage($messageType,$context,$message,$logLevel)
418 {
419 if (!$this->loggingEnabled || empty($logLevel))
420 return;
421
422 if (empty($messageType))
423 $messageType = 'default';
424
425 $category = self::LOG_CATEGORY . '.' . $messageType;
426
427 if (!empty($context) && is_array($context))
428 $category .= '.'.implode('.',$context);
429
430 $logInfo = '';
431
432 if(($user=Yii::app()->getComponent('user',false))!==null)
433 $logInfo='User: '.$user->getName().' (ID: '.$user->getId().') ';
434
435
436 $logInfo .= 'Route: '. Yii::app()->controller->getRoute().' ';
437 $logInfo .= 'IP: ' . Yii::app()->getRequest()->userHostAddress.' ';
438
439 $message = $logInfo . 'Message: ' . $message;
440
441 $logVars = array();
442 if ($logLevel == 'error' && !empty($this->errorLogVars))
443 foreach($this->errorLogVars as $name)
444 {
445 if(!empty($GLOBALS[$name]))
446 $logVars[]="\${$name}=".var_export($GLOBALS[$name],true);
447 }
448
449 if (!empty($logVars))
450 $message .= "\n" . implode("\n",$logVars);
451
452 Yii::log($message,$logLevel,$category);
453 }
454
455 456 457 458 459
460 public function registerClientScript()
461 {
462 if ($this->_registerJQuery)
463 Yii::app()->clientScript->registerCoreScript('jquery');
464
465 if (!empty($this->initScript) && is_string($this->initScript))
466 Yii::app()->clientScript->registerScript(__CLASS__.'#'.$this->getId(), $this->initScript);
467 }
468
469 470 471
472 public function run()
473 {
474 if ($this->renderMessages())
475 $this->registerClientScript();
476 }
477
478 479 480 481 482 483 484
485 public static function renderFlashes($controller,$properties=array())
486 {
487 $widget=$controller->createWidget('EUserFlash',$properties);
488 $renderedCount = $widget->renderMessages();
489 if ($renderedCount)
490 $widget->registerClientScript();
491 return $renderedCount;
492 }
493
494 }