]> git.mjollnir.org Git - moodle.git/commitdiff
some events code/testing code
authortoyomoyo <toyomoyo>
Thu, 26 Apr 2007 08:50:29 +0000 (08:50 +0000)
committertoyomoyo <toyomoyo>
Thu, 26 Apr 2007 08:50:29 +0000 (08:50 +0000)
lib/eventslib.php
lib/simpletest/testeventslib.php [new file with mode: 0755]

index 6f44cc6c7b30d43b81e0faa65bbf5d79de29dbfb..763192e5f88fbe7371da6416cca8bca1ccf1ee4f 100755 (executable)
@@ -111,7 +111,7 @@ function events_update_definition($component='moodle') {
             if (!empty($cachedevents[$eventname])) {
                 if ($cachedevents[$eventname] == $fileevent) {
                     unset($cachedevents[$eventname]);  
-                    continue; // breaks the cachedevents loop                
+                    continue; // breaks the cachedevents loop
                 }
             }
             // if we are here, no break is called, file event is new
@@ -149,4 +149,161 @@ function events_cleanup($component, $cachedevents) {
     return $deletecount;
 }
 
+/****************** End of Events handler Definition code *******************/
+
+
+/**
+ * puts a handler on queue
+ * @param object handler - event handler object from db
+ * @param object eventdata - event data object
+ * @param bool failed -  whether this handler is queued because of a failed event trigger
+ * @return
+ */
+function queue_handler($handler, $eventdata, $failed=false) {
+    global $USER;
+    // adds a record to events_queue (if not exist)
+    if (!$existing_event = get_record('events_queue', 'eventdata', serialize($eventdata))) {
+        // add it 
+        $eq = new object;
+        $eq->userid = $USER->id;
+        $eq->schedule = $eventdata->schedule;
+        $eq->eventdata = serialize($eventdata);
+        $eq->stackdump = '';
+        $eq->timecreated = time();
+        $eventid = insert_record('events_queue', $eq); 
+    } else {
+        $eventid = $existing_event->id;
+    }
+    
+    // check if this event handler is already queued
+    if (!$qh = get_record('events_queue_handlers', 'queuedeventid', $eventid, 'handlerid', $handler->id)) {
+        // make a new one
+        $qh = new object;
+        $qh->queuedeventid = $eventid;
+        $qh->handlerid = $handler->id;
+        $qh->status = 0;
+        $qh->errormessage = '';
+        $qh->timemodified = time();
+        return insert_record('events_queue_handlers', $qh);
+    } else {
+        // update existing one, failed again
+        $qh->states++;
+        $qh->timemodified = time();
+        update_record('events_queue_handlers', $qh);
+        return -1; // failed
+    }
+}
+
+/**
+ * function to call all eventhandlers when triggering an event
+ * @param eventname - name of the event
+ * @param eventdata - event data object
+ * @return number of failed events
+ */
+function trigger_events($eventname, $eventdata) {
+    $failedevent = 0; // number of failed events.
+    // pull out all registered event handlers
+    if ($handlers = get_records('events_handlers', 'eventname', $eventname)) {
+        foreach ($handlers as $handler) {
+            // either excute it now
+            
+            // if event type is 
+            if ($eventdata->schedule == "instant") {
+                if (trigger_event($handler, $eventdata)) {
+                    continue;
+                } else {
+                    // update the failed flag
+                    $failed = true;
+                    $failedevent ++;
+                }
+            }
+            // if even type is not instant, or trigger failed, queue it
+            $queuedevent++;
+            queue_handler($handler, $eventdata, $failed);        
+        }      
+    }
+    return $failedevent;
+}
+
+/**
+ * trigger a single event with a specified handler
+ * @param handler - hander object from db
+ * @param eventdata - event dataobject
+ * @return bool - success or fail
+ */
+function trigger_event($handler, $eventdata) {
+    
+    global $CFG;
+    // checks for handler validity
+    
+    // check if the same handler is queued already, if so, return false so we can queue it
+    // TODO
+    
+    include_once($CFG->dirroot.$handler->handlerfile);
+    return call_user_func($handler->handlerfunction, $eventdata);
+}
+
+/**
+ * given a queued handler, call the respective event handler to process the event
+ * @input object handler- events_queued_handler object from db
+ * @return fail or custom function value
+ */
+function events_process_queued_handler($handler) {
+    // checks for handler validity
+    global $CFG;
+    
+    // get handler
+    if (!$eventhandler = get_record('events_handlers', 'id', $handler->handlerid)) {
+        // can't proceed with no handler
+        return false;  
+    }
+    // get event object
+    if (!$eventobject = get_record('events_queue', 'id', $handler->queuedeventid)) {
+        // can't proceed with no event object
+        return false;  
+    }
+    // call the function sepcified by the handler
+
+    return trigger_event($eventhandler, unserialize($eventobject->eventdata));
+}
+
+/**
+ * Events cron will try to empty the events queue by processing all the queued events handlers
+ */
+function events_cron() {
+    
+    global $CFG;
+    
+    if ($handlers = get_records_select('events_queue_handlers', '', 'timemodified')) {
+        foreach ($handlers as $handler) {
+            if (events_process_queued_handler($handler)) {
+                // dequeue();
+                events_dequeue($handler);  
+            } else {
+                // failed again, put back on queue
+                $handler->timemodified = time();
+                $handler->status++;
+                update_record('events_queue_handlers', $handler); 
+            }
+        }      
+    }
+}
+
+/**
+ * removes this queued handler from the events_queued_handler table
+ * removes events_queue record from events_queue if no more references to this event object exists
+ * @input object handler - events_queued_handler object from db
+ */
+function events_dequeue($handler) {
+    
+    if (delete_records('events_queue_handlers', 'id', $handler->id)) {
+        // if no more queued handler is pointing to the same event
+        if (!record_exists('events_queue_handlers', 'queuedeventid', $handler->queuedeventid)) {
+            delete_records('events_queue', 'id', $handler->queuedeventid); 
+        }
+        return true;
+    } else {
+        return false;  
+    }
+}
 ?>
\ No newline at end of file
diff --git a/lib/simpletest/testeventslib.php b/lib/simpletest/testeventslib.php
new file mode 100755 (executable)
index 0000000..37b1d1a
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+
+/** $Id */
+require_once(dirname(__FILE__) . '/../../config.php');
+
+global $CFG;
+require_once($CFG->libdir . '/simpletestlib.php');
+require_once($CFG->libdir . '/eventslib.php');
+require_once($CFG->libdir . '/dmllib.php');
+
+// dummy test function
+function plusone($eventdata) {
+    return $eventdata->data+1;  
+}
+
+class eventslib_test extends UnitTestCase {
+
+    var $handlerid;
+    var $handler;
+    var $storedhandler;
+    /**
+     * Create temporary entries in the database for these tests.
+     * These tests have to work no matter the data currently in the database
+     * (meaning they should run on a brand new site). This means several items of
+     * data have to be artificially inseminated (:-) in the DB.
+     */
+    function setUp() {
+        
+        global $CFG;
+        
+        // make a dummy event
+        $eventhandler -> eventname = 'testevent';
+        $eventhandler -> handlermodule = 'unittext';
+        $eventhandler -> handlerfile = '/lib/simpletest/testeventslib.php';
+        $eventhandler -> handlerfunction = 'plusone';
+        
+        $this -> handler = $eventhandler;
+        $this -> handlerid = insert_record('events_handlers', $eventhandler);
+        $this -> handler->id = $this->handlerid;
+
+    }
+
+    /**
+     * Delete temporary entries from the database
+     */
+    function tearDown() 
+    {
+        delete_records('events_handlers', 'id', $this->handlerid);
+    }
+    
+    /**
+     * tests queue_handler() and events_process_queued_handler() and trigger_event()
+     */
+    function test_events_process_queued_handler_handler() {
+        
+        $eventdata = new object;
+        $eventdata->data = 1;
+        $eventdata->schedule = 'instant';
+        $id = queue_handler($this->handler, $eventdata);
+        $storedhandler = get_record('events_queue_handlers', 'id', $id);
+        $retval = events_process_queued_handler($storedhandler);
+        $this->assertEqual(2, $retval);
+        $this->storedhandler = $storedhandler;
+    }
+    
+    /**
+     * tests events_dequeue()
+     */
+    function test_events_dequeue() {
+        $this->assertTrue(events_dequeue($this->storedhandler));        
+    }
+    
+    /** 
+     * tests trigger_events funtion()
+     */
+    function test_trigger_events() {
+        $eventdata = new object;
+        $eventdata->data = 2;
+        $eventdata->schedule = 'instant';
+        $this->assertEqual(0, trigger_events('testevent', $eventdata));
+    }
+}
+
+?>
\ No newline at end of file