Skip to content
This repository
Browse code

Merge pull request #2 from devlance/master

Updates and fixes to eventful plugin
  • Loading branch information...
commit fa4cfc8073ddee0a0dc7ca213bc528597ec41f3b 2 parents daaccae + 584f2b1
Kjell Bublitz authored November 06, 2011
245  README 100755 → 100644
@@ -4,10 +4,11 @@ Event System for CakePHP
4 4
 
5 5
 Installation:
6 6
 ----------------------------------------------------------------------------------------
7  
-- Put "events" to APP
8  
-- Put "plugins/eventful" to APP.PLUGINS
9  
-- Add "Eventful.Event" to AppController::$components <- ControllerEvents, Bootstrap
  7
+- Put "events" to APP folder
  8
+- Put "plugins/eventful" to APP.PLUGINS folder.
  9
+- Add "Eventful.Event" to AppController::$components array <- ControllerEvents, Bootstrap
10 10
 - Optional: Add "Eventful.Event" to AppModel::$actsAs array <- ModelEvents
  11
+- Optional: Add "Event" to shell $tasks array: $tasks = array('Event');
11 12
 - Optional: Copy "/app/events" layout into your plugin to dispatch events to plugins
12 13
 
13 14
 Current Version:
@@ -16,118 +17,168 @@ Current Version:
16 17
 
17 18
 How to use:
18 19
 ----------------------------------------------------------------------------------------
19  
-Listener classes need to have the same name as the controller file + "_events" at
20  
-the end. So if you want to write event handlers for "movies_controller.php" you need 
21  
-to create a file called "movies_controller_events.php" in the folder /app/events/controllers/.
22  
-Same goes for models. The matching "user.php" event class filename is "user_events.php".
23  
-
24  
-Since it all follows the cake conventions event listener classes within plugins need to 
25  
-prefix the plugin name. If you have a "pizza" plugin the name for a controller event 
26  
-listener class should be: "pizza_orders_controller_events.php"
27  
-
28  
-Note: Just because you are dispatching events from one controller it is not required 
29  
-that the listener class file exists.  
30  
-
31  
-Withing the listener classes you need to prefix your event handler methods with 
32  
-the "on" keyword. If you dispatch a event called "userSignUp" like so:
33  
-
34  
-<?php 
35  
-	$this->Event->dispatch('userSignUp') 
36  
-?>
37  
-
38  
-The method within the class needs to be named "onUserSignUp". More specific:
  20
+	Listener classes need to have the same name as the controller file + "_events" at
  21
+	the end. So if you want to write event handlers for "movies_controller.php" you need 
  22
+	to create a file called "movies_controller_events.php" in the folder /app/events/controllers/.
  23
+	Same goes for models. The matching "user.php" event class filename is "user_events.php".
  24
+	
  25
+	Using the event listener classes within plugins requires that you name the files following
  26
+	CakePHP conventions by prefixing the plugin name. For example, if you have a "pizza" plugin 
  27
+	the name for a controller event listener class should be: "pizza_orders_controller_events.php"
39 28
 
40  
-<?php
41  
-	// users_controller_events.php
42  
-	class UsersControllerEvents extends AppControllerEvents {
  29
+Dispatching events: 
  30
+	To dispatch events in controllers or shells:
43 31
 	
44  
-		function onUserSignUp($event) { 
45  
-			// ... do stuff.
46  
-		}	
47  
-	}
48  
-?>
  32
+	<?php 
  33
+		$this->Event->dispatch('userSignUp') 
  34
+	?>
  35
+	
  36
+	To dispatch events in models:
  37
+	<?php 
  38
+		$this->dispatch('userSignUp') 
  39
+	?>
  40
+	
  41
+	Calling the dispatch method does not require that the dispatch event code exist. You can add
  42
+	dispatch events in your application and later develop the code to handle the events.
49 43
 
50  
-As you can see, we extend the AppControllerEvents class. This class is of same 
51  
-nature as the app_controller.php. It is the default base class for all events. 
52  
-We also have AppModelEvents for model events.
  44
+Writing event code:
  45
+	In your listener class file, you define your event methods by prefixing the "on" keyword:
  46
+	
  47
+	<?php
  48
+		// users_controller_events.php
  49
+		class UsersControllerEvents extends AppControllerEvents {
  50
+		
  51
+			function onUserSignUp($event) { 
  52
+				// ... do stuff.
  53
+			}	
  54
+		}
  55
+	?>
  56
+	
  57
+	You can listen for events across multiple listener classes. You can also catch an event to 
  58
+	in your users_model_events.php file:
  59
+	<?php
  60
+		// users_model_events.php
  61
+		class UsersModelEvents extends AppModelEvents {
  62
+		
  63
+			function onUserSignUp($event) { 
  64
+				// ... do different stuff
  65
+			}	
  66
+		}
  67
+	?>
  68
+	
  69
+	This allows for flexibility in your code and to maintain a degree of MVC architecture in 
  70
+	your code logic. For example, you might trigger an email in the controller event and update a record
  71
+	in the model event.
53 72
 
54  
-You can overwrite the AppControllerEvents class by creating the file
55  
-"app_controller_events.php" in the APP folder. Same spot as app_helper.php, etc.
56  
-But that's optional... a good place for shared events.
  73
+Base classes:
57 74
 
58  
-About the "$event" parameter. Passed to all handlers by default. If the event 
59  
-is a controller event you can access the controller object at $event->Controller.
60  
-If the event is a model event you can access the model at $event->Model.
  75
+	As you can see, we extend the AppControllerEvents class. This class is of same 
  76
+	nature as the app_controller.php. It is the default base class for all events. 
  77
+	We also have AppModelEvents for model events.
  78
+	
  79
+	You can overwrite the AppControllerEvents class by creating the file
  80
+	"app_controller_events.php" in the APP folder. Same spot as app_helper.php, etc.
  81
+	But that's optional... a good place for shared events.
61 82
 
62  
-There is also a optional $data parameter in the EventComponent dispatch method.
  83
+Event method Parameters:
  84
+----------------------------------------------------------------------------------------
63 85
 
64  
-<?php
65  
-	$this->Event->dispatch('userSignUp', array('hello' => 'kitty'));
66  
-?>
  86
+	The $event object is passed to all handlers by default. If the event 
  87
+	is a controller event, you can access the controller object at $event->Controller. If the 
  88
+	event is a model event, you can access the model at $event->Model. If the event is a shell
  89
+	event, you can access the shell at $event->Dispatcher.
67 90
 
68  
-The event handler method can access the value of "hello" at the event object
69 91
 
70  
-<?php
71  
-	class UsersControllerEvents extends AppControllerEvents {
  92
+Passing data to your event code:
  93
+	You can specify a second $data parameter in the EventComponent dispatch method and pass
  94
+	an array that contains any information your event might require.
72 95
 	
73  
-		function onUserSignUp($event) {
74  
-			return $event->hello; //=> kitty
  96
+	<?php
  97
+		$this->Event->dispatch('userSignUp', array('hello' => 'kitty'));
  98
+	?>
  99
+	
  100
+	The event handler method can access the value of "hello" at the event object
  101
+	
  102
+	<?php
  103
+		class UsersControllerEvents extends AppControllerEvents {
  104
+		
  105
+			function onUserSignUp($event) {
  106
+				return $event->hello; //=> kitty
  107
+			}
75 108
 		}
76  
-	}
77  
-?>
  109
+	?>
78 110
 
79 111
 Trigger all Events
80 112
 ----------------------------------------------------------------------------------------
81  
-If you specify the same event listener method in other listener classes the event dispatch
82  
-will fire them too.
83  
-
84  
-Fire -> "usersIndex" in any controller
85  
-Execs -> *.*ControllerEvents::onUsersIndex()
86  
-
87  
-Be careful about how you name the events.
88  
-
89  
-Check out this output: 
90  
-
91  
-Array
92  
-(
93  
-    [MoviesControllerEvents] => I am the MoviesController Event Listener!
94  
-    [UsersControllerEvents] => I am the UsersController Event Listener!
95  
-    [PizzaMoviesControllerEvents] => I am the Pizza.MoviesController Event Listener!
96  
-)
97  
-
98  
-This array is the default return format from the dispatch method. 
99  
-That way you can sort the returns from all events as you need them
100  
-
101  
-To get the above in my example application i wrote in my action:
102  
-
103  
-function index() {
104  
-  $result = $this->Event->dispatch('usersIndex');
105  
-  pr ($result);
106  
-}
  113
+	If you specify the same event listener method in other listener classes the event dispatch
  114
+	will fire them too.
  115
+	
  116
+	Fire -> "usersIndex" in any controller
  117
+	Execs -> *.*ControllerEvents::onUsersIndex()
  118
+	
  119
+	Be careful about how you name the events.
  120
+	
  121
+	Check out this output: 
  122
+	
  123
+	Array
  124
+	(
  125
+	    [MoviesControllerEvents] => I am the MoviesController Event Listener!
  126
+	    [UsersControllerEvents] => I am the UsersController Event Listener!
  127
+	    [PizzaMoviesControllerEvents] => I am the Pizza.MoviesController Event Listener!
  128
+	)
  129
+	
  130
+	This array is the default return format from the dispatch method. 
  131
+	That way you can sort the returns from all events as you need them
  132
+	
  133
+	To get the above in my example application i wrote in my action:
  134
+	
  135
+	function index() {
  136
+	  $result = $this->Event->dispatch('usersIndex');
  137
+	  pr ($result);
  138
+	}
107 139
 
108 140
 Model Events:
109 141
 --------------------------------------------------------------------------------------
110  
-Basicly everything from above applies. Filename for user.php would be user_events.php.
111  
-There are default events that are fired from within the behavior. 
112  
-
113  
-- onBeforeFind (available infos: 'query')
114  
-- onAfterFind (available infos: 'results', 'primary');
115  
-- onBeforeValidate (available infos: )
116  
-- onBeforeSave (available infos: )
117  
-- onAfterSave (available infos: 'created')
118  
-- onBeforeDelete (available infos: 'cascade')
119  
-- onAfterDelete (available infos: 'created')
120  
-- onDatasourceError (available infos: 'error')
121  
-
122  
-The triggering of the default events can be disabled. 
123  
-
124  
-var $actsAs = array(
125  
-  'Eventful.Event' => array(
126  
-		'triggerDefaults' => false
127  
-	)
128  
-);
  142
+	Basicly everything from above applies. Filename for user.php would be user_events.php.
  143
+	There are default events that are fired from within the behavior. 
  144
+	
  145
+	- onBeforeFind (available infos: 'query')
  146
+	- onAfterFind (available infos: 'results', 'primary');
  147
+	- onBeforeValidate (available infos: )
  148
+	- onBeforeSave (available infos: )
  149
+	- onAfterSave (available infos: 'created')
  150
+	- onBeforeDelete (available infos: 'cascade')
  151
+	- onAfterDelete (available infos: 'created')
  152
+	- onDatasourceError (available infos: 'error')
  153
+	
  154
+	The triggering of the default events can be disabled. 
  155
+	
  156
+	var $actsAs = array(
  157
+	  'Eventful.Event' => array(
  158
+			'triggerDefaults' => false
  159
+		)
  160
+	);
129 161
 
130  
-Everything else is up to you.
  162
+Some additional help for writing event code:
  163
+----------------------------------------------------------------------------------------
  164
+	One of the common scenarios for event driven programming is triggering automatic emails
  165
+	when a condition occurs. If you need to send email from an event, you can import the 
  166
+	Email component in the following manner:
  167
+	
  168
+	<?php
  169
+		function onUserSignUp($event){
  170
+			App::import('Component', 'Email');
  171
+	    $email = new EmailComponent();
  172
+	    $email->startup($controller);
  173
+	    $email->to = $event->userEmail;
  174
+	    //additional email logic
  175
+	    $email->send($body);
  176
+		}
  177
+	?>
  178
+	You might consider adding similar a "sendMail" method to your config/bootstrap.php 
  179
+	instead if you find you need to send emails from a variety of locations outside of 
  180
+	controller classes. In that case you would be able to call sendMail($params...); 
  181
+	anywhere in your application.
131 182
 
132 183
 --------------------------------------------------------------------------------------
133 184
 
0  events/shells/empty
No changes.
14  plugins/eventful/models/behaviors/event.php
@@ -70,6 +70,20 @@ function dispatchEvent($model, $event, $data = array()) {
70 70
 		$cake_events = CakeEvents::getInstance();
71 71
 		return $cake_events->dispatchEvent($event, am($data, array('Model' => $model)));
72 72
 	}
  73
+	
  74
+	/**
  75
+	 * Alias for dispatchEvent to be consistent with dispatching events
  76
+	 * @param object $model
  77
+	 * @param string $event
  78
+	 * @param array $data (optional)
  79
+	 * @access public
  80
+	 * @see dispatchEvent method
  81
+	 * 
  82
+	 * @access public
  83
+	 */
  84
+	function dispatch($model, $event, $data = array()){
  85
+	  return $this->dispatchEvent($model, $event, $data);
  86
+	}
73 87
 
74 88
 	/**
75 89
 	 * Before find callback
2  plugins/eventful/vendors/cake_events.php
@@ -147,6 +147,8 @@ public function eventFilePaths($dir = 'controllers') {
147 147
 	public function addListener($eventClassName, $type = 'app', $plugin = '') {
148 148
 
149 149
 		if ($type == 'plugin' && empty($plugin)) return false;
  150
+		
  151
+		if ($eventClassName == 'Empty') return false;  //Catch if eventClass is passed as "Empty" when nothing was configured. Was resulting in "Class 'Empty' not found" was the fatal error message.
150 152
 
151 153
 		if ($plugin) { // disabled unless i find out how to create a fallback class at runtime
152 154
 			# App::import('File', PLUGINS. $plugin .DS. $plugin . '_app_controller_events.php');
10  plugins/eventful/shells/tasks/event.php → plugins/eventful/vendors/shells/tasks/event.php
@@ -6,10 +6,20 @@
6 6
  * @author Gustavo Dutra <mechamo@gustavodutra.com> 
7 7
  * @package eventful
8 8
  * @subpackage shells
  9
+ * @modifiedby    $LastChangedBy$
  10
+ * @lastmodified  $Date: 2011-11-04 16:00:58 $
9 11
  */
10 12
 
11 13
  /**
12 14
   * EventTask
  15
+  * 
  16
+  * Usage:
  17
+  * 
  18
+  * In your shell add:
  19
+  * public $tasks = array('Event');
  20
+  * 
  21
+  * Currently Cake finds the Tasks without prefixing the plugin name. In the future
  22
+  * the above might need to be specified as array('Eventful.Event').
13 23
   */
14 24
 class EventTask extends Shell {
15 25
 
10  plugins/eventful/vendors/startup.php
@@ -39,8 +39,9 @@
39 39
 	App::import('Vendor', 'Eventful.ShellEvents');
40 40
 
41 41
 	// Lookup app folder for custom base classes
42  
-	App::import('File', APP . 'app_model_events.php');
43  
-	App::import('File', APP . 'app_controller_events.php');
  42
+	App::import('File','AppModelEvents',false,array(), APP . 'app_model_events.php');	
  43
+	App::import('File','AppControllerEvents',false,array(), APP . 'app_controller_events.php');	
  44
+	App::import('File','AppShellEvents',false,array(), APP . 'app_shell_events.php');	
44 45
 
45 46
 	// Define default custom base classes if none available
46 47
 	if (!class_exists('AppControllerEvents')) {
@@ -53,4 +54,9 @@ class AppModelEvents extends ModelEvents {
53 54
 			var $name = 'AppModelEvents';
54 55
 		}
55 56
 	}
  57
+	if (!class_exists('AppShellEvents')) {
  58
+		class AppShellEvents extends ModelEvents {
  59
+			var $name = 'AppShellEvents';
  60
+		}
  61
+	}
56 62
 }

0 notes on commit fa4cfc8

Please sign in to comment.
Something went wrong with that request. Please try again.