Chuck's Horde 4 Thoughts Overall Design - http://www.25hoursaday.com/weblog/2008/08/04/[AvoidingTheSecondSystemEffectInSoftwareDevelopment](AvoidingTheSecondSystemEffectInSoftwareDevelopment).aspx Controllers Horde_Controller - make Horde_Controller_Dispatcher Horde_FrontController_Http or similar, then add other front controllers for Soap, XmlRpc, JsonRpc, Cli ... User Interface - Get rid of popups. Any new window functionality should be in an ajax overlay, or a full new browser window. API design - http://www.lornajane.net/posts/2009/Error-Feedback-for-Web-Services - http://www.lornajane.net/posts/2009/Status-Codes-for-Web-Services - http://www.lornajane.net/posts/2009/Version-Parameters-for-Web-Services Documentation Developer docs (PHPDoc alternatives) - http://ajaxian.com/archives/beautiful-code-documentation - http://sphinx.pocoo.org/ Debug support - http://code.google.com/p/webgrind/ - http://www.sitepoint.com/blogs/2008/05/13/useful-in-browser-development-tools-for-php/ - http://badapi.trib.tv/ - http://bergie.iki.fi/blog/sql-level\_debugging\_with\_midgard.html - http://code.google.com/p/formaldehyde/ - Debug "wrapper" drivers - encapsulate another driver and delegate all calls, but provide before/after hooks for any function along with timing, profiling, reporting of calls and arguments, etc. URLs - We should sign (with a timestamp and HMAC, per Horde::signQueryString) all URLs that perform destructive actions. Configuration - use Horde_Policy - Allow conf.d directory styles, like Apache2 config (see http://bugs.horde.org/ticket/4747\). - Use return $... in PHP config files to avoid defining local-scope variables? (http://www.urdalen.com/blog/?p=257\) Permissions - http://blog.wolff-hamburg.de/archives/25-A-pragmatic-approach-to-rights-management.html - http://stonean.com/wiki/lockdown Profiling Lots of overlap with debugging - http://docs.kohanaphp.com/libraries/profiler - See Zend_Db_Profiler, and idea for Cache profiler also, including Firebug plugins for both Testing - http://www.phpunit.de/pocket\_guide/3.2/en/database.html - http://sebastian-bergmann.de/archives/702-Data-Providers-in-PHPUnit-3.2.html - http://www.xaprb.com/blog/2008/08/19/how-to-unit-test-code-that-interacts-with-a-database/ - http://mikenaberezny.com/2008/10/17/php-temporary-streams/ Error handling - http://derickrethans.nl/five\_reasons\_why\_the\_shutop\_operator\_@\_should\_be\_avoided.php - http://eirikhoem.wordpress.com/2008/03/15/dying-with-grace-phps-register\_shutdown\_function/ Jabber/XMPP support - http://www.xmpp.org/extensions/xep-0114.html DFS/DHT uses - http://en.wikipedia.org/wiki/Distributed\_hash\_table - http://www.danga.com/mogilefs/ - http://hadoop.apache.org/core/ - http://hadoop.apache.org/core/docs/r0.16.4/hdfs\_design.html - http://en.wikipedia.org/wiki/Hadoop - http://wiki.apache.org/hadoop/[ProjectDescription](ProjectDescription) - http://code.google.com/p/the-cassandra-project/ Idea sources Don't get too caught up in everything everyone else is doing. However, some things that might be useful food for thought are listed below. Projects may be added to or discarded from this list quickly as they are synthesized. - http://kohanaphp.com/home.html - http://code.whytheluckystiff.net/camping - http://api.rubyonrails.com/ - http://toys.lerdorf.com/archives/38-The-no-framework-PHP-MVC-framework.html - http://www.xml.lt/Resources/Framework - http://cognifty.com/ - http://docs.kohanaphp.com/ - http://merbivore.com/documentation.html - http://weblog.rubyonrails.org/2009/2/1/rails-2-3-0-rc1-templates-engines-rack-metal-much-more - http://static.repoze.org/bfgdocs/ - http://oddments.org/?p=78 - http://www.brandonsavage.net/use-registry-to-remember-objects-so-you-dont-have-to/ Horde 4 Administratation - http://bergie.iki.fi/blog/asgard\_welcome\_page\_just\_got\_useful.html Package structure - http://www.apsstandard.com/doc Unsorted http://incubator.apache.org/thrift/ http://www.gearmanproject.org/ http://codeigniter.com/wiki/Modular\_Extensions\_-\_HMVC/ http://ojay.othermedia.org/articles/keyboard.html http://www.lkozma.net/autocomplete.html http://writer.bighugelabs.com/ http://www.spread.org/ http://www.backhand.org/wackamole/ protocol-independent URLs: http://nedbatchelder.com/blog/200710.html#e20071017T215538 - return a 304 if the file hasn't been modified since the If-Modified-Since date - no point in resending all the data if the browser already has it cachedif (function_exists("apache_request_headers")) {
  $headers = apache\_request\_headers\(\);



  if \($headers\['If-Modified-Since'\]\) \{

      $ims = strtotime\($headers\['If-Modified-Since'\]\);

      if \($ims \>= $serve\_data\['modified\_time'\]\) \{

          Header \("HTTP/1.0 304 Not Modified"\);

          exit\(0\);

      \}

  \}
} horde apps - "instance" of a horde app == installed horde app + a group of horde_policies that configure it let those policies be named instead of using shipping/foo api calls, use $instance->foo() $Horde->api->method() (chaining)? I just went through my first signup process that required an SMS-capable device for confirmation. It also didn't make me pick my credit card type, and instead used my country code (+1) to decide on a card detection algorithm. update_client.pl /modules/future_contribution /modules/future_signup I think I found now the right mysql-server settings, with which the performance is quite Ok. Increasing the sort_buffer_size was one of the changes that helped. skip-external-locking skip-thread-priority key_buffer = 64M max_connections = 1024 max_connect_errors = 1000 max_allowed_packet = 8M table_cache = 512 sort_buffer_size = 8M read_buffer_size = 1M read_rnd_buffer_size = 2M myisam_sort_buffer_size = 64M thread_cache_size = 50 query_cache_size = 128M tmp_table_size= 1024M thread_concurrency = 12 wait_timeout = 60 interactive_timeout = 60 log_slow_queries add dynamic finders (find_by_name, find_by_id, etc.) to Rdo Mappers or Horde_Db_Model or whatever Controller classes/objects vs. Action classes/objects vs. Resources vs. API how to develop? give up central config? http://www.w3.org/Provider/Style/URI index.php - global dispatcher how to do themes/custom templates? chain local -> app -> horde? a horde 4 installation: config/ lib/ apps/ public/ <- with app/ subdirs containing images, etc. everything routable goes in apps/ apps/ login/ help/ prefs/ admin/ etc... ... auto-install web files to a writable dir, either in web ui or in cli? keep apps self-contained that way? app name is the first part of the route > /login subdomain support route aliases an app should uncompress over a horde/ dir - /config/app/*.php -> config dir is compiled/cached horde is not rails. it is designed as a container for multiple, collaborating apps need Horde_Db, whatever implements DML, DDL, and SQL - Mad? MDB2? - prefer PHP over XML merge Rdo and Mad into Horde_Db allow for overriding the mappers so that non-SQL can be used, but, default to SQL/sqlite and leverage it framework repository/module Horde/lib/... Rampage/lib/...
 use subpackages or multiple \*.xml for packages to avoid silliness?
apps should be installable into a horde container. shouldn't be tied to the app name - keep imp, krono, etc, but install as mail, cal, events (should be able to install two versions of krono w/ different permissions - see HordeSpaces) installing gives a slug, that slug manages config, templates, themes, perms, etc. figure out how to merge luxor into Chora for now, build Horde_Content_* based on Rdo, then move to Horde_Db Horde_Db provides Horde_Db_Mapper which creates Horde_Model_Base objects apps have a config/ dir, but that's just defaults and defining base routes, polices, etc. user settings are stored in the db or a global directory. should have parallel web and cli configuration and installation/update tools; web requires webserver to have write access to a config/ dir and to public/; cli tools do not (if run as another user) Horde 4 app - a Horde 3.x app updated for PHP 5 and to use the latest libraries Rampage app - "RAD" (rapid application development) MVC app that uses Horde 4 /horde/page/ -> dispatcher for Rampage modules w/ views (overridable), routes, controllers, etc.? have generic views for rampage_login, rampage_admin_*, etc. configuration: config/routes.php config/routes_local.php -> do this for all config files Horde_Content_Index -> horde-wide search Random Horde Ideas mini-cms for building your own sidebar/menu/etc? - shortcuts to any bit of horde labels labels labels keywords also or just labels? probably just flexible labels "smart folders" Getting Things Done support? (other apps that do it - Tracks, Kinkless GTD, Midnight Inbox) make mnemo into more of a snippet keeper? sort of like a personal cms - or wiki. carry the encryption feature through to other kinds of content create an outliner! tags/labels for mail rename virtual folders to smart folders? too apple? freetext boolean mail searches: apples & oranges apples | oranges apples ! oranges (apples but not oranges) apples & (oranges | lemons) security of redirects: http://www.xssed.com/mirror/39494/ This is sort of an interesting one. For the actual attack he merely figured out that we are base64 encoding the successurl and reflecting back whatever is there. The interesting thing is that merely filtering the unecoded data is not going to save us here. The string was javascript:alert(/XSS.By.Mityo/) and was being loaded into the URL field of a meta redirect. So our max filter of strip_tags is useless. It just illustrates the rationale for Phase 2 of the security build out where we have to be careful when we are dealing with redirects. In this particular case, we need to make sure we are getting a valid URL format. That will prevent javascript insertions. But we also want to make sure the URL is not redirecting outside the intended domain for some phishing scam. In this case I will fix the problem by validating the URL on the cons/login.inc.php where the data is coming in but will also try doing it on the generic show_redirect_message() call if I think I can do so without breaking other pages. Event-driven apps: "Understanding and implementing this event model can free your application from the constraints of defined elements. For example, instead of applying an event listener for each link in a menu, you can assign a single listener to the menu item itself and retrieve the event target. That way you don?t need to change your script when the menu gets larger or when links get removed from it." http://yuiblog.com/blog/2007/01/17/event-plan/ tagging/instant hierarchies as specialized permission-based search RBAC what is horde? groupware? horde data services? horde data access? ui layers be the php dojo framework? or the php yui framework? see http://tigermouse.epsi.pl/ ? or, don't do desktop-like widgets? see UI design bookmarks move away from gettext, at least as a default? midgard i18n notes: http://www.midgard-project.org/discussion/developer-forum/midgard-s-multilang-support/ try to rely only on thread-safe extensions? reduce dependency tree avoid globals and non horde-namespaced functions/methods in framework and core app code class-based registry apis against edge cases: http://www.bakesalehq.com/contents/show/12/ features from Prado? http://www.urdalen.com/blog/?p=198 use functions where appropriate for shortcuts/helpers, like Mike's t("translated string") function? but would be horde_t? would call configured translation system helper sets for dojo, protaculous, yui - simple functions like dojo_editor(), dojo_pane(), yui_map(), etc. Load with something like Horde/Layout/Helpers/YUI.php, etc. See http://www.ngcoders.com/projax/ Horde as a set of apps and methodology needs to pick a js lib, pick a template methodology, etc. - this is Rampage Horde as a framework can allow for flexibility To make it even better, separate the control logic from the presentation. That way, back could be reverse, etc. I do this in all my forms since application logic and presentation "word play" are two distinct things to me. This is what I use:
back" value="reverse" type="submit" />   next" value="speed ahead" type="submit" />   home" value="no place like home" type="submit" />
Then, you can have a simple routine that captures submit actions regardless of the presentation value. You check for the array submit -- count 1 and whitelist against the acceptable values. A multi-row table can expand upon the theme by using this: submitedit_3, submitdelete_3m submitedit_5, etc. caching make sure Rdo and other services allow dropping in caching rules http://sebastian-bergmann.de/pages/talks.html phpunit - @test markup in methods phpunit + selenium cruise control? really hope google will integrate any product of theirs with any other products of theirs? receive an email, transform it to document, add spreadheet, add notes, add bookmarks saved from search history and a link to an event in calendar anyone? From nyphp-talk:
The other day I had to get an application started in a hurry.  It's
doing something useful at < 700 lines, but I'm considering options that could grow it out to about 10 times that. It depends on a "core library" that's < 500 lines. This library deals with common issues in string handling, parameter handling, and HTML form generation.
About 10% of the application,  or 70 lines,  is a microframework
that's loosely built on Struts. About 20 of those lines are in 2 functions which would be generally useful for microframeworks (such as file_exists_in_include_path()). Like Struts, the microframework chooses an "action" based on form parameters: the action then chooses a "view" -- a "view" is basically a template that a designer can edit which can be supplemented by an optional "query" which pulls stuff out of the database. Like Ruby-on-Rails, the microframework uses convention instead of configuration: the dispatcher computes an "action name" based on query parameters, and uses that to compute a filename... It checks that the file exists and executes it with the "require method".
The microframework uses no object-oriented techniques.  That's not
because I have any antipathy to OO, but because I didn't need it, and I like writing my actions, queries, and views in a style that "feels like PHP".
Yes, my microframework is nowhere near as powerful as [CakePHP](CakePHP) or
Symfony. Yet, it's more flexible, because I can codesign it with my application. Because it's so simple, I can easily adapt it to do what I want. If I decide I really hate it, I can write a new one in an hour. I'm an expert on it, because I developed it, and I wouldn't have to take on the technical, social and emotional burdens of "forking" an open-source codebase if I wanted to make a change in direction.
I'm moving towards a vision of web app architecture where we move
towards shared vocabulary and standardized interfaces. Rather than working with a "comprehensive framework" that does everything, I'd like to have a "framework construction set" that contains a number of elements that I can take or leave." Resources: http://www.ryandaigle.com/articles/2006/06/30/whats-new-in-edge-rails-activeresource-is-here mixins: http://www.symfony-project.com/book/trunk/17-Extending-Symfony split db ideas: http://pear.php.net/pepr/pepr-proposal-show.php?id=359 http://dataspill.org/pages/projects/ruby-activeldap More php features to look in to: __toString works everywhere SPL features: Regex Iterators, SplFileObject CSV support, Caching Iterator Data: stream support DateTime and DateTimeZone classes set date.timezone ini setting automatically based on user? Search engine sitemap stuff - of use at all? maybe support in rampage cms http://p7.hostingprod.com/@www.ysearchblog.com/archives/000437.html - I want a registration info tab like Inbox.lv where they can change their personal stuff they put on file with us on the signup forms. - We may need Windows address book synchronization(this is a feature that fastmail is adding, and hotmail already has, so I guess we will have to also?) It is not a must in my books. - I want to add a new feature next to the attach button that is like send message after attached, so if they are uploading a big file the can leave and it will be sent automatically. - We MUST have an easy user interface. Fastmail has lots of features and they try to make it where you can do everything in 2 clicks or less. We need to try to do this. Fastmail is all bunched up and looks like shit though. We need to make ours more of a packed with features like fastmail, but spread out like AOL has or fastmail. This will attract all the old people and beginners of the internet who have just gotten off of AOL and moved to DSL Fastmail looks like it is only made for advanced users and is hard to get used to. We need to Have a main Navigation bar and which is on every page, which has all the mail icons that people use the most like, compose, inbox, addressbook, options, and the main Navagation bar should be on every page at the top.Then we wil have a subnavagation bar for each other page , for example, if you were to hit the calander icon on the main navagition bar that is on the top of EVERY page, then it would take you to the calander page and show you the calander and the subnavagation bar would have all the calander icons like add events ect. I was thinking, in IMP we could have the logo at the top left coner of the page, then on the top right we could have all the main navagation icons. Both the logo and the main navagitions would be o every sign page in IMP, so it would be easy to get around. Then the sub navagation bars coulkd go where the main navagition bar is now on IMP, understand? - Make a bounce button like fastmail.fm. This is how fastmail explains their bounce button: 'Bounce' takes the currently selected emails and sends back an email to the addresses the email(s) came from saying basically that 'the email address does not exist' in a standard internet email protocol way. Some more organised spammers remove these from their lists. After sending the bounce response, the messages are deleted." - If accessed with a browser, public folder is also a personal web-site, accessible at http://username.fastmail.fm - Provide tool allowing synchronization of Outlook Express etc address book with FastMail contacts, possibly using LDAP - Use JavaScript for browsers that support it to speed up many actions, such as searching through the address book - A general notification system, so you can send a pager message, SMS message, instant message, or short email eGroupWare over Horde reasons Linking: There is the "infolog" for linking items. An infolog item can be a to-do, call, or note. It can link to the addressbook, projects, calendar, or another infolog item. That is very flexible. Access Control: Under Preferences, there is a "Grant Access" link for the calendar, addressbook, infolog, and projects. It allows you to select Read, Add, Edit, Delete, and Private access for each group and each user. Again, very flexible. Categories: Multiple category selection is allowed in the addressbook, projects, calendar and infolog. Custom Fields: I can create custom fields. PHP_SELF Executive summary: PHP_SELF intentionally includes extra URL garbage (or valuable URL variables, take your pick) tacked on by the user. Don't use it without knowing what it does. Here's what you get when you hit the URL: http://example.com/info.php/testing1?testing2 : _SERVER["REQUEST_URI"] /info.php/testing1?testing2 _SERVER["PHP_SELF"] /info.php/testing1 _SERVER["SCRIPT_NAME"] /info.php Get it? If you don't want that extra stuff tacked on by the user, use the correct _SERVER variable. If you use REQUEST_URI or PHP_SELF, be aware the user can affect the contents of that variable. 99% of the time, you want SCRIPT_NAME, not PHP_SELF. By the way, here's another test: http://example.com/info.php/testing\