r23208 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r23207‎ | r23208 | r23209 >
Date:11:21, 22 June 2007
Author:mkroetzsch
Status:old
Tags:
Comment:
New printers for novel query architecture. All old printers converted.
Modified paths:
  • /trunk/extensions/SemanticMediaWiki/includes/SMW_QueryPrinters.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticMediaWiki/includes/SMW_QueryPrinters.php
@@ -20,7 +20,6 @@
2121 protected $mLinkOthers; // should article names of other columns (besides the first) be linked?
2222 protected $mDefault = ''; // default return value for empty queries
2323 protected $mShowHeaders = true; // should the headers (property names) be printed?
24 - protected $mMainLabel = NULL; // label used for displaying the subject, or NULL if none was given
2524 protected $mInline; // is this query result "inline" in some page (only then a link to unshown results is created, error handling may also be affected)
2625 protected $mLinker; // Linker object as needed for making result links. Might come from some skin at some time.
2726
@@ -87,9 +86,6 @@
8887 $this->mShowHeaders = true;
8988 }
9089 }
91 - if (array_key_exists('mainlabel', $params)) {
92 - $this->mMainLabel = htmlspecialchars($params['mainlabel']);
93 - }
9490 }
9591
9692 /**
@@ -185,7 +181,7 @@
186182 SMWResultPrinter::readParameters($params);
187183
188184 if (array_key_exists('sep', $params)) {
189 - $this->mSep = htmlspecialchars($params['sep']);
 185+ $this->mSep = htmlspecialchars(str_replace('_',' ',$params['sep']));
190186 }
191187 if (array_key_exists('template', $params)) {
192188 $this->mSep = $params['template'];
@@ -306,9 +302,388 @@
307303 }
308304
309305
 306+/**
 307+ * New implementation of SMW's printer for timeline data.
 308+ */
 309+class SMWTimelineResultPrinter extends SMWResultPrinter {
310310
 311+ protected $m_tlstart = ''; // name of the start-date property if any
 312+ protected $m_tlend = ''; // name of the end-date property if any
 313+ protected $m_tlsize = ''; // CSS-compatible size (such as 400px)
 314+ protected $m_tlbands = ''; // array of band IDs (MONTH, YEAR, ...)
 315+ protected $m_tlpos = ''; // position identifier (start, end, today, middle)
311316
 317+ protected function readParameters($params) {
 318+ SMWResultPrinter::readParameters($params);
312319
 320+ if (array_key_exists('timelinestart', $params)) {
 321+ $this->m_tlstart = smwfNormalTitleDBKey($params['timelinestart']);
 322+ }
 323+ if (array_key_exists('timelineend', $params)) {
 324+ $this->m_tlstart = smwfNormalTitleDBKey($params['timelineend']);
 325+ }
 326+ if (array_key_exists('timelinesize', $params)) {
 327+ $this->m_tlsize = htmlspecialchars(str_replace(';', ' ', strtolower($params['timelinesize'])));
 328+ // str_replace makes sure this is only one value, not mutliple CSS fields (prevent CSS attacks)
 329+ } else {
 330+ $this->m_tlsize = '300px';
 331+ }
 332+ if (array_key_exists('timelinebands', $params)) {
 333+ //check for band parameter, should look like "DAY,MONTH,YEAR"
 334+ $this->m_tlbands = preg_split('/[,][\s]*/',$params['timelinebands']);
 335+ } else {
 336+ $this->m_tlbands = array('MONTH','YEAR'); // TODO: check what default the JavaScript uses
 337+ }
 338+ if (array_key_exists('timelineposition', $params)) {
 339+ $this->m_tlpos = strtolower($params['timelineposition']);
 340+ } else {
 341+ $this->m_tlpos = 'middle';
 342+ }
 343+ }
 344+
 345+ public function getHTML($res) {
 346+ global $smwgIQRunningNumber;
 347+
 348+ $eventline = ('eventline' == $this->mFormat);
 349+
 350+ if ( !$eventline && ($this->m_tlstart == '') ) { // seek defaults
 351+ foreach ($res->getPrintRequests() as $pr) {
 352+ if ( ($pr->getMode() == SMW_PRINT_ATTS) && ($pr->getDatavalue()->getTypeID() == 'datetime') ) {
 353+ if ( ($this->m_tlend == '') && ($this->m_tlstart != '') &&
 354+ ($this->m_tlstart != $pr->getTitle()->getText()) ) {
 355+ $this->m_tlend = $pr->getTitle()->getText();
 356+ } elseif ( ($this->m_tlstart == '') && ($this->m_tlend != $pr->getTitle()->getText()) ) {
 357+ $this->m_tlstart = $pr->getTitle()->getText();
 358+ }
 359+ }
 360+ }
 361+ }
 362+
 363+ // print header
 364+ $result = "<div class=\"smwtimeline\" id=\"smwtimeline$smwgIQRunningNumber\" style=\"height: $this->m_tlsize\">";
 365+ $result .= '<span class="smwtlcomment">' . wfMsgForContent('smw_iq_nojs',$res->getQueryURL()) . '</span>'; // note for people without JavaScript
 366+
 367+ foreach ($this->m_tlbands as $band) {
 368+ $result .= '<span class="smwtlband">' . htmlspecialchars($band) . '</span>';
 369+ //just print any "band" given, the JavaScript will figure out what to make of it
 370+ }
 371+
 372+ // print all result rows
 373+ $positions = array(); // possible positions, collected to select one for centering
 374+ $curcolor = 0; // color cycling is used for eventline
 375+ if ( ($this->m_tlstart != '') || $eventline ) {
 376+ $output = false; // true if output for the popup was given on current line
 377+ if ($eventline) $events = array(); // array of events that are to be printed
 378+ while ( $row = $res->getNext() ) {
 379+ $hastime = false; // true as soon as some startdate value was found
 380+ $hastitle = false; // true as soon as some label for the event was found
 381+ $curdata = ''; // current *inner* print data (within some event span)
 382+ $curmeta = ''; // current event meta data
 383+ $curarticle = ''; // label of current article, if it was found; needed only for eventline labeling
 384+ $first_col = true;
 385+ foreach ($row as $field) {
 386+ $first_value = true;
 387+ $pr = $field->getPrintRequest();
 388+ while ( ($object = $field->getNextObject()) !== false ) {
 389+ // Obtain string value ...
 390+ // TODO: this would be simpler with uniform Datavalue usage
 391+ $urlobject = false; // is our current object having a URL representation string?
 392+ if ($object instanceof SMWDataValue) { //print data values
 393+ $objectlabel = $object->getShortHTMLText(NULL); // TODO: support linked datavalues once
 394+ } elseif ($object instanceof Title) { // print Title objects
 395+ if ($this->getLinker($first_col) === NULL) {
 396+ $objectlabel = htmlspecialchars($object->getPrefixedText());
 397+ } else {
 398+ $urlobject = true;
 399+ if ($pr->getMode() == SMW_PRINT_THIS) { // "this" results must exist
 400+ $objectlabel = $this->getLinker($first_col)->makeKnownLinkObj($object);
 401+ } else {
 402+ $objectlabel = $this->getLinker($first_col)->makeLinkObj($object);
 403+ }
 404+ }
 405+ } // ... done.
 406+ $header = '';
 407+ if ($first_value) {
 408+ // find header for current value:
 409+ if ( $this->mShowHeaders && ('' != $pr->getLabel()) ) {
 410+ $header = $pr->getHTMLText($this->mLinker) . ' ';
 411+ }
 412+ // is this a start date?
 413+ if ( ($pr->getMode() == SMW_PRINT_ATTS) &&
 414+ ($pr->getTitle()->getText() == $this->m_tlstart) ) {
 415+ //FIXME: Timeline scripts should support XSD format explicitly. They
 416+ //currently seem to implement iso8601 which deviates from XSD in cases.
 417+ //NOTE: We can assume $object to be an SMWDataValue in this case.
 418+ $curmeta .= '<span class="smwtlstart">' . $object->getXSDValue() . '</span>';
 419+ $positions[$object->getNumericValue()] = $object->getXSDValue();
 420+ $hastime = true;
 421+ }
 422+ // is this the end date?
 423+ if ( ($pr->getMode() == SMW_PRINT_ATTS) &&
 424+ ($pr->getTitle()->getText() == $this->m_tlend) ) {
 425+ //NOTE: We can assume $object to be an SMWDataValue in this case.
 426+ $curmeta .= '<span class="smwtlend">' . $object->getXSDValue() . '</span>';
 427+ }
 428+ // find title for displaying event
 429+ if ( !$hastitle ) {
 430+ if ($urlobject) {
 431+ $curmeta .= '<span class="smwtlurl">' . $objectlabel . '</span>';
 432+ } else {
 433+ $curmeta .= '<span class="smwtltitle">' . $objectlabel . '</span>';
 434+ }
 435+ if ( ($pr->getMode() == SMW_PRINT_THIS) ) {
 436+ // NOTE: type Title of $object implied
 437+ $curarticle = $object->getText();
 438+ }
 439+ $hastitle = true;
 440+ }
 441+ } elseif ($output) $curdata .= ', '; //it *can* happen that output is false here, if the subject was not printed (fixed subject query) and mutliple items appear in the first row
 442+ if (!$first_col || !$first_value || $eventline) {
 443+ $curdata .= $header . $objectlabel;
 444+ $output = true;
 445+ }
 446+ if ($eventline && ($pr->getMode() == SMW_PRINT_ATTS) && ($pr->getDatavalue()->getTypeID() == 'datetime') && ('' != $pr->getLabel()) && ($pr->getTitle()->getText() != $this->m_tlstart) && ($pr->getTitle()->getText() != $this->m_tlend) ) {
 447+ $events[] = array($object->getXSDValue(), $pr->getLabel(), $object->getNumericValue());
 448+ }
 449+ $first_value = false;
 450+ }
 451+ if ($output) $curdata .= "<br />";
 452+ $output = false;
 453+ $first_col = false;
 454+ }
 455+
 456+ if ( $hastime ) {
 457+ $result .= '<span class="smwtlevent">' . $curmeta . '<span class="smwtlcoloricon">' . $curcolor . '</span>' . $curdata . '</span>';
 458+ }
 459+ if ( $eventline ) {
 460+ foreach ($events as $event) {
 461+ $result .= '<span class="smwtlevent"><span class="smwtlstart">' . $event[0] . '</span><span class="smwtlurl">' . $event[1] . '</span><span class="smwtlcoloricon">' . $curcolor . '</span>';
 462+ if ( $curarticle != '' ) $result .= '<span class="smwtlprefix">' . $curarticle . ' </span>';
 463+ $result .= $curdata . '</span>';
 464+ $positions[$event[2]] = $event[0];
 465+ }
 466+ $events = array();
 467+ $curcolor = ($curcolor + 1) % 10;
 468+ }
 469+ }
 470+ ksort($positions);
 471+ $positions = array_values($positions);
 472+ switch ($this->m_tlpos) {
 473+ case 'start':
 474+ $result .= '<span class="smwtlposition">' . $positions[0] . '</span>';
 475+ break;
 476+ case 'end':
 477+ $result .= '<span class="smwtlposition">' . $positions[count($positions)-1] . '</span>';
 478+ break;
 479+ case 'today': break; // default
 480+ case 'middle': default:
 481+ $result .= '<span class="smwtlposition">' . $positions[ceil(count($positions)/2)-1] . '</span>';
 482+ break;
 483+ }
 484+ }
 485+ //no further results displayed ...
 486+
 487+ // print footer
 488+ $result .= "</div>";
 489+ return $result;
 490+ }
 491+}
 492+
 493+
 494+/**
 495+ * Printer for template data. Passes a result row as anonymous parameters to
 496+ * a given template (which might ignore them or not) and prints the result.
 497+ */
 498+class SMWTemplateResultPrinter extends SMWResultPrinter {
 499+
 500+ protected $m_template;
 501+
 502+ protected function readParameters($params) {
 503+ SMWResultPrinter::readParameters($params);
 504+
 505+ if (array_key_exists('template', $params)) {
 506+ $this->m_template = $params['template'];
 507+ } else {
 508+ $this->m_template = false;
 509+ }
 510+ }
 511+
 512+ public function getHTML($res) {
 513+ // handle factbox
 514+ global $smwgStoreActive, $wgTitle;
 515+
 516+ // print all result rows
 517+ if ($this->m_template == false) {
 518+ return 'Please provide parameter "template" for query to work.'; // TODO: internationalise, beautify
 519+ }
 520+
 521+ $old_smwgStoreActive = $smwgStoreActive;
 522+ $smwgStoreActive = false; // no annotations stored, no factbox printed
 523+
 524+ $parserinput = $this->mIntro;
 525+
 526+ $parser_options = new ParserOptions();
 527+ $parser_options->setEditSection(false); // embedded sections should not have edit links
 528+ $parser = new Parser();
 529+ while ( $row = $res->getNext() ) {
 530+ $wikitext = '';
 531+ $firstcol = true;
 532+ foreach ($row as $field) {
 533+ $wikitext .= "|";
 534+ $first = true;
 535+ while ( ($text = $field->getNextWikiText($this->getLinker($firstcol))) !== false ) {
 536+ if ($first) {
 537+ $first = false;
 538+ } else {
 539+ $wikitext .= ', ';
 540+ }
 541+ $wikitext .= $text;
 542+ }
 543+ $firstcol = false;
 544+ }
 545+ $parserinput .= '{{' . $this->m_template . str_replace('=','&#x007C;', $wikitext) . '}}'; // encode '=' for use in templates (templates fail otherwise)
 546+ }
 547+ $parserOutput = $parser->parse($parserinput, $wgTitle, $parser_options);
 548+ $result = $parserOutput->getText();
 549+ // show link to more results
 550+ if ($this->mInline && $res->hasFurtherResults()) {
 551+ $label = $this->mSearchlabel;
 552+ if ($label === NULL) { //apply defaults
 553+ $label = wfMsgForContent('smw_iq_moreresults');
 554+ }
 555+ if ($label != '') {
 556+ $result .= '<a href="' . $res->getQueryURL() . '">' . $label . '</a>';
 557+ }
 558+ }
 559+
 560+ $smwgStoreActive = $old_smwgStoreActive;
 561+ return $result;
 562+ }
 563+}
 564+
 565+
 566+/**
 567+ * Printer for embedded data.
 568+ * Embeds in the page output the contents of the pages in the query result set.
 569+ * Only the first column of the query is considered. If it is a page reference then that page's contents is embedded.
 570+ * The optional "titlestyle" formatting parameter can be used to apply a format to the headings for the page titles.
 571+ * If "titlestyle" is not specified, a <h1> tag is used.
 572+ * @author Fernando Correia
 573+ * @author Markus Kr�tzsch
 574+ */
 575+class SMWEmbeddedResultPrinter extends SMWResultPrinter {
 576+
 577+ protected $m_showhead;
 578+ protected $m_embedformat;
 579+
 580+ protected function readParameters($params) {
 581+ SMWResultPrinter::readParameters($params);
 582+
 583+ if (array_key_exists('embedonly', $params)) {
 584+ $this->m_showhead = false;
 585+ } else {
 586+ $this->m_showhead = true;
 587+ }
 588+ if (array_key_exists('embedformat', $params)) {
 589+ $this->m_embedformat = $params['embedformat'];
 590+ } else {
 591+ $this->m_embedformat = 'h1';
 592+ }
 593+ }
 594+
 595+ public function getHTML($res) {
 596+ // handle factbox
 597+ global $smwgStoreActive;
 598+ $old_smwgStoreActive = $smwgStoreActive;
 599+ $smwgStoreActive = false; // no annotations stored, no factbox printed
 600+
 601+ // print header
 602+ $result = $this->mIntro;
 603+
 604+ switch ($this->m_embedformat) {
 605+ case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6':
 606+ $footer = '';
 607+ $embstart = '';
 608+ $headstart = '<' . $this->m_embedformat . '>';
 609+ $headend = '</' . $this->m_embedformat . ">\n";
 610+ $embend = '';
 611+ break;
 612+ case 'ul': case 'ol':
 613+ $result .= '<' . $this->m_embedformat . '>';
 614+ $footer = '</' . $this->m_embedformat . '>';
 615+ $embstart = '<li>';
 616+ $headstart = '';
 617+ $headend = "<br />\n";
 618+ $embend = "</li>\n";
 619+ break;
 620+ }
 621+
 622+ // print all result rows
 623+ $parser_options = new ParserOptions();
 624+ $parser_options->setEditSection(false); // embedded sections should not have edit links
 625+ $parser = new Parser();
 626+
 627+ while ( $row = $res->getNext() ) {
 628+ $first_col = true;
 629+ foreach ($row as $field) {
 630+ if ( ($field->getPrintRequest()->getMode() == SMW_PRINT_RELS) ||
 631+ ($field->getPrintRequest()->getMode() == SMW_PRINT_THIS) ) { // ensure that we deal with titles
 632+ while ( ($object = $field->getNextObject()) !== false ) {
 633+ $result .= $embstart;
 634+ // create text version (this will improve with the unified datavalue framework) ...
 635+ if ($this->getLinker(true) === NULL) {
 636+ $text = htmlspecialchars($object->getPrefixedText());
 637+ } else {
 638+ if ($field->getPrintRequest()->getMode() == SMW_PRINT_THIS) { // "this" results must exist
 639+ $text = $this->getLinker(true)->makeKnownLinkObj($object);
 640+ } else {
 641+ $text = $this->getLinker(true)->makeLinkObj($object);
 642+ }
 643+ } // ... done
 644+ if ($this->m_showhead) {
 645+ $result .= $headstart . $text . $headend;
 646+ }
 647+ if ($object->getNamespace() == NS_MAIN) {
 648+ $articlename = ':' . $object->getText();
 649+ } else {
 650+ $articlename = $object->getPrefixedText();
 651+ }
 652+ $parserOutput = $parser->parse('{{' . $articlename . '}}', $object, $parser_options);
 653+ $result .= $parserOutput->getText();
 654+ $result .= $embend;
 655+ }
 656+ }
 657+ break; // only use first column for now
 658+ }
 659+ }
 660+
 661+ // show link to more results
 662+ if ($this->mInline && $res->hasFurtherResults()) {
 663+ $label = $this->mSearchlabel;
 664+ if ($label === NULL) { //apply defaults
 665+ $label = wfMsgForContent('smw_iq_moreresults');
 666+ }
 667+ if ($label != '') {
 668+ $result .= $embstart . '<a href="' . $res->getQueryURL() . '">' . $label . '</a>' . $embend ;
 669+ }
 670+ }
 671+ $result .= $footer;
 672+
 673+ $smwgStoreActive = $old_smwgStoreActive;
 674+ return $result;
 675+ }
 676+}
 677+
 678+
 679+
 680+
 681+
 682+
 683+
 684+
 685+
 686+
 687+
313688 ///////////////////////////////////////////////////////////////////////////////
314689 ///////////////////////////////////////////////////////////////////////////////
315690 ///////////////////////////////////////////////////////////////////////////////

Status & tagging log