From: Joe E. <jo...@or...> - 2001-11-20 18:22:37
|
RFC: EmailNotification Coding Strategy 0 QUESTIONS & ISSUES I have some questions about how to implement the functionality described in the other RFC-- "EmailNotification Syntax and Features". Notably: (1) I would like to implement all of this using plugins which are only loaded by those who need the functionality. This will require an extension of the plugin concept to allow for "event-based" in addition to "content-based" plugins, and the placement of hooks inside WikiDB.php to trigger events. (2) I would also like to modify the existing code to keep track of the time that links were created, and I have some questions about how best to do that. (3) I would like to ask the various experts here on the list how they think my plugin can deal with the database in the most portable, modular, and flexible way. (4) I will explain a little how the plugins will work internally. 1.1 EVENT-BASED PLUGINS The event-based plugin functionality is orthogonal to the existing content plugin functionality, and it could be a completely separate thing. It seems like it makes sense to allow plugins to be both at once, though. Imagine a plugin for a database-backed tree-hierarchy organization of pages based on multidimensional scaling or clustering on page text: the event-side could do the necessary reindexing every time a page is modified, and the content-side would allow people to view the index using the "<?plugin?>" syntax. The principal thing that an event-based plugin needs to do is register one or more functions or methods to be triggered at certain times by the WikiEventManager using a line like: new WikiEventHandler ('onMajorRevision', 'function_that_checks_for_notifications'); It can do this registration when it is include()ed, I guess. Since these functions won't be loaded by the content-plugin engine unless they're used, they'll need to be included manually from index.php if they're going to be turned on. include('lib/plugin/NotifyAboutLinks.php'); include('lib/plugin/NotifyAboutChanges.php'); Much functionality which transcends mere content could be refactored into event plugins. Logging, for instance, is event-driven, as is maintanence of the "recent" table (which could sit together with the existing RecentChanges plugin code). All of the wacky indexing schemes that have been proposed could be done with plugins possessing and event/content dual nature. 1.2 HOOKS INSIDE WikiDB::createRevision WikiDB::createRevision seems to be the most sensible place to check for needed notifications, because it stands above the database backends and is not tied to a particular user action like savepage.php is. I intend to add four lines to this function like: if (!$data['is_minor_edit']) { global $WikiEventManager; $WikiEventManager->triggerEvent('onMajorRevision', $this); } and, depending on how I solve the link.ctime problem below, perhaps also two lines like: foreach ($backend->get_new_links() as $new_link) $WikiEventManager->triggerEvent('onNewLink', array( $this, $new_link )); Unless handlers for these events have been installed, these calls will be no-ops. This will be made possible be two little classes called WikiEventManager and WikiEventHandler which I'll place in lib/WikiEventManager.php. 2. TRACKING THE LINK.CTIME PhpWiki already keeps information about which pages link to which other pages in the "link" table for use by BackLinks and certain other features. Currently, when a page is revised, all the old information about what the page linked to is deleted from the database, the new page data is scanned for links, and all of these links are added to the database fresh, even though most of them may have been in the previous revision. For my application, I need to know which links are new, and I need to store information about when each link on a page was added in the database. I could do this with a separate table, but that would involve an inelegant & abnormal replication of the link table and would obscure what should probably be a central service. I need to know which links are new so that I can fire off "onNewLink" events from createRevision (described above). I need to store the age of links in the database so that, when notifications are being sent, the script can notify about just those links that the users haven't been notified about yet. The simplest thing to do would be to hack the PearDB::set_links function so that it registers a ctime for new links, doesn't clobber old links, and stores a list of the new links in some hidden instance variable; then I could write a getter function (backend::get_new_links()) for that instance variable which would only work when called immediately after a set_links call. Then WikiDB::createRevision could call that getter and use it to trigger "onNewLink" events. The most sophisticated thing to do would be to create a WikiDB_Link object similar to WikiDB_Page and WikiDB_PageRevision and have that object support arbitrary data get() and set() like the others, and do the same kind of translation between a $data[] array and the database fields. This involves serious changes to the API for both the various backends and WikiDB, complicates the code, and is something to be very careful about because certain functions would be changing their return values from arrays to iterators. If the consensus is that this is the only way to do it, however, I will try and do it myself in Jeff's style. With this approach it is still unclear where the best place to trigger "onNewLink" events would be. I should also note that, for efficiency, link.ctime needs to be indexible in the database, so there would be a link.ctime added to the database table (rather than just a serialized "linkdata") anyway. There are various solutions in between the simple one and the sophisticated one. For instance, rather than hack set_links as per the simple approach, I could expand the backend API to include "add_links" and "remove_links" and raise the detection of new links up into WikiDB's sphere of influence. Personally, I don't think it makes sense to do the sophisticated thing now. If we find out that we need a layer of abstraction around links in the future, we can always do it then. But that's just me, what do you think I should do? 3. WHERE SHOULD I PUT MY DATA? Aside from link.ctime, which is covered above, the NotifyAboutLinks plugin needs to track two additional peices of data. (1) For each page which has a NotifyAboutLinks (older than X) block on it, we need to cache that page's "expiration date", which is the earliest date on which the last notification for the most recent event could be sent out. This will save us from parsing through the full text of every page in the database every time we check for notifications. Since most pages won't have expiration dates (they will tend to be on Category pages), I think it makes sense to use a separate table for this. (2) For the entire wiki, I would like to store the date on which the last check for notifications was run, so that we can check for notifications that have become necessary in between then and now. Existing plugins use code in WikiDB and in the backends to talk with the database. This is very portable but not so modular-- even folks who never use the plugin have to wait while PHP parses the DB code for it on page loads. It seems to make sense to leave WikiDB as is and put mysql-only code directly into the plugin file. Is that right? Also, is there any preference as to how I store wiki-wide dynamic data? Should I make a "wiki" table with one row and (for now) one column? Is this something specific to my application or something that people would a general (WikiDB) interface to? 4 ABOUT THE PLUGIN 4.1 SQL STATEMENTS The most important SQL statement, run on every invocation of admin/notify.php, finds the pages that need to be examined for outgoing notifications, and looks like this: select page_id from page_notify where expire_date > [DATE OF LAST NOTIFICATION] The "expire_date" is a calculated cached (ab-normalized) value that takes the last time anything was linked to the page ("max(ctime) from link where to=page_id") and adds the maximum time interval mentioned on the page in an "(older than X UNITS)" clause. If the last time we notified people all the links on the page were too old to get notifications, and there have been no new links, we don't need to check that page. The other important SQL statement, run per-page on every page returned by the first query, identifies, for each "(older than X UNITS)" block on each page, which new links notifications should be sent out to all the emails listed in that block. Any link that has become relevant in between now and the last notify is included. It looks like this: select "from" from link where to=[PAGE_ID] and ctime > [DATE OF LAST NOTIFICATION] - ["OLDER THAN" DELAY] and ctime < now() - ["OLDER THAN" DELAY"] 4.2 DATA MAINTANENCE Whenever there is a new link to a page with a NotifyAboutLinks keyword, or whenever a NotifyAboutLinks time duration is added, removed, or changed, we need to update that page's expiration_date. 4.3 NEW FILES admin/notify.php // functions to do actual notification lib/WikiEventManager.php // A simple class for abstracting the hooking mechanism used below lib/plugin/WikiEmails.php // Classes for the new syntax & for sending emails lib/plugin/NotifyAboutLinks.php // handlers for the feature lib/plugin/NotifyAboutChanges.php // handlers for the feature 4.4 CLASSES A CLASS FOR PARSING THE SYNTAX class WikiEmailList Constructor: new WikiEmailList( $wikiPage, $keywordString ); Methods: $w->findOnPage(); // returns 1 if another keyword-headed block is found $w->emails(); // returns a list of email address strings from the current block $w->args(); // returns "older than" thingie if it's there in the current block class NotifyAboutChangesList extends WikiEmailList Constructor: new NotifyAboutChangesList( $wikiPage ); class NotifyAboutLinksList extends WikiEmailList Constructor: new NotifyAboutLinksList( $wikiPage ); Methods: $n->delay(); // returns the "older than" delay for this block in seconds A CLASS FOR THE OUTGOING EMAILS class WikiEmail Constructor: new WikiEmail( $msg ); Methods: $e->sendToBlindly( $addresses[] ); class NotifyAboutChangesEmail extends WikiEmail Constructor: new NotifyAboutChangesEmail( $wikiPage ); class NotifyAboutLinksEmail extends WikiEmail Constructor: new NotifyAboutLinksEmail( $fromPages[] ); A CLASS FOR DISPATCHING ON EVENTS class WikiEventHandler Constructor: new WikiEventHandler( $eventName, $handlingFunction ) Methods: $eh->destroy(); // unregisters the event handler $eh->getEventName(); $eh->trigger( $data[] ); class WikiEventManager Constructor: **singleton** Methods: $em->register( $handler ); $em->unregister( $handler ); $em->trigger( $eventName ); |
From: Jeff D. <da...@da...> - 2001-11-20 21:53:36
|
You bring up several issues, most of which are inter-related. Here's some ramblings on those and related subjects. > 3. WHERE SHOULD I PUT MY DATA? This is certainly one of the bigger unresolved issues in PhpWiki development that I see today. I'm not real happy with any of the proposed solutions (either yours or mine) yet. (What follows is mostly more questions, not many answers...) There is all kinds of data we might like to store which currently doesn't fit into the WikiDB. Plugins might want to have their own data storage. (e.g. FileUploads & weblog plugins.) In some of these cases it might be nice if the data were stored right in the page text, a la what I proposed in my last reply: <?plugin NotifyAboutChanges -- JoeEdelman ?> where everything after the '--' is 'meta-data'. What if there were any API by which the plugin could modify that data itself? Then the "notify me when this page is edited" button could become reality. (Eh.. maybe it's a crackpot idea.) In other cases, the plugin might like meta-data which can't be edited by the user, so the data would need to be stored some other way. (Page meta-data in WikiDB may be handle much of this?) The file upload case is taxing in that image files, etc.. are big. We probably don't want them in the (e.g. SQL) database, but rather as flat files somewhere. (One slick syntax for handling file uploads which just occured to me might be: <?plugin Inclusion type="image/gif" ?> After such a plugin invocation is added to a page, the marked-up page will show a file upload form where the plugin is. After a file is uploaded, the uploaded file is shown instead. If the plugin invocation is deleted, then the uploaded file (if any) is deleted as well. (Of course, I'm still not sure how this all would be implemented.)) > Existing plugins use code in WikiDB and in the backends to talk with the > database. This is very portable but not so modular-- even folks who never > use the plugin have to wait while PHP parses the DB code for it on page > loads. It seems to make sense to leave WikiDB as is and put mysql-only code > directly into the plugin file. Is that right? I don't think I understand your objections. I don't really see very many situations where you could do anything useful without the DB code (if you want any page text, or page meta-data it has to come from the DB). Also, I would think that mysql-only code is to be avoided. One of my peeves with 1.2.x is that the featureset is different for each back end. (Page scoring only works with some backends, the syntax for title/full-text searches varies among the different backends, etc...) I guess, to some degree, that is unavoidable, but I would prefer to see the features coded as portably as possible. (Suppose a plugin is written to only work with mysql, then someone comes along and want to make with work with dba data store. Does he need to create a whole new plugin?) > Also, is there any preference as to how I store wiki-wide dynamic data? > Should I make a "wiki" table with one row and (for now) one column? Is this > something specific to my application or something that people would a > general (WikiDB) interface to? I almost included an API in WikiDB to do just that. Then I managed to work around needing global meta-data. It may well be worthwhile to add. A way to hack around it may be to attach the global meta-data to a "special" page name (like '' (the empty string)). =================== > 1.1 EVENT-BASED PLUGINS > include('lib/plugin/NotifyAboutLinks.php'); > include('lib/plugin/NotifyAboutChanges.php'); My proposed <?plugin NotifyAboutChanges -- ... ?> syntax would eliminate the need for these particular explicit include()s. In general though, the idea of solely event-based plugins is probably a useful one. =================== Link ctimes & extra link meta-data: One alternative which doesn't require the storage of new link meta-data, and thus doesn't require big changes to the database backend is as follows: New (and deleted) link detection: Whenever the page is modified, get a list of links before the modification, and compare it to the list of links after modification. This is simple and I think should work fine. Stale link detection: Whenever a link for which stale link detection has been requested is added to a page, register an alarm (but only if no alarm already exists for that link/page combination) with the timer manager (see below). When a link is deleted from a page, check for and delete any pending alarms which are keyed to that link. This is not quite so simple, but should work fine. > The most sophisticated thing to do would be to create a WikiDB_Link object > similar to WikiDB_Page and WikiDB_PageRevision and have that object support > arbitrary data get() and set() like the others, and do the same kind of > translation between a $data[] array and the database fields. If you really feel the need to add ctime meta-data to the links, I think this is the way to go. > This involves serious changes to the API for both the various backends and WikiDB, > complicates the code, and is something to be very careful about because > certain functions would be changing their return values from arrays to > iterators. Yes. :-) > With this approach it is still unclear where the best place to trigger > "onNewLink" events would be. My first guess would be to register an "onNewPageRevision" (or similar) handler which checks for new links and calls the 'onNewLink' handlers appropriately. ==================== Scheduling actions: Page expire_date's: As a more general mechanism, I'd suggest the implementation of alarms (or, more generally still, timers). class WikiTimerManager Constructor: **singleton** Methods: $am->registerAlarm( $key, $timeout, $handler [, $data ]) $key (string) unique identifier for queued alarm. $timeout expiry time of alarm $handler callback: either global function name (string) or pair: array($object, 'methodName'). (Or maybe it's time to implement a WikiCallback class.) Callsbacks should return: TIMER_OK: TIMER_DELETE: Unregister this timer. $data Arbitrary data to be passed to handler $type $am->registerTimer( $key, $interval, $handler [, $data]) Similar to registerAlarm, except registers a recurring callback. $am->unregister( $key ); (Probably methods to iterate through the registered timers would be needed....) $am->run(); Run any pending alarms. (Other API's are possible. My only strong feeling here is that a TimerManager or some such would make for cleaner code than messing with page expire_date's (and also be more generally useful for other scheduling tasks, as well). =============== > class WikiEventHandler > Constructor: new WikiEventHandler( $eventName, $handlingFunction ) > Methods: > $eh->destroy(); // unregisters the event handler > $eh->getEventName(); > $eh->trigger( $data[] ); > > class WikiEventManager > Constructor: **singleton** > Methods: > $em->register( $handler ); > $em->unregister( $handler ); > $em->trigger( $eventName ); A fine idea. However, I'm not sure WikiEventHandler is necessary, what about just: class WikiEventManager Constructor: **singleton** Methods: $em->register( $eventName, $callback [, $extra_data] ); $em->trigger( $eventName, $args ); Perhaps there is a way to combine WikiEventManager and WikiTimerManager? Maybe not though... WikiTimerManager manages a persistent queue, WikiEventManager does not (at least, I don't think so). =============== Okay, enough rambling for now. Jeff |
From: Reini U. <ru...@x-...> - 2001-11-21 15:03:32
|
> > 3. WHERE SHOULD I PUT MY DATA? another wiki-like crakpot idea: WHY NOT DO IT SIMILAR TO A UNIX-MAILBOX FORMAT? A single page, a header with all metadata, editable by the owner and the system, and the body which is viewable, editable by all. (dependent on some header info, like permissions (for locks, plugin execution, ...), header plugins like notifiers, timers, ...) So we could have standard headers (formerly called meta-data) plus header plugins for the owner, plus body plugins for the users: <begin samplepage> >From WikiOwner Sun Jul 1 03:47:45 2001 Subject: WikiPage Message-ID: <23...@ph...> From: Wik...@ph... Date: Sun, 1 Jul 2001 03:47:45 +0200 Mime-Version: 1.0 (Produced by PhpWiki 1.3.x) Content-Transfer-Encoding: iso8859-1 Content-Type: application/x-phpwiki Keywords: php wiki mailboxformat X-Revision: 1.14 X-Created: 2001-08-01 13:00:00 X-Group: root X-HeaderPermissions: -rwxr-xr-x X-BodyPermissions: -rwxrwxrwx X-Plugin-NotifyAboutChanges: WikiOwner X-Plugin-PageAlias: OtherPageName X-Plugin-MaxSize: 2000 X-Plugin-WikiTimer: action="SetHeader"; value="BodyPermissions: -rwxr-xr-x"; when="2001-12-27 22:00:01" X-Plugin-BodyTransformPCRE: trigger="/regex/ig"; to="/$1 regex/"; when="before" X-Plugin-BodyTransformPCRE: trigger="/<code>(.*)</code>/"; to="/$1/"; transform="wtm_code"; mode="WT_MODE_MARKUP"; when="before" X-Plugin-BodyRegisterToken: token='RELATEDPAGES'; eval='<?php echo "blabla" . LinkRelatedPages($dbi, $name) ?>' This a WikiPage in a unix mailbox format (header-body) <?plugin NotifyAboutChanges -- JoeEdelman ?> <?plugin BodyTransformPCRE trigger="/WikiPage/g"; to="/Sample $1/"; when="before" ?> See ###MYRELATEDPAGES### <eof samplepage> The X-Plugin-WikiTimer is the WikiTimer plugin which performs <?plugin SetHeader BodyPermissions: -rwxr-xr-x ?> at a certain time. (recurring or once) Via the standard `at` scheduler probably. this works on unix and windows at least. so we would have a good time syntax available. platform dependent of course, but cute. Permissions: Any user may edit the whole page with headers via action="adminedit", defined by X-HeaderPermissions w for u (owner), g (group) or o (other). Similar to X-BodyPermissions which implements locks for groups and world. Haven't got an idea yet how to define group ownership in the header. Similar to a stupid unix-filesystem or an ACL list? Is this good enough to add it to the phpwiki page? I also like jeff's idea of a global '' page for global meta-data. very wiki-like. To parse out a header from the pagename is not slower than a seperate db access for the meta-data, and it is easier for the fs version. See http://www.landfield.com/rfcs/rfc2822.html for the reference. jeff already did it for the zipdump. just the quoted-printable mime-type is questionable. I would strongly prefer 8-bit Latin-1, since we don't have to transport that over SMTP. the zipdumps could then be the standard format, which would make backups much easier to handle. For now it looks like: >From ro...@xa... Mon Jul 2 09:50:50 2001 Subject: OrphanedPages From: ro...@xa... (PhpWiki) Date: Sun, 1 Jul 2001 03:47:45 +0200 Mime-Version: 1.0 (Produced by PhpWiki 1.3.0pre5) Content-Type: application/x-phpwiki; pagename=OrphanedPages; author=PhpWiki%20-%20dynamic; version=0; flags=PAGE_LOCKED; lastmodified=993952065; created=993952065 Content-Transfer-Encoding: quoted-printable Jeff Dairiki schrieb: > You bring up several issues, most of which are inter-related. > Here's some ramblings on those and related subjects. > > > 3. WHERE SHOULD I PUT MY DATA? > > This is certainly one of the bigger unresolved issues in PhpWiki > development that I see today. I'm not real happy with any of the > proposed solutions (either yours or mine) yet. (What follows is > mostly more questions, not many answers...) > > There is all kinds of data we might like to store which currently > doesn't fit into the WikiDB. > > Plugins might want to have their own data storage. > (e.g. FileUploads & weblog plugins.) > > In some of these cases it might be nice if the data were stored > right in the page text, a la what I proposed in my last reply: > <?plugin NotifyAboutChanges -- > JoeEdelman ?> > where everything after the '--' is 'meta-data'. What if there > were any API by which the plugin could modify that data itself? > Then the "notify me when this page is edited" button could become > reality. (Eh.. maybe it's a crackpot idea.) > > In other cases, the plugin might like meta-data which can't be > edited by the user, so the data would need to be stored some other way. > (Page meta-data in WikiDB may be handle much of this?) -- Reini Urban http://xarch.tu-graz.ac.at/home/rurban/ |
From: Adam S. <ad...@pe...> - 2001-11-21 15:26:43
|
> So we could have standard headers (formerly called meta-data) plus > header plugins for the owner, plus body plugins for the users: i like the idea of page meta data being stored in the page *very* much. however i'm not so keen on actualy using mbox format for it. unless it's much easier to parse because of mime modules for php (or similar reason) i would like to see a more human readable syntax. something like: #Owner: AdamShand #Group: SomeGroup #HeaderPermissions: -rwxr-x--- #BodyPermissions: -rwxrwxr-x and then the page SomeGroup could have: #Owner: SteveWainstead #GroupMembers: SteveWainstead Jeff Dairiki AdamShand #HeaderPermissions: -rwx------ #BodyPermissions: -rwxr-xr-x etc etc. > Haven't got an idea yet how to define group ownership in the header. > Similar to a stupid unix-filesystem or an ACL list? i think unix file system permissions are sufficient and they are fairly well groked by the public. > To parse out a header from the pagename is not slower than a seperate > db access for the meta-data, and it is easier for the fs version. it's also wiki'ish in the sense that the wiki page actually contains all the information about itself, in itself. adam. ps. i just re-read this and i'm not sure i've done anything useful. i think i just removed what was novel about reini's approach and obfuscated joe's ... but for what it's worth ... here it is anyway. |
From: Joe E. <jo...@or...> - 2001-11-21 16:26:05
|
First of all, thanks for your fast & deep& encouraging response. Here are some preliminary notes. "Jeff Dairiki" <da...@da...> wrote: > Plugins might want to have their own data storage. > (e.g. FileUploads & weblog plugins.) Still thinking. Looks like it won't be necessary for this plugin because I'm going to accept your alarm/timer proposal. But I agree-- we need a general mechanism for plugins to add their own code into the WikiDB monolith. Perhaps plugins should be able to register new backend functions to multiple DB backends from within their one plugin file. Page metadata will be able to handle much of this too, but there's no way to SELECT on page metadata efficiently, right now. Still thinking. > In some of these cases it might be nice if the data were stored > right in the page text, a la what I proposed in my last reply: I think it's a great idea generally, but not for this application. I would prefer a syntax that left the inside data clean-looking: <?plugin-begin NotMyPlugin?> Slurped data <?plugin-end?> But again, I don't think this is a good approach for NotifyAboutChanges, because it moves away from PlainEnglish. I'll go into it more later. > I managed to > work around needing global meta-data. It may well be worthwhile to add. > A way to hack around it may be to attach the global meta-data to a > "special" page name (like '' (the empty string)). It's a hack, but that's okay for my first cut at this. If you want me to add wiki-wide data to WikiDB, I'll be happy to do that too. > New (and deleted) link detection: > Whenever the page is modified, get a list of links before the > modification, and compare it to the list of links after modification. > This is simple and I think should work fine. This is what I was going to do anyway. > Stale link detection: > Whenever a link for which stale link detection has been requested > is added to a page, register an alarm (but only if no alarm already > exists for that link/page combination) with the timer manager (see > below). > When a link is deleted from a page, check for and delete any pending > alarms which are keyed to that link. > This is not quite so simple, but should work fine. Still thinking about it. > My first guess would be to register an "onNewPageRevision" (or similar) handler > which checks for new links and calls the 'onNewLink' handlers appropriately. That's fine. Good suggestion. > Scheduling actions: Page expire_date's: > > As a more general mechanism, I'd suggest the implementation of alarms > (or, more generally still, timers). > > class WikiTimerManager Excellent! Okay, I'll do that. Your API looks good to me. > A fine idea. However, I'm not sure WikiEventHandler is necessary It's not. I'll leave it out. > class WikiEventManager > Constructor: **singleton** > Methods: > $em->register( $eventName, $callback [, $extra_data] ); > $em->trigger( $eventName, $args ); Okay. But I'm going to do an unregister function too, so that hacks like this work: $em->register( 'onWikiLinkDetectedInTransform', 'add_to_links_array', $pagename ); do_transform( $pagetext ); $em->clear( 'onWikiLinkDetectedInTransform', 'add_to_links_array' ); > Perhaps there is a way to combine WikiEventManager and WikiTimerManager? > Maybe not though... WikiTimerManager manages a persistent queue, > WikiEventManager does not (at least, I don't think so). Yes, I think it's best to leave them separate. WEM should be real simple, and WTM might get pretty sophisticated. Joe |
From: Jeff D. <da...@da...> - 2001-11-21 17:38:51
|
On Wed, 21 Nov 2001 11:11:03 -0500 "Joe Edelman" <jo...@or...> wrote: > Page metadata > will be able to handle much of this too, but there's no way to SELECT on > page metadata efficiently, right now. Still thinking. Yes, this is problem. I've got vague notions of adding an API to WikiDB to allow the addition of arbitrary "indexes" or something. (Think about want to add new and experimental page "score" algorithms.) It would be nice to abstract the process away from the SQL model. I haven't come up with a clean way to do this yet. > Okay. But I'm going to do an unregister function too, so that hacks like > this work: > > $em->register( 'onWikiLinkDetectedInTransform', 'add_to_links_array', > $pagename ); > do_transform( $pagetext ); > $em->clear( 'onWikiLinkDetectedInTransform', 'add_to_links_array' ); The main reason I proposed the $key argument to WikiTimerManager::registerTimer, is to provide for clean identification of handlers when one wants to unregister it. Adding a (perhaps optional) $key argument to $em->register would probably be a good idea. (Or perhaps better, though it's yet another different API, have $em->register return a key or handle while can be used to unregister the callback.) And, in case I didn't mention it before, it's probably time to implement WikiCallback as a bona fide class. There are already a number of places where callbacks are passed around. class WikiCallback Constructor: new WikiCallback($globalFunctionName) new WikiCallback($object, $methodName) Methods: $cb->call([$args [,...]]); $cb->call_array($arrayOfArgs); $cb->getPearCb(); Returns Pear style callback: either a string for a global func, or an array of length two for an object method callback. In fact, if I find time this morning, I'll try to code it up. Jeff PS. I'll be gone for Thanksgiving, so if I'm silent, that's why. |
From: Joe E. <jo...@or...> - 2001-11-21 22:53:04
|
> Yes, this is problem. I've got vague notions of adding an API to WikiDB > to allow the addition of arbitrary "indexes" or something. Yes. Something like that. I feel like we're reinventing SQL... I guess that's the right thing to do! > Adding a (perhaps optional) $key argument to $em->register would > probably be a good idea. Okay. > (Or perhaps better, though it's yet another different > API, have $em->register return a key or handle while can be used to unregister the > callback.) Well that's why I had the WikiEventHandler class before, so you could say: $eh = new WikiEventHandler ( $event, $function ); and $eh->destroy(); > And, in case I didn't mention it before, it's probably time to implement > WikiCallback as a bona fide class. Sure. Makes sense. Joe |
From: Steve W. <sw...@pa...> - 2001-12-01 21:03:45
|
On Wed, 21 Nov 2001, Joe Edelman wrote: > > Yes, this is problem. I've got vague notions of adding an API to WikiDB > > to allow the addition of arbitrary "indexes" or something. > > Yes. Something like that. I feel like we're reinventing SQL... I guess > that's the right thing to do! And CVS and HTML... let's not neglect other technologies being reinvented here ;-) ~swain --- http://www.panix.com/~swain/ "Without music to decorate it, time is just a bunch of boring production deadlines or dates by which bills must be paid." -- Frank Zappa |