Issue:Call to a member function getPrefixedDBkey() on a non-object

From FollowTheScore
Jump to: navigation, search
Description: Call to a member function getPrefixedDBkey() on a non-object
Extension / Version: DPL   /   1.7.3
Type / Status: Bug   /   open

Problem

From file version 20080505195057!Semeb_extensions.zip onwards, using mediawiki 1.12.0 I get this error when accessing any page that uses DPL:

Fatal error: Call to a member function getPrefixedDBkey() on a non-object in /var/www/mediawiki-1.12.0/includes/Preprocessor_DOM.php on line 972

Previous versions are OK.

Test Case

Test case now on this wiki (since upgrade to 1.13): paste the following into a page.

{{#dpl:
| uses=Template:Issue
| include={Issue}:Description,#Problem[200]
| table=class="wikitable sortable", Issue,Problem
}}

Ianb1469 19:26, 27 August 2008 (UTC)

Reply

I was able to track the problem down to two minimalistic files, called Xxx and Yyy. Xxx contains the following code

{{#dpl:
| titlematch=%Yyy%
| include=#X
}}

But the offending statement comes from the parser itself. Could you please try to involve those people who made the new parser?

Gero 21:19, 27 August 2008 (UTC)

Is there a test case that triggers this without using DPL then? Ianb1469 05:13, 28 August 2008 (UTC)

Unfortunately not, so far. Maybe I can shrink the code down, but I guess the effect can only be shown if one writes an extension which calls that parser function in a certain way. I am pretty sure that the calling code does not pass any corrupted paranmeters but this has still to be shown. Can you program or at least read php? Gero 06:59, 28 August 2008 (UTC)
No, I've never really programmed php. I've plenty of Ada, C and Perl experience, so I could probably make sense of it, but writing php definitely not. Ianb1469 18:52, 28 August 2008 (UTC)

Parser function only

Hi, I also have the same problem but I realised the error only appears when {{#dpl:}} syntax is used instead of <DPL></DPL>, which works correctly. -EmuWikiAdmin1 - July 19th 2008

Heading Inclusion

I realised that Line 972 was meant to threat some data related to heading and I tried removing the heading (=Heading Example=) from my list separators and it worked. So basically it's a problem with heading generation -EmuWikiAdmin1 - July 20th 2008

Yes, this seems to be the case. The first example triggers the bug, the second does not. (Mwiki 1.12, DPL 1.7.6)

Triggers bug:
{{#dpl:
| category=test
| include={template1}:name,#Chaptername
| table=class="wikitable sortable", X,Y,Z
}}

OK:
{{#dpl:
| category=test
| include={template1}:name
| table=class="wikitable sortable", X,Y,Z
}}

Ianb1469 00:33, 27 August 2008 (CEST)

Occurring in MW 1.13.0

I just started getting this problem after a MediaWiki 1.13.0 upgrade. Here is the DPL query in question:

{{#dpl:
|category = My category name
|format = ,\n=[[%PAGE%|%TITLE%]]=\n\n,,
|includepage = %0
|includetrim = true
|noresultsheader = No entries
|ordercollation = latin1_general_ci
|reset = templates
}}

All articles in the category are in the Template namespace.

The error is:

Fatal error: Call to a member function getPrefixedDBkey() on a non-object in ...\includes\parser\Preprocessor_DOM.php on line 994

The line is:

$titleText = $this->title->getPrefixedDBkey();

in function expand(). The above example worked fine in 1.12.0. --Maiden taiwan 16:10, 20 August 2008 (CEST)

Related Error Message

It may be unrelated, but it sometimes occurs with two other error messages (dpl 1.7.6_

Notice: Uninitialized string offset: 0 in /var/www/mediawiki-1.12.0/extensions/DynamicPageList-1.7.4/DynamicPageList2.php on line 2351

Notice: Uninitialized string offset: 0 in /var/www/mediawiki-1.12.0/extensions/DynamicPageList-1.7.4/DynamicPageList2.php on line 2351

Fatal error: Call to a member function getPrefixedDBkey() on a non-object in /var/www/mediawiki-1.12.0/includes/Preprocessor_DOM.php on line 972 Ianb1469 00:40, 27 August 2008 (CEST)

I also get this bug in MW 1.13.2

Fatal error: Call to a member function getPrefixedDBkey() on a non-object in ...../includes/parser/Preprocessor_DOM.php on line 994

It's when I try to save a page which is in a category (the categories have dpl). Will post more detail when I have time Jonathan 00:13, 6 October 2008 (UTC)

Update: it gives the error when I go to save the page, but MW has saved the page, and if I reload the page MW does display it correctly. Jonathan 00:19, 6 October 2008 (UTC)

But when I try to save a category page which contains a call to the template (which has the dpl) it won't save. Jonathan 00:23, 6 October 2008 (UTC)

Final update (I hope): It was when the page to be saved belonged to a category whose DPL page included part of that page; if the page to be saved would have had NO text included then the category broke. If that's not clear, then please do ask Jonathan 00:37, 6 October 2008 (UTC)

Same error with MW 1.13.2 and DPL 1.7.4

Some DPL work, some don't, I had to revert an upgrade quite late in testing after realizing that. PAges seem to have in common:

  • call with compact form {{#dpl...}}
  • all of them use the chapter inclusion function

Help ;-). --Ycombarnous 20:54, 7 December 2008 (UTC)

  • Note 1: I just tried with DPL 1.7.2, and everything seems to work fine there!??! --Ycombarnous 21:36, 7 December 2008 (UTC)
  • Note 2: I can confirm I have the same pattern in my DPL as XXX example from Ianb1469. I include chapters from page that have sub-chapters. Only in that case do I get the issue.
  • Note 3: and also confirm that using the <DPL></DPL> syntax, I don't get the same error, but sections from the included chapter do not show in new TOC, whereas it did before.
  • Note 4: when using debug=5 I get the proper wikitext in above Xxx example. Gah, this is getting me mad.
  • Note 5: I have no issue with #lsth usage, is that because it uses still the old parser? --Ycombarnous 22:30, 7 December 2008 (UTC)
  • Note 6: could this help: [1] ? --Ycombarnous 10:21, 8 December 2008 (UTC)

Reply

I invested a couple of hours and finally found out that a small change in one of the MediaWiki sources solves the problem. The change does not seam to produce any harm but it is certainly not the real solution of the problem.

Nevertheless I think my finding might help you:

look into includes/parser/Preprocessor_DOM.php; somewhere near line 990 you will find the following line: $titleText = $this->title->getPrefixedDBkey();

comment this line out and replace it by something like

       $titleText = '?????'; 

For me this patch works and I would like to know if it also works for you. If yes we should start further investigations ...

Gero 18:31, 9 December 2008 (UTC)

Test result

  • Thanks, indeed the page now displays. But unfortunately, for any section of this page I try to edit, I get know to the edit page of section X of page ?????'. So this breaks MW badly. --Ycombarnous 22:13, 9 December 2008 (UTC)
  • The issue looks as if the dpl did not get replaced by wikitext early enough in page parsing and validation.
  • Probably the best would be for you to look at lst extension. It is done by people pretty close to MW development, and they went through 1.12 issues. See [2], look for string 1.12. I didn't have the chance yet, but it would be worth including a section with chapters in a test page both with #lst and #dpl parser functions, to compare results (use #lst, not #lsth, as they say it has not been adapted to 1.12 yet).
  • Another idea could be when including chapters to replace sub-chapters by html H1, H2, H3, etc... tags before sending to preprocessor. This is what you do already for headingmode. Benefits:
    1. should fix the issue, as headingmode=H2 seem to work fine
    2. also should make included headings not editable and not part of TOC, which will avoid confusion when people try to edit a section that comes from an included page (MW section count got confused and you ended up editing another section)


Same Error on Mediawiki 13.2 and DPL 1.7.4

  1. I got the same error if i use the call syntax

    Extension:DynamicPageList (DPL), version 3.2.1: Error: No selection criteria found! You must use at least one of the following parameters: category, namespace, titlematch, linksto, uses, createdby, modifiedby, lastmodifiedby, or their 'not' variants


Extension:DynamicPageList (DPL), version 3.2.1: Warning: No results.

  1. Yes this problem can be solved by using <DPL> syntax.
  2. But then i got another problem:
%DPL-1.7.4-WARNING: Wrong '$0' parameter: 'randomseed'! Using default: '20081217'. Help: $0= .

DPL Syntax:

<DPL> category =Lesenswerter Artikel mode =none randomseed ={{#time:Ymd}} randomcount =1 include =* </DPL>

System:


I suspect, that this problem has something to do with the parsing and evaluation of the wikitext by Mediawiki.

Thanks for help. --Silversurfer 12:32, 17 December 2008 (UTC)

Same error with MW 13.3 and DPL 1.7.4

My example is

{{#dpl:
namespace=Template
|category=Contacts
|titlematch=Business Contacts (%
|format=,==%TITLE%==\n²{%TITLE%}²\n,,
}}

i.e. it selects a number of templates and shows for each template its title and contents (a very useful DPL application). This also triggers the error. A pragmatic workaround is replacing == by <h2> .. </h2>.

RV1971 12:56, 2 January 2009 (UTC)

Update?

Are there plans to fix this soon? This is a bad one. Thanks. Maiden taiwan 17:47, 14 January 2009 (UTC)

Proposed Solution

Could you please try to make the following patch within includes/parser/Preprocessor_DOM.php (somewhere near line 987):

         # Insert a heading marker only for <h> children of <root>
         # This is to stop extractSections from going over multiple tree levels
         if ( $contextNode->parentNode->nodeName == 'root'
                     && $this->parser->ot['html'] )
         {
	# Insert heading index marker
	$headingIndex = $contextNode->getAttribute( 'i' );
// !gs
	if (!is_object($this->title)) 	$titleText = 'abcxyz';
	else							$titleText = $this->title->getPrefixedDBkey();
//gs!						 
	$this->parser->mHeadings[] = array( $titleText, $headingIndex );
	$serial = count( $this->parser->mHeadings ) - 1;
	$marker = "{$this->parser->mUniqPrefix}-h-$serial-" . Parser::MARKER_SUFFIX;
		$count = $contextNode->getAttribute( 'level' );
	$s = substr( $s, 0, $count ) . $marker . substr( $s, $count );
						$this->parser->mStripState->general->setPair( $marker, '' );
	}

I hope this works. Gero 16:11, 23 January 2009 (UTC)

Nope, does not work

  • Users can still edit the sections included from DPL, and then they get on a new page called "abcxyz".
  • The only way around I see is to rewrite the include code the same way as LST was rewritten for 1.12 (probably code can be extracted from there). One has to work on the DOM, not the wikitext to fix this issue apparently. Unformatunately, this represents some hours/days of work.

Another proposal solution

						# Insert heading index marker
						$headingIndex = $contextNode->getAttribute( 'i' );
						
try{
	$titleText = $this->title->getPrefixedDBkey();
}catch(SomeClassError $AAAAAA){
}
					

						$this->parser->mHeadings[] = array( $titleText, $headingIndex );

Daro 16:36, 24 January 2009 (UTC)

Sorry, the proposed solution doesn't work in my environment. --Silversurfer 11:52, 16 February 2009 (UTC)

Same problem ...

... when using DPL to transclude the part of a page before the first heading. If the first heading is itself from a transcluded page (rather than coded as ==heading== in the page text) then this error displays.Jonathan 23:48, 29 January 2009 (UTC)


Next iteration ;-)

  1. Look for a file named Preprocessor_DOM.php in your wikihome/includes/parser/ directory.
  2. look for the following text near line 990
# Insert heading index marker
$headingIndex = $contextNode->getAttribute( 'i' );
  1. now add an if-block around the next piece of text (about 7 lines) which prevents this block from being executed if the title is not an object; the source code should look like this after your patch:
<code>
                # Insert a heading marker only for <h> children of <root>
                # This is to stop extractSections from going over multiple tree levels
                if ( $contextNode->parentNode->nodeName == 'root'
                     && $this->parser->ot['html'] )
                {
                    # Insert heading index marker
                    $headingIndex = $contextNode->getAttribute( 'i' );
 /* !DPL2 */        if (is_object($this->title))
 /* !DPL2 */        {
                        $titleText = $this->title->getPrefixedDBkey();
                        $this->parser->mHeadings[] = array( $titleText, $headingIndex );
                        $serial = count( $this->parser->mHeadings ) - 1;
                        $marker = "{$this->parser->mUniqPrefix}-h-$serial-" . Parser::MARKER_SUFFIX;
                        $count = $contextNode->getAttribute( 'level' );
                        $s = substr( $s, 0, $count ) . $marker . substr( $s, $count );
                        $this->parser->mStripState->general->setPair( $marker, '' );
 /* !DPL2 */        }
                }
                $out .= $s;
</code>

This patch should not do any harm to your wiki installation as it only prevents the parser from running into an exception.

If you only apply the patch described above you will see section edit links in the output which point to the page which contains the DPL statement. But the section numbers are numerically increased based on the amount of sections in the generated code - sop they will point to non-existing or wrong sections. Therefore you shoould use the NOEDITSECTION pragma (put two leading and two trailing underscores around NOEDITSECTION).


I applied the above patch to the wiki on this website and now we can test if this solves the problem (at least to some extent). See Test transclusion bug ..

Gero 19:13, 16 February 2009 (UTC)

Hi Gero ... your fix seems to work, but the real question is: Why this->title is not set. --Silversurfer 19:45, 16 February 2009 (UTC)
You are absolutely right, but I am afraif this will need more understanding of MW internals than I have or can afford to acquire ... Gero 20:41, 17 February 2009 (UTC)
There is a small problem with this solution. After Save page the redirect to the saved page don't work anymore. I see only a white page. But the save itself worked well. May be, that we have to much lines in the if statement ? --Silversurfer 21:42, 17 February 2009 (UTC)
Update. The white page after save was my fault. The fix work fine with mediawiki 13.2--Silversurfer 12:14, 21 February 2009 (UTC)

1.14.0 observations

My original issue was with saving a certain page which had a template that was being included in dpl elsewhere in my wiki. Updating to MediaWiki 1.4.0 entirely solved that issue for me, requiring no patching. Investigating this, here is the code in the new 1.14.0 Preprocessor_DOM.php

                    # Insert a heading marker only for <h> children of <root>
                    # This is to stop extractSections from going over multiple tree levels
                    if ( $contextNode->parentNode->nodeName == 'root'
                      && $this->parser->ot['html'] )
                    {
						# Insert heading index marker
						$headingIndex = $contextNode->getAttribute( 'i' );
						$titleText = $this->title->getPrefixedDBkey();
						$this->parser->mHeadings[] = array( $titleText, $headingIndex );
						$serial = count( $this->parser->mHeadings ) - 1;
						$marker = "{$this->parser->mUniqPrefix}-h-$serial-" . Parser::MARKER_SUFFIX;
						$count = $contextNode->getAttribute( 'level' );
						$s = substr( $s, 0, $count ) . $marker . substr( $s, $count );
						$this->parser->mStripState->general->setPair( $marker, '' );
					}
					$out .= $s;

However, the original "Call to a member function getPrefixedDBkey() on a non-object" issue is now seen on the other page which *does* have dpl code to build some tables. I'm using dpl to build tables of pages which contain a certain link. The offending code is:

{{#dpl:
 |namespace=
 |linksto=do
 |include=%0[1000]
 |includetrim=true
 |table=,Article,Text
 |count=3
}}

I can thin this down and reproduce the error with just this:

{{#dpl:
 |linksto=do
}}

And when re-testing, suddenly it's another dpl usage on that page which is acting up. I'm exploring. Now this works again...

{{#dpl:
 |linksto=do
}}

Something is odd.

I'm unable to explore more. When I try to use previously-valid code, I am now given a blank table with no entries. Example:

{{#dpl:
 |namespace=
 |linksto=do
 |include=%0[1000]
 |includetrim=true
 |table=,Article,Text
 |count=3
}}

The documentation is far too complicated for me to understand and troubleshoot the blank table or explore variations, so I'm just using this special:whatlinkshere/do kind of thing:

{{#dpl:
 |linksto=do
}}

I hope my notes help. anonguy9 15:15, 19 March 2009 (UTC)

Possible fix

I think I found a fix for this problem. Two, in fact. The source of the bug is this:

        return array( // normal parser needs to be coaxed to do further recursive processing
	        $parser->getPreprocessor()->preprocessToObj($dplresult, Parser::PTD_FOR_INCLUSION ),
	        "isChildObj" => true
        );

If I replace isChildObj with isLocalObj, it's fixed, but I'm not sure if this will introduce any other bugs:

        return array( // normal parser needs to be coaxed to do further recursive processing
	        $parser->getPreprocessor()->preprocessToObj($dplresult, Parser::PTD_FOR_INCLUSION ),
	        "isLocalObj" => true
        );

Alternatively, isChildObj requires a title:

  return array( // normal parser needs to be coaxed to do further recursive processing
    $parser->getPreprocessor()->preprocessToObj($dplresult, Parser::PTD_FOR_INCLUSION ),
    "isChildObj" => true,
    "title" => $parser->getTitle()
  );

although I think instead of $parser->getTitle() it should be the title of the article included. Nx 17:30, 25 April 2009 (UTC)

Thank you very much for this finding! As far as I can see (after some testing) the use of 'isLocalObj' solves the problem. The patch of one of the MW parser sources (which was my favourite solution so far) seems no longer to be required. I am going to adopt your fix in the next release. I will check which "title" is appropriate. Gero 05:20, 4 June 2009 (UTC)
If you use isLocalObj, title is not necessary. However, the [edit] links that appear when using include=* will point to the current article (and give errors when clicked). If you modify self::dynamicPageList to return the title of the included page, and use isChildObj, the [edit] links will actually work. Try this hardcoded example:
  return array( // normal parser needs to be coaxed to do further recursive processing
    $parser->getPreprocessor()->preprocessToObj($dplresult, Parser::PTD_FOR_INCLUSION ),
    "isChildObj" => true,
    "title" => Title::newFromText("Talk:Old_Homepage")
  );
then go here and the edit links will appear and work Nx 17:10, 6 June 2009 (UTC)

mw 1.14 and dpl 1.7.8

I am getting the following error,

PHP Fatal error: Call to a member function getPrefixedDBkey() on a non-object in C:\inetpub\wwwroot\mediawiki\includes\parser\Preprocessor_DOM.php on line 996 

I get this anytime I include this template for transclusion

Here are my template contents

 {{#dpl:
  |category       = {{{projectname}}}
  |notcategory    = Category
  |notcategory    = Features
  |include        = *
  |format         = {{{!}} class="wikitable" width="100%",\n{{!}}-\n{{!}}\n=%PAGE%=\n,,\n{{!}}}
}}
__TOC__
{{#dpl:
  |category       = {{{projectname}}}
  |notcategory    = Category
  |notcategory    = Projects
  |include        = *
  |format         = {{{!}} class="wikitable" width="100%",\n{{!}}-\n{{!}}\n=%PAGE%=\n,,\n{{!}}}
}} 

the odd thing is that expand templates extension is able to transclude it properly.

actually doing some more testing i am finding that its the second dpl function that is causing the problem. so it must be something about the pages i am transcluding?

if i set debug=5 on that function the page displays and the wiki text is proper. any thoughts at all?

changing line 949 of DynamicPageList2.php from:
"isChildObj" => true
to:
"isLocalObj" => true

worked!

-Jlbuser 19:48, 4 June 2009 (UTC)