00001 <?php
00002
00020 abstract class SMWQueryUI extends SpecialPage {
00026 protected $uiCore;
00027
00028 const ENABLE_AUTO_SUGGEST = true;
00029 const DISABLE_AUTO_SUGGEST = false;
00030
00044 public function execute( $p ) {
00045 global $wgOut, $wgRequest, $smwgQEnabled, $wgFeedClasses;
00046
00047 $this->setHeaders();
00048
00049 if ( !$smwgQEnabled ) {
00050 $wgOut->addHTML( '<br />' . wfMsg( 'smw_iq_disabled' ) );
00051 return;
00052 }
00053
00054
00055 $ajaxMode = $this->processFormatOptions( $wgRequest );
00056
00057
00058 if ( !$ajaxMode ) {
00059
00060 if ( $this->processQueryFormBox( $wgRequest ) !== false ) {
00061 $params = $this->processParams();
00062 $this->uiCore = SMWQueryUIHelper::makeForUI(
00063 $this->processQueryFormBox( $wgRequest ),
00064 $params, array(), false );
00065 if ( $this->uiCore->getQueryString() !== '' ) {
00066 $this->uiCore->execute();
00067 }
00068 } else {
00069 $this->uiCore = SMWQueryUIHelper::makeForInfoLink( $p );
00070 }
00071
00072
00073 if ( $this->isSyndicated() &&
00074 $this->uiCore->getQueryString() !== '' &&
00075
00076 method_exists( $wgOut, 'addFeedlink' ) &&
00077 array_key_exists( 'rss', $wgFeedClasses ) ) {
00078 $res = $this->uiCore->getResultObject();
00079 $link = $res->getQueryLink();
00080 $link->setParameter( 'rss', 'format' );
00081 $link->setParameter( $this->uiCore->getLimit(), 'limit' );
00082 $wgOut->addFeedLink( 'rss', $link->getURl() );
00083 }
00084
00085 $wgOut->addHTML( $this->makePage( $p ) );
00086 }
00087
00088
00089 SMWOutputs::commitToOutputPage( $wgOut );
00090 }
00091
00102 protected abstract function processParams();
00103
00111 protected abstract function makePage( $p );
00112
00119 public function isSyndicated() {
00120 return true;
00121 }
00122
00129 protected function getAskEmbedBox() {
00130 $result = '';
00131 if ( $this->uiCore->getQueryString() != "" ) {
00132 $result = Html::rawElement(
00133 'div',
00134 array( 'id' => 'inlinequeryembed' ),
00135 Html::rawElement(
00136 'div',
00137 array( 'id' => 'inlinequeryembedinstruct' ),
00138 wfMsg( 'smw_ask_embed_instr' )
00139 ) .
00140 Html::element( 'textarea',
00141 array( 'id' => 'inlinequeryembedarea',
00142 'readonly' => 'yes',
00143 'cols' => '20',
00144 'rows' => '6',
00145 'onclick' => 'this.select()'
00146 ),
00147 $this->uiCore->getAsk() )
00148 );
00149 }
00150 return $result;
00151 }
00152
00156 protected function getErrorsHtml() {
00157 $result = Html::openElement( 'ul' );
00158 $errors = $this->uiCore->getErrors();
00159 foreach ( $errors as $error ) {
00160 $result .= '<span class="smwwarning"><li>' . $error . '</li></span>';
00161 }
00162 $result .= '</ul>';
00163 return $result;
00164 }
00165
00169 protected function enableAutocompletion() {
00170 SMWOutputs::requireResource( 'jquery.ui.autocomplete' );
00171
00172 $javascriptAutocompleteText = <<<END
00173 <script type="text/javascript">
00174 function smw_split( val ) {
00175 return val.split( '\\n' );
00176 }
00177
00178 function smw_extractLast( term ) {
00179 return smw_split( term ).pop();
00180 }
00181
00182 function smw_escapeQuestion( term ){
00183 if ( term.substring( 0, 1 ) == "?" ) {
00184 return term.substring( 1 );
00185 } else {
00186 return term;
00187 }
00188 }
00189
00190
00191 jQuery.ui.autocomplete.prototype._renderItem = function( ul, item ) {
00192 var term_without_q = smw_escapeQuestion( smw_extractLast( this.term ) );
00193 var re = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term_without_q.replace("/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi", "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi");
00194 var loc = item.label.search( re );
00195 if ( loc >= 0 ) {
00196 var t = item.label.substr( 0, loc ) + '<strong>' + item.label.substr( loc, term_without_q.length ) + '</strong>' + item.label.substr( loc + term_without_q.length );
00197 } else {
00198 var t = item.label;
00199 }
00200 jQuery( "<li></li>" )
00201 .data( "item.autocomplete", item )
00202 .append( " <a>" + t + "</a>" )
00203 .appendTo( ul );
00204 };
00205
00207 jQuery.extend( jQuery.ui.autocomplete, {
00208 filter: function( array, term ) {
00209 var matcher = new RegExp( "\\\b" + jQuery.ui.autocomplete.escapeRegex( term ), "i" );
00210 return jQuery.grep( array, function( value ) {
00211 return matcher.test( value.label || value.value || value );
00212 } );
00213 }
00214 } );
00215 </script>
00216 END;
00217
00218 SMWOutputs::requireScript( 'smwAutocompleteQueryUICore', $javascriptAutocompleteText );
00219
00220 }
00221
00237 public function getNavigationBar( $limit, $offset, $hasFurtherResults ) {
00238 global $smwgQMaxInlineLimit, $wgLang;
00239
00240 if ( $offset > 0 ) {
00241 $this->setUrlArgs(
00242 array( 'offset' => max( 0, $offset - $limit ), 'limit' => $limit )
00243 );
00244 $navigation = Html::element(
00245 'a',
00246 array(
00247 'href' => $this->getTitle()->getLocalURL( wfArrayToCGI( $this->getUrlArgs() ) ),
00248 'rel' => 'nofollow'
00249 ),
00250 wfMsg( 'smw_result_prev' )
00251 );
00252
00253 } else {
00254 $navigation = wfMsg( 'smw_result_prev' );
00255 }
00256
00257 $navigation .=
00258 '     <b>' .
00259 wfMsg( 'smw_result_results' ) . ' ' . $wgLang->formatNum( $offset + 1 ) .
00260 ' - ' .
00261 $wgLang->formatNum( $offset + $this->uiCore->getResultCount() ) .
00262 '</b>    ';
00263
00264 if ( $hasFurtherResults ) {
00265 $this->setUrlArgs(
00266 array( 'offset' => max( 0, $offset + $limit ), 'limit' => $limit )
00267 );
00268 $navigation .= Html::element(
00269 'a',
00270 array(
00271 'href' => $this->getTitle()->getLocalURL( wfArrayToCGI( $this->getUrlArgs() ) ),
00272 'rel' => 'nofollow'
00273 ),
00274 wfMsg( 'smw_result_next' )
00275 );
00276 } else {
00277 $navigation .= wfMsg( 'smw_result_next' );
00278 }
00279
00280 $first = true;
00281
00282 foreach ( array( 20, 50, 100, 250, 500 ) as $l ) {
00283 if ( $l > $smwgQMaxInlineLimit ) break;
00284
00285 if ( $first ) {
00286 $navigation .= '        (';
00287 $first = false;
00288 } else {
00289 $navigation .= ' | ';
00290 }
00291
00292 if ( $limit != $l ) {
00293 $this->setUrlArgs( array( 'offset' => $offset, 'limit' => $l ) );
00294 $navigation .= Html::element(
00295 'a',
00296 array(
00297 'href' => $this->getTitle()->getLocalURL( wfArrayToCGI( $this->getUrlArgs() ) ),
00298 'rel' => 'nofollow'
00299 ),
00300 $wgLang->formatNum( $l, false )
00301 );
00302 } else {
00303 $navigation .= '<b>' . $wgLang->formatNum( $l ) . '</b>';
00304 }
00305 }
00306
00307 $navigation .= ')';
00308
00309 return $navigation;
00310 }
00311
00320 protected function getQueryFormBox() {
00321 $this->setUrlArgs( array( 'q' => $this->uiCore->getQueryString() ) );
00322 $result = '<div>' .
00323 Html::element( 'textarea',
00324 array( 'name' => 'q', 'id' => 'querybox', 'rows'=>'3' ),
00325 $this->uiCore->getQueryString()
00326 ) .
00327 '</div>';
00328 return $result;
00329 }
00330
00339 protected function processQueryFormBox( WebRequest $wgRequest ) {
00340 if ( $wgRequest->getCheck( 'q' ) ) {
00341 $query = $wgRequest->getVal( 'q' );
00342 return $query;
00343 } else {
00344 return false;
00345 }
00346 }
00347
00358 protected function processPoSortFormBox( WebRequest $wgRequest ) {
00359 global $smwgQSortingSupport, $wgContLang;
00360
00361 $params = array();
00362
00363 $orderValues = $wgRequest->getArray( 'order' );
00364 $propertyValues = $wgRequest->getArray( 'property' );
00365 $propertyLabelValues = $wgRequest->getArray( 'prop_label' );
00366 $propertyLimitValues = $wgRequest->getArray( 'prop_limit' );
00367 $propertyFormatValues = $wgRequest->getArray( 'prop_format' );
00368 $categoryValues = $wgRequest->getArray( 'category' );
00369 $categoryLabelValues = $wgRequest->getArray( 'cat_label' );
00370 $categoryYesValues = $wgRequest->getArray( 'cat_yes' );
00371 $categoryNoValues = $wgRequest->getArray( 'cat_no' );
00372 $mainColumnLabels = $wgRequest->getArray( 'maincol_label' );
00373
00374 $po = array();
00375
00376 $mainLabel = $wgRequest->getVal( 'pmainlabel', '' );
00377 $params['mainlabel'] = $mainLabel;
00378
00379
00380 if ( is_array( $mainColumnLabels ) ) {
00381 foreach ( $mainColumnLabels as $key => $label ) {
00382 if ( $label === '' ) {
00383 $po[$key] = "?";
00384 } else {
00385 $po[$key] = "? = $label";
00386 }
00387 }
00388 }
00389
00390 $categoryNamespace = $wgContLang->getNsText( NS_CATEGORY );
00391 if ( is_array( $categoryValues ) ) {
00392 foreach ( $categoryValues as $key => $value ) {
00393 if ( trim( $value ) === '' ) {
00394 $po[$key] = "?$categoryNamespace" ;
00395 } else {
00396 $po[$key] = "?$categoryNamespace:$value";
00397 if ( is_array( $categoryYesValues )
00398 && is_array( $categoryNoValues )
00399 && array_key_exists( $key, $categoryYesValues )
00400 && array_key_exists( $key, $categoryNoValues ) )
00401 {
00402 if ( $categoryYesValues[$key] !== ''
00403 && $categoryNoValues[$key] !== '' )
00404 {
00405 $po[$key] .= "#$categoryYesValues[$key],$categoryNoValues[$key]";
00406 }
00407 }
00408 }
00409 }
00410 }
00411 if ( is_array( $categoryLabelValues ) ) {
00412 foreach ( $categoryLabelValues as $key => $value ) {
00413 if ( trim( $value ) !== '' ) {
00414 $po[$key] .= ' = ' . $value;
00415 }
00416 }
00417 }
00418
00419 if ( is_array( $propertyValues ) ) {
00420 $params['sort'] = '';
00421 $params['order'] = '';
00422 foreach ( $propertyValues as $key => $propertyValue ) {
00423 $propertyValues[$key] = trim( $propertyValue );
00424 if ( $propertyValues[$key] === '' ) {
00425 unset( $propertyValues[$key] );
00426 }
00427 if ( $smwgQSortingSupport
00428 && is_array( $orderValues )
00429 && array_key_exists( $key, $orderValues )
00430 && $orderValues[$key] != 'NONE' )
00431 {
00432 $params['sort'] .= ( $params['sort'] !== '' ? ',':'' ) . $propertyValues[$key];
00433 $params['order'] .= ( $params['order'] !== '' ? ',':'' ) . $orderValues[$key];
00434 }
00435 }
00436 if ( $params['sort'] === '' ) {
00437 unset ( $params['sort'] );
00438 }
00439 if ( $params['order'] === '' ) {
00440 unset ( $params['order'] );
00441 }
00442 $displayValues = $wgRequest->getArray( 'display' );
00443 if ( is_array( $displayValues ) ) {
00444 foreach ( $displayValues as $key => $value ) {
00445 if ( $value == '1' && array_key_exists( $key, $propertyValues ) ) {
00446 $propertyValues[$key] = '?' . trim( $propertyValues[$key] );
00447 if ( is_array( $propertyFormatValues )
00448 && array_key_exists( $key, $propertyFormatValues )
00449 && $propertyFormatValues[$key] !== '' )
00450 {
00451 $propertyValues[$key] .= '#' . $propertyFormatValues[$key];
00452 }
00453 if ( is_array( $propertyLabelValues )
00454 && array_key_exists( $key, $propertyLabelValues )
00455 && $propertyLabelValues[$key] !== '' )
00456 {
00457 $propertyValues[$key] .= ' = ' . $propertyLabelValues[$key];
00458 }
00459 if ( is_array( $propertyLimitValues )
00460 && array_key_exists( $key, $propertyLimitValues )
00461 && $propertyLimitValues[$key] !== '' )
00462 {
00463
00464 $po[] = $propertyValues[$key];
00465 $po[] = '+limit=' . $propertyLimitValues[$key];
00466 } else {
00467 $po[$key] = $propertyValues[$key];
00468 }
00469 }
00470 }
00471 }
00472 }
00473 ksort( $po );
00474 if ( $smwgQSortingSupport ) {
00475 $po = array_merge( $params, $po );
00476 }
00477 return $po;
00478 }
00479
00493 protected function getPoSortFormBox( $enableAutocomplete = SMWQueryUI::ENABLE_AUTO_SUGGEST ) {
00494 global $smwgQSortingSupport, $wgRequest, $smwgScriptPath;
00495 global $smwgQRandSortingSupport, $smwgQPrintoutLimit;
00496
00497 SMWOutputs::requireResource( 'jquery.ui.autocomplete' );
00498 SMWOutputs::requireResource( 'jquery.ui.dialog' );
00499 SMWOutputs::requireResource( 'ext.smw.style' );
00500
00501 $result = '<span id="smwposortbox">';
00502 $params = $this->uiCore->getParameters();
00503
00504
00505 if ( is_array( $params ) && array_key_exists( 'mainlabel', $params ) ) {
00506 $mainLabel = $params['mainlabel'];
00507 } else {
00508 $mainLabel = '';
00509 }
00510 if ( $mainLabel == '-' ) {
00511 $mainLabelText = '';
00512 $formDisplay = 'none';
00513 } else {
00514 $mainLabelText = $mainLabel;
00515 $formDisplay = 'block';
00516 }
00517 $result .= Html::openElement(
00518 'div',
00519 array( 'id' => 'smwmainlabel',
00520 'class' => 'smwsort',
00521 'style' => "display:$formDisplay;" )
00522 ) .
00523 Html::openElement( 'span',
00524 array( 'class' => 'smwquisortlabel' ) ) .
00525 Html::openElement( 'span',
00526 array( 'class' => 'smw-remove' ) ) .
00527 Html::openElement( 'a',
00528 array( 'href' => 'javascript:smwRemoveMainLabel()' ) ) .
00529 '<img src="' . $smwgScriptPath . '/skins/images/close-button.png" alt="' . wfMsg( 'smw_qui_delete' ) . '">' .
00530 '</a>' .
00531 '</span><strong>' .
00532 wfMsg( 'smw_qui_rescol' ) .
00533 '</strong></span>' .
00534 Xml::openElement( 'div',
00535 array( 'id' => 'mainlabel-dialog',
00536 'title' => wfMsg( 'smw_qui_mainlabopts' ),
00537 'class' => 'smwmainlabdialog' )
00538 ) .
00539 '<table align="center" ><tr>' .
00540 '<td>' . wfMsg( 'smw_qui_dlabel' ) . '</td>' .
00541 '<td><input size="25" value="' . $mainLabelText . '" id="mainlabelvis" /></td>' .
00542 '</tr></table>' .
00543 '</div>' .
00544 '<input type="hidden" name="pmainlabel" value="' . $mainLabel . '" id="mainlabelhid" /> ' .
00545 '<a class="smwq-more" href="javascript:smw_makeMainlabelDialog()">' . wfMsg( 'smw_qui_options' ) . '</a> ' .
00546 '</div>';
00547 $urlArgs = array();
00548 $urlArgs['pmainlabel'] = $mainLabel;
00549
00550
00551
00552 $propertyValues = $wgRequest->getArray( 'property', array() );
00553 $propertyLabelValues = $wgRequest->getArray( 'prop_label', array() );
00554 $propertyFormatValues = $wgRequest->getArray( 'prop_format', array() );
00555 $propertyLimitValues = $wgRequest->getArray( 'prop_limit', array() );
00556 $orderValues = $wgRequest->getArray( 'order', array() );
00557 $displayValues = $wgRequest->getArray( 'display', array() );
00558 $categoryValues = $wgRequest->getArray( 'category', array() );
00559 $categoryLabelValues = $wgRequest->getArray( 'cat_label', array() );
00560 $categoryYesValues = $wgRequest->getArray( 'cat_yes', array() );
00561 $categoryNoValues = $wgRequest->getArray( 'cat_no', array() );
00562 $mainColumnLabels = $wgRequest->getArray( 'maincol_label', array() );
00563
00564 $mainLabelCheck = $wgRequest->getCheck( 'pmainlabel' );
00565
00566 if ( !$mainLabelCheck ) {
00567
00568
00569
00570
00571
00572
00573 if ( array_key_exists( 'sort', $params ) && array_key_exists( 'order', $params ) ) {
00574 $sortVal = explode( ',', trim( strtolower( $params['sort'] ) ) );
00575 $orderVal = explode( ',', $params['order'] );
00576 reset( $sortVal );
00577 reset( $orderVal );
00578
00579 if ( count( $sortVal ) !== count( $orderVal ) ) {
00580 $orderVal = array();
00581 $sortVal = array();
00582 }
00583 } else {
00584 $orderVal = array();
00585 $sortVal = array();
00586 }
00587 $printOuts = ( $this->uiCore->getPrintOuts() );
00588 $counter = 0;
00589 foreach ( $printOuts as $poValue ) {
00590 if ( $poValue->getMode() == SMWPrintRequest::PRINT_CATS ) {
00591 $categoryValues[$counter] = ' ';
00592 $categoryLabelValues[$counter] = $poValue->getLabel();
00593 $categoryYesValues[$counter] = '';
00594 $categoryNoValues[$counter] = '';
00595 $counter++;
00596 } elseif ( $poValue->getMode() == SMWPrintRequest::PRINT_PROP ) {
00597 $tempProperty = trim( strtolower( $poValue->getData()->getText() ) );
00598 $searchKey = array_search( $tempProperty, $sortVal );
00599 if ( !( $searchKey === false ) ) {
00600 while ( $searchKey != 0 ) {
00601 $propertyValues[$counter] = array_shift( $sortVal );
00602 $orderValues[$counter] = array_shift( $orderVal );
00603 $propertyLabelValues[$counter] = '';
00604 $propertyFormatValues[$counter] = '';
00605 $propertyLimitValues[$counter] = '';
00606 $counter++;
00607 $searchKey--;
00608 }
00609 $propertyValues[$counter] = $poValue->getData()->getText();
00610
00611 $propertyLabelValues[$counter] =
00612 ( $poValue->getLabel() == $propertyValues[$counter] ) ? '':$poValue->getLabel();
00613
00614 $propertyFormatValues[$counter] = $poValue->getOutputFormat();
00615
00616 $propertyLimitValues[$counter] =
00617 ( $poValue->getParameter( 'limit' ) ) ? $poValue->getParameter( 'limit' ):'';
00618
00619 $orderValues[$counter] = $orderVal[0];
00620 $displayValues[$counter] = '1';
00621 $counter++;
00622 array_shift( $orderVal );
00623 array_shift( $sortVal );
00624 } else {
00625 $propertyValues[$counter] = $poValue->getData()->getText();
00626
00627 $propertyLabelValues[$counter] =
00628 ( $poValue->getLabel() == $propertyValues[$counter] ) ? '':$poValue->getLabel();
00629
00630 $propertyFormatValues[$counter] = $poValue->getOutputFormat();
00631
00632 $propertyLimitValues[$counter] =
00633 ( $poValue->getParameter( 'limit' ) ) ? $poValue->getParameter( 'limit' ):'';
00634
00635 $displayValues[$counter] = '1';
00636 $counter++;
00637 }
00638 } elseif ( $poValue->getMode() == SMWPrintRequest::PRINT_THIS ) {
00639 $mainColumnLabels[$counter] = $poValue->getLabel();
00640 $counter++;
00641 } elseif ( $poValue->getMode() == SMWPrintRequest::PRINT_CCAT ) {
00642 $outputFormat = explode( ',', $poValue->getOutputFormat() );
00643 if ( !array_key_exists( 1, $outputFormat ) ) {
00644 $outputFormat[1] = '';
00645 }
00646 $categoryValues[$counter] = $poValue->getData()->getText();
00647 $categoryLabelValues[$counter] = $poValue->getLabel();
00648 $categoryYesValues[$counter] = $outputFormat[0];
00649 $categoryNoValues[$counter] = $outputFormat[1];
00650 $counter++;
00651 }
00652
00653 }
00654 while ( !empty( $sortVal ) ) {
00655 $propertyValues[$counter] = array_shift( $sortVal );
00656 $orderValues[$counter] = array_shift( $orderVal );
00657 $propertyLabelValues[$counter] = '';
00658 $propertyFormatValues[$counter] = '';
00659 $propertyLimitValues[$counter] = '';
00660 $counter++;
00661 }
00662 }
00663
00664 $i = 0;
00665 $additionalPOs = array();
00666
00667 $keys = array_keys( $propertyValues );
00668 foreach ( $keys as $value ) {
00669 $additionalPOs[$value] = $propertyValues[$value];
00670
00671 }
00672
00673
00674 $keys = array_keys( $categoryValues );
00675 foreach ( $keys as $value ) {
00676 $additionalPOs[$value] = $categoryValues[$value];
00677
00678 }
00679
00680 $keys = array_keys( $mainColumnLabels );
00681 foreach ( $keys as $value ) {
00682 $additionalPOs[$value] = $mainColumnLabels[$value];
00683
00684 }
00685
00686 ksort( $additionalPOs );
00687 foreach ( $additionalPOs as $key => $value ) {
00688 if ( array_key_exists( $key, $propertyValues ) ) {
00689
00690
00691
00692 $result .= Html::openElement(
00693 'div',
00694 array( 'id' => "sort_div_$i", 'class' => 'smwsort' )
00695 );
00696
00697 $result .= '<span class="smwquisortlabel">' .
00698 '<span class="smw-remove">' .
00699 '<a href="javascript:removePOInstance(\'sort_div_' . $i . '\')">' .
00700 '<img src="' . $smwgScriptPath . '/skins/images/close-button.png"' .
00701 'alt="' . wfMsg( 'smw_qui_delete' ) .
00702 '">' .
00703 '</a></span>';
00704 $result .= wfMsg( 'smw_qui_property' ) . '</span>';
00705
00706 $result .= Html::input( 'property[' . $i . ']',
00707 $propertyValues[$key],
00708 'text',
00709 array( 'size' => '25', 'id' => "property$i" ) ) .
00710 "\n";
00711
00712 $urlArgs["property[$i]"] = $propertyValues[$key];
00713 if ( $smwgQSortingSupport ) {
00714 $result .= Html::openElement(
00715 'select',
00716 array( 'name' => "order[$i]" )
00717 );
00718 if ( array_key_exists( $key, $orderValues ) ) {
00719 $urlArgs["order[$i]"] = $orderValues[$key];
00720 }
00721 $if1 = ( !array_key_exists( $key, $orderValues ) || $orderValues[$key] == 'NONE' );
00722 $result .= Xml::option( wfMsg( 'smw_qui_nosort' ), "NONE", $if1 );
00723
00724 $if2 = ( array_key_exists( $key, $orderValues ) && $orderValues[$key] == 'ASC' );
00725 $result .= Xml::option( wfMsg( 'smw_qui_ascorder' ), "ASC", $if2 );
00726
00727 $if3 = ( array_key_exists( $key, $orderValues ) && $orderValues[$key] == 'DESC' );
00728 $result .= Xml::option( wfMsg( 'smw_qui_descorder' ), "DESC", $if3 );
00729
00730 if ( $smwgQRandSortingSupport ) {
00731 $if4 = ( array_key_exists( $key, $orderValues ) && $orderValues[$key] == 'RANDOM' );
00732 $result .= Xml::option( wfMsg( 'smw_qui_randorder' ), "RANDOM", $if4 );
00733 }
00734
00735 $result .= Xml::closeElement( 'select' );
00736
00737 $if5 = ( array_key_exists( $key, $displayValues ) );
00738 $result .= Xml::checkLabel( wfMsg( 'smw_qui_shownresults' ), "display[$i]", "display$i", $if5 );
00739 if ( $if5 ) {
00740 $urlArgs["display[$i]"] = '1';
00741 }
00742 }
00743 if ( array_key_exists( $key, $propertyLabelValues ) ) {
00744 $result .= Html::hidden(
00745 "prop_label[$i]",
00746 $propertyLabelValues[$key],
00747 array( 'id' => "prop_label$i" )
00748 );
00749 $urlArgs["prop_label[$i]"] = $propertyLabelValues[$key];
00750 } else {
00751 $result .= Html::hidden( "prop_label[$i]",
00752 '',
00753 array( 'id' => "prop_label$i" )
00754 );
00755 }
00756 if ( array_key_exists( $key, $propertyFormatValues ) ) {
00757 $result .= Html::hidden( "prop_format[$i]",
00758 $propertyFormatValues[$key],
00759 array( 'id' => "prop_format$i" )
00760 );
00761 $urlArgs["prop_format[$i]"] = $propertyFormatValues[$key];
00762 } else {
00763 $result .= Html::hidden( "prop_format[$i]",
00764 '',
00765 array( 'id' => "prop_format$i" )
00766 );
00767 }
00768 if ( array_key_exists( $key, $propertyLimitValues ) ) {
00769 $result .= Html::hidden( "prop_limit[$i]",
00770 $propertyLimitValues[$key],
00771 array( 'id' => "prop_limit$i" )
00772 );
00773 $urlArgs["prop_limit[$i]"] = $propertyLimitValues[$key];
00774 } else {
00775 $result .= Html::hidden( "prop_limit[$i]",
00776 '',
00777 array( 'id' => "prop_limit$i" )
00778 );
00779 }
00780 $result .= Html::element( 'a',
00781 array( 'id' => "more$i",
00782 'class' => 'smwq-more',
00783 'href' => "javascript:smw_makePropDialog('$i')"
00784 ),
00785 WfMsg( 'smw_qui_options' )
00786 );
00787
00788 $result .= Xml::closeElement( 'div' );
00789 $i++;
00790 }
00791 if ( array_key_exists( $key, $categoryValues ) ) {
00792 if ( !array_key_exists( $key, $categoryLabelValues ) ) {
00793 $categoryLabelValues[$key] = '';
00794 }
00795 if ( !array_key_exists( $key, $categoryYesValues ) ) {
00796 $categoryYesValues[$key] = '';
00797 }
00798 if ( !array_key_exists( $key, $categoryNoValues ) ) {
00799 $categoryNoValues[$key] = '';
00800 }
00801 /*
00802 * Make an element for additional categories
00803 */
00804 $result .= Html::openElement( 'div',
00805 array( 'id' => "sort_div_$i", 'class' => 'smwsort' )
00806 );
00807 $result .= '<span class="smwquisortlabel">' .
00808 '<span class="smw-remove">' .
00809 Html::openElement( 'a',
00810 array( 'href' => "javascript:removePOInstance('sort_div_$i')" )
00811 ) .
00812 '<img src="' . $smwgScriptPath . '/skins/images/close-button.png" alt="' . wfMsg( 'smw_qui_delete' ) . '">' .
00813 '</a>' .
00814 '</span>' .
00815 wfMsg( 'smw_qui_category' ) .
00816 '</span>' .
00817 Xml::input( "category[$i]",
00818 '25',
00819 $categoryValues[$key],
00820 array( 'id' => "category$i" )
00821 ) . " " .
00822 Html::hidden( "cat_label[$i]",
00823 $categoryLabelValues[$key],
00824 array( 'id' => "cat_label$i" )
00825 ) .
00826 Html::hidden( "cat_yes[$i]",
00827 $categoryYesValues[$key],
00828 array( 'id' => "cat_yes$i" )
00829 ) .
00830 Html::hidden( "cat_no[$i]",
00831 $categoryNoValues[$key],
00832 array( 'id' => "cat_no$i" )
00833 ) .
00834 Html::element( 'a',
00835 array( 'id' => "more$i",
00836 'class' => 'smwq-more',
00837 'href' => "javascript:smw_makeCatDialog('$i')" ),
00838 WfMsg( 'smw_qui_options' )
00839 ) .
00840 Xml::closeElement( 'div' );
00841 $urlArgs["category[$i]"] =
00842 ( $categoryValues[$key] === '' ) ? ' ':$categoryValues[$key];
00843
00844 $urlArgs["cat_label[$i]"] = $categoryLabelValues[$key];
00845 $urlArgs["cat_yes[$i]"] = $categoryYesValues[$key];
00846 $urlArgs["cat_no[$i]"] = $categoryNoValues[$key];
00847 $i++;
00848 }
00849 if ( array_key_exists( $key, $mainColumnLabels ) ) {
00850 /*
00851 * Make an element for main column aka query-matches
00852 */
00853 $result .= Html::openElement( 'div',
00854 array( 'id' => "sort_div_$i", 'class' => 'smwsort' )
00855 ) .
00856 '<span class="smwquisortlabel">' .
00857 '<span class="smw-remove">' .
00858 Html::openelement( 'a',
00859 array( 'href' => "javascript:removePOInstance('sort_div_$i')" )
00860 ) .
00861 '<img src="' . $smwgScriptPath . '/skins/images/close-button.png" alt="' . wfMsg( 'smw_qui_delete' ) . '">' .
00862 '</a>' .
00863 '</span><strong>' .
00864 wfMsg( 'smw_qui_rescol' ) .
00865 '</strong></span>' .
00866 Html::hidden( "maincol_label[$i]",
00867 $mainColumnLabels[$key],
00868 array ( 'id' => "maincol_label$i" )
00869 ) . " " .
00870 '<a class="smwq-more" href="javascript:smw_makeQueryMatchesDialog(\'' . $i . '\')">' . wfMsg( 'smw_qui_options' ) . '</a> ' .
00871 '</div>';
00872 $urlArgs["maincol_label[$i]"] =
00873 ( $mainColumnLabels[$key] === '' ) ? ' ':$mainColumnLabels[$key];
00874 $i++;
00875 }
00876 }
00877 $numSortValues = $i;
00878 $this->setUrlArgs( $urlArgs );
00879 // END: create form elements already submitted earlier via form
00880
00881 // create hidden form elements to be cloned later
00882 // property
00883 $hiddenProperty = Html::openElement( 'div',
00884 array( 'id' => 'property_starter',
00885 'style' => 'display:none' )
00886 ) .
00887 '<span class="smwquisortlabel">' .
00888 '<span class="smw-remove">' .
00889 '<a>' .
00890 '<img src="' . $smwgScriptPath . '/skins/images/close-button.png" alt="' . wfMsg( 'smw_qui_delete' ) . '">' .
00891 '</a>' .
00892 '</span>' .
00893 wfMsg( 'smw_qui_property' ) .
00894 '</span>' .
00895 Xml::input( 'property_num', '25' ) . " " ;
00896 if ( $smwgQSortingSupport ) {
00897 $hiddenProperty .= Html::openElement( 'select', array( 'name' => 'order_num' ) ) .
00898 Xml::option( wfMsg( 'smw_qui_nosort' ), 'NONE' ) .
00899 Xml::option( wfMsg( 'smw_qui_ascorder' ), 'ASC' ) .
00900 Xml::option( wfMsg( 'smw_qui_descorder' ), 'DESC' );
00901 if ( $smwgQRandSortingSupport ) {
00902 $hiddenProperty .= Xml::option( wfMsg( 'smw_qui_randorder' ), 'RANDOM' );
00903 }
00904 $hiddenProperty .= Xml::closeElement( 'select' ) .
00905 Xml::checkLabel( wfMsg( 'smw_qui_shownresults' ), "display_num", '', true );
00906 }
00907 $hiddenProperty .= Html::hidden( 'prop_label_num', '' ) .
00908 Html::hidden( 'prop_format_num', '' ) .
00909 Html::hidden( 'prop_limit_num', '' ) .
00910 Xml::closeElement( 'div' );
00911 $hiddenProperty = json_encode( $hiddenProperty );
00912 // category
00913 $hiddenCategory = Html::openElement( 'div',
00914 array( 'id' => 'category_starter',
00915 'style' => 'display:none' )
00916 ) .
00917 '<span class="smwquisortlabel">' .
00918 '<span class="smw-remove">' .
00919 '<a>' .
00920 '<img src="' . $smwgScriptPath . '/skins/images/close-button.png" alt="' . wfMsg( 'smw_qui_delete' ) . '">' .
00921 '</a>' .
00922 '</span>' .
00923 wfMsg( 'smw_qui_category' ) . '</span>' .
00924 Xml::input( "category_num", '25' ) . " " .
00925 '<input type="hidden" name="cat_label_num" />' .
00926 '<input type="hidden" name="cat_yes_num" />' .
00927 '<input type="hidden" name="cat_no_num" />' .
00928 Xml::closeElement( 'div' );
00929 $hiddenCategory = json_encode( $hiddenCategory );
00930 // For '?' printouts
00931 $hiddenMainColumn = Html::openElement( 'div',
00932 array( 'id' => 'maincol_starter',
00933 'style' => 'display:none' )
00934 ) .
00935 '<span class="smwquisortlabel">' .
00936 '<span class="smw-remove">' .
00937 '<a>' .
00938 '<img src="' . $smwgScriptPath . '/skins/images/close-button.png" alt="' . wfMsg( 'smw_qui_delete' ) . '">' .
00939 '</a>' .
00940 '</span><strong>' .
00941 wfMsg( 'smw_qui_rescol' ) . '</strong></span>' .
00942 Html::hidden( "maincol_label_num", '' ) . " " .
00943 Xml::closeElement( 'div' );
00944 $hiddenMainColumn = json_encode( $hiddenMainColumn );
00945
00946 // Create dialog-boxes
00947 // create dialogbox for Property options
00948 $propertyHtml = Xml::inputLabelSep( wfMsg( 'smw_qui_prop' ),
00949 '',
00950 'd-property',
00951 'd-property'
00952 );
00953 $propertyLabelHtml = Xml::inputLabelSep( wfMsg( 'smw_qui_labl' ),
00954 '',
00955 'd-prop-label',
00956 'd-prop-label'
00957 );
00958 $propertyFormatHtml = Xml::inputLabelSep( wfMsg( 'smw_qui_formt' ),
00959 '',
00960 'd-prop-format',
00961 'd-prop-format'
00962 );
00963 $propertyLimitHtml = Xml::inputLabelSep( wfMsg( 'smw_qui_limt' ),
00964 'd-prop-limit',
00965 'd-prop-limit'
00966 );
00967 $propertyDialogBox = Xml::openElement(
00968 'div',
00969 array( 'id' => 'prop-dialog',
00970 'title' => wfMsg( 'smw_prp_options' ),
00971 'class' => 'smwpropdialog' )
00972 ) .
00973 '<table align="center">' .
00974 '<tr><td>' . $propertyHtml[0] . '</td><td>' . $propertyHtml[1] . '</td></tr>' .
00975 '<tr><td>' . $propertyLabelHtml[0] . '</td><td>' . $propertyLabelHtml[1] . '</td></tr>' .
00976 '<tr><td>' . $propertyLimitHtml[0] . '</td><td>' . $propertyLimitHtml[1] . '</td></tr>' .
00977 '<tr><td>' . $propertyFormatHtml[0] . '</td><td>' . $propertyFormatHtml[1] . '</td></tr>' .
00978 '</table>' .
00979 Xml::closeElement( 'div' );
00980
00981 // create dialogbox for Category options
00982 $categoryHtml = Xml::inputLabelSep( wfMsg( 'smw_qui_dcategory' ),
00983 '',
00984 'd-category',
00985 'd-category'
00986 );
00987 $categoryLabelHtml = Xml::inputLabelSep( wfMsg( 'smw_qui_dlabel' ),
00988 '',
00989 'd-category-label',
00990 'd-category-label'
00991 );
00992 $categoryYesHtml = Xml::inputLabelSep( wfMsg( 'smw_qui_dcatyes' ),
00993 '',
00994 'd-category-yes',
00995 'd-category-yes'
00996 );
00997 $categoryNoHtml = Xml::inputLabelSep( wfMsg( 'smw_qui_dcatno' ),
00998 '',
00999 'd-category-no',
01000 'd-category-no' );
01001 $categoryDialogBox = Xml::openElement( 'div',
01002 array( 'id' => 'cat-dialog',
01003 'title' => wfMsg( 'smw_qui_catopts' ),
01004 'class' => 'smwcatdialog' )
01005 ) .
01006 '<table align="center">' .
01007 '<tr><td>' . $categoryHtml[0] . '</td><td>' . $categoryHtml[1] . '</td></tr>' .
01008 '<tr><td>' . $categoryLabelHtml[0] . '</td><td>' . $categoryLabelHtml[1] . '</td></tr>' .
01009 '</table><br/><table align="center">' .
01010 '<tr><td>' . $categoryYesHtml[0] . '</td><td>' . $categoryYesHtml[1] . '</td></tr>' .
01011 '<tr><td>' . $categoryNoHtml[0] . '</td><td>' . $categoryNoHtml[1] . '</td></tr>' .
01012 '</table>' .
01013 Xml::closeElement( 'div' );
01014
01015 // Create dialog box for QueryMatches
01016 $mainResLabelHtml = Xml::inputLabelSep( wfMsg( 'smw_qui_dlabel' ), '', 'd-mainres-label' );
01017 $mainResDialogBox = Xml::openElement( 'div',
01018 array( 'id' => 'mainres-dialog',
01019 'title' => wfMsg( 'smw_qui_mainlabopts' ),
01020 'class' => 'smwmainlabdialog' )
01021 ) .
01022 '<table align="center">' .
01023 '<tr><td>' . $mainResLabelHtml[0] . '</td><td>' . $mainResLabelHtml[1] . '</td></tr>' .
01024 '</table>' .
01025 Xml::closeElement( 'div' );
01026
01027 $result .= '<div id="sorting_main"></div>' . "\n";
01028 $result .= '[<a href="javascript:smw_addPropertyInstance(\'property_starter\', \'sorting_main\')">' . wfMsg( 'smw_qui_addnprop' ) . '</a>]' .
01029 '[<a href="javascript:smw_addCategoryInstance(\'category_starter\', \'sorting_main\')">' . wfMsg( 'smw_qui_addcategory' ) . '</a>]' .
01030 '[<a href="javascript:smw_addMainColInstance(\'maincol_starter\', \'sorting_main\')">' . wfMsg( 'smw_qui_addrescol' ) . '</a>]' .
01031 "\n";
01032
01033
01034 if ( $enableAutocomplete == SMWQueryUI::ENABLE_AUTO_SUGGEST ) {
01035 $this->enableAutocompletion();
01036 }
01037
01038 $optionsMsg = wfMsg( 'smw_qui_options' );
01039 $okMsg = wfMsg( 'smw_qui_ok' );
01040 $cancelMsg = wfMsg( 'smw_qui_cancel' );
01041 $javascriptText = <<<EOT
01042 <script type="text/javascript">
01043 var num_elements = {$numSortValues};
01044 var smwgQPrintoutLimit={$smwgQPrintoutLimit};
01045 EOT;
01046
01047 if ( $enableAutocomplete == SMWQueryUI::ENABLE_AUTO_SUGGEST ) {
01048 $javascriptText .= <<<EOT
01049
01050 function smw_property_autocomplete(){
01051 jQuery( '[name*="property"]' ).autocomplete( {
01052 minLength: 2,
01053 source: function( request, response ) {
01054 url = wgScriptPath+'/api.php?action=opensearch&limit=10&namespace='+wgNamespaceIds['property']+'&format=jsonfm';
01055
01056 jQuery.getJSON( url, 'search='+request.term, function( data ) {
01057
01058 for( i=0; i < data[1].length; i++ ){
01059 data[1][i]=data[1][i].substr(data[1][i].indexOf(':')+1);
01060 }
01061 response(data[1]);
01062 });
01063 }
01064 } );
01065 }
01066
01067 function smw_category_autocomplete(){
01068 jQuery( '[name*="category"]' ).autocomplete( {
01069 minLength: 2,
01070 source: function(request, response) {
01071 url = wgScriptPath+'/api.php?action=opensearch&limit=10&namespace='+wgNamespaceIds['category']+'&format=jsonfm';
01072
01073 jQuery.getJSON( url, 'search='+request.term, function( data ){
01074
01075 for( i=0; i<data[1].length; i++ ){
01076 data[1][i]=data[1][i].substr(data[1][i].indexOf(':')+1);
01077 }
01078 response(data[1]);
01079 });
01080 }
01081 });
01082 }
01083 EOT;
01084 } else {
01085 $javascriptText .= <<<EOT
01086 function smw_property_autocomplete(){
01087 }
01088
01089 function smw_category_autocomplete(){
01090 }
01091
01092 EOT;
01093 }
01094
01095 $javascriptText .= <<<EOT
01096
01097 function smw_makeMainlabelDialog(){
01098 jQuery('#mainlabel-dialog').dialog("open");
01099 }
01100
01101 function smwRemoveMainLabel(){
01102 jQuery( '#mainlabelhid' ).attr( 'value', '-' );
01103 jQuery( '#mainlabelvis' ).attr( 'value', '' );
01104 jQuery( '#smwmainlabel' ).hide();
01105 }
01106
01107
01108 function smw_makeQueryMatchesDialog( qm_id ){
01109 qmLabel=jQuery('#maincol_label'+qm_id).attr('value');
01110 jQuery('#d-mainres-label').attr('value', qmLabel);
01111 jQuery( '#mainres-dialog' ).dialog.sortid = qm_id;
01112 jQuery( '#mainres-dialog' ).dialog( 'open' );
01113 }
01114
01115 function smw_makeCatDialog( cat_id ){
01116 jQuery( '#prop-cat input' ).attr('value','');
01117
01118 cat=jQuery('#category'+cat_id)[0].value;
01119 label=jQuery('#cat_label'+cat_id)[0].value;
01120 yes = jQuery('#cat_yes'+cat_id)[0].value;
01121 no = jQuery('#cat_no'+cat_id)[0].value;
01122
01123 jQuery('#d-category-yes').attr('value',yes);
01124 jQuery('#d-category-no').attr('value',no);
01125 jQuery('#d-category-label').attr('value',label);
01126 jQuery('#d-category').attr('value',cat);
01127
01128 jQuery('#cat-dialog').dialog.id=cat_id;
01129 jQuery('#cat-dialog').dialog('open');
01130 }
01131
01132 function smw_makePropDialog(prop_id){
01133 jQuery('#prop-dialog input').attr('value','');
01134 prop=jQuery('#property'+prop_id).attr('value');
01135 label=jQuery('#prop_label'+prop_id).attr('value');
01136 format=jQuery('#prop_format'+prop_id).attr('value');
01137 limit=jQuery('#prop_limit'+prop_id).attr('value');
01138 jQuery('#d-property').attr('value', prop);
01139 jQuery('#d-prop-label').attr('value', label);
01140 jQuery('#d-prop-limit').attr('value', limit);
01141 jQuery('#d-prop-format').attr('value', format);
01142 jQuery('#prop-dialog').dialog.id=prop_id;
01143 jQuery('#prop-dialog').dialog('open');
01144 }
01145
01146
01147 function smw_addPropertyInstance(starter_div_id, main_div_id) {
01148 if( jQuery( '.smwsort' ).length > smwgQPrintoutLimit ) return;
01149
01150 var starter_div = document.getElementById(starter_div_id);
01151 var main_div = document.getElementById(main_div_id);
01152
01153
01154 var new_div = starter_div.cloneNode(true);
01155 var div_id = 'sort_div_' + num_elements;
01156 new_div.id = div_id;
01157 new_div.style.display = 'block';
01158 jQuery(new_div.getElementsByTagName('label')).attr('for', 'display'+num_elements);
01159 jQuery(new_div).addClass( 'smwsort' );
01160 var children = new_div.getElementsByTagName('*');
01161 var x;
01162 for (x = 0; x < children.length; x++) {
01163 if (jQuery(children[x]).attr('for')) jQuery(children[x]).attr('for',"display"+num_elements);
01164 if (children[x].name){
01165 children[x].id = children[x].name.replace(/_num/, ''+num_elements);
01166 children[x].name = children[x].name.replace(/_num/, '[' + num_elements + ']');
01167 }
01168 }
01169
01170
01171 var more_button =document.createElement('span');
01172 more_button.innerHTML = ' <a class="smwq-more" href="javascript:smw_makePropDialog(\'' + num_elements + '\')">{$optionsMsg}</a> ';
01173 more_button.id = 'more'+num_elements;
01174 new_div.appendChild(more_button);
01175
01176 //Add the new instance
01177 main_div.appendChild(new_div);
01178
01179 // initialize delete button
01180 st='sort_div_'+num_elements;
01181 jQuery('#'+new_div.id).find(".smw-remove a")[0].href="javascript:removePOInstance('"+st+"')";
01182 num_elements++;
01183 smw_property_autocomplete();
01184 }
01185
01186 function smw_addCategoryInstance(starter_div_id, main_div_id) {
01187 if( jQuery( '.smwsort' ).length > smwgQPrintoutLimit ) return;
01188
01189 var starter_div = document.getElementById(starter_div_id);
01190 var main_div = document.getElementById(main_div_id);
01191
01192 //Create the new instance
01193 var new_div = starter_div.cloneNode(true);
01194 var div_id = 'sort_div_' + num_elements;
01195 new_div.id = div_id;
01196 new_div.style.display = 'block';
01197 jQuery(new_div.getElementsByTagName('label')).attr('for', 'display'+num_elements);
01198 jQuery(new_div).addClass( 'smwsort' );
01199 var children = new_div.getElementsByTagName('*');
01200 var x;
01201 for (x = 0; x < children.length; x++) {
01202 if (jQuery(children[x]).attr('for')) jQuery(children[x]).attr('for',"display"+num_elements);
01203 if (children[x].name){
01204 children[x].id = children[x].name.replace(/_num/, ''+num_elements);
01205 children[x].name = children[x].name.replace(/_num/, '[' + num_elements + ']');
01206 }
01207 }
01208
01209 //Create 'options' link
01210 var more_button =document.createElement('span');
01211 more_button.innerHTML = ' <a class="smwq-more" href="javascript:smw_makeCatDialog(\'' + num_elements + '\')">{$optionsMsg}</a> ';
01212 more_button.id = 'more'+num_elements;
01213 new_div.appendChild(more_button);
01214
01215 //Add the new instance
01216 main_div.appendChild(new_div);
01217
01218 // initialize delete button
01219 st='sort_div_'+num_elements;
01220 jQuery('#'+new_div.id).find(".smw-remove a")[0].href="javascript:removePOInstance('"+st+"')";
01221 num_elements++;
01222 smw_category_autocomplete();
01223 }
01224
01225 function smw_addMainColInstance(starter_div_id, main_div_id) {
01226 if( (jQuery('#smwmainlabel').css('display')=='none')
01227 && (jQuery('.smwsort').length==1)
01228 ){
01229 jQuery('#mainlabelhid').attr('value','');
01230 jQuery('#mainlabelvis').attr('value','');
01231 jQuery('#smwmainlabel').show();
01232 } else {
01233 if( jQuery( '.smwsort' ).length > smwgQPrintoutLimit ){
01234 return;
01235 }
01236 var starter_div = document.getElementById(starter_div_id);
01237 var main_div = document.getElementById(main_div_id);
01238
01239 //Create the new instance
01240 var new_div = starter_div.cloneNode(true);
01241 var div_id = 'sort_div_' + num_elements;
01242 new_div.id = div_id;
01243 new_div.style.display = 'block';
01244 jQuery(new_div.getElementsByTagName('label')).attr('for', 'display'+num_elements);
01245 jQuery(new_div).addClass( 'smwsort' );
01246 var children = new_div.getElementsByTagName('*');
01247 var x;
01248 for (x = 0; x < children.length; x++) {
01249 if (jQuery(children[x]).attr('for')) jQuery(children[x]).attr('for',"display"+num_elements);
01250 if (children[x].name){
01251 children[x].id = children[x].name.replace(/_num/, ''+num_elements);
01252 children[x].name = children[x].name.replace(/_num/, '[' + num_elements + ']');
01253 }
01254 }
01255 //Create 'options' link
01256 var more_button =document.createElement('span');
01257 more_button.innerHTML = ' <a class="smwq-more" href="javascript:smw_makeQueryMatchesDialog(\'' + num_elements + '\')">{$optionsMsg}</a> ';
01258 more_button.id = 'more'+num_elements;
01259 new_div.appendChild(more_button);
01260
01261 //Add the new instance
01262 main_div.appendChild(new_div);
01263
01264 // initialize delete button
01265 st='sort_div_'+num_elements;
01266 jQuery('#'+new_div.id).find(".smw-remove a")[0].href="javascript:removePOInstance('"+st+"')";
01267 num_elements++;
01268 }
01269 }
01270
01271 function removePOInstance(div_id) {
01272 var olddiv = document.getElementById(div_id);
01273 var parent = olddiv.parentNode;
01274 parent.removeChild(olddiv);
01275 }
01276
01277 jQuery(function(){
01278 jQuery('$hiddenProperty').appendTo(document.body);
01279 jQuery('$hiddenCategory').appendTo(document.body);
01280 jQuery('$hiddenMainColumn').appendTo(document.body);
01281 jQuery('$propertyDialogBox').appendTo(document.body);
01282 jQuery('$categoryDialogBox').appendTo(document.body);
01283 jQuery('$mainResDialogBox').appendTo(document.body);
01284
01285 jQuery( '#mainlabel-dialog' ).dialog( {
01286 autoOpen: false,
01287 modal: true,
01288 resizable: true,
01289 minWidth: 400,
01290 buttons: {
01291 "{$okMsg}": function(){
01292 jQuery('#mainlabelhid').attr('value',jQuery('#mainlabelvis').attr('value'));
01293 jQuery(this).dialog("close");
01294 },
01295 "{$cancelMsg}": function(){
01296 jQuery(this).dialog("close");
01297 }
01298 }
01299 } );
01300
01301 jQuery( '#mainres-dialog' ).dialog( {
01302 autoOpen: false,
01303 modal: true,
01304 resizable: true,
01305 minWidth: 400,
01306 buttons: {
01307 "{$okMsg}": function(){
01308 id = jQuery( this ).dialog.sortid;
01309 label = jQuery('#d-mainres-label');
01310 jQuery('#maincol_label'+id).attr('value', label);
01311 jQuery(this).dialog("close");
01312 },
01313 "{$cancelMsg}": function(){
01314 jQuery(this).dialog("close");
01315 }
01316 }
01317 } );
01318
01319 jQuery( '#cat-dialog' ).dialog( {
01320 autoOpen: false,
01321 modal: true,
01322 resizable: true,
01323 minHeight: 200,
01324 minWidth: 400,
01325 buttons: {
01326 "{$okMsg}": function(){
01327 cat = jQuery('#d-category').attr('value');
01328 label = jQuery('#d-category-label').attr('value');
01329 yes = jQuery('#d-category-yes').attr('value');
01330 no = jQuery('#d-category-no').attr('value');
01331 id=jQuery(this).dialog.id;
01332
01333 jQuery('#category'+id).attr('value',cat);
01334 jQuery('#cat_label'+id).attr('value',label);
01335 jQuery('#cat_yes'+id).attr('value',yes);
01336 jQuery('#cat_no'+id).attr('value',no);
01337 jQuery(this).dialog("close");
01338 },
01339 "{$cancelMsg}": function(){
01340 jQuery('#cat-dialog input').attr('value','');
01341 jQuery(this).dialog("close");
01342 }
01343 }
01344 });
01345
01346 jQuery('#prop-dialog').dialog({
01347 autoOpen: false,
01348 modal: true,
01349 resizable: true,
01350 minWidth: 400,
01351 buttons: {
01352 "{$okMsg}": function(){
01353 id=jQuery(this).dialog.id;
01354 property=jQuery('#d-property').attr('value');
01355 label=jQuery('#d-prop-label').attr('value');
01356 limit=jQuery('#d-prop-limit').attr('value');
01357 format=jQuery('#d-prop-format').attr('value');
01358
01359
01360 jQuery('#property'+id).attr('value',property);
01361 jQuery('#prop_label'+id).attr('value',label);
01362 jQuery('#prop_limit'+id).attr('value',limit);
01363 jQuery('#prop_format'+id).attr('value',format);
01364 jQuery(this).dialog("close");
01365 },
01366 "{$cancelMsg}": function(){
01367 jQuery('#prop-dialog input').attr('value','');
01368 jQuery(this).dialog("close");
01369 }
01370 }
01371 });
01372 jQuery('#sort-more').click(function(){jQuery('#prop-dialog').dialog("open");});
01373 jQuery('#d-category').bind('change keyup focus click',function(){
01374 if(jQuery(this).attr('value')==''){
01375 jQuery('#d-category-yes').css('visibility','hidden');
01376 jQuery('#d-category-no').css('visibility','hidden');
01377 jQuery('#cat-dialog [for="d-category-no"]').css('visibility','hidden');
01378 jQuery('#cat-dialog [for="d-category-yes"]').css('visibility','hidden');
01379 } else {
01380 jQuery('#d-category-yes').css('visibility','visible');
01381 jQuery('#d-category-no').css('visibility','visible');
01382 jQuery('#cat-dialog [for="d-category-no"]').css('visibility','visible');
01383 jQuery('#cat-dialog [for="d-category-yes"]').css('visibility','visible');
01384 }
01385 });
01386 });
01387
01388 jQuery(document).ready(smw_property_autocomplete);
01389 jQuery(document).ready(smw_category_autocomplete);
01390 </script>
01391
01392 EOT;
01393
01394 SMWOutputs::requireScript( 'smwAutocompleteQueryUI', $javascriptText );
01395 $result .= '</span>';
01396 return $result;
01397 }
01398
01410 protected function getSortingFormBox() {
01411 global $smwgQSortingSupport, $wgRequest;
01412
01413 if ( !$smwgQSortingSupport ) return '';
01414 $params = $this->uiCore->getParameters();
01415
01416 $result = '';
01417 if ( array_key_exists( 'sort', $params ) && array_key_exists( 'order', $params ) ) {
01418 $sorts = explode( ',', $params['sort'] );
01419 $orders = explode( ',', $params['order'] );
01420 reset( $sorts );
01421 } else {
01422 $orders = array(); // do not even show one sort input here
01423 }
01424
01425 foreach ( $orders as $i => $order ) {
01426 $urlArgs = array();
01427 $result .= "<div id=\"sort_div_$i\">" . wfMsg( 'smw_ask_sortby' ) . ' <input type="text" name="sort[' . $i . ']" value="' .
01428 htmlspecialchars( $sorts[$i] ) . "\" size=\"25\"/>\n" . '<select name="order[' . $i . ']"><option ';
01429 $urlArgs["sort[$i]"] = htmlspecialchars( $sorts[$i] );
01430 $urlArgs["order[$i]"] = $order;
01431 if ( $order == 'ASC' ) $result .= 'selected="selected" ';
01432 $result .= 'value="ASC">' . wfMsg( 'smw_qui_ascorder' ) . '</option><option ';
01433 if ( $order == 'DESC' ) $result .= 'selected="selected" ';
01434
01435 $result .= 'value="DESC">' . wfMsg( 'smw_qui_descorder' ) . "</option></select>\n";
01436 $result .= '[<a class="smwq-remove" href="javascript:removeInstance(\'sort_div_' . $i . '\')">' . wfMsg( 'smw_qui_delete' ) . '</a>]' . "\n";
01437 $result .= "</div>\n";
01438 $this->setUrlArgs( $urlArgs );
01439 }
01440
01441 $hidden = '<div id="sorting_starter" style="display: none">' . wfMsg( 'smw_ask_sortby' ) . ' <input type="text" size="25" />' . "\n";
01442 $hidden .= ' <select name="order_num">' . "\n";
01443 $hidden .= ' <option value="ASC">' . wfMsg( 'smw_qui_ascorder' ) . "</option>\n";
01444 $hidden .= ' <option value="DESC">' . wfMsg( 'smw_qui_descorder' ) . "</option>\n</select>\n";
01445 $hidden .= "</div>\n";
01446 $hidden = json_encode( $hidden );
01447
01448 $result .= '<div id="sorting_main"></div>' . "\n";
01449 $result .= '<a href="javascript:addInstance(\'sorting_starter\', \'sorting_main\')">' . wfMsg( 'smw_add_sortcondition' ) . '</a>' . "\n";
01450
01451 $num_sort_values = 0;
01452
01453 if ( !array_key_exists( 'sort', $params ) ) {
01454 $sort_values = $wgRequest->getArray( 'sort' );
01455 if ( is_array( $sort_values ) ) {
01456 $params['sort'] = implode( ',', $sort_values );
01457 $num_sort_values = count( $sort_values );
01458 }
01459 }
01460
01461 $delete_msg = wfMsg( 'smw_qui_delete' );
01462
01463 SMWOutputs::requireResource( 'jquery' );
01464 $javascriptText = <<<EOT
01465 <script type="text/javascript">
01466
01467 jQuery(document).ready(function(){
01468 jQuery('$hidden').appendTo(document.body);
01469 });
01470 var num_elements = {$num_sort_values};
01471
01472 function addInstance(starter_div_id, main_div_id) {
01473 var starter_div = document.getElementById(starter_div_id);
01474 var main_div = document.getElementById(main_div_id);
01475
01476
01477 var new_div = starter_div.cloneNode(true);
01478 var div_id = 'sort_div_' + num_elements;
01479 new_div.className = 'multipleTemplate';
01480 new_div.id = div_id;
01481 new_div.style.display = 'block';
01482
01483 var children = new_div.getElementsByTagName('*');
01484 var x;
01485 for (x = 0; x < children.length; x++) {
01486 if (children[x].name)
01487 children[x].name = children[x].name.replace(/_num/, '[' + num_elements + ']');
01488 }
01489
01490
01491 var remove_button = document.createElement('span');
01492 remove_button.innerHTML = '[<a href="javascript:removeInstance(\'sort_div_' + num_elements + '\')">{$delete_msg}</a>]';
01493 new_div.appendChild(remove_button);
01494
01495 //Add the new instance
01496 main_div.appendChild(new_div);
01497 num_elements++;
01498 }
01499
01500 function removeInstance(div_id) {
01501 var olddiv = document.getElementById(div_id);
01502 var parent = olddiv.parentNode;
01503 parent.removeChild(olddiv);
01504 }
01505 </script>
01506
01507 EOT;
01508
01509 SMWOutputs::requireScript( 'smwPrintoutControlsQueryUI', $javascriptText );
01510 return $result;
01511 }
01512
01523 protected function processSortingFormBox( WebRequest $wgRequest ) {
01524 global $smwgQSortingSupport;
01525 if ( !$smwgQSortingSupport ) return array();
01526
01527 $params = array();
01528 $orderValues = $wgRequest->getArray( 'order' );
01529 if ( is_array( $orderValues ) ) {
01530 $params['order'] = '';
01531 foreach ( $orderValues as $order_value ) {
01532 if ( $order_value === '' ) {
01533 $order_value = 'ASC';
01534 }
01535 $params['order'] .= ( $params['order'] !== '' ? ',' : '' ) . $order_value;
01536 }
01537 }
01538
01539 $sort_values = $wgRequest->getArray( 'sort' );
01540 if ( is_array( $sort_values ) ) {
01541 $params['sort'] = '';
01542 foreach ( $sort_values as $sort_value ) {
01543 $params['sort'] .= ( $params['sort'] !== '' ? ',' : '' ) . $sort_value;
01544 }
01545 }
01546 return $params;
01547
01548 }
01549
01559 protected function getPOFormBox( $enableAutocomplete = SMWQueryUI::ENABLE_AUTO_SUGGEST ) {
01560 if ( $enableAutocomplete ) {
01561 $this->enableAutocompletion();
01562 $javascriptAutocompleteText = <<<EOT
01563 <script type="text/javascript">
01564 jQuery(document).ready(function(){
01565 jQuery("#add_property").autocomplete({
01566 minLength: 2,
01567 source: function(request, response) {
01568 request.term=request.term.substr(request.term.lastIndexOf("\\n")+1);
01569 url=wgScriptPath+'/api.php?action=opensearch&limit=10&namespace='+wgNamespaceIds['property']+'&format=jsonfm';
01570
01571 jQuery.getJSON(url, 'search='+request.term, function(data){
01572 //remove the namespace prefix 'Property:' from returned data and add prefix '?'
01573 for(i=0;i<data[1].length;i++) data[1][i]="?"+data[1][i].substr(data[1][i].indexOf(':')+1);
01574 response(jQuery.ui.autocomplete.filter(data[1], smw_escapeQuestion(smw_extractLast(request.term))));
01575 });
01576 },
01577 focus: function() {
01578 // prevent value inserted on focus
01579 return false;
01580 },
01581 select: function(event, ui) {
01582 var terms = smw_split( this.value );
01583 // remove the current input
01584 terms.pop();
01585 // add the selected item
01586 terms.push( ui.item.value );
01587 // add placeholder to get the comma-and-space at the end
01588 terms.push("");
01589 this.value = terms.join("\\n");
01590 return false;
01591 }
01592 });
01593 });
01594 </script>
01595 EOT;
01596
01597 SMWOutputs::requireScript( 'smwPrintoutAutocompleteQueryUI', $javascriptAutocompleteText );
01598
01599 }
01600 $this->setUrlArgs( array( 'po' => $this->getPOStrings() ) );
01601 return Html::element( 'textarea', array( 'id' => 'add_property', 'name' => 'po', 'cols' => '20', 'rows' => '6' ), $this->getPOStrings() );
01602 }
01603
01612 protected function processPOFormBox( WebRequest $wgRequest ) {
01613 $postring = $wgRequest->getText( 'po' );
01614 $poArray = array();
01615
01616 if ( $postring !== '' ) { // parameters from HTML input fields
01617 $ps = explode( "\n", $postring ); // params separated by newlines here (compatible with text-input for printouts)
01618
01619 foreach ( $ps as $param ) { // add initial ? if omitted (all params considered as printouts)
01620 $param = trim( $param );
01621
01622 if ( ( $param !== '' ) && ( $param[0] != '?' ) ) {
01623 $param = '?' . $param;
01624 }
01625
01626 $poArray[] = $param;
01627 }
01628 }
01629
01630 return $poArray;
01631 }
01632
01638 protected $urlArgs = array();
01639
01646 protected function setUrlArgs( array $args ) {
01647 $this->urlArgs = array_merge( $this->urlArgs, $args );
01648 }
01649
01654 protected function getUrlArgs() {
01655 return $this->urlArgs;
01656 }
01657
01658 protected function resetUrlArgs() {
01659 $this->urlArgs = array();
01660 }
01661
01662
01673 protected function showFormatOptions( $format, array $paramValues, array $ignoredAttribs = array() ) {
01674 $printer = SMWQueryProcessor::getResultPrinter( $format, SMWQueryProcessor::SPECIAL_PAGE );
01675
01676 $params = method_exists( $printer, 'getValidatorParameters' ) ? $printer->getValidatorParameters() : array();
01677
01678 $optionsHtml = array();
01679 $urlArgs = array();
01680
01681 foreach ( $params as $param ) {
01682 // Ignore the parameters for which we have a special control in the GUI already.
01683 if ( in_array( $param->getName(), $ignoredAttribs ) ) {
01684 continue;
01685 }
01686
01687 $currentValue = array_key_exists( $param->getName(), $paramValues ) ? $paramValues[$param->getName()] : false;
01688
01689 $optionsHtml[] =
01690 Html::rawElement(
01691 'div',
01692 array(
01693 'style' => 'width: 30%; min-width:220px; margin:5px; padding: 1px; float: left;'
01694 ),
01695 '<label for="p[' . htmlspecialchars( $param->getName() ) . ']">' . htmlspecialchars( $param->getName() ) . ': </label>' .
01696 $this->showFormatOption( $param, $currentValue ) .
01697 '<br />' .
01698 Html::element( 'em', array(), $param->getDescription() )
01699 );
01700 $urlArgs['p[' . htmlspecialchars( $param->getName() ) . ']'] = $currentValue;
01701 }
01702 $this->setUrlArgs( $urlArgs );
01703
01704 for ( $i = 0, $n = count( $optionsHtml ); $i < $n; $i++ ) {
01705 if ( $i % 3 == 2 || $i == $n - 1 ) {
01706 $optionsHtml[$i] .= "<div style=\"clear: both\";></div>\n";
01707 }
01708 }
01709
01710 $i = 0;
01711 $rowHtml = '';
01712 $resultHtml = '';
01713 $flipStyle = true;
01714 $flipCount = 0;
01715 while ( $option = array_shift( $optionsHtml ) ) {
01716 $rowHtml .= $option;
01717 $i++;
01718
01719 $resultHtml .= Html::rawElement(
01720 'div',
01721 array(
01722 'style' => 'background: ' . ( $flipStyle ? 'white' : '#dddddd' ) . ';'
01723 ),
01724 $rowHtml
01725 );
01726
01727 $rowHtml = '';
01728 $flipCount++;
01729 if ( $flipCount == 3 ) {
01730 $flipStyle = !$flipStyle;
01731 $flipCount = 0;
01732 }
01733
01734 }
01735
01736 return $resultHtml;
01737 }
01738
01739
01748 protected function showFormatOption( Parameter $parameter, $currentValue ) {
01749 $input = new ParameterInput( $parameter );
01750 $input->setInputName( 'p[' . $parameter->getName() . ']' );
01751
01752 if ( $currentValue !== false ) {
01753 $input->setCurrentValue( $currentValue );
01754 }
01755
01756 return $input->getHtml();
01757 }
01758
01773 protected function getFormatSelectBoxSep( $defaultFormat = 'broadtable' ) {
01774 global $smwgResultFormats;
01775
01776 SMWOutputs::requireResource( 'jquery' );
01777
01778
01779 $defFormat = 'broadtable';
01780 if ( array_key_exists( $defaultFormat, $smwgResultFormats ) ) {
01781 $defFormat = $defaultFormat;
01782 }
01783
01784 $printer = SMWQueryProcessor::getResultPrinter( $defFormat, SMWQueryProcessor::SPECIAL_PAGE );
01785 $url = $this->getTitle()->getLocalURL( "showformatoptions=' + this.value + '" );
01786
01787 foreach ( $this->uiCore->getParameters() as $param => $value ) {
01788 if ( $param !== 'format' ) {
01789 $url .= '¶ms[' . Xml::escapeJsString( $param ) . ']=' . Xml::escapeJsString( $value );
01790 }
01791 }
01792
01793 $result[0] = "\n" . '<select id="formatSelector" name="p[format]" onChange="JavaScript:updateOtherOptions(\'' . $url . '\')">' . "\n" .
01794 '<option value="' . $defFormat . '">' . $printer->getName() .
01795 ' (' . wfMsg( 'smw_ask_defaultformat' ) . ')</option>' . "\n";
01796
01797 $formats = array();
01798 foreach ( array_keys( $smwgResultFormats ) as $format ) {
01799 // Special formats "count" and "debug" currently not supported.
01800 if ( $format != $defFormat && $format != 'count' && $format != 'debug' ) {
01801 $printer = SMWQueryProcessor::getResultPrinter( $format, SMWQueryProcessor::SPECIAL_PAGE );
01802 $formats[$format] = $printer->getName();
01803 }
01804 }
01805 natcasesort( $formats );
01806
01807 $params = $this->uiCore->getParameters();
01808 foreach ( $formats as $format => $name ) {
01809 $result[0] .= '<option value="' . $format . '"' . ( $params['format'] == $format ? ' selected' : '' ) . '>' . $name . "</option>\n";
01810 }
01811
01812 $result[0] .= "</select>";
01813 $result[0] .= "\n";
01814 $result[] .= '<div id="other_options"> ' . $this->showFormatOptions( $params['format'], $params ) . ' </div>';
01815
01816 // BEGIN: add javascript for updating formating options by ajax
01817 $javascript = <<<END
01818 <script type="text/javascript">
01819 function updateOtherOptions(strURL) {
01820 jQuery.ajax({ url: strURL, context: document.body, success: function(data){
01821 jQuery("#other_options").html(data);
01822 }});
01823 }
01824 </script>
01825 END;
01826
01827 SMWOutputs::requireScript( 'smwUpdateOptionsQueryUI', $javascript );
01828 // END: add javascript for updating formating options by ajax
01829
01830 return $result;
01831 }
01832
01841 protected function processFormatSelectBox( WebRequest $wgRequest ) {
01842 $queryVal = $wgRequest->getVal( 'p' );
01843
01844 if ( !empty( $queryVal ) ) {
01845 $params = SMWInfolink::decodeParameters( $queryVal, false );
01846 } else {
01847 $queryValues = $wgRequest->getArray( 'p' );
01848
01849 if ( is_array( $queryValues ) ) {
01850 foreach ( $queryValues as $key => $val ) {
01851 if ( empty( $val ) ) unset( $queryValues[$key] );
01852 }
01853 }
01854
01855 // p is used for any additional parameters in certain links.
01856 $params = SMWInfolink::decodeParameters( $queryValues, false );
01857 }
01858
01859 return $params;
01860 }
01861
01872 protected function processFormatOptions( $wgRequest ) {
01873 global $wgOut;
01874 if ( $wgRequest->getCheck( 'showformatoptions' ) ) {
01875 // handle Ajax action
01876 $format = $wgRequest->getVal( 'showformatoptions' );
01877 $params = $wgRequest->getArray( 'params' );
01878 $wgOut->disable();
01879 echo $this->showFormatOptions( $format, $params );
01880 return true;
01881 } else {
01882 return false;
01883 }
01884 }
01885
01893 public function getPOStrings() {
01894 $string = '';
01895 $printOuts = $this->uiCore->getPrintOuts();
01896 if ( !empty( $printOuts ) ) {
01897 foreach ( $printOuts as $value ) {
01898 $string .= $value->getSerialisation() . "\n";
01899 }
01900 }
01901 return $string;
01902 }
01903
01910 protected function usesNavigationBar() {
01911 // hide if no results are found
01912 return ( $this->uiCore->getResultCount() != 0 );
01913 }
01914
01915 }