Index: trunk/extensions/SemanticMediaWiki/RELEASE-NOTES |
— | — | @@ -7,6 +7,7 @@ |
8 | 8 | (required for French) |
9 | 9 | * Extended translations |
10 | 10 | * Update job generation actually works now |
| 11 | +* Query format "csv" to export data as file of comma-separated values |
11 | 12 | * Prevent crashes for very long property values (due to PHP PCRE) |
12 | 13 | * Various other bugfixes |
13 | 14 | |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_QP_CSV.php |
— | — | @@ -0,0 +1,80 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * CSV export for SMW Queries |
| 5 | + */ |
| 6 | + |
| 7 | +/** |
| 8 | + * Printer class for generating CSV output |
| 9 | + * @author Nathan R. Yergler |
| 10 | + * @note AUTOLOADED |
| 11 | + */ |
| 12 | +class SMWCsvResultPrinter extends SMWResultPrinter { |
| 13 | + protected $m_sep; |
| 14 | + |
| 15 | + protected function readParameters($params,$outputmode) { |
| 16 | + SMWResultPrinter::readParameters($params,$outputmode); |
| 17 | + if (array_key_exists('sep', $params)) { |
| 18 | + $this->m_sep = str_replace('_',' ',$params['sep']); |
| 19 | + } else { |
| 20 | + $this->m_sep = ','; |
| 21 | + } |
| 22 | + } |
| 23 | + |
| 24 | + public function getResult($results, $params, $outputmode) { |
| 25 | + // skip checks, results with 0 entries are normal |
| 26 | + $this->readParameters($params,$outputmode); |
| 27 | + return $this->getResultText($results,$outputmode) . $this->getErrorString($results); |
| 28 | + } |
| 29 | + |
| 30 | + public function getMimeType($res) { |
| 31 | + return 'text/csv'; |
| 32 | + } |
| 33 | + |
| 34 | + public function getFileName($res) { |
| 35 | + return 'result.csv'; |
| 36 | + } |
| 37 | + |
| 38 | + protected function getResultText($res, $outputmode) { |
| 39 | + |
| 40 | + global $smwgIQRunningNumber, $wgSitename, $wgServer, $wgRequest; |
| 41 | + $result = ''; |
| 42 | + |
| 43 | + if ($outputmode == SMW_OUTPUT_FILE) { // make CSV file |
| 44 | + $csv = fopen('php://memory', 'r+'); |
| 45 | + while ( $row = $res->getNext() ) { |
| 46 | + $row_items = array(); |
| 47 | + foreach ($row as $field) { |
| 48 | + $growing = array(); |
| 49 | + while (($object = $field->getNextObject()) !== false) { |
| 50 | + $text = Sanitizer::decodeCharReferences($object->getWikiValue()); |
| 51 | + // decode: CSV knows nothing of possible HTML entities |
| 52 | + $growing[] = $text; |
| 53 | + } // while... |
| 54 | + $row_items[] = implode(',', $growing); |
| 55 | + } // foreach... |
| 56 | + fputcsv($csv, $row_items, $this->m_sep); |
| 57 | + } // while... |
| 58 | + |
| 59 | + rewind($csv); |
| 60 | + $result .= stream_get_contents($csv); |
| 61 | + } else { // just make link to feed |
| 62 | + if ($this->mSearchlabel) { |
| 63 | + $label = $this->mSearchlabel; |
| 64 | + } else { |
| 65 | + $label = wfMsgForContent('smw_csv_link'); |
| 66 | + } |
| 67 | + |
| 68 | + $link = $res->getQueryLink($label); |
| 69 | + $link->setParameter('csv','format'); |
| 70 | + $link->setParameter($this->m_sep,'sep'); |
| 71 | + if (array_key_exists('limit', $this->m_params)) { |
| 72 | + $link->setParameter($this->m_params['limit'],'limit'); |
| 73 | + } else { // use a reasonable default limit |
| 74 | + $link->setParameter(100,'limit'); |
| 75 | + } |
| 76 | + $result .= $link->getText($outputmode,$this->mLinker); |
| 77 | + } |
| 78 | + return $result; |
| 79 | + } |
| 80 | + |
| 81 | +} |
Property changes on: trunk/extensions/SemanticMediaWiki/includes/SMW_QP_CSV.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 82 | + native |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_QueryProcessor.php |
— | — | @@ -38,7 +38,8 @@ |
39 | 39 | 'debug' => 'SMWListResultPrinter', |
40 | 40 | 'rss' => 'SMWRSSResultPrinter', |
41 | 41 | 'icalendar' => 'SMWiCalendarResultPrinter', |
42 | | - 'vcard' => 'SMWvCardResultPrinter'); |
| 42 | + 'vcard' => 'SMWvCardResultPrinter', |
| 43 | + 'csv' => 'SMWCsvResultPrinter'); |
43 | 44 | |
44 | 45 | /** |
45 | 46 | * Parse a query string given in SMW's query language to create |
— | — | @@ -75,7 +76,7 @@ |
76 | 77 | $querymode = SMWQuery::MODE_COUNT; |
77 | 78 | } elseif ($format == 'debug') { |
78 | 79 | $querymode = SMWQuery::MODE_DEBUG; |
79 | | - } elseif (in_array($format, array('rss','icalendar','vcard'))) { |
| 80 | + } elseif (in_array($format, array('rss','icalendar','vcard','csv'))) { |
80 | 81 | $querymode = SMWQuery::MODE_NONE; |
81 | 82 | } else { |
82 | 83 | $querymode = SMWQuery::MODE_INSTANCES; |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_GlobalFunctions.php |
— | — | @@ -111,6 +111,7 @@ |
112 | 112 | $wgAutoloadClasses['SMWRSSResultPrinter'] = $smwgIP . '/includes/SMW_QP_RSSlink.php'; |
113 | 113 | $wgAutoloadClasses['SMWiCalendarResultPrinter'] = $smwgIP . '/includes/SMW_QP_iCalendar.php'; |
114 | 114 | $wgAutoloadClasses['SMWvCardResultPrinter'] = $smwgIP . '/includes/SMW_QP_vCard.php'; |
| 115 | + $wgAutoloadClasses['SMWCsvResultPrinter'] = $smwgIP . '/includes/SMW_QP_CSV.php'; |
115 | 116 | //// datavalues |
116 | 117 | $wgAutoloadClasses['SMWDataValue'] = $smwgIP . '/includes/SMW_DataValue.php'; |
117 | 118 | $wgAutoloadClasses['SMWErrorvalue'] = $smwgIP . '/includes/SMW_DV_Error.php'; |
Index: trunk/extensions/SemanticMediaWiki/languages/SMW_Messages.php |
— | — | @@ -29,6 +29,8 @@ |
30 | 30 | |
31 | 31 | // Link to RSS feeds |
32 | 32 | 'smw_rss_link' => 'RSS', |
| 33 | + // Link to CSV feeds |
| 34 | + 'smw_csv_link' => 'CSV', |
33 | 35 | |
34 | 36 | // Link to iCalendar and vCard files |
35 | 37 | 'smw_icalendar_link' => 'iCalendar', |
Index: trunk/extensions/SemanticMediaWiki/README |
— | — | @@ -45,7 +45,7 @@ |
46 | 46 | |
47 | 47 | * Code has been contributed by (in no particular order) Kai Hüner, Fernando Correia, |
48 | 48 | Yaron Koren, and Nick Grandy, Jörg Heizmann, Daniel Herzig, Nikolas Iwan, Tobias Matzner, |
49 | | - Thomas Bleher, Felix Kratzer, Frank Dengler. |
| 49 | + Thomas Bleher, Felix Kratzer, Frank Dengler, Nathan R. Yergler. |
50 | 50 | |
51 | 51 | * The new logo and related artwork for Semantic MediaWiki (see semanticweb.org) |
52 | 52 | has been designed and realised by Rozana Vrandecic. |