[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