[wp-trac] Re: [WordPress Trac] #2866: WP can't be used from a single source installation

WordPress Trac wp-trac at lists.automattic.com
Wed Jun 28 11:04:08 GMT 2006


#2866: WP can't be used from a single source installation
-------------------------+--------------------------------------------------
 Reporter:  RuddO        |        Owner:  anonymous
     Type:  enhancement  |       Status:  new      
 Priority:  normal       |    Milestone:           
Component:  General      |      Version:           
 Severity:  normal       |   Resolution:           
 Keywords:               |  
-------------------------+--------------------------------------------------
Comment (by RuddO):

 OK.  Let's recap.  This bug touches two different (and sensitive issues):

 == ISSUE 1: THE WP-CONFIG ISSUE IN WP CORE ==

 say we have A: a pristine WP source dir
 say we have B, C, D: three different Apache DocumentRoots, targets for WP

 How can we work with a single source dir, instead of having to manually
 propagate changes from B into A, C, D?

 Answer: UNIX symlinks.  Make B, C and D be full with folders and symlinks
 to A's contents, as an exact mirror.  Then place a wp-config.php file on
 B, C and D.

 Results?  Edit a file in A, and B C D see the updates.  The same applies
 in all other directions.  Add one level of indirection (say, make A a
 mirror of a WP 2.0.3 source tree) and a bit of care, and you're set for
 nearly atomic WP updates (zero downtime) because you can later on swap A
 for A', which may be a symlink mirror of WP 2.1 source.

 (the actual case is actually much, much more complicated -- but fully
 automated now -- since I'm integrating disparate wp-contents, wp-
 content/themes and wp-content/plugins for each DocumentRoot, but this is
 the fundamental principle.  I only mention this to show that it isn't
 actually possible to build a conditional wp-config.php because the three
 sites must have different contents and some of those contents come from a
 disparate branch checkouts, but some of those contents are shared,
 including pristine WP core and a base of free plugins which undergo
 constant updates and bug fixes by me.  No, I can't start checking wp-
 configs.php into my SVN repos - that would be asking for real trouble with
 my customers in a few days - plus wp-config.php is CONFIG, not APP code -
 it doesn't just belong in an app repo.)

 The fact that WP includes wp-config.php using __FILE__ which does not work
 when the WP source directory is a tree of symlinks, because for some
 reason __FILE__ will point to the symlink target instead of the symlink.
 Since __FILE__ points to the real file, dirname(__FILE__) . "/../" usually
 points to the file's parent directory instead of the "symlink mirror dir"
 with the actual wp-config.php.  Obviously, wp-config.php does not exist in
 the actual source drop which is taken as a model to build the symlink
 mirror.  The *only* way to get wp-config.php is to look at the output of
 getcwd(), which apart from being faster than dirname() calls, actually
 uses the CWD (current working dir) - which is correct for symlink shadow
 copies.

 The tree of symlinks is used over here *a lot* to avoid duplication of
 files and work on single source checkouts (and it should also be used in
 large hosting farms, because this lets people upgrade their WP atomically
 - a big boon in large hosting farms again).  This in practice means that
 as I update one site's code, the others automatically get the fix, without
 me needing to manually merge changes in N repositories.

 Of course, with a tree of symlinks, five or ten different Web sites can
 run from a single source checkout.  Imagine making N WP's running off N
 databases, without actually having to manage separate source drops...
 BTW, If someone is reading this and wants to save a huge amount of disk
 space and money in his big, big WP deployment, sure, e-mail me (rudd-o at
 rudd-o dot com) and I'll do it for you at fair rates ;-).  I built the
 software to create and automate this task.

 == ISSUE 2: PLUGINS USING THE __FILE__ METHOD ==

 Of course, fixing wpcore was the easy part (a few greps and seds, and
 that's it).  But I later discovered that the Widgets plugin was not
 working on my newly setup blogs.  I couldn't drag or drop any sidebar
 widgets.  I took the time to inspect the source of the admin page, and, lo
 and behold, script language=javascript
 src=/home/rudd-o/Projects/Websites/...

 I said "what the HELL?  How can a plugin be issuing an HTML resource
 request with an absolute path?

 The culprit was the source lines I changed on the plugin (you can see the
 diff).  What was going on?  Simple.  The widgets plugin was attempting to
 determine its wp-content public directory (to load the JS files) by
 str_replacing dirname(__FILE__) with get_settings(siteurl).  Forgetting
 for a moment that this is hackish (to say the least) and it might lead to
 problems under certain setups, I posit the following:

 All plugins that use this method are broken.  BRO-KEN.  By design.  In
 other words, it's a really dumb idea.

 Why?  Because str_replace(dirname__FILE__ with siteurl) can't be assumed
 to yield the right URL.

 - odd WP installation paths or Apache mappings can make the replacement
 useless
 - *of course* __FILE__ may very well be a symlink, but __FILE__ will point
 to the actual file.  If you have your WP source at /home/r/wpsource and
 you have your DocumentRoot be a symlink shadow, the replacement won't work
 at all.

 Basically the Widgets plugin as it currently stands punts the issue,
 completely ignoring the fact that a file can have two completely ifferent
 paths on UNIX, and still be the same file.  PHP compounds the problem, of
 course.

 The fix I submitted for the Widgets plugin was the most reasonable
 compromise I could find.  It still dynamically computes its installation
 directory (while it should actually be traversing *up* the dir hier to
 find wp-content and then use the children dirs - a technique I've seen
 successfully used in countless plugins, and a technique that actually
 yields much better results than the one used in Widgets).

 Matt, what you just said about "other countless plugins" using the same
 technique... dude, that theory doesn't hold water.  The theory that
 countless other plugins are broken (and in my personal supercharged
 3rdparty plugin mishmash, so far I haven't found any that uses this
 technique) does NOT matter ZILCH in the face of the fact that Widgets also
 needs fixing.  I respect your opinion, but the "other boys do the same
 brokenness as well" argument just doesn't fly with me :-)

 Ryan: your proposed solution can't work either because (if I understood
 you correctly) the actual source dir can't have a wp-config.php - it's a
 pristine source directory.

 I actually don't see a problem with the changeset I submitted (at least
 for the WP core changes).  It's short, it does not touch large amounts of
 files, the changes it introduces are localized... I've tested it throughly
 and no bugs seemed to have arisen at all.

 If anything, advanced sysadmins have gained a new choice (choice that of
 course why should be denied?).  As I already stated, using __FILE__ in
 plugins to generate relative URLs in plugins is broken code that should
 not be relied upon and is asking for trouble.  They can of course just use
 getcwd() which throws correct results in all situations (except made for
 the wp-admin/ case where of course this can be tested for in a short one-
 liner or simply hard-coded depending on what the plugin wants to do).  By
 correct, I mean "what the sysadmin configured as DocumentRoot".

 Sorry for such a longish reply.  I felt I had to explain the motivations
 in deep detail.  I also meant to call the attention of you guys to this
 seemingly okay __FILE__ issue (most of the uses of __FILE__ in WP are fine
 and dandy, and that's why you didn't see me changing them all - I just
 changed the ones pertaining to wp-config and of course the widgets
 plugin).

-- 
Ticket URL: <http://trac.wordpress.org/ticket/2866>
WordPress Trac <http://wordpress.org/>
WordPress blogging software


More information about the wp-trac mailing list