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 |