Index: trunk/extensions/SemanticMediaWiki/includes/SMW_InlineQueries.php |
— | — | @@ -262,7 +262,7 @@ |
263 | 263 | } |
264 | 264 | if (array_key_exists('format', $param)) { |
265 | 265 | $this->mFormat = strtolower($param['format']); |
266 | | - if (($this->mFormat != 'ul') && ($this->mFormat != 'ol') && ($this->mFormat != 'list') && ($this->mFormat != 'table') && ($this->mFormat != 'broadtable')) |
| 266 | + if (($this->mFormat != 'ul') && ($this->mFormat != 'ol') && ($this->mFormat != 'list') && ($this->mFormat != 'table') && ($this->mFormat != 'broadtable') && ($this->mFormat != 'timeline')) |
267 | 267 | $this->mFormat = 'auto'; // If it is an unknown format, default to list again |
268 | 268 | } |
269 | 269 | if (array_key_exists('intro', $param)) { |
— | — | @@ -523,6 +523,9 @@ |
524 | 524 | case 'ul': case 'ol': case 'list': |
525 | 525 | $printer = new SMWListPrinter($this,$sq); |
526 | 526 | break; |
| 527 | + case 'timeline': |
| 528 | + $printer = new SMWTimelinePrinter($this,$sq); |
| 529 | + break; |
527 | 530 | default: $printer = new SMWListPrinter($this,$sq); |
528 | 531 | } |
529 | 532 | $result = $printer->printResult(); |
— | — | @@ -940,7 +943,7 @@ |
941 | 944 | global $wgContLang; |
942 | 945 | $row = $this->mDB->fetchRow($this->mRes); |
943 | 946 | if ($row) |
944 | | - return $this->mIQ->makeTitleString($wgContLang->getNsText(NS_CATEGORY) . ':' . $row['cl_to'],'',$this->mLinked); |
| 947 | + return array($this->mIQ->makeTitleString($wgContLang->getNsText(NS_CATEGORY) . ':' . $row['cl_to'],'',$this->mLinked)); |
945 | 948 | else return false; |
946 | 949 | } |
947 | 950 | } |
— | — | @@ -963,7 +966,7 @@ |
964 | 967 | $row = $this->mDB->fetchRow($this->mRes); |
965 | 968 | if ($row) { |
966 | 969 | $this->mDatavalue->setXSDValue($row['value_xsd'],$row['value_unit']); |
967 | | - return $this->mDatavalue->getStringValue(); |
| 970 | + return array($this->mDatavalue->getStringValue(), $this->mDatavalue); |
968 | 971 | } else return false; |
969 | 972 | } |
970 | 973 | } |
— | — | @@ -988,7 +991,7 @@ |
989 | 992 | global $wgContLang; |
990 | 993 | $row = $this->mDB->fetchRow($this->mRes); |
991 | 994 | if ($row) { |
992 | | - return $this->mIQ->makeTitleString($wgContLang->getNsText($row['object_namespace']) . ':' . $row['object_title'],'',$this->mLinked); |
| 995 | + return array($this->mIQ->makeTitleString($wgContLang->getNsText($row['object_namespace']) . ':' . $row['object_title'],'',$this->mLinked)); |
993 | 996 | } else return false; |
994 | 997 | } |
995 | 998 | } |
— | — | @@ -1007,7 +1010,7 @@ |
1008 | 1011 | public function getNext() { |
1009 | 1012 | if ($this->mHasNext) { |
1010 | 1013 | $this->mHasNext = false; |
1011 | | - return $this->mValue; |
| 1014 | + return array($this->mValue); |
1012 | 1015 | } else return false; |
1013 | 1016 | } |
1014 | 1017 | } |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_GlobalFunctions.php |
— | — | @@ -29,6 +29,12 @@ |
30 | 30 | // include images. Changes in the above must always be coordinated with the script! |
31 | 31 | $out->addScript($sortTableScript); |
32 | 32 | |
| 33 | + // TODO: we should rather have a script that only pulls the whole Timeline on demand, if possible |
| 34 | + $TimelineScript = '<script type="text/javascript" src="' . $smwgScriptPath . '/skins/SimileTimeline/timeline-api.js"></script>'; |
| 35 | + $SMWTimelineScript = '<script type="text/javascript" src="' . $smwgScriptPath . '/skins/SMW_timeline.js"></script>'; |
| 36 | + $out->addScript($TimelineScript); |
| 37 | + $out->addScript($SMWTimelineScript); |
| 38 | + |
33 | 39 | // Also we add a custom CSS file for our needs |
34 | 40 | $customCssUrl = $smwgScriptPath . '/skins/SMW_custom.css'; |
35 | 41 | $out->addLink(array( |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_QueryPrinters.php |
— | — | @@ -53,7 +53,7 @@ |
54 | 54 | $first = true; |
55 | 55 | while ($cur = $iterator->getNext()) { |
56 | 56 | if ($first) $first = false; else $result .= '<br />'; |
57 | | - $result .= $cur; |
| 57 | + $result .= $cur[0]; |
58 | 58 | } |
59 | 59 | $result .= "</td>"; |
60 | 60 | $firstcol = false; |
— | — | @@ -146,7 +146,7 @@ |
147 | 147 | $result .= $print_data[0] . ' '; |
148 | 148 | } |
149 | 149 | } |
150 | | - $result .= $cur; // actual output value |
| 150 | + $result .= $cur[0]; // actual output value |
151 | 151 | } |
152 | 152 | $first_col = false; |
153 | 153 | } |
— | — | @@ -175,4 +175,136 @@ |
176 | 176 | } |
177 | 177 | } |
178 | 178 | |
| 179 | +/** |
| 180 | + * Printer for timeline data. |
| 181 | + */ |
| 182 | +class SMWTimelinePrinter implements SMWQueryPrinter { |
| 183 | + private $mIQ; // the querying object that called the printer |
| 184 | + private $mQuery; // the query that was executed and whose results are to be printed |
| 185 | + |
| 186 | + public function SMWTimelinePrinter($iq, $query) { |
| 187 | + $this->mIQ = $iq; |
| 188 | + $this->mQuery = $query; |
| 189 | + } |
| 190 | + |
| 191 | + public function printResult() { |
| 192 | + global $smwgIQRunningNumber; |
| 193 | + |
| 194 | + $params = $this->mIQ->getParameters(); |
| 195 | + if (array_key_exists('timelinestart', $params)) { |
| 196 | + $startdate = smwfNormalTitleDBKey($params['timelinestart']); |
| 197 | + } else $startdate = ''; |
| 198 | + if (array_key_exists('timelineend', $params)) { |
| 199 | + $enddate = smwfNormalTitleDBKey($params['timelineend']); |
| 200 | + } else $enddate = ''; |
| 201 | + |
| 202 | + if ( ($startdate == '') ) { // seek defaults |
| 203 | + foreach ($this->mQuery->mPrint as $print_data) { |
| 204 | + if ( ($print_data[1] == SMW_IQ_PRINT_ATTS) && ($print_data[3]->getTypeID() == 'datetime' ) ) { |
| 205 | + if ( ($enddate == '') && ($startdate != '') && ($startdate != $print_data[2]) ) |
| 206 | + $enddate = $print_data[2]; |
| 207 | + if ( ($startdate == '') && ($enddate != $print_data[2]) ) |
| 208 | + $startdate = $print_data[2]; |
| 209 | + } |
| 210 | + } |
| 211 | + } |
| 212 | + |
| 213 | + if (array_key_exists('timelinesize', $params)) { |
| 214 | + $size = htmlspecialchars(str_replace(';', ' ', $params['timelinesize'])); // str_replace makes sure this is only one value, not mutliple CSS fields (prevent CSS attacks) |
| 215 | + } else $size = "300px"; |
| 216 | + |
| 217 | + // print header |
| 218 | + $result = "<div class=\"smwtimeline\" id=\"smwtimeline$smwgIQRunningNumber\" style=\"height: $size\">"; |
| 219 | + $result .= '<span class="smwtlcomment">' . wfMsgForContent('smw_iq_nojs',$this->mIQ->getQueryURL()) . '</span>'; // note for people without JavaScript |
| 220 | + |
| 221 | + if (array_key_exists('timelinebands', $params)) { //check for band parameter, should look like "DAY,MONTH,YEAR" |
| 222 | + $bands = preg_split('/[,][\s]?/',$params['timelinebands']); |
| 223 | + foreach ($bands as $band) { |
| 224 | + $result .= '<span class="smwtlband">' . htmlspecialchars($band) . '</span>'; |
| 225 | + //just print any "band" given, the JavaScript will figure out what to make of it |
| 226 | + } |
| 227 | + } |
| 228 | + |
| 229 | + // print all result rows |
| 230 | + $positions = array(); // possible positions, collected to select one for centering |
| 231 | + if ($startdate != '') { |
| 232 | + $output = false; // true if output was given on current line |
| 233 | + while ( $row = $this->mIQ->getNextRow() ) { |
| 234 | + $hastime = false; // true as soon as some startdate value was found |
| 235 | + $curdata = '<span class="smwtlevent">'; |
| 236 | + $first_col = true; |
| 237 | + foreach ($this->mQuery->mPrint as $print_data) { |
| 238 | + $iterator = $this->mIQ->getIterator($print_data,$row,$first_col); |
| 239 | + $first_value = true; |
| 240 | + while ($cur = $iterator->getNext()) { |
| 241 | + if ($first_value) { |
| 242 | + $first_value = false; |
| 243 | + if ( ($print_data[1] == SMW_IQ_PRINT_ATTS) && ($print_data[2] == $startdate) ) { |
| 244 | + //FIXME: Timeline scripts should support XSD format explicitly. They |
| 245 | + //currently seem to implement iso8601 which deviates from XSD in cases. |
| 246 | + $curdata .= '<span class="smwtlstart">' . $cur[1]->getXSDValue() . '</span>'; |
| 247 | + $positions[$cur[1]->getNumericValue()] = $cur[1]->getXSDValue(); |
| 248 | + $hastime = true; |
| 249 | + } |
| 250 | + if ( ($print_data[1] == SMW_IQ_PRINT_ATTS) && ($print_data[2] == $enddate) ) { |
| 251 | + //FIXME: Timeline scripts should support XSD format explicitly. They |
| 252 | + //currently seem to implement iso8601 which deviates from XSD in cases. |
| 253 | + $curdata .= '<span class="smwtlend">' . $cur[1]->getXSDValue() . '</span>'; |
| 254 | + } |
| 255 | + if ( $this->mIQ->showHeaders() && ('' != $print_data[0]) ) { |
| 256 | + $curdata .= $print_data[0] . ' '; |
| 257 | + } |
| 258 | + if ( $first_col ) { |
| 259 | + $curdata .= '<span class="smwtlurl">' . $cur[0] . '</span>'; |
| 260 | + } |
| 261 | + } else $curdata .= ', '; |
| 262 | + if (!$first_col) { |
| 263 | + $curdata .= $cur[0]; |
| 264 | + $output = true; |
| 265 | + } |
| 266 | + } |
| 267 | + if ($output) $curdata .= "<br />"; |
| 268 | + $output = false; |
| 269 | + $first_col = false; |
| 270 | + } |
| 271 | + if ( $hastime ) |
| 272 | + $result .= $curdata . "</span>"; |
| 273 | + } |
| 274 | + // find display position: |
| 275 | + if (array_key_exists('timelineposition', $params)) { |
| 276 | + $pos = $params['timelineposition']; |
| 277 | + } else $pos = 'middle'; |
| 278 | + ksort($positions); |
| 279 | + $positions = array_values($positions); |
| 280 | + switch ($pos) { |
| 281 | + case 'start': |
| 282 | + $result .= '<span class="smwtlposition">' . $positions[0] . '</span>'; |
| 283 | + break; |
| 284 | + case 'end': |
| 285 | + $result .= '<span class="smwtlposition">' . $positions[count($positions)-1] . '</span>'; |
| 286 | + break; |
| 287 | + case 'today': break; // default |
| 288 | + case 'middle': default: |
| 289 | + $result .= '<span class="smwtlposition">' . $positions[ceil(count($positions)/2)-1] . '</span>'; |
| 290 | + break; |
| 291 | + } |
| 292 | + } |
| 293 | + |
| 294 | +// if ($this->mIQ->isInline() && $this->mIQ->hasFurtherResults()) { |
| 295 | +// $label = $this->mIQ->getSearchLabel(); |
| 296 | +// if ($label === NULL) { //apply default |
| 297 | +// $label = wfMsgForContent('smw_iq_moreresults'); |
| 298 | +// } |
| 299 | +// if ($label != '') { |
| 300 | +// $result .= "\n\t\t<tr class=\"smwfooter\"><td class=\"sortbottom\" colspan=\"" . count($this->mQuery->mPrint) . '\"> <a href="' . $this->mIQ->getQueryURL() . '">' . $label . '</a></td></tr>'; |
| 301 | +// } |
| 302 | +// } |
| 303 | + |
| 304 | + // print footer |
| 305 | + $result .= "</div>"; |
| 306 | + |
| 307 | + return $result; |
| 308 | + } |
| 309 | +} |
| 310 | + |
179 | 311 | ?> |
\ No newline at end of file |
Index: trunk/extensions/SemanticMediaWiki/languages/SMW_LanguageEn.php |
— | — | @@ -20,6 +20,7 @@ |
21 | 21 | /*Messages and strings for inline queries*/ |
22 | 22 | 'smw_iq_disabled' => "<span class='smwwarning'>Sorry. Inline queries have been disabled for this wiki.</span>", |
23 | 23 | 'smw_iq_moreresults' => '… further results', |
| 24 | + 'smw_iq_nojs' => 'Use a JavaScript-enabled browser to view this element, or directly <a href="$1">browse the result list</a>.', |
24 | 25 | /*Messages and strings for ontology resued (import) */ |
25 | 26 | 'smw_unknown_importns' => '[Sorry, import functions are not avalable for namespace "$1".]', |
26 | 27 | 'smw_nonright_importtype' => '[Sorry, $1 can only be used for articles with namespace "$2"]', |
Index: trunk/extensions/SemanticMediaWiki/languages/SMW_LanguageEs.php |
— | — | @@ -20,6 +20,7 @@ |
21 | 21 | /*Messages and strings for inline queries*/ |
22 | 22 | 'smw_iq_disabled' => "<span class='smwwarning'>Lo sentimos. Las búsquedas en los artículos de este wiki no están autorizadas</span>", |
23 | 23 | 'smw_iq_moreresults' => '… further results', // TODO: translate |
| 24 | + 'smw_iq_nojs' => 'Use a JavaScript-enabled browser to view this element, or directly <a href="$1">browse the result list</a>.', // TODO: translate |
24 | 25 | /*Messages and strings for ontology resued (import) */ |
25 | 26 | 'smw_unknown_importns' => '[Lo sentimos. Ninguna función de importación está disponible para el espacio de nombres "$1".]', |
26 | 27 | 'smw_nonright_importtype' => '[El elemento "$1" no puede ser empleado más que para los artículos del espacio de nombres "$2".]', |
Index: trunk/extensions/SemanticMediaWiki/languages/SMW_LanguageFr.php |
— | — | @@ -20,6 +20,7 @@ |
21 | 21 | /*Messages and strings for inline queries*/ |
22 | 22 | 'smw_iq_disabled' => "<span class='smwwarning'>Désolé. Les recherches dans les articles de ce wiki ne sont pas autorisées</span>", |
23 | 23 | 'smw_iq_moreresults' => '… further results', // TODO: translate |
| 24 | + 'smw_iq_nojs' => 'Use a JavaScript-enabled browser to view this element, or directly <a href="$1">browse the result list</a>.', // TODO: translate |
24 | 25 | /*Messages and strings for ontology resued (import) */ |
25 | 26 | 'smw_unknown_importns' => '[Désolé. Aucune fonction d\'import n\'est disponible pour l\'espace de nommage "$1".]', |
26 | 27 | 'smw_nonright_importtype' => '[L\'élément "$1" ne peut être employé que pour des articles de l\'espace de nommage "$2".]', |
Index: trunk/extensions/SemanticMediaWiki/languages/SMW_LanguageDe.php |
— | — | @@ -20,6 +20,8 @@ |
21 | 21 | /*Messages and strings for inline queries*/ |
22 | 22 | 'smw_iq_disabled' => "<span class='smwwarning'>Anfragen in Artikeln sind in diesem Wiki leider nicht erlaubt.</span>", |
23 | 23 | 'smw_iq_moreresults' => '… weitere Ergebnisse', |
| 24 | + 'smw_iq_nojs' => 'Der Inhalt dieses Elementes kann mit einem Browser mit JavaScript-Unterstützung oder als |
| 25 | + <a href="$1">Liste einzelner Suchergebnisse</a> betrachtet werden.', // TODO: translate |
24 | 26 | /*Messages and strings for ontology resued (import) */ |
25 | 27 | 'smw_unknown_importns' => '[Für den Namensraum "$1" sind leider keine Importfunktionen verfügbar.]', |
26 | 28 | 'smw_nonright_importtype' => '[Das Element "$1" kann nur für Artikel im Namensraum "$2" verwendet werden.]', |