Problem/Motivation

User wanted to patch D7 regarding the bootstrap process

Proposed resolution

It was decided to not apply the patch, but instead put information into the documentation for drupal_bootstrap()

Remaining tasks

Add documentation to http://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/drupal_bootstrap/7

API changes

Original report by [coolestdude1]

// Text of original report here.
I already have a fix for this and a follow up comment will supply a patch.
Basically to understand what is going on from D6 to D7.....
Drupal changed the way that files are included now to be more dynamic (this is perfectly fine and is actually great) problem is they only declare that variable in root level documents such as index.php and install.php etc.
When you are loading the bootstrap process from a file that is not one of those you will get a php fatal error on all bootstrapping that requires that variable.
Drupal processes bootstrapping of higher level phases by iterating over all previous phases until the specified level of bootstrapping is attained (this is from documentation).
Now I get that one way would be to include that in your 'other' file but that should not be common place we can fix this in core rather easily and painlessly without affecting other modules.

First off in my patch you will see that bootstrap.inc now has the variable definition in the right spot to be global to all of drupal. And the rest of the patch deals with the root level documents.

This patch makes sense to add to drupal as we are not redefining it in multiple places, so if I am in the wrong here please explain, I would be more than happy to further explain myself here, but for the most part it seems pretty strait forward.

NOTE: I do not know how to patch install.php, update.php those two files get real tricky real quick so maybe a supplement patch will have to be added for them. Otherwise you might get a duplicate definition warning.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

coolestdude1’s picture

Status: Active » Needs review
FileSize
3.34 KB

Here is the patch file

tstoeckler’s picture

Priority: Critical » Normal
Status: Needs review » Active

Please read the definition of the issue queue priority levels: http://drupal.org/node/45111
This is by no means critical.

The workflow for external scripts to bootstrap Drupal is:


define('DRUPAL_ROOT', '/path/to/drupal');
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_boostrap(DRUPAL_BOOTSTRAP_FULL);

Or something like that.
Please describe the problem you have with that.
Is the only problem the duplication of the definition of the constant in index.php, update.php, etc.? That doesn't seem to be much of a problem, I think.

tstoeckler’s picture

Status: Active » Needs review

Crosspost, so setting to "needs review". For me personally, this is a "won't fix", though. I think the code flow described in #2 is quite nice, because it allows other scripts to integrate with Drupal regardless of where Drupal is relative is to the script, simply by adapting DRUPAL_ROOT.

coolestdude1’s picture

Yup you are right about the priority, I guess what I mean by critical is mainly that this is an easy fix. But yeah my bad sorries.

My point in changing this is a couple of reasons
-Drupal should be as simple as possible to extend so as to promote community enhancements and contribs
-Moving the definition of DRUPAL_ROOT reduces code in other files making them easier to read/understand
-This workflow was undocumented in drupal_bootstrap
-It makes bootstrapping simpler
-Do we really want external devs changing DRUPAL_ROOT?
-Since this variable is for DRUPAL_ROOT drupal can easily create it and other devs will be non the wiser

tstoeckler’s picture

No harm taken. It is just that marking issues critical can stop development because of the issue queue thresholds: http://drupal.org/node/1201874

Regarding changing DRUPAL_ROOT, I meant the following: I develop an external script, which integrates with Drupal, then I can do write my script as I did in #2, and then tell people in my installation instructions: "Change the value of DRUPAL_ROOT to where your installation of Drupal is." I think that is better than: "Change the first part of the require_once line to point to the Drupal installation."

In the end it's a matter of taste, though.
See: http://drupal.org/node/259623 for additional considerations.

carlos8f’s picture

Status: Needs review » Closed (works as designed)

The whole purpose of DRUPAL_ROOT is to make it possible for cwd() to be a directory *other* than the Drupal root. The patch has define('DRUPAL_ROOT', getcwd()); inside bootstrap.inc, which is regressing to D6 thinking and clearly defeating the purpose. Nothing is broken here, unless it's a lack of documentation, which is a separate issue.

coolestdude1’s picture

Priority: Normal » Minor
Status: Closed (works as designed) » Active

carlos8f: I fail to see your point, if drupal is running it should know where it's working directory is and just create the variable. A dev should not have to change that variable unless we want to make this variable accessible inside of settings.php (blah at this). Also that call is directly from index.php and the other root entry points. In all that variable is declared multiple times to handle the same functionality.

I also want to mention that I may not have the right solution for everyone as I do have to change the entry points to defined paths. So maybe an even better solution is to check to see if the variable exists from the bootstrap perspective and then create it if it doesn't. This will make the only changed file bootstrap.inc in both d7 and d8, but it will also allow for proper bootstrapping to occur without fatals.

tstoeckler: I read over that issue and it all seems really good, I understand doing these globals speeds up the whole process minimally. I also agree it is tastes.

I want to keep this discussion going because it still does not seem right to me.

I am pushing this further down in priority as people seem to have mixed opinions myself included.

Also to note it changes bootstrapping
FROM

define('DRUPAL_ROOT', $_SERVER['DOCUMENT_ROOT']);
include_once DRUPAL_ROOT '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

TO

chdir($_SERVER['DOCUMENT_ROOT']);
include_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

Keeping in mind that this is being called from /sites/all/modules/modulefolder
So getcwd does not work here cause it will return the parent directory.

In either case we should make an effort to change the documentation to match whatever the decision of the community is.

carlos8f’s picture

Version: 7.x-dev » 8.x-dev
Category: bug » feature

I'm not going to play issue ping-pong. But just so we're clear, there is no bug here. And there's no chance of changing the D7 API a year after it was released, so please discuss new stuff in the context of D8.

tstoeckler’s picture

Title: Drupal Bootstrap fails on all bootstraping from non core file due to one variable the new DRUPAL_ROOT » Document how to bootstrap Drupal from other scripts.
Component: base system » documentation
Category: feature » task
Priority: Minor » Normal

Moving this to documentation.
I also think DRUPAL_ROOT is fine the way it is, but you are correct that #2 should be documented somewhere. I could swear that I have seen this somewhere before, but a quick search on d.o didn't reveal anything, so.
The API doc for drupal_bootstrap() says:

To access the Drupal database from a script without loading anything else, include bootstrap.inc and call drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE).

(http://api.drupal.org/api/drupal/core!includes!bootstrap.inc/function/dr...)
But I think that could be more explicit.
Also not sure, whether this should be online documentation or in-code or both.

tstoeckler’s picture

Title: Document how to bootstrap Drupal from other scripts. » Document how to bootstrap Drupal from other scripts

Fix title.

jhodgdon’s picture

Issue tags: +Novice, +Needs backport to D7

So it sounds like the proposed resolution here is to put the information from #2 into the documentation for drupal_bootstrap()? If so, I think this is a fine idea.

Then in addition if someone wants to write up an expanded page on the subject and put it into the online Community Documentation somewhere (somewhere below http://drupal.org/documentation that is), that would also be a fine idea.

Adding this information seems like a good Novice project?

coolestdude1’s picture

Roger that, alright I am updating my code to use this style. Thank you all very much, hopefully we can make this more clear for future devs that may want to bootstrap. Other than that the process works really well.

dandaman’s picture

Status: Active » Needs review
FileSize
802 bytes

I've taken the code from #2 and put it into a patch to the documentation of bootstrap.inc.

jhodgdon’s picture

Status: Needs review » Needs work

Umm. I think it should replace the sentence in the previous paragraph that says:

To access the Drupal database from a script without loading anything else, include bootstrap.inc and call drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE).

right?

dandaman’s picture

Maybe you're right. But I'd expect that there would be reasons to do a full bootstrap and also to do a database-only bootstrap in other cases. I'll admit that I've never done either of these; I'm just trying to help out the documentation in the event that I do need them and try to look it up.

tstoeckler’s picture

Maybe something like this:

In order to bootstrap Drupal from another PHP script, you can use this code:
@code
define('DRUPAL_ROOT', '/path/to/drupal');
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_boostrap(DRUPAL_BOOTSTRAP_FULL);
@endcode
In this example the Drupal installation to bootstrap is located at '/path/to/drupal'. If you only want to bootstrap the Drupal database you can use DRUPAL_BOOTSTRAP_DATABASE instead of DRUPAL_BOOTSTRAP_FULL. For a full description of the different bootstrap levels see the $phase argument below.
...
@param $phase
A Drupal bootstrap constant. The possible bootstrap levels are:
- DRUPAL_BOOTSTRAP_CONFIGURATION: Initializes configuration.
- DRUPAL_BOOTSTRAP_PAGE_CACHE: Tries to server a cached page.
- DRUPAL_BOOTSTRAP_DATABASE: Initializes the database layer.
- DRUPAL_BOOTSTRAP_VARIABLES: Initializes the variable system.
- DRUPAL_BOOTSTRAP_SESSION: Initializes session handling.
- DRUPAL_BOOTSTRAP_PAGE_HEADER: Sets up the page header.
- DRUPAL_BOOTSTRAP_LANGUAGE: Finds out the language of the page.
- DRUPAL_BOOTSTRAP_FULL: Fully loads Drupal. Validates and fixes input data.

I removed the 'fully' from the top sentence and referenced the $phase parameter for the bootstrap levels. There I documented all the levels explicitly. I think that is more obvious than the current documentation. The downside is that the in-code documentation of the constants is largely duplicated, but I think that is worth it. Also got rid of the word 'included' as that could be mistaken by the PHP include statement. I also added a note about the '/path/to/drupal' bit.

I can't be bothered to roll a patch right now, so just as text for now.

jhodgdon’s picture

I think that this wording (#16) would be good.

colette’s picture

Status: Needs work » Needs review
FileSize
1.84 KB

Here's a patch with the updated documentation.

Anonymous’s picture

Status: Needs review » Needs work

Looks pretty good! just a few code style issues, but should be pretty easy to fix

+++ b/core/includes/bootstrap.incundefined
@@ -1971,9 +1971,29 @@ function drupal_anonymous_user() {
+ * ¶

This line has a whitespace on it.

+++ b/core/includes/bootstrap.incundefined
@@ -1971,9 +1971,29 @@ function drupal_anonymous_user() {
+ * In this example the Drupal installation to bootstrap is located at ¶

Whitespace at the end of this line.

+++ b/core/includes/bootstrap.incundefined
@@ -1971,9 +1971,29 @@ function drupal_anonymous_user() {
+ *   - DRUPAL_BOOTSTRAP_FULL: Fully loads Drupal. Validates and fixes input
+ *   data.

Since this bullet point runs multiple lines, you will want to indent 'data' so that it lines up with the DRUPAL above.

-2 days to next Drupal core point release.

Anonymous’s picture

Having looked at this more, I think the original paragraph can be removed and the new paragraph can be changed to:

 * In this example the Drupal installation to bootstrap is located at 
 * '/path/to/drupal'. If you only want to bootstrap the Drupal database you can
 * use DRUPAL_BOOTSTRAP_DATABASE instead of DRUPAL_BOOTSTRAP_FULL. Each phase
 * adds to the previous one, so invoking a later phase automatically runs the
 * earlier phases as well. For a full description of the different bootstrap
 * levels see the $phase argument below.

This paragraph now includes the sentence from the original paragraph:

Each phase adds to the previous one, so invoking a later phase automatically runs the earlier phases as well.

The other parts of that paragraph seem to have been covered in the new text already.

tstoeckler’s picture

Since this needs a re-roll anyways:

+++ b/core/includes/bootstrap.inc
@@ -1971,9 +1971,29 @@ function drupal_anonymous_user() {
+ * description of the different bootstrap levels see the $phase argument below.

Since we do "@param" maybe we should call it "$phase parameter" instead of "$phase argument".

colette’s picture

Status: Needs work » Needs review
FileSize
2.17 KB

Here's the fixed version.

jhodgdon’s picture

Status: Needs review » Needs work

Ummm... Unless I am mistaken, we don't actually want to lose this line, which describes what this function does:

 /**
- * Ensures Drupal is bootstrapped to the specified phase.

We also don't want to lose this information that describes that earlier phases are automatically run if you request a later phase:

- * The bootstrap phase is an integer constant identifying a phase of Drupal
- * to load. Each phase adds to the previous one, so invoking a later phase
- * automatically runs the earlier phases as well. 

Oh, I see, it's been added to the paragraph about how to bootstrap Drupal. I don't think it belongs with that paragraph. It needs to be where it was, in its own paragraph, with the sample code afterwards.

Also, this line has a typo:

+ *   - DRUPAL_BOOTSTRAP_PAGE_CACHE: Tries to server a cached page.

server -> serve... I guess? It doesn't quite make sense to me, maybe could be rewritten to be clearer what it means.

Also, just below the fixed lines in this patch, I see:

 *   A boolean, set to FALSE if calling drupal_bootstrap from inside a
  *   function called from drupal_bootstrap (recursion).

Whenever a function is referred to in documentation, put () after the function name.

Anonymous’s picture

- * The bootstrap phase is an integer constant identifying a phase of Drupal
- * to load.

I suggested to colette that she remove this... is it just me, or is this a really awkward way to say this? Maybe something like:

Functions calling drupal_bootstrap should pass in one of the phase constants below. Each phase adds to the previous one, so invoking a later phase automatically runs the earlier phases as well.

jhodgdon’s picture

I think the suggested wording in #24 is better. Something like that could go into the @param $phase documentation actually... maybe saying:

 @param $phase
    A constant telling which phase to boostrap to. When you bootstrap to a particular phase, all earlier phases are run automatically. Possible values:
(list goes here)

That might still be a bit awkward... it's getting kind of late and my brain is not working well, but something similar should work, and I think putting it with the @param documentation makes more sense than having it above.

Albert Volkman’s picture

Status: Needs work » Needs review
FileSize
1.66 KB
1.84 KB

I *think* I caught all of the suggestions from above. Interdiff'd against #22.

jhodgdon’s picture

Status: Needs review » Needs work

Looks good! One thing to fix... This is an 8.x patch, so this line isn't correct:

+ *   require_once DRUPAL_ROOT . '/includes/bootstrap.inc';

The path should be core/includes.

Albert Volkman’s picture

Status: Needs work » Needs review
FileSize
554 bytes
1.85 KB

Yeah, that makes sense.

tstoeckler’s picture

Status: Needs review » Needs work
+++ b/core/includes/bootstrap.inc
@@ -2130,14 +2130,26 @@ function drupal_anonymous_user() {
+ *   - DRUPAL_BOOTSTRAP_LANGUAGE: Finds out the language of the page.

Sadly, I need to mark this "needs work" again. In the meantime our bootstrap constants have changed. Specifically DRUPAL_BOOTSTRAP_LANGUAGE was removed and at the same point (after _PAGE_HEADER and before _FULL) there should now be DRUPAL_BOOTSTRAP_CODE. The line should read:
"DRUPAL_BOOTSTRAP_CODE: Loads code for subsystems and modules."

Albert Volkman’s picture

Status: Needs work » Needs review
FileSize
1.04 KB
1.85 KB

Interdiff'd against #26.

tstoeckler’s picture

Status: Needs review » Reviewed & tested by the community

Awesome!

Tor Arne Thune’s picture

+++ b/core/includes/bootstrap.incundefined
@@ -2091,14 +2091,26 @@ function drupal_anonymous_user() {
+ *   A constant telling which phase to boostrap to. When you bootstrap to a

Typo: boostrap.

Albert Volkman’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
1.36 KB
1.85 KB

Fixed.

tim.plunkett’s picture

Status: Needs review » Reviewed & tested by the community

Good catch, @Tor Arne Thune.

jhodgdon’s picture

Version: 8.x-dev » 7.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Thanks all -- a real group effort here! I've committed the patch there to 8.x. The port to 7.x will need to have slightly different bootstrap constants in it, since the function is different there.

Albert Volkman’s picture

Status: Patch (to be ported) » Needs review
FileSize
1.82 KB

D7 backport.

tstoeckler’s picture

Status: Needs review » Reviewed & tested by the community

I verified that the bootstrap constants, including their order and their description are correct. Also the "core" directory is correctly removed from the example code include statement.

Looks good to me.

jhodgdon’s picture

Status: Reviewed & tested by the community » Fixed

Looks good to me too -- thanks all! Committed to 7.x.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

rmorelli’s picture

I must that the trick with
define('DRUPAL_ROOT', '/var/www/drupal');
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION);

doesn't always work out of the box.

eg. I am using it with PMapper but immediately after PMapper does complete all its includes, if not something in drupal_bootstrap fools PMapper as it tries to include from root filesystem (linux here) resulting in PMapper not loading.

rmorelli’s picture

Issue summary: View changes

updating issue summary