├── tests └── .gitignore ├── media ├── images │ └── notices │ │ ├── help.png │ │ ├── info.png │ │ ├── tip.png │ │ ├── denied.png │ │ ├── error.png │ │ ├── event.png │ │ ├── wizard.png │ │ ├── message.png │ │ ├── success.png │ │ ├── warning.png │ │ └── notice-close.png ├── js │ └── notices.js └── css │ └── notices.css ├── classes ├── Notices.php └── Kohana │ └── Notices.php ├── config └── notices.php ├── guide ├── menu.notices.md ├── notices.overview.md ├── notices.new_types.md └── notices.installation.md ├── README.md └── views └── notices ├── notice.php └── demo.php /tests/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /media/images/notices/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synapsestudios/kohana-notices/HEAD/media/images/notices/help.png -------------------------------------------------------------------------------- /media/images/notices/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synapsestudios/kohana-notices/HEAD/media/images/notices/info.png -------------------------------------------------------------------------------- /media/images/notices/tip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synapsestudios/kohana-notices/HEAD/media/images/notices/tip.png -------------------------------------------------------------------------------- /media/images/notices/denied.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synapsestudios/kohana-notices/HEAD/media/images/notices/denied.png -------------------------------------------------------------------------------- /media/images/notices/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synapsestudios/kohana-notices/HEAD/media/images/notices/error.png -------------------------------------------------------------------------------- /media/images/notices/event.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synapsestudios/kohana-notices/HEAD/media/images/notices/event.png -------------------------------------------------------------------------------- /media/images/notices/wizard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synapsestudios/kohana-notices/HEAD/media/images/notices/wizard.png -------------------------------------------------------------------------------- /media/images/notices/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synapsestudios/kohana-notices/HEAD/media/images/notices/message.png -------------------------------------------------------------------------------- /media/images/notices/success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synapsestudios/kohana-notices/HEAD/media/images/notices/success.png -------------------------------------------------------------------------------- /media/images/notices/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synapsestudios/kohana-notices/HEAD/media/images/notices/warning.png -------------------------------------------------------------------------------- /classes/Notices.php: -------------------------------------------------------------------------------- 1 | 'media/images/', 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /guide/menu.notices.md: -------------------------------------------------------------------------------- 1 | 1. **Notices** 2 | - [Overview](notices.overview) 3 | - [Installation](notices.installation) 4 | - [Adding New Types](notices.new_types) 5 | - [API](api/Notices) 6 | - [Demo](../notice/demo) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Notices 2 | 3 | *Notices module for Kohana 3.x* 4 | 5 | - **Module Version:** 3.0.x 6 | - **Module URL:** 7 | - **Compatible Kohana Version(s):** 3.1.x 8 | 9 | ## Description 10 | 11 | The purpose of this module is to provide an easy way to send messages to the 12 | user on any page, based on events and decisions in the application. Most 13 | commonly, these message are used to inform users of errors. The Notices module 14 | uses the session to pass messages on to the next page. 15 | -------------------------------------------------------------------------------- /views/notices/notice.php: -------------------------------------------------------------------------------- 1 |
2 |
3 | type)) ?>: 4 | message ?> 5 |
6 |
7 | uri(array('hash' => $notice->hash)), 9 | __('Close'), 10 | array('title' => __('Close')) 11 | ) ?> 12 |
13 |
14 |
15 | -------------------------------------------------------------------------------- /guide/notices.overview.md: -------------------------------------------------------------------------------- 1 | Notices Module 2 | ============== 3 | 4 | A Ko3 Module by [**Jeremy Lindblom**](http://twitter.com/jeremeamia) of 5 | **[Synapse Studios](http://synapsestudios.com)** 6 | 7 | Introduction 8 | ------------ 9 | 10 | The purpose of this module is to provide an easy way to send messages to the 11 | user on any page, based on events and decisions in the application. Most 12 | commonly, these message are used to inform users of errors. The Notices module 13 | uses the session to pass messages on to the next page. 14 | 15 | The following example illustrates a possible use case: 16 | 17 | //... 18 | if ($comment->check()) 19 | { 20 | $comment->save(); 21 | Notices::add('success', 'Your comment has been saved.'); 22 | $this->request->redirect('comment/index'); 23 | } 24 | else 25 | { 26 | $errors = $comment->errors(); 27 | Notices::add('error', 'Your comment is invalid.'); 28 | } 29 | //... 30 | 31 | Then in the template (or any other view file) `` 32 | is called to display any notices in the queue. The Notices module supports any 33 | type of Notice, but there are 10 types that already have CSS and images defining 34 | their styles: 35 | 36 | - denied 37 | - error 38 | - event 39 | - help 40 | - info 41 | - message 42 | - success 43 | - tip 44 | - warning 45 | - wizard 46 | 47 | To see Notices in action, please look at the [demo page](../notice/demo). -------------------------------------------------------------------------------- /guide/notices.new_types.md: -------------------------------------------------------------------------------- 1 | Notices Module - Adding New Notice Types 2 | ======================================== 3 | 4 | The Notices module has 10 Notice types that are already styled; however, the 5 | module can support any arbitrary Notice types. All Notice types without styles 6 | will default to the style of the *message* type. When you add new Notice types 7 | to your project, you must do the following: 8 | 9 | 1. Create a 32x32-pixel png image to graphically represent your new Notice type. 10 | This should be placed in the `media/js/notices` folder. 11 | 2. Write CSS styles for your Notice type to override the styles of the *message* 12 | type. You can use the following CSS styles but replace `[[type-name]]` with the 13 | name of your new Notice type and replace the colors with the ones you would like 14 | to use. 15 | 16 |

17 | div.notice.[[type-name]] strong.notice-type {color: #181818;}
18 | div.notice.[[type-name]] {
19 | 	border-color: #181818;
20 | 	background-color: #cccccc;
21 | 	background-image: -moz-linear-gradient(top, #ffffff, #bbbbbb);
22 | 	background-image: -webkit-gradient(linear, left top, left bottom,
23 | 		color-stop(0, #ffffff),color-stop(1, #bbbbbb));
24 | 	filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,
25 | 		startColorstr='#ffffff', endColorstr='#bbbbbb');
26 | 	-ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0,
27 | 		startColorstr='#ffffff', endColorstr='#bbbbbb')";
28 | }
29 | 
30 | 31 | The gradients work for Safari, Chrome, Firefox 3.6+, and IE 6+. If you want to 32 | ensure that the gradients are seen by all, then you should consider using a 33 | tiled background image. -------------------------------------------------------------------------------- /media/js/notices.js: -------------------------------------------------------------------------------- 1 | if (typeof jQuery != "undefined"){ 2 | 3 | // On DOM Ready 4 | (function($){$(document).ready(function(){ 5 | 6 | // Show closing "X"s 7 | $("div.notice-close").show(); 8 | //$('div.notice').width($('div.notice').width()); 9 | 10 | // Close a notice if the "X" is clicked 11 | $('div.notice-close a').live("click", function(){ 12 | var notice = $(this).closest("div.notice"); 13 | var persistent = notice.hasClass('notice-persistent'); 14 | notice.hide("fast"); 15 | 16 | if (persistent){ 17 | var ajax_url = $(this).attr("href"); 18 | $.ajax({ 19 | url: ajax_url, 20 | cache: false, 21 | dataType: 'json', 22 | success: $.noop(), 23 | error: $.noop() 24 | }); 25 | } 26 | 27 | return false; 28 | }); 29 | 30 | // Extending the jQuery object to add notices 31 | // Example: $('div.notices-container').add_notice('success', 'You have succeeded!', true); 32 | jQuery.fn.add_notice = function(type, message, persist){ 33 | 34 | var container = $(this); 35 | 36 | var ajax_url = '/notice/add'; 37 | if (type != undefined){ 38 | ajax_url += '/'+escape(type); 39 | if (message != undefined){ 40 | ajax_url += '/'+escape(message); 41 | if (persist == true){ 42 | ajax_url += '/TRUE'; 43 | } 44 | } 45 | } 46 | 47 | $.ajax({ 48 | url: ajax_url, 49 | cache: false, 50 | dataType: 'json', 51 | success: function(response){ 52 | if (response.status == "success"){ 53 | container.append(response.data); 54 | container.find("div.notice-close:last").show(); 55 | } 56 | }, 57 | error: $.noop() 58 | }); 59 | }; 60 | 61 | })})(jQuery); // Prevent conflicts with other js libraries 62 | } -------------------------------------------------------------------------------- /views/notices/demo.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Notices Demo 7 | 8 | 9 | 10 | 21 | 22 | 23 |

Notices Demo

24 |

Number of notices in queue before display:

25 | 26 |
27 | 28 |
29 | 30 |
31 | 32 |
33 |

Add a Notice via AJAX

34 |

35 | 36 |
37 | 38 |

39 |

40 | 41 |
42 | 43 |

44 |

45 | 46 |
47 | 51 |

52 |

53 | 54 |

55 |
56 | 57 | -------------------------------------------------------------------------------- /guide/notices.installation.md: -------------------------------------------------------------------------------- 1 | Notices Module - Installation 2 | ============================= 3 | 4 | Assets: 5 | ------- 6 | 7 | The Notices module includes some media files in the `media` folder. These should 8 | be copied into a `media` folder in the web root so that they are accessible. You 9 | will need to make sure the following files are included into your template or 10 | assests system so that notices are styled and functioning properly on the pages 11 | you desire: 12 | 13 | - media/css/notices.css 14 | - media/js/notices.js 15 | 16 | JavaScript: 17 | ----------- 18 | 19 | The JavaScript for this module uses 20 | [jQuery](http://docs.jquery.com/Downloading_jQuery), so please load jQuery 21 | before attempting to use the Notices module's JavaScript. The easiest way to do 22 | this is to [load jQuery via Google's 23 | CDN](http://code.google.com/apis/ajaxlibs/documentation/#jquery). 24 | 25 | **Note:** The JavaScript for Notices is not required for the module to function, 26 | but does enhance the module with the ability to add and remove notices on the 27 | live page via AJAX. 28 | 29 | Icons: 30 | ------ 31 | 32 | Excluding the wizard hat icon, all of the icons in this module are from the 33 | [FatCow: Farm-Fresh Web Icons](http://www.fatcow.com/free-icons) library. Please 34 | refer to their website for Terms of Use. The wizard hat icon was designed by 35 | [Edgar Hassler](http://twitter.com/edgarhassler) and must always be included 36 | with this module in order to preserve his legacy. 37 | 38 | PHP Version: 39 | ------------ 40 | 41 | PHP 5.3+ is the preferred PHP version for using of this module. The 42 | `__callStatic()` magic method is used to simplify the API; however, PHP 5.3 is 43 | not required. The `Notices::add()` method backwards compatible and may be the 44 | preferred choice by some developers. Here is the difference: 45 | 46 | // PHP 5.3+ Version 47 | Notices::success('Congratulations! You did it!'); 48 | 49 | // PHP 5.2 Version 50 | Notices::add('success', 'Congratulations! You did it!'); -------------------------------------------------------------------------------- /classes/Kohana/Notices.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright Copyright (c) 2009 Synapse Studios 11 | */ 12 | class Kohana_Notices 13 | { 14 | /** 15 | * @var array The queue of notices to be rendered and displayed 16 | */ 17 | protected static $notices = array(); 18 | 19 | /** 20 | * Adds a new notice to the notices queue. The notice type corresponds to a 21 | * CSS class used for styling. 22 | * 23 | * @param string $type The type of notice 24 | * @param string $key The the key of the message to be sent to the user 25 | * @param array $values Values to replace the ones in the message using `__()` 26 | * @return Notice 27 | */ 28 | public static function add($type, $key, array $values = NULL) 29 | { 30 | // Fetch notices from Session 31 | Notices::$notices = Session::instance()->get('notices', array()); 32 | 33 | // The hash acts as a unique identifier. 34 | Notices::$notices[$type] = array 35 | ( 36 | 'type' => $type, 37 | 'key' => $key, 38 | 'values' => $values, 39 | ); 40 | 41 | Session::instance()->set('notices', Notices::$notices); 42 | } 43 | 44 | /** 45 | * Retrieves a set of notices based on type, and rendered state 46 | * 47 | * @param mixed $types Notice types 48 | * @param boolean $once Whether or not to remove the notice 49 | * @return array 50 | */ 51 | public static function get($types = NULL, $once = TRUE) 52 | { 53 | // Fetch notices from Session 54 | Notices::$notices = Session::instance()->get('notices', array()); 55 | 56 | if (is_string($types)) 57 | { 58 | $results = Arr::get(Notices::$notices, $types); 59 | 60 | if ($once) 61 | unset(Notices::$notices[$types]); 62 | } 63 | elseif (is_array($types)) 64 | { 65 | $results = array(); 66 | 67 | foreach ($types as $type) 68 | { 69 | $results[$type] = Arr::get(Notices::$notices, $type); 70 | 71 | if ($once) 72 | unset(Notices::$notices[$type]); 73 | } 74 | } 75 | else 76 | { 77 | // Return all of them 78 | $results = Notices::$notices; 79 | 80 | if ($once) 81 | Notices::$notices = array(); 82 | } 83 | 84 | Session::instance()->set('notices', Notices::$notices); 85 | 86 | return $results; 87 | } 88 | 89 | /** 90 | * The `__callStatic()` allows the creation of notices using the shorter 91 | * syntax: `Notices::success('message');` This works for PHP 5.3+ only 92 | * 93 | * @param string $method Method name 94 | * @param array $args method arguments 95 | * @return mixed 96 | */ 97 | public static function __callStatic($method, $args) 98 | { 99 | return Notices::add($method, Arr::get($args, 0), Arr::get($args, 1), Arr::get($args, 2)); 100 | } 101 | 102 | /* 103 | * Enforce static behavior 104 | */ 105 | final private function __construct() 106 | { 107 | // Enforce static behavior 108 | } 109 | 110 | } // End Notices 111 | -------------------------------------------------------------------------------- /media/css/notices.css: -------------------------------------------------------------------------------- 1 | div.notice { 2 | border: 2px solid #181818; 3 | background-color: #dddddd; 4 | background-image: -moz-linear-gradient(top, #ffffff, #dddddd); /* FF3.6 */ 5 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff),color-stop(1, #dddddd)); /* Saf4+, Chrome */ 6 | filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#dddddd'); /* IE 6,7 */ 7 | -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ffffff', endColorstr='#dddddd')"; /* IE 8 */ 8 | -moz-border-radius: 5px; /* FF1+ */ 9 | -webkit-border-radius: 5px; /* Saf3+, Chrome */ 10 | -khtml-border-radius: 5px; /* Konqueror */ 11 | border-radius: 5px; /* Opera 10.5, IE 9 */ 12 | color: #181818; 13 | font-family: "Segoe UI", Candara, Trebuchet, "Trebuchet MS", "DejaVu Sans", "Bitstream Vera Sans", "Liberation Sans", Verdana, "Verdana Ref", sans-serif; 14 | font-size: 16px; 15 | line-height: 1.5em; 16 | margin: 4px 8px 6px 8px; 17 | padding: 12px; 18 | position: relative; 19 | text-align: left; 20 | width: auto; 21 | zoom: 1; /* Sets the layout so gradients work in IE */ 22 | } 23 | 24 | /***********************/ 25 | /* BACKGROUND IMAGES */ 26 | /***********************/ 27 | div.error div.notice-content { 28 | background: url(../images/error.png) no-repeat; 29 | } 30 | div.info div.notice-content { 31 | background: url(../images/info.png) no-repeat; 32 | } 33 | div.tip div.notice-content { 34 | background: url(../images/tip.png) no-repeat; 35 | } 36 | div.denied div.notice-content { 37 | background: url(../images/denied.png) no-repeat; 38 | } 39 | div.event div.notice-content { 40 | background: url(../images/event.png) no-repeat; 41 | } 42 | div.help div.notice-content { 43 | background: url(../images/help.png) no-repeat; 44 | } 45 | div.message div.notice-content { 46 | background: url(../images/message.png) no-repeat; 47 | } 48 | div.success div.notice-content { 49 | background: url(../images/success.png) no-repeat; 50 | } 51 | div.warning div.notice-content { 52 | background: url(../images/warning.png) no-repeat; 53 | } 54 | div.wizard div.notice-content { 55 | background: url(../images/wizard.png) no-repeat; 56 | } 57 | div.notice div.notice-close { 58 | height: 16px; width: 16px; 59 | /* Will cut off the text after the close button is added */ 60 | overflow: hidden; 61 | } 62 | div.notice div.notice-close a { 63 | background: url(../images/notice-close.png) no-repeat; 64 | /* Shove the text below the div */ 65 | padding-left: 20px; 66 | } 67 | 68 | div.notice div.notice-content { 69 | margin: 4px 26px 0 0; 70 | padding: 5px 0 5px 37px; 71 | } 72 | 73 | div.notice strong.notice-type { 74 | font-size: 18px; 75 | font-weight: bold; 76 | padding-right: 8px; 77 | text-shadow:1px 1px 1px #fff; 78 | text-transform: uppercase; 79 | } 80 | 81 | div.notice-clear { 82 | clear: left; 83 | } 84 | 85 | div.notice-close { 86 | display: none; 87 | position: absolute; 88 | top: 18px; 89 | right: 10px; 90 | } 91 | 92 | /************/ 93 | /* COLORS */ 94 | /************/ 95 | 96 | /*div.notice.message strong.notice-type {display: none;}*/ 97 | 98 | div.notice.info strong.notice-type, div.notice.tip strong.notice-type, div.notice.help strong.notice-type {color: #00a;} 99 | div.notice.info, div.notice.tip, div.notice.help { 100 | border-color: #00a; 101 | background-color: #ccccff; 102 | background-image: -moz-linear-gradient(top, #eeeeff, #ccccff); /* FF3.6 */ 103 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #eeeeff),color-stop(1, #ccccff)); /* Saf4+, Chrome */ 104 | filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#eeeeff', endColorstr='#ccccff'); 105 | -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#eeeeff', endColorstr='#ccccff')"; 106 | } 107 | 108 | div.notice.denied strong.notice-type, div.notice.error strong.notice-type {color: #900;} 109 | div.notice.denied, div.notice.error { 110 | border-color: #900; 111 | background-color: #f8c0c0; 112 | background-image: -moz-linear-gradient(top, #ffeeee, #f8c0c0); /* FF3.6 */ 113 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffeeee),color-stop(1, #f8c0c0)); /* Saf4+, Chrome */ 114 | filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ffeeee', endColorstr='#f8c0c0'); 115 | -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ffeeee', endColorstr='#f8c0c0')"; 116 | } 117 | 118 | div.notice.success strong.notice-type {color: #370;} 119 | div.notice.success { 120 | border-color: #370; 121 | background-color: #e8f8bb; 122 | background-image: -moz-linear-gradient(top, #f4ffee, #e8f8bb); /* FF3.6 */ 123 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #f4ffee),color-stop(1, #e8f8bb)); /* Saf4+, Chrome */ 124 | filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#f4ffee', endColorstr='#e8f8bb'); 125 | -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#f4ffee', endColorstr='#e8f8bb')"; 126 | } 127 | 128 | div.notice.event strong.notice-type {color: #840;} 129 | div.notice.event { 130 | border-color: #840; 131 | background-color: #ffcc66; 132 | background-image: -moz-linear-gradient(top, #fff8e4, #ffcc66); /* FF3.6 */ 133 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff8e4),color-stop(1, #ffcc66)); /* Saf4+, Chrome */ 134 | filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#fff8e4', endColorstr='#ffcc66'); 135 | -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#fff8e4', endColorstr='#ffcc66')"; 136 | } 137 | 138 | div.notice.warning strong.notice-type {color: #220;} 139 | div.notice.warning { 140 | border-color: #220; 141 | background-color: #fff888; 142 | background-image: -moz-linear-gradient(top, #ffffee, #fff888); /* FF3.6 */ 143 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffee),color-stop(1, #fff888)); /* Saf4+, Chrome */ 144 | filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ffffee', endColorstr='#fff888'); 145 | -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#ffffee', endColorstr='#fff888')"; 146 | } 147 | 148 | div.notice.wizard strong.notice-type {color: #306;} 149 | div.notice.wizard { 150 | border-color: #306; 151 | background-color: #ddbbff; 152 | background-image: -moz-linear-gradient(top, #eeddff, #ddbbff); /* FF3.6 */ 153 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #eeddff),color-stop(1, #ddbbff)); /* Saf4+, Chrome */ 154 | filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#eeddff', endColorstr='#ddbbff'); 155 | -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0, startColorstr='#eeddff', endColorstr='#ddbbff')"; 156 | } 157 | --------------------------------------------------------------------------------