From: toyomoyo Date: Thu, 26 Apr 2007 08:50:29 +0000 (+0000) Subject: some events code/testing code X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=8aaf935a1febc3422f0c98f3d96998608769846f;p=moodle.git some events code/testing code --- diff --git a/lib/eventslib.php b/lib/eventslib.php index 6f44cc6c7b..763192e5f8 100755 --- a/lib/eventslib.php +++ b/lib/eventslib.php @@ -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 index 0000000000..37b1d1a562 --- /dev/null +++ b/lib/simpletest/testeventslib.php @@ -0,0 +1,84 @@ +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