(bug 454) Merge e-notif 2.00
[lhc/web/wiklou.git] / includes / Skin.php
index 118f90c..ebb3018 100644 (file)
@@ -83,7 +83,15 @@ class Skin {
        /**#@-*/
 
        function Skin() {
-               $this->linktrail = wfMsgForContent('linktrail');
+               global $wgContLang;
+               $this->linktrail = $wgContLang->linkTrail();
+               
+               # Cache option lookups done very frequently
+               $options = array( 'highlightbroken', 'hover' );
+               foreach( $options as $opt ) {
+                       global $wgUser;
+                       $this->mOptions[$opt] = $wgUser->getOption( $opt );
+               }
        }
 
        function getSkinNames() {
@@ -255,7 +263,7 @@ class Skin {
                        # Force no underline
                        $s .= "a { text-decoration: none; }\n";
                }
-               if ( 1 == $wgUser->getOption( 'highlightbroken' ) ) {
+               if ( 1 == $this->mOptions['highlightbroken'] ) {
                        $s .= "a.new, #quickbar a.new { color: #CC2200; }\n";
                }
                if ( 1 == $wgUser->getOption( 'justify' ) ) {
@@ -293,7 +301,7 @@ class Skin {
        }
 
        function getExternalLinkAttributes( $link, $text, $class='' ) {
-               global $wgUser, $wgOut, $wgContLang;
+               global $wgContLang;
 
                $same = ($link == $text);
                $link = urldecode( $link );
@@ -303,20 +311,18 @@ class Skin {
 
                $r = ($class != '') ? " class='$class'" : " class='external'";
 
-               if ( !$same && $wgUser->getOption( 'hover' ) ) {
+               if( !$same && $this->mOptions['hover'] ) {
                        $r .= " title=\"{$link}\"";
                }
                return $r;
        }
 
        function getInternalLinkAttributes( $link, $text, $broken = false ) {
-               global $wgUser, $wgOut;
-
                $link = urldecode( $link );
                $link = str_replace( '_', ' ', $link );
                $link = htmlspecialchars( $link );
 
-               if ( $broken == 'stub' ) {
+               if( $broken == 'stub' ) {
                        $r = ' class="stub"';
                } else if ( $broken == 'yes' ) {
                        $r = ' class="new"';
@@ -324,7 +330,7 @@ class Skin {
                        $r = '';
                }
 
-               if ( 1 == $wgUser->getOption( 'hover' ) ) {
+               if( $this->mOptions['hover'] ) {
                        $r .= " title=\"{$link}\"";
                }
                return $r;
@@ -334,9 +340,7 @@ class Skin {
         * @param bool $broken
         */
        function getInternalLinkAttributesObj( &$nt, $text, $broken = false ) {
-               global $wgUser, $wgOut;
-
-               if ( $broken == 'stub' ) {
+               if( $broken == 'stub' ) {
                        $r = ' class="stub"';
                } else if ( $broken == 'yes' ) {
                        $r = ' class="new"';
@@ -344,7 +348,7 @@ class Skin {
                        $r = '';
                }
 
-               if ( 1 == $wgUser->getOption( 'hover' ) ) {
+               if( $this->mOptions['hover'] ) {
                        $r .= ' title="' . $nt->getEscapedText() . '"';
                }
                return $r;
@@ -531,9 +535,12 @@ class Skin {
                if ( $wgOut->isArticleRelated() ) {
                        if ( $wgTitle->getNamespace() == Namespace::getImage() ) {
                                $name = $wgTitle->getDBkey();
-                               $link = htmlspecialchars( Image::wfImageUrl( $name ) );
-                               $style = $this->getInternalLinkAttributes( $link, $name );
-                               $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
+                               $image = new Image( $wgTitle->getDBkey() );
+                               if( $image->exists() ) {
+                                       $link = htmlspecialchars( $image->getURL() );
+                                       $style = $this->getInternalLinkAttributes( $link, $name );
+                                       $s .= " | <a href=\"{$link}\"{$style}>{$name}</a>";
+                               }
                        }
                        # This will show the "Approve" link if $wgUseApproval=true;
                        if ( isset ( $wgUseApproval ) && $wgUseApproval )
@@ -790,8 +797,8 @@ class Skin {
        }
 
        function pageStats() {
-               global $wgOut, $wgLang, $wgArticle, $wgRequest;
-               global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax;
+               global $wgOut, $wgLang, $wgArticle, $wgRequest, $wgUser;
+               global $wgDisableCounters, $wgMaxCredits, $wgShowCreditsIfMax, $wgTitle, $wgPageShowWatchingUsers;
 
                extract( $wgRequest->getValues( 'oldid', 'diff' ) );
                if ( ! $wgOut->isArticle() ) { return ''; }
@@ -813,6 +820,17 @@ class Skin {
                    $s .= $this->lastModified();
                }
 
+               if ($wgPageShowWatchingUsers && $wgUser->getOption( 'shownumberswatching' )) {
+                       $dbr =& wfGetDB( DB_SLAVE );
+                       extract( $dbr->tableNames( 'watchlist' ) );
+                       $sql = "SELECT COUNT(*) AS n FROM $watchlist
+                               WHERE wl_title='" . $dbr->strencode($wgTitle->getDBKey()) .
+                               "' AND  wl_namespace=" . $wgTitle->getNamespace() ;
+                       $res = $dbr->query( $sql, 'Skin::pageStats');
+                       $x = $dbr->fetchObject( $res );
+                       $s .= ' ' . wfMsg('number_of_watching_users_pageview', $x->n );
+               }
+
                return $s . ' ' .  $this->getCopyright();
        }
 
@@ -1094,7 +1112,10 @@ class Skin {
                return $wgEnableEmail &&
                       $wgEnableUserEmail &&
                       0 != $wgUser->getID() && # show only to signed in users
-                      0 != $id; # can only email non-anons
+                      0 != $id; # we can only email to non-anons ..
+#                     '' != $id->getEmail() && # who must have an email address stored ..
+#                     0 != $id->getEmailauthenticationtimestamp() && # .. which is authenticated
+#                     1 != $wgUser->getOption('disablemail'); # and not disabled
        }
        
        function emailUserLink() {
@@ -1322,13 +1343,17 @@ class Skin {
        function makeLinkObj( &$nt, $text= '', $query = '', $trail = '', $prefix = '' ) {
                global $wgOut, $wgUser, $wgLinkHolders;
                $fname = 'Skin::makeLinkObj';
+               wfProfileIn( $fname );
 
                # Fail gracefully
                if ( ! isset($nt) ) {
                        # wfDebugDieBacktrace();
+                       wfProfileOut( $fname );
                        return "<!-- ERROR -->{$prefix}{$text}{$trail}";
                }
 
+               $ns = $nt->getNamespace();
+               $dbkey = $nt->getDBkey();
                if ( $nt->isExternal() ) {
                        $u = $nt->getFullURL();
                        $link = $nt->getPrefixedURL();
@@ -1348,60 +1373,68 @@ class Skin {
                        $t = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>";
                        $nr = array_push($wgInterwikiLinkHolders, $t);
                        $retVal = '<!--IWLINK '. ($nr-1) ."-->{$trail}";
-               } elseif ( 0 == $nt->getNamespace() && "" == $nt->getText() ) {
+               } elseif ( 0 == $ns && "" == $dbkey ) {
+                       # A self-link with a fragment; skip existence check.
                        $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
-               } elseif ( ( -1 == $nt->getNamespace() ) ||
-                               ( NS_IMAGE == $nt->getNamespace() ) ) {
+               } elseif ( ( NS_SPECIAL == $ns ) || ( NS_IMAGE == $ns ) ) {
+                       # These are always shown as existing, currently.
+                       # Special pages don't exist in the database; images may
+                       # occasionally be present when there is no description
+                       # page per se, so we always shown them.
                        $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
-               } else {
-                       if ( $this->postParseLinkColour() ) {
-                               $inside = '';
-                               if ( '' != $trail ) {
-                                       if ( preg_match( $this->linktrail, $trail, $m ) ) {
-                                               $inside = $m[1];
-                                               $trail = $m[2];
-                                       }
+               } elseif ( $this->postParseLinkColour ) {
+                       wfProfileIn( $fname.'-postparse' );
+                       # Insert a placeholder, and we'll work out the existence checks
+                       # in a big lump later.
+                       $inside = '';
+                       if ( '' != $trail ) {
+                               if ( preg_match( $this->linktrail, $trail, $m ) ) {
+                                       $inside = $m[1];
+                                       $trail = $m[2];
                                }
+                       }
 
-                               # Allows wiki to bypass using linkcache, see OutputPage::parseLinkHolders()
-                               $nr = array_push( $wgLinkHolders['namespaces'], $nt->getNamespace() );
-                               $wgLinkHolders['dbkeys'][] = $nt->getDBkey();
-                               $wgLinkHolders['queries'][] = $query;
-                               $wgLinkHolders['texts'][] = $prefix.$text.$inside;
-                               $wgLinkHolders['titles'][] = $nt;
+                       # These get picked up by Parser::replaceLinkHolders()
+                       $nr = array_push( $wgLinkHolders['namespaces'], $nt->getNamespace() );
+                       $wgLinkHolders['dbkeys'][] = $dbkey;
+                       $wgLinkHolders['queries'][] = $query;
+                       $wgLinkHolders['texts'][] = $prefix.$text.$inside;
+                       $wgLinkHolders['titles'][] =& $nt;
 
-                               $retVal = '<!--LINK '. ($nr-1) ."-->{$trail}";
+                       $retVal = '<!--LINK '. ($nr-1) ."-->{$trail}";
+                       wfProfileOut( $fname.'-postparse' );
+               } else {
+                       wfProfileIn( $fname.'-immediate' );
+                       # Work out link colour immediately
+                       $aid = $nt->getArticleID() ;
+                       if ( 0 == $aid ) {
+                               $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
                        } else {
-                               # Work out link colour immediately
-                               $aid = $nt->getArticleID() ;
-                               if ( 0 == $aid ) {
-                                       $retVal = $this->makeBrokenLinkObj( $nt, $text, $query, $trail, $prefix );
-                               } else {
-                                       $threshold = $wgUser->getOption('stubthreshold') ;
-                                       if ( $threshold > 0 ) {
-                                               $dbr =& wfGetDB( DB_SLAVE );
-                                               $s = $dbr->selectRow( 'cur', array( 'LENGTH(cur_text) AS x', 'cur_namespace',
-                                                       'cur_is_redirect' ), array( 'cur_id' => $aid ), $fname ) ;
-                                               if ( $s !== false ) {
-                                                       $size = $s->x;
-                                                       if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
-                                                               $size = $threshold*2 ; # Really big
-                                                       }
-                                                       $dbr->freeResult( $res );
-                                               } else {
+                               $threshold = $wgUser->getOption('stubthreshold') ;
+                               if ( $threshold > 0 ) {
+                                       $dbr =& wfGetDB( DB_SLAVE );
+                                       $s = $dbr->selectRow( 'cur', array( 'LENGTH(cur_text) AS x', 'cur_namespace',
+                                               'cur_is_redirect' ), array( 'cur_id' => $aid ), $fname ) ;
+                                       if ( $s !== false ) {
+                                               $size = $s->x;
+                                               if ( $s->cur_is_redirect OR $s->cur_namespace != 0 ) {
                                                        $size = $threshold*2 ; # Really big
                                                }
                                        } else {
-                                               $size = 1 ;
-                                       }
-                                       if ( $size < $threshold ) {
-                                               $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
-                                       } else {
-                                               $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
+                                               $size = $threshold*2 ; # Really big
                                        }
+                               } else {
+                                       $size = 1 ;
+                               }
+                               if ( $size < $threshold ) {
+                                       $retVal = $this->makeStubLinkObj( $nt, $text, $query, $trail, $prefix );
+                               } else {
+                                       $retVal = $this->makeKnownLinkObj( $nt, $text, $query, $trail, $prefix );
                                }
                        }
+                       wfProfileOut( $fname.'-immediate' );
                }
+               wfProfileOut( $fname );
                return $retVal;
        }
 
@@ -1455,8 +1488,6 @@ class Skin {
         * Pass a title object, not a title string
         */
        function makeBrokenLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
-               global $wgOut, $wgUser;
-
                # Fail gracefully
                if ( ! isset($nt) ) {
                        # wfDebugDieBacktrace();
@@ -1485,7 +1516,7 @@ class Skin {
                                $trail = $m[2];
                        }
                }
-               if ( $wgUser->getOption( 'highlightbroken' ) ) {
+               if ( $this->mOptions['highlightbroken'] ) {
                        $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
                } else {
                        $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>?</a>{$trail}";
@@ -1499,8 +1530,6 @@ class Skin {
         * Pass a title object, not a title string
         */
        function makeStubLinkObj( &$nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
-               global $wgOut, $wgUser;
-
                $link = $nt->getPrefixedURL();
 
                $u = $nt->escapeLocalURL( $query );
@@ -1517,7 +1546,7 @@ class Skin {
                                $trail = $m[2];
                        }
                }
-               if ( $wgUser->getOption( 'highlightbroken' ) ) {
+               if ( $this->mOptions['highlightbroken'] ) {
                        $s = "<a href=\"{$u}\"{$style}>{$prefix}{$text}{$inside}</a>{$trail}";
                } else {
                        $s = "{$prefix}{$text}{$inside}<a href=\"{$u}\"{$style}>!</a>{$trail}";
@@ -1913,7 +1942,6 @@ class Skin {
                return '<a href="'.$url.'"'.$style.'>'.$text.'</a>';
        }
 
-
        /**
         * This function is called by all recent changes variants, by the page history,
         * and by the user contributions list. It is responsible for formatting edit