Index: trunk/extensions/SemanticMediaWiki/maintenance/SMW_refreshData.php |
— | — | @@ -153,8 +153,8 @@ |
154 | 154 | if ( smwfIsSemanticsProcessed($title->getNamespace()) ) { |
155 | 155 | $revision = Revision::newFromTitle( $title ); |
156 | 156 | if ( $revision === NULL ) continue; |
157 | | - $wgParser->parse($revision->getText(), $title, $options, true, true, $revision->getID()); |
158 | | - SMWFactbox::storeData(true); |
| 157 | + $output = $wgParser->parse($revision->getText(), $title, $options, true, true, $revision->getID()); |
| 158 | + SMWParseData::storeData($output, $title, false); |
159 | 159 | // sleep to be nice to the server |
160 | 160 | if ( ($delay !== false) && (($num_files+1) % 100 === 0) ) { |
161 | 161 | usleep($delay); |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_ParseData.php |
— | — | @@ -0,0 +1,199 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * The class in this file manages semantic data collected during parsing of |
| 5 | + * an article. |
| 6 | + * @file |
| 7 | + * @ingroup SMW |
| 8 | + * @author Markus Krötzsch |
| 9 | + */ |
| 10 | + |
| 11 | +/** |
| 12 | + * Static class for managing semantic data collected during parsing. All methods |
| 13 | + * in this class are stateless: data is stored persistently only in a given parser |
| 14 | + * output. |
| 15 | + * @ingroup SMW |
| 16 | + */ |
| 17 | +class SMWParseData { |
| 18 | + |
| 19 | + /** |
| 20 | + * This function retrieves the SMW data from a given parser, and creates |
| 21 | + * a new empty container if it is not initiated yet. |
| 22 | + */ |
| 23 | + static public function getSMWdata(Parser $parser) { |
| 24 | + $output = $parser->getOutput(); |
| 25 | + $title = $parser->getTitle(); |
| 26 | + if (!isset($output) || !isset($title)) return NULL; // no parsing, create error |
| 27 | + if (!isset($output->mSMWData)) { // no data container yet |
| 28 | + $dv = SMWDataValueFactory::newTypeIDValue('_wpg'); |
| 29 | + $dv->setValues($title->getDBkey(), $title->getNamespace()); |
| 30 | + $output->mSMWData = new SMWSemanticData($dv); |
| 31 | + } |
| 32 | + return $output->mSMWData; |
| 33 | + } |
| 34 | + |
| 35 | + /** |
| 36 | + * Clear all stored data for a given parser. |
| 37 | + */ |
| 38 | + static public function clearStorage(Parser $parser) { |
| 39 | + $output = $parser->getOutput(); |
| 40 | + $title = $parser->getTitle(); |
| 41 | + if (!isset($output) || !isset($title)) return; |
| 42 | + $dv = SMWDataValueFactory::newTypeIDValue('_wpg'); |
| 43 | + $dv->setValues($title->getDBkey(), $title->getNamespace()); |
| 44 | + $output->mSMWData = new SMWSemanticData($dv); |
| 45 | + } |
| 46 | + |
| 47 | + /** |
| 48 | + * This method adds a new property with the given value to the storage. It is |
| 49 | + * intended to be used on user input, and property and value are sepcified by |
| 50 | + * strings as they might be found in a wiki. The function returns a datavalue |
| 51 | + * object that contains the result of the operation. |
| 52 | + */ |
| 53 | + static public function addProperty($propertyname, $value, $caption, Parser $parser, $storeannotation = true) { |
| 54 | + wfProfileIn("SMWParseData::addProperty (SMW)"); |
| 55 | + global $smwgContLang; |
| 56 | + // See if this property is a special one, such as e.g. "has type" |
| 57 | + $propertyname = smwfNormalTitleText($propertyname); //slightly normalize label |
| 58 | + $special = $smwgContLang->findSpecialPropertyID($propertyname); |
| 59 | + |
| 60 | + switch ($special) { |
| 61 | + case false: // normal property |
| 62 | + $result = SMWDataValueFactory::newPropertyValue($propertyname,$value,$caption); |
| 63 | + if ($storeannotation && (SMWParseData::getSMWData($parser) !== NULL)) { |
| 64 | + SMWParseData::getSMWData($parser)->addPropertyValue($propertyname,$result); |
| 65 | + } |
| 66 | + wfProfileOut("SMWParseData::addProperty (SMW)"); |
| 67 | + return $result; |
| 68 | + default: // generic special property |
| 69 | + $result = SMWDataValueFactory::newSpecialValue($special,$value,$caption); |
| 70 | + if ($storeannotation && (SMWParseData::getSMWData($parser) !== NULL)) { |
| 71 | + SMWParseData::getSMWData($parser)->addSpecialValue($special,$result); |
| 72 | + } |
| 73 | + wfProfileOut("SMWParseData::addProperty (SMW)"); |
| 74 | + return $result; |
| 75 | + } |
| 76 | + } |
| 77 | + |
| 78 | + |
| 79 | + /** |
| 80 | + * This function takes care of storing the collected semantic data and takes |
| 81 | + * care of clearing out any outdated entries for the processed page. It assume that |
| 82 | + * parsing has happened and that all relevant data is contained in the provided parser |
| 83 | + * output. |
| 84 | + * |
| 85 | + * Optionally, this function also takes care of triggering indirect updates that might be |
| 86 | + * needed for overall database consistency. If the saved page describes a property or data type, |
| 87 | + * the method checks whether the property type, the data type, the allowed values, or the |
| 88 | + * conversion factors have changed. If so, it triggers SMWUpdateJobs for the relevant articles, |
| 89 | + * which then asynchronously update the semantic data in the database. |
| 90 | + * |
| 91 | + * @todo Known bug/limitation: Updatejobs are triggered when a property or type |
| 92 | + * definition has changed, so that all affected pages get updated. However, if a |
| 93 | + * page uses a property but the given value caused an error, then there is no record |
| 94 | + * of that page using the property, so that it will not be updated. To fix this, one |
| 95 | + * would need to store errors as well. |
| 96 | + * |
| 97 | + * @param $parseroutput ParserOutput object that contains the results of parsing which will |
| 98 | + * be stored. |
| 99 | + * @param $title Title object specifying the page that should be safed. |
| 100 | + * @param $makejobs Bool stating whether jobs should be created to trigger further updates if |
| 101 | + * this appears to be necessary after this update. |
| 102 | + * |
| 103 | + * @bug This still refers to SMWFactbox::isNewArticle(). Move this somewhere else or find a way to kill it (the new store does not need it anyway). |
| 104 | + * @bug Some job generations here might create too many jobs at once on a large wiki. Use incremental jobs instead. |
| 105 | + */ |
| 106 | + static public function storeData($parseroutput, $title, $makejobs = true) { |
| 107 | + global $smwgEnableUpdateJobs; |
| 108 | + $semdata = $parseroutput->mSMWData; |
| 109 | + $namespace = $title->getNamespace(); |
| 110 | + $processSemantics = smwfIsSemanticsProcessed($namespace); |
| 111 | + if (!isset($semdata)) { // no data at all? |
| 112 | + $dv = SMWDataValueFactory::newTypeIDValue('_wpg'); |
| 113 | + $dv->setValues($title->getDBKey(), $namespace); |
| 114 | + $semdata = new SMWSemanticData($dv); |
| 115 | + } elseif (!$processSemantics) { // data found, but do all operations as if it was empty |
| 116 | + $semdata = new SMWSemanticData($semdata->getSubject()); |
| 117 | + } |
| 118 | + |
| 119 | + // Check if the semantic data has been changed. |
| 120 | + // Sets the updateflag to true if so. |
| 121 | + // Careful: storage access must happen *before* the storage update; |
| 122 | + // even finding uses of a property fails after its type was changed. |
| 123 | + $updatejobflag = false; |
| 124 | + $jobs = array(); |
| 125 | + if ($makejobs && $smwgEnableUpdateJobs && ($namespace == SMW_NS_PROPERTY) ) { |
| 126 | + // if it is a property, then we need to check if the type or |
| 127 | + // the allowed values have been changed |
| 128 | + $oldtype = smwfGetStore()->getSpecialValues($title, SMW_SP_HAS_TYPE); |
| 129 | + $newtype = $semdata->getPropertyValues(SMW_SP_HAS_TYPE); |
| 130 | + |
| 131 | + if (!SMWParseData::equalDatavalues($oldtype, $newtype)) { |
| 132 | + $updatejobflag = true; |
| 133 | + } else { |
| 134 | + $oldvalues = smwfGetStore()->getSpecialValues($title, SMW_SP_POSSIBLE_VALUE); |
| 135 | + $newvalues = $semdata->getPropertyValues(SMW_SP_POSSIBLE_VALUE); |
| 136 | + $updatejobflag = !SMWParseData::equalDatavalues($oldvalues, $newvalues); |
| 137 | + } |
| 138 | + |
| 139 | + if ($updatejobflag) { |
| 140 | + $subjects = smwfGetStore()->getAllPropertySubjects($title); |
| 141 | + foreach ($subjects as $subject) { |
| 142 | + $jobs[] = new SMWUpdateJob($subject); |
| 143 | + } |
| 144 | + } |
| 145 | + } elseif ($makejobs && $smwgEnableUpdateJobs && ($namespace == SMW_NS_TYPE) ) { |
| 146 | + // if it is a type we need to check if the conversion factors have been changed |
| 147 | + $oldfactors = smwfGetStore()->getSpecialValues($title, SMW_SP_CONVERSION_FACTOR); |
| 148 | + $newfactors = $semdata->getPropertyValues(SMW_SP_CONVERSION_FACTOR); |
| 149 | + $updatejobflag = !SMWParseData::equalDatavalues($oldfactors, $newfactors); |
| 150 | + if ($updatejobflag) { |
| 151 | + $store = smwfGetStore(); |
| 152 | + /// FIXME: this would kill large wikis! Use incremental updates! |
| 153 | + $dv = SMWDataValueFactory::newSpecialValue(SMW_SP_HAS_TYPE,$title->getDBkey()); |
| 154 | + $subjects = $store->getSpecialSubjects(SMW_SP_HAS_TYPE, $dv); |
| 155 | + foreach ($subjects as $valueofpropertypagestoupdate) { |
| 156 | + $subjectsPropertyPages = $store->getAllPropertySubjects($valueofpropertypagestoupdate->getTitle()); |
| 157 | + $jobs[] = new SMWUpdateJob($valueofpropertypagestoupdate->getTitle()); |
| 158 | + foreach ($subjectsPropertyPages as $titleOfPageToUpdate) { |
| 159 | + $jobs[] = new SMWUpdateJob($titleOfPageToUpdate); |
| 160 | + } |
| 161 | + } |
| 162 | + } |
| 163 | + } |
| 164 | + |
| 165 | + // Actually store semantic data, or at least clear it if needed |
| 166 | + if ($processSemantics) { |
| 167 | + smwfGetStore()->updateData($semdata, SMWFactbox::isNewArticle()); |
| 168 | + } else { |
| 169 | + smwfGetStore()->clearData($semdata->getSubject()->getTitle(), SMWFactbox::isNewArticle()); |
| 170 | + } |
| 171 | + |
| 172 | + // Finally trigger relevant Updatejobs if necessary |
| 173 | + if ($updatejobflag) { |
| 174 | + Job::batchInsert($jobs); ///NOTE: this only happens if $smwgEnableUpdateJobs was true above |
| 175 | + } |
| 176 | + return true; |
| 177 | + } |
| 178 | + |
| 179 | + /** |
| 180 | + * Compares if two arrays of data values contain the same content. |
| 181 | + * Returns true if the two arrays contain the same data values, |
| 182 | + * false otherwise. |
| 183 | + */ |
| 184 | + static public function equalDatavalues($dv1, $dv2) { |
| 185 | + // The hashes of all values of both arrays are taken, then sorted |
| 186 | + // and finally concatenated, thus creating one long hash out of each |
| 187 | + // of the data value arrays. These are compared. |
| 188 | + $values = array(); |
| 189 | + foreach($dv1 as $v) $values[] = $v->getHash(); |
| 190 | + sort($values); |
| 191 | + $dv1hash = implode("___", $values); |
| 192 | + $values = array(); |
| 193 | + foreach($dv2 as $v) $values[] = $v->getHash(); |
| 194 | + sort($values); |
| 195 | + $dv2hash = implode("___", $values); |
| 196 | + |
| 197 | + return ($dv1hash == $dv2hash); |
| 198 | + } |
| 199 | + |
| 200 | +} |
\ No newline at end of file |
Property changes on: trunk/extensions/SemanticMediaWiki/includes/SMW_ParseData.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 201 | + native |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_Data.php |
— | — | @@ -57,8 +57,7 @@ |
58 | 58 | $subject = $parts[1]; |
59 | 59 | // Adds the fact to the factbox, which may be problematic in case |
60 | 60 | // the parser gets called several times... |
61 | | - if (!SMWFactbox::$semdata) SMWFactBox::initStorage($parser->getTitle()); |
62 | | - SMWFactbox::addProperty( $property, $subject, false, true ); |
| 61 | + SMWParseData::addProperty( $property, $subject, false, $parser, true ); |
63 | 62 | } |
64 | 63 | } |
65 | 64 | return; |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_Hooks.php |
— | — | @@ -16,13 +16,11 @@ |
17 | 17 | * at the end of the article. |
18 | 18 | */ |
19 | 19 | function smwfParserHook(&$parser, &$text) { |
20 | | - global $smwgStoreAnnotations, $smwgTempStoreAnnotations, $smwgStoreActive, $smwgLinksInValues; |
21 | | - SMWFactbox::initStorage($parser->getTitle()); // be sure we have our title, strange things happen in parsing |
22 | | - SMWFactbox::setWritelock(true); // disallow changes to the title object by other hooks! |
| 20 | + global $smwgStoreAnnotations, $smwgTempStoreAnnotations, $smwgLinksInValues, $smwgTempParser; |
23 | 21 | |
24 | 22 | // store the results if enabled (we have to parse them in any case, in order to |
25 | 23 | // clean the wiki source for further processing) |
26 | | - if ( $smwgStoreActive && smwfIsSemanticsProcessed($parser->getTitle()->getNamespace()) ) { |
| 24 | + if ( smwfIsSemanticsProcessed($parser->getTitle()->getNamespace()) ) { |
27 | 25 | $smwgStoreAnnotations = true; |
28 | 26 | } else { |
29 | 27 | $smwgStoreAnnotations = false; |
— | — | @@ -35,10 +33,11 @@ |
36 | 34 | if ($rt !== NULL) { |
37 | 35 | $dv = SMWDataValueFactory::newSpecialValue(SMW_SP_REDIRECTS_TO,$rt->getPrefixedText()); |
38 | 36 | if ($smwgStoreAnnotations) { |
39 | | - SMWFactbox::$semdata->addSpecialValue(SMW_SP_REDIRECTS_TO,$dv); |
| 37 | + SMWParseData::getSMWData($parser)->addSpecialValue(SMW_SP_REDIRECTS_TO,$dv); |
40 | 38 | } |
41 | 39 | } |
42 | 40 | |
| 41 | + $smwgTempParser = $parser; // only used in subsequent callbacks, forgotten afterwards |
43 | 42 | // In the regexp matches below, leading ':' escapes the markup, as |
44 | 43 | // known for Categories. |
45 | 44 | // Parse links to extract semantic properties |
— | — | @@ -62,7 +61,7 @@ |
63 | 62 | /xu'; |
64 | 63 | $text = preg_replace_callback($semanticLinkPattern, 'smwfSimpleParsePropertiesCallback', $text); |
65 | 64 | } |
66 | | - SMWFactbox::printFactbox($text); |
| 65 | + SMWFactbox::printFactbox($text, $parser); |
67 | 66 | |
68 | 67 | // add link to RDF to HTML header |
69 | 68 | smwfRequireHeadItem('smw_rdf', '<link rel="alternate" type="application/rdf+xml" title="' . |
— | — | @@ -71,7 +70,6 @@ |
72 | 71 | 'ExportRDF/' . $parser->getTitle()->getPrefixedText(), 'xmlmime=rdf' |
73 | 72 | )) . "\" />"); |
74 | 73 | |
75 | | - SMWFactbox::setWritelock(false); // free Factbox again (the hope of course is that it is only reset after the data we just gathered was processed; but this then might be okay, e.g. if some jobs are processed) |
76 | 74 | return true; // always return true, in order not to stop MW's hook processing! |
77 | 75 | } |
78 | 76 | |
— | — | @@ -106,7 +104,7 @@ |
107 | 105 | * link. Expected parameter: array(linktext, properties, value, caption) |
108 | 106 | */ |
109 | 107 | function smwfParsePropertiesCallback($semanticLink) { |
110 | | - global $smwgInlineErrors, $smwgStoreAnnotations, $smwgTempStoreAnnotations; |
| 108 | + global $smwgInlineErrors, $smwgStoreAnnotations, $smwgTempStoreAnnotations, $smwgTempParser; |
111 | 109 | wfProfileIn("smwfParsePropertiesCallback (SMW)"); |
112 | 110 | if (array_key_exists(1,$semanticLink)) { |
113 | 111 | $property = $semanticLink[1]; |
— | — | @@ -131,7 +129,7 @@ |
132 | 130 | //extract annotations and create tooltip |
133 | 131 | $properties = preg_split('/:[=:]/u', $property); |
134 | 132 | foreach($properties as $singleprop) { |
135 | | - $dv = SMWFactbox::addProperty($singleprop,$value,$valueCaption, $smwgStoreAnnotations && $smwgTempStoreAnnotations); |
| 133 | + $dv = SMWParseData::addProperty($singleprop,$value,$valueCaption, $smwgTempParser, $smwgStoreAnnotations && $smwgTempStoreAnnotations); |
136 | 134 | } |
137 | 135 | $result = $dv->getShortWikitext(true); |
138 | 136 | if ( ($smwgInlineErrors && $smwgStoreAnnotations && $smwgTempStoreAnnotations) && (!$dv->isValid()) ) { |
— | — | @@ -167,116 +165,11 @@ |
168 | 166 | * Used to updates data after changes of templates, but also at each saving of an article. |
169 | 167 | */ |
170 | 168 | function smwfLinkUpdateHook($links_update) { |
171 | | - smwfSaveDataForTitle($links_update->mTitle); |
| 169 | + SMWParseData::storeData($links_update->mParserOutput, $links_update->mTitle, true); |
172 | 170 | return true; |
173 | 171 | } |
174 | 172 | |
175 | 173 | /** |
176 | | - * Compares if two arrays of data values contain the same content. |
177 | | - * Returns true if the two arrays contain the same data values, |
178 | | - * false otherwise. |
179 | | - */ |
180 | | -function smwfEqualDatavalues($dv1, $dv2) { |
181 | | - // The hashes of all values of both arrays are taken, then sorted |
182 | | - // and finally concatenated, thus creating one long hash out of each |
183 | | - // of the data value arrays. These are compared. |
184 | | - |
185 | | - $values = array(); |
186 | | - foreach($dv1 as $v) $values[] = $v->getHash(); |
187 | | - sort($values); |
188 | | - $dv1hash = implode("___", $values); |
189 | | - $values = array(); |
190 | | - foreach($dv2 as $v) $values[] = $v->getHash(); |
191 | | - sort($values); |
192 | | - $dv2hash = implode("___", $values); |
193 | | - |
194 | | - return ($dv1hash == $dv2hash); |
195 | | -} |
196 | | - |
197 | | -/** |
198 | | - * The generic safe method for some title. It is assumed that parsing has happened and that |
199 | | - * SMWFactbox contains all relevant data. If the saved page describes a property or data type, |
200 | | - * the method checks whether the property type, the data type, the allowed values, or the |
201 | | - * conversion factors have changed. If so, it triggers SMWUpdateJobs for the relevant articles, |
202 | | - * which then asynchronously update the semantic data in the database. |
203 | | - * |
204 | | - * Known bug/limitation -- TODO |
205 | | - * Updatejobs are triggered when a property or type definition has |
206 | | - * changed, so that all affected pages get updated. However, if a page |
207 | | - * uses a property but the given value caused an error, then there is |
208 | | - * no record of that page using the property, so that it will not be |
209 | | - * updated. To fix this, one would need to store errors as well. |
210 | | - */ |
211 | | -function smwfSaveDataForTitle($title) { |
212 | | - global $smwgEnableUpdateJobs; |
213 | | - SMWFactbox::initStorage($title); // be sure we have our title, strange things happen in parsing |
214 | | - $namespace = $title->getNamespace(); |
215 | | - $processSemantics = smwfIsSemanticsProcessed($namespace); |
216 | | - if ($processSemantics) { |
217 | | - $newdata = SMWFactbox::$semdata; |
218 | | - } else { // nothing stored, use empty container |
219 | | - $dv = SMWDataValueFactory::newTypeIDValue('_wpg'); |
220 | | - $dv->setValues($title->getDBkey(), $title->getNamespace()); |
221 | | - $newdata = new SMWSemanticData($dv); |
222 | | - } |
223 | | - |
224 | | - // Check if the semantic data has been changed. |
225 | | - // Sets the updateflag to true if so. |
226 | | - // Careful: storage access must happen *before* the storage update; |
227 | | - // even finding uses of a property fails after its type was changed. |
228 | | - $updatejobflag = false; |
229 | | - $jobs = array(); |
230 | | - if ($smwgEnableUpdateJobs && ($namespace == SMW_NS_PROPERTY) ) { |
231 | | - // if it is a property, then we need to check if the type or |
232 | | - // the allowed values have been changed |
233 | | - $oldtype = smwfGetStore()->getSpecialValues($title, SMW_SP_HAS_TYPE); |
234 | | - $newtype = $newdata->getPropertyValues(SMW_SP_HAS_TYPE); |
235 | | - |
236 | | - if (!smwfEqualDatavalues($oldtype, $newtype)) { |
237 | | - $updatejobflag = true; |
238 | | - } else { |
239 | | - $oldvalues = smwfGetStore()->getSpecialValues($title, SMW_SP_POSSIBLE_VALUE); |
240 | | - $newvalues = $newdata->getPropertyValues(SMW_SP_POSSIBLE_VALUE); |
241 | | - $updatejobflag = !smwfEqualDatavalues($oldvalues, $newvalues); |
242 | | - } |
243 | | - |
244 | | - if ($updatejobflag) { |
245 | | - $subjects = smwfGetStore()->getAllPropertySubjects($title); |
246 | | - foreach ($subjects as $subject) { |
247 | | - $jobs[] = new SMWUpdateJob($subject); |
248 | | - } |
249 | | - } |
250 | | - } elseif ($smwgEnableUpdateJobs && ($namespace == SMW_NS_TYPE) ) { |
251 | | - // if it is a type we need to check if the conversion factors have been changed |
252 | | - $oldfactors = smwfGetStore()->getSpecialValues($title, SMW_SP_CONVERSION_FACTOR); |
253 | | - $newfactors = $newdata->getPropertyValues(SMW_SP_CONVERSION_FACTOR); |
254 | | - $updatejobflag = !smwfEqualDatavalues($oldfactors, $newfactors); |
255 | | - if ($updatejobflag) { |
256 | | - $store = smwfGetStore(); |
257 | | - /// FIXME: this would kill large wikis! Use incremental updates! |
258 | | - $dv = SMWDataValueFactory::newSpecialValue(SMW_SP_HAS_TYPE,$title->getDBkey()); |
259 | | - $subjects = $store->getSpecialSubjects(SMW_SP_HAS_TYPE, $dv); |
260 | | - foreach ($subjects as $valueofpropertypagestoupdate) { |
261 | | - $subjectsPropertyPages = $store->getAllPropertySubjects($valueofpropertypagestoupdate->getTitle()); |
262 | | - $jobs[] = new SMWUpdateJob($valueofpropertypagestoupdate->getTitle()); |
263 | | - foreach ($subjectsPropertyPages as $titleOfPageToUpdate) { |
264 | | - $jobs[] = new SMWUpdateJob($titleOfPageToUpdate); |
265 | | - } |
266 | | - } |
267 | | - } |
268 | | - } |
269 | | - |
270 | | - // Actually store semantic data |
271 | | - SMWFactbox::storeData($processSemantics); |
272 | | - |
273 | | - // Trigger relevant Updatejobs if necessary |
274 | | - if ($updatejobflag) { |
275 | | - Job::batchInsert($jobs); ///NOTE: this only happens if $smwgEnableUpdateJobs was true above |
276 | | - } |
277 | | - return true; |
278 | | -} |
279 | | - |
280 | | -/** |
281 | 174 | * This method will be called whenever an article is deleted so that |
282 | 175 | * semantic properties are cleared appropriately. |
283 | 176 | */ |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_Factbox.php |
— | — | @@ -1,27 +1,19 @@ |
2 | 2 | <?php |
3 | 3 | /** |
4 | | - * The class in this file manages the parsing, displaying, and storing of semantic |
5 | | - * data that is usually displayed within the factbox. |
| 4 | + * The class in this file provides means of rendering a "Factbox" in articles. |
6 | 5 | * @file |
7 | 6 | * @ingroup SMW |
8 | 7 | * @author Markus Krötzsch |
9 | 8 | */ |
10 | 9 | |
11 | 10 | /** |
12 | | - * Static class for representing semantic data, which accepts user |
13 | | - * inputs and provides methods for printing and storing its contents. |
14 | | - * Its main purpose is to provide a persistent storage to keep semantic |
15 | | - * data between hooks for parsing and storing. |
16 | | - * @note AUTOLOADED |
| 11 | + * Static class for printing semantic data in a "Factbox". |
| 12 | + * @ingroup SMW |
| 13 | + * @bug The Factbox should not be printed in a parser hook but by the skin. This would also make some hacky fields such as m_printed and m_blocked obsolete. |
17 | 14 | */ |
18 | 15 | class SMWFactbox { |
19 | 16 | |
20 | 17 | /** |
21 | | - * The actual container for the semantic annotations. Public, since |
22 | | - * it is ref-passed to others for further processing. |
23 | | - */ |
24 | | - static $semdata = NULL; |
25 | | - /** |
26 | 18 | * True if the respective article is newly created. This affects some |
27 | 19 | * storage operations. |
28 | 20 | */ |
— | — | @@ -37,64 +29,6 @@ |
38 | 30 | static protected $m_blocked = false; |
39 | 31 | |
40 | 32 | /** |
41 | | - * True *while* the Factbox is used for writing, prevents |
42 | | - * broken submethods of MW and extensions to screw up our |
43 | | - * subject title due to illegal $wgTitle uses in parsing. |
44 | | - */ |
45 | | - static protected $m_writelock = false; |
46 | | - |
47 | | - /** |
48 | | - * To prevent cross-firing parser hooks (e.g. by other extensions' subparsers) |
49 | | - * from resetting our global data, cache the last non-empty data set and restore |
50 | | - * it later if we should "return" to this article. |
51 | | - */ |
52 | | - static protected $m_oldsemdata = NULL; |
53 | | - |
54 | | - /** |
55 | | - * Initialisation method. Must be called before anything else happens. |
56 | | - */ |
57 | | - static function initStorage($title) { |
58 | | - // reset only if title exists, is new and is not the notorious |
59 | | - // NO TITLE thing the MW parser creates |
60 | | - if ( SMWFactbox::$m_writelock || $title === NULL || $title->getText() == 'NO TITLE' ) return; |
61 | | - if ( (SMWFactbox::$semdata === NULL) || |
62 | | - (SMWFactbox::$semdata->getSubject()->getDBkey() != $title->getDBkey()) || |
63 | | - (SMWFactbox::$semdata->getSubject()->getNamespace() != $title->getNamespace()) ) { |
64 | | - $curdata = SMWFactbox::$semdata; |
65 | | - // check if we can restore the previous (non-empty) data container: |
66 | | - if ( (SMWFactbox::$m_oldsemdata !== NULL) && |
67 | | - (SMWFactbox::$m_oldsemdata->getSubject()->getDBkey() == $title->getDBkey()) && |
68 | | - (SMWFactbox::$m_oldsemdata->getSubject()->getNamespace() == $title->getNamespace()) ) { |
69 | | - SMWFactbox::$semdata = SMWFactbox::$m_oldsemdata; |
70 | | - } else { // otherwise make a new data container |
71 | | - $dv = SMWDataValueFactory::newTypeIDValue('_wpg'); |
72 | | - $dv->setValues($title->getDBkey(), $title->getNamespace()); |
73 | | - SMWFactbox::$semdata = new SMWSemanticData($dv); // reset data |
74 | | - SMWFactbox::$m_printed = false; |
75 | | - } |
76 | | - // store non-empty existing data, just in case we need it later again |
77 | | - if ( ($curdata !== NULL) && |
78 | | - ($curdata->hasProperties() || $curdata->hasSpecialProperties() ) ) { |
79 | | - SMWFactbox::$m_oldsemdata = $curdata; |
80 | | - } |
81 | | - //print " Title set: " . $title->getPrefixedText() . "\n"; // useful for debug |
82 | | - } |
83 | | - //SMWFactbox::$m_new = false; // do not reset, keep (order of hooks can be strange ...) |
84 | | - } |
85 | | - |
86 | | - /** |
87 | | - * Clear all stored data. |
88 | | - */ |
89 | | - static function clearStorage() { |
90 | | - global $smwgStoreActive; |
91 | | - if ($smwgStoreActive) { |
92 | | - SMWFactbox::$semdata->clear(); |
93 | | - SMWFactbox::$m_oldsemdata = NULL; |
94 | | - SMWFactbox::$m_printed = false; |
95 | | - } |
96 | | - } |
97 | | - |
98 | | - /** |
99 | 33 | * Blocks the next rendering of the Factbox |
100 | 34 | */ |
101 | 35 | static function blockOnce() { |
— | — | @@ -102,15 +36,6 @@ |
103 | 37 | } |
104 | 38 | |
105 | 39 | /** |
106 | | - * Set the writlock (true while the Factbox is used for writing, |
107 | | - * ensures that our title object cannot be changed by cross-firing |
108 | | - * hooks). |
109 | | - */ |
110 | | - static function setWriteLock($value) { |
111 | | - SMWFactbox::$m_writelock = $value; |
112 | | - } |
113 | | - |
114 | | - /** |
115 | 40 | * True if the respective article is newly created, but always false until |
116 | 41 | * an article is actually saved. |
117 | 42 | */ |
— | — | @@ -128,45 +53,14 @@ |
129 | 54 | SMWFactbox::$m_new = true; |
130 | 55 | } |
131 | 56 | |
132 | | - /** |
133 | | - * This method adds a new property with the given value to the storage. |
134 | | - * It returns a datavlue object that contains the result of the operation. |
135 | | - */ |
136 | | - static function addProperty($propertyname, $value, $caption, $storeannotation = true) { |
137 | | - wfProfileIn("SMWFactbox::addProperty (SMW)"); |
138 | | - global $smwgContLang; |
139 | | - // See if this property is a special one, such as e.g. "has type" |
140 | | - $propertyname = smwfNormalTitleText($propertyname); //slightly normalize label |
141 | | - $special = $smwgContLang->findSpecialPropertyID($propertyname); |
142 | | - |
143 | | - switch ($special) { |
144 | | - case false: // normal property |
145 | | - $result = SMWDataValueFactory::newPropertyValue($propertyname,$value,$caption); |
146 | | - if ($storeannotation && (SMWFactbox::$semdata !== NULL)) { |
147 | | - SMWFactbox::$semdata->addPropertyValue($propertyname,$result); |
148 | | - } |
149 | | - wfProfileOut("SMWFactbox::addProperty (SMW)"); |
150 | | - return $result; |
151 | | - default: // generic special property |
152 | | - $result = SMWDataValueFactory::newSpecialValue($special,$value,$caption); |
153 | | - if ($storeannotation && (SMWFactbox::$semdata !== NULL)) { |
154 | | - SMWFactbox::$semdata->addSpecialValue($special,$result); |
155 | | - } |
156 | | - wfProfileOut("SMWFactbox::addProperty (SMW)"); |
157 | | - return $result; |
158 | | - } |
159 | | - } |
160 | | - |
161 | | - |
162 | 57 | //// Methods for printing the content of this object into an factbox */ |
163 | 58 | |
164 | 59 | /** |
165 | 60 | * This method prints semantic data at the bottom of an article. |
166 | 61 | */ |
167 | | - static function printFactbox(&$text) { |
168 | | - global $wgContLang, $wgServer, $smwgShowFactbox, $smwgShowFactboxEdit, $smwgStoreActive, $smwgIP, $wgRequest; |
| 62 | + static function printFactbox(&$text, $parser) { |
| 63 | + global $wgContLang, $wgServer, $smwgShowFactbox, $smwgShowFactboxEdit, $smwgIP, $wgRequest; |
169 | 64 | if (SMWFactbox::$m_blocked) { SMWFactbox::$m_blocked = false; return;} |
170 | | - if (!$smwgStoreActive) return; |
171 | 65 | if (SMWFactbox::$m_printed) return; |
172 | 66 | wfProfileIn("SMWFactbox::printFactbox (SMW)"); |
173 | 67 | |
— | — | @@ -192,20 +86,20 @@ |
193 | 87 | SMWFactbox::$m_printed = true; // do not print again, period (the other cases may safely try again, if new data should come in) |
194 | 88 | return; |
195 | 89 | case SMW_FACTBOX_SPECIAL: // only when there are special properties |
196 | | - if ( (SMWFactbox::$semdata === NULL) || (!SMWFactbox::$semdata->hasVisibleSpecialProperties()) ) { |
| 90 | + if ( (SMWParseData::getSMWData($parser) === NULL) || (!SMWParseData::getSMWData($parser)->hasVisibleSpecialProperties()) ) { |
197 | 91 | wfProfileOut("SMWFactbox::printFactbox (SMW)"); |
198 | 92 | return; |
199 | 93 | } |
200 | 94 | break; |
201 | 95 | case SMW_FACTBOX_NONEMPTY: // only when non-empty |
202 | | - if ( (SMWFactbox::$semdata === NULL) || (!SMWFactbox::$semdata->hasProperties()) && (!SMWFactbox::$semdata->hasVisibleSpecialProperties()) ) { |
| 96 | + if ( (SMWParseData::getSMWData($parser) === NULL) || (!SMWParseData::getSMWData($parser)->hasProperties()) && (!SMWParseData::getSMWData($parser)->hasVisibleSpecialProperties()) ) { |
203 | 97 | wfProfileOut("SMWFactbox::printFactbox (SMW)"); |
204 | 98 | return; |
205 | 99 | } |
206 | 100 | break; |
207 | 101 | case SMW_FACTBOX_SHOWN: // escape only if we have no data container at all |
208 | 102 | ///NOTE: this should not happen, but we have no way of being fully sure, hence be prepared |
209 | | - if (SMWFactbox::$semdata === NULL) { |
| 103 | + if (SMWParseData::getSMWData($parser) === NULL) { |
210 | 104 | wfProfileOut("SMWFactbox::printFactbox (SMW)"); |
211 | 105 | return; |
212 | 106 | } |
— | — | @@ -214,9 +108,9 @@ |
215 | 109 | SMWFactbox::$m_printed = true; |
216 | 110 | |
217 | 111 | smwfRequireHeadItem(SMW_HEADER_STYLE); |
218 | | - $rdflink = SMWInfolink::newInternalLink(wfMsgForContent('smw_viewasrdf'), $wgContLang->getNsText(NS_SPECIAL) . ':ExportRDF/' . SMWFactbox::$semdata->getSubject()->getWikiValue(), 'rdflink'); |
| 112 | + $rdflink = SMWInfolink::newInternalLink(wfMsgForContent('smw_viewasrdf'), $wgContLang->getNsText(NS_SPECIAL) . ':ExportRDF/' . SMWParseData::getSMWData($parser)->getSubject()->getWikiValue(), 'rdflink'); |
219 | 113 | |
220 | | - $browselink = SMWInfolink::newBrowsingLink(SMWFactbox::$semdata->getSubject()->getText(), SMWFactbox::$semdata->getSubject()->getWikiValue(), 'swmfactboxheadbrowse'); |
| 114 | + $browselink = SMWInfolink::newBrowsingLink(SMWParseData::getSMWData($parser)->getSubject()->getText(), SMWParseData::getSMWData($parser)->getSubject()->getWikiValue(), 'swmfactboxheadbrowse'); |
221 | 115 | // The "\n" is to ensure that lists on the end of articles are terminated |
222 | 116 | // before the div starts. It would of course be much cleaner to print the |
223 | 117 | // factbox in another way, similar to the way that categories are printed |
— | — | @@ -225,7 +119,7 @@ |
226 | 120 | '<span class="smwfactboxhead">' . wfMsgForContent('smw_factbox_head', $browselink->getWikiText() ) . '</span>' . |
227 | 121 | '<span class="smwrdflink">' . $rdflink->getWikiText() . '</span>' . |
228 | 122 | '<table class="smwfacttable">' . "\n"; |
229 | | - SMWFactbox::printProperties($text); |
| 123 | + SMWFactbox::printProperties($text, $parser); |
230 | 124 | $text .= '</table></div>'; |
231 | 125 | wfProfileOut("SMWFactbox::printFactbox (SMW)"); |
232 | 126 | } |
— | — | @@ -233,15 +127,15 @@ |
234 | 128 | /** |
235 | 129 | * This method prints (special) property values at the bottom of an article. |
236 | 130 | */ |
237 | | - static protected function printProperties(&$text) { |
238 | | - if (!SMWFactbox::$semdata->hasProperties() && !SMWFactbox::$semdata->hasSpecialProperties()) { |
| 131 | + static protected function printProperties(&$text, $parser) { |
| 132 | + if (!SMWParseData::getSMWData($parser)->hasProperties() && !SMWParseData::getSMWData($parser)->hasSpecialProperties()) { |
239 | 133 | return; |
240 | 134 | } |
241 | 135 | global $wgContLang; |
242 | 136 | |
243 | 137 | wfLoadExtensionMessages('SemanticMediaWiki'); |
244 | 138 | |
245 | | - foreach(SMWFactbox::$semdata->getProperties() as $key => $property) { |
| 139 | + foreach(SMWParseData::getSMWData($parser)->getProperties() as $key => $property) { |
246 | 140 | if ($property instanceof Title) { |
247 | 141 | $text .= '<tr><td class="smwpropname">[[' . $property->getPrefixedText() . '|' . preg_replace('/[ ]/u',' ',$property->getText(),2) . ']] </td><td class="smwprops">'; |
248 | 142 | // TODO: the preg_replace is a kind of hack to ensure that the left column does not get too narrow; maybe we can find something nicer later |
— | — | @@ -254,7 +148,7 @@ |
255 | 149 | '</span></span></td><td class="smwspecs">'; |
256 | 150 | } |
257 | 151 | |
258 | | - $propvalues = SMWFactbox::$semdata->getPropertyValues($property); |
| 152 | + $propvalues = SMWParseData::getSMWData($parser)->getPropertyValues($property); |
259 | 153 | $l = count($propvalues); |
260 | 154 | $i=0; |
261 | 155 | foreach ($propvalues as $propvalue) { |
— | — | @@ -272,22 +166,4 @@ |
273 | 167 | } |
274 | 168 | } |
275 | 169 | |
276 | | -//// Methods for writing the content of this object |
277 | | - |
278 | | - /** |
279 | | - * This method stores the semantic data, and clears any outdated entries |
280 | | - * for the current article. |
281 | | - */ |
282 | | - static function storeData($processSemantics) { |
283 | | - // clear data even if semantics are not processed for this namespace |
284 | | - // (this setting might have been changed, so that data still exists) |
285 | | - if ($processSemantics) { |
286 | | - smwfGetStore()->updateData(SMWFactbox::$semdata, SMWFactbox::$m_new); |
287 | | - } else { |
288 | | - smwfGetStore()->clearData(SMWFactbox::$semdata->getSubject()->getTitle(), SMWFactbox::$m_new); |
289 | | - } |
290 | | - } |
291 | | - |
292 | 170 | } |
293 | | - |
294 | | - |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_SemanticData.php |
— | — | @@ -13,19 +13,30 @@ |
14 | 14 | * article (subject), similar what is typically displayed in the factbox. |
15 | 15 | * This is a light-weight data container. |
16 | 16 | * @note: AUTOLOADED |
| 17 | + * @ingroup SMW |
17 | 18 | */ |
18 | 19 | class SMWSemanticData { |
19 | | - protected $attribvals = array(); /// text keys and arrays of datavalue objects |
20 | | - protected $attribtitles = array(); /// text keys and title objects |
21 | | - protected $hasprops = false; /// any normal properties yet? |
22 | | - protected $hasspecs = false; /// any special properties yet? |
23 | | - protected $hasvisiblespecs = false; /// any displayable special properties yet? (some are internal only withot a display name) |
24 | | - protected $m_noduplicates; /// avoid repeated values? |
25 | | - /// NOTE: not needing (e.g. when loading from store) can safe much time, |
26 | | - /// since objects can remain stubs until someone really acesses their value |
27 | | - static protected $m_propertyprefix = false; /// cache for the local version of "Property:" |
| 20 | + /// Text keys and arrays of datavalue objects. |
| 21 | + protected $attribvals = array(); |
| 22 | + /// Text keys and title objects. |
| 23 | + protected $attribtitles = array(); |
| 24 | + /// Boolean, stating whether the container holds any normal properties. |
| 25 | + protected $hasprops = false; |
| 26 | + /// Boolean, stating whether the container holds any special properties. |
| 27 | + protected $hasspecs = false; |
| 28 | + /// Boolean, stating whether the container holds any displayable special properties (some are internal only without a display name). |
| 29 | + protected $hasvisiblespecs = false; |
| 30 | + /** |
| 31 | + * Boolean, stating whether repeated values should be avoided. Not needing duplicte elimination |
| 32 | + * (e.g. when loading from store) can safe much time, since objects can remain stubs until someone |
| 33 | + * really acesses their value. |
| 34 | + */ |
| 35 | + protected $m_noduplicates; |
| 36 | + /// Cache for the local version of "Property:" |
| 37 | + static protected $m_propertyprefix = false; |
28 | 38 | |
29 | | - protected $subject; /// SMWWikiPageValue object |
| 39 | + /// SMWWikiPageValue object that is the subject of this container. |
| 40 | + protected $subject; |
30 | 41 | |
31 | 42 | public function __construct(SMWWikiPageValue $subject, $noduplicates = true) { |
32 | 43 | $this->subject = $subject; |
— | — | @@ -33,8 +44,20 @@ |
34 | 45 | } |
35 | 46 | |
36 | 47 | /** |
| 48 | + * This object is added to the parser output of MediaWiki, but it is not useful to have all its data as part of the parser cache |
| 49 | + * since the data is already stored in more accessible format in SMW. Hence this implementation of __sleep() makes sure only the |
| 50 | + * subject is serialised, yielding a minimal stub data container after unserialisation. This is a little safer than serialising |
| 51 | + * nothing: if, for any reason, SMW should ever access an unserialised parser output, then the Semdata container will at least |
| 52 | + * look as if properly initialised (though empty). |
| 53 | + * @note It might be even better to have other members with stub object data that is used for serializing, thus using much less data. |
| 54 | + */ |
| 55 | + public function __sleep() { |
| 56 | + return array('subject'); |
| 57 | + } |
| 58 | + |
| 59 | + /** |
37 | 60 | * Return subject to which the stored semantic annotation refer to. |
38 | | - * |
| 61 | + * |
39 | 62 | * @return SMWWikiPageValue subject |
40 | 63 | */ |
41 | 64 | public function getSubject() { |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_DataValueFactory.php |
— | — | @@ -262,20 +262,6 @@ |
263 | 263 | // NOTE: all ids must start with underscores, where two underscores indicate |
264 | 264 | // truly internal (non user-acessible types). All others should also get a |
265 | 265 | // translation in the language files, or they won't be available for users. |
266 | | - $wgAutoloadClasses['SMWStringValue'] = $smwgIP . '/includes/SMW_DV_String.php'; |
267 | | - $wgAutoloadClasses['SMWWikiPageValue'] = $smwgIP . '/includes/SMW_DV_WikiPage.php'; |
268 | | - $wgAutoloadClasses['SMWURIValue'] = $smwgIP . '/includes/SMW_DV_URI.php'; |
269 | | - $wgAutoloadClasses['SMWTypesValue'] = $smwgIP . '/includes/SMW_DV_Types.php'; |
270 | | - $wgAutoloadClasses['SMWNAryValue'] = $smwgIP . '/includes/SMW_DV_NAry.php'; |
271 | | - $wgAutoloadClasses['SMWErrorValue'] = $smwgIP . '/includes/SMW_DV_Error.php'; |
272 | | - $wgAutoloadClasses['SMWNumberValue'] = $smwgIP . '/includes/SMW_DV_Number.php'; |
273 | | - $wgAutoloadClasses['SMWTemperatureValue'] = $smwgIP . '/includes/SMW_DV_Temperature.php'; |
274 | | - $wgAutoloadClasses['SMWLinearValue'] = $smwgIP . '/includes/SMW_DV_Linear.php'; |
275 | | - $wgAutoloadClasses['SMWTimeValue'] = $smwgIP . '/includes/SMW_DV_Time.php'; |
276 | | - $wgAutoloadClasses['SMWGeoCoordsValue'] = $smwgIP . '/includes/SMW_DV_GeoCoords.php'; |
277 | | - $wgAutoloadClasses['SMWBoolValue'] = $smwgIP . '/includes/SMW_DV_Bool.php'; |
278 | | - $wgAutoloadClasses['SMWConceptValue'] = $smwgIP . '/includes/SMW_DV_Concept.php'; |
279 | | - $wgAutoloadClasses['SMWImportValue'] = $smwgIP . '/includes/SMW_DV_Import.php'; |
280 | 266 | SMWDataValueFactory::$m_typeclasses = array( |
281 | 267 | '_txt' => 'SMWStringValue', |
282 | 268 | '_cod' => 'SMWStringValue', |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_DV_Import.php |
— | — | @@ -73,30 +73,31 @@ |
74 | 74 | } |
75 | 75 | |
76 | 76 | // check whether element of correct type was found (extracts data from factbox) |
77 | | - if(SMWFactbox::$semdata instanceof SMWSemanticData) { |
78 | | - $this_ns = SMWFactbox::$semdata->getSubject()->getNamespace(); |
79 | | - $error = NULL; |
80 | | - switch ($elemtype) { |
81 | | - case SMW_NS_PROPERTY: case NS_CATEGORY: |
82 | | - if ($this_ns != $elemtype) { |
83 | | - $error = wfMsgForContent('smw_nonright_importtype',$value, $wgContLang->getNsText($elemtype)); |
84 | | - } |
85 | | - break; |
86 | | - case NS_MAIN: |
87 | | - if ( (SMW_NS_PROPERTY == $this_ns) || (NS_CATEGORY == $this_ns)) { |
88 | | - $error = wfMsgForContent('smw_wrong_importtype',$value, $wgContLang->getNsText($this_ns)); |
89 | | - } |
90 | | - break; |
91 | | - case -1: |
92 | | - $error = wfMsgForContent('smw_no_importelement',$value); |
93 | | - } |
| 77 | + ///TODO: parser needed to do that |
| 78 | +// if(SMWParseData::getSMWData($parser) instanceof SMWSemanticData) { |
| 79 | +// $this_ns = SMWParseData::getSMWData($parser)->getSubject()->getNamespace(); |
| 80 | +// $error = NULL; |
| 81 | +// switch ($elemtype) { |
| 82 | +// case SMW_NS_PROPERTY: case NS_CATEGORY: |
| 83 | +// if ($this_ns != $elemtype) { |
| 84 | +// $error = wfMsgForContent('smw_nonright_importtype',$value, $wgContLang->getNsText($elemtype)); |
| 85 | +// } |
| 86 | +// break; |
| 87 | +// case NS_MAIN: |
| 88 | +// if ( (SMW_NS_PROPERTY == $this_ns) || (NS_CATEGORY == $this_ns)) { |
| 89 | +// $error = wfMsgForContent('smw_wrong_importtype',$value, $wgContLang->getNsText($this_ns)); |
| 90 | +// } |
| 91 | +// break; |
| 92 | +// case -1: |
| 93 | +// $error = wfMsgForContent('smw_no_importelement',$value); |
| 94 | +// } |
| 95 | +// |
| 96 | +// if (NULL != $error) { |
| 97 | +// $this->addError($error); |
| 98 | +// return true; |
| 99 | +// } |
| 100 | +// } |
94 | 101 | |
95 | | - if (NULL != $error) { |
96 | | - $this->addError($error); |
97 | | - return true; |
98 | | - } |
99 | | - } |
100 | | - |
101 | 102 | //create String to be returned by getShort/LongWikiText |
102 | 103 | $this->m_wikilink = "[".$this->m_uri." ".$this->m_value."] (".$this->m_name.")"; |
103 | 104 | |
Index: trunk/extensions/SemanticMediaWiki/includes/jobs/SMW_UpdateJob.php |
— | — | @@ -54,14 +54,13 @@ |
55 | 55 | /// parser member variables, so that other parsers do not affect one parser's data. |
56 | 56 | $cur_headitems = $smwgHeadItems; |
57 | 57 | $smwgHeadItems = array(); |
58 | | - $wgParser->parse($revision->getText(), $this->title, $options, true, true, $revision->getID()); |
| 58 | + $output = $wgParser->parse($revision->getText(), $this->title, $options, true, true, $revision->getID()); |
59 | 59 | $smwgHeadItems = $cur_headitems; |
60 | 60 | |
61 | 61 | wfProfileOut( __METHOD__.'-parse' ); |
62 | 62 | wfProfileIn( __METHOD__.'-update' ); |
63 | 63 | |
64 | | - SMWFactbox::initStorage($this->title); // be sure we have our title, strange things happen in parsing |
65 | | - SMWFactbox::storeData(smwfIsSemanticsProcessed($this->title->getNamespace())); |
| 64 | + SMWParseData::storeData($output, $this->title, false); |
66 | 65 | wfProfileOut( __METHOD__.'-update' ); |
67 | 66 | wfProfileOut('SMWUpdateJob::run (SMW)'); |
68 | 67 | return true; |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_GlobalFunctions.php |
— | — | @@ -14,7 +14,7 @@ |
15 | 15 | * @defgroup SMW Semantic MediaWiki |
16 | 16 | */ |
17 | 17 | |
18 | | -define('SMW_VERSION','1.4a-SVN'); |
| 18 | +define('SMW_VERSION','1.4b-SVN'); |
19 | 19 | |
20 | 20 | // constants for special properties, used for datatype assignment and storage |
21 | 21 | define('SMW_SP_HAS_TYPE',1); |
— | — | @@ -111,6 +111,7 @@ |
112 | 112 | ///// Add "@note AUTOLOADED" to their class documentation. This avoids useless includes. |
113 | 113 | $wgAutoloadClasses['SMWInfolink'] = $smwgIP . '/includes/SMW_Infolink.php'; |
114 | 114 | $wgAutoloadClasses['SMWFactbox'] = $smwgIP . '/includes/SMW_Factbox.php'; |
| 115 | + $wgAutoloadClasses['SMWParseData'] = $smwgIP . '/includes/SMW_ParseData.php'; |
115 | 116 | $wgAutoloadClasses['SMWSemanticData'] = $smwgIP . '/includes/SMW_SemanticData.php'; |
116 | 117 | $wgAutoloadClasses['SMWOrderedListPage'] = $smwgIP . '/includes/articlepages/SMW_OrderedListPage.php'; |
117 | 118 | $wgAutoloadClasses['SMWTypePage'] = $smwgIP . '/includes/articlepages/SMW_TypePage.php'; |
— | — | @@ -128,13 +129,23 @@ |
129 | 130 | $wgAutoloadClasses['SMWvCardResultPrinter'] = $smwgIP . '/includes/SMW_QP_vCard.php'; |
130 | 131 | $wgAutoloadClasses['SMWCsvResultPrinter'] = $smwgIP . '/includes/SMW_QP_CSV.php'; |
131 | 132 | //// datavalues |
| 133 | + $wgAutoloadClasses['SMWDataValueFactory'] = $smwgIP . '/includes/SMW_DataValueFactory.php'; |
132 | 134 | $wgAutoloadClasses['SMWDataValue'] = $smwgIP . '/includes/SMW_DataValue.php'; |
133 | 135 | $wgAutoloadClasses['SMWErrorvalue'] = $smwgIP . '/includes/SMW_DV_Error.php'; |
134 | | - ///NOTE: other DataValues are registered for autoloading later on by the factory, use the hook |
135 | | - /// smwInitDatatypes to modify paths for datatype implementations and for registering new types. |
136 | | - $wgAutoloadClasses['SMWDataValueFactory'] = $smwgIP . '/includes/SMW_DataValueFactory.php'; |
137 | | - // the builtin types are registered by SMWDataValueFactory if needed, will be reliably available |
138 | | - // to other DV-implementations that register to the factory. |
| 136 | + $wgAutoloadClasses['SMWStringValue'] = $smwgIP . '/includes/SMW_DV_String.php'; |
| 137 | + $wgAutoloadClasses['SMWWikiPageValue'] = $smwgIP . '/includes/SMW_DV_WikiPage.php'; |
| 138 | + $wgAutoloadClasses['SMWURIValue'] = $smwgIP . '/includes/SMW_DV_URI.php'; |
| 139 | + $wgAutoloadClasses['SMWTypesValue'] = $smwgIP . '/includes/SMW_DV_Types.php'; |
| 140 | + $wgAutoloadClasses['SMWNAryValue'] = $smwgIP . '/includes/SMW_DV_NAry.php'; |
| 141 | + $wgAutoloadClasses['SMWErrorValue'] = $smwgIP . '/includes/SMW_DV_Error.php'; |
| 142 | + $wgAutoloadClasses['SMWNumberValue'] = $smwgIP . '/includes/SMW_DV_Number.php'; |
| 143 | + $wgAutoloadClasses['SMWTemperatureValue'] = $smwgIP . '/includes/SMW_DV_Temperature.php'; |
| 144 | + $wgAutoloadClasses['SMWLinearValue'] = $smwgIP . '/includes/SMW_DV_Linear.php'; |
| 145 | + $wgAutoloadClasses['SMWTimeValue'] = $smwgIP . '/includes/SMW_DV_Time.php'; |
| 146 | + $wgAutoloadClasses['SMWGeoCoordsValue'] = $smwgIP . '/includes/SMW_DV_GeoCoords.php'; |
| 147 | + $wgAutoloadClasses['SMWBoolValue'] = $smwgIP . '/includes/SMW_DV_Bool.php'; |
| 148 | + $wgAutoloadClasses['SMWConceptValue'] = $smwgIP . '/includes/SMW_DV_Concept.php'; |
| 149 | + $wgAutoloadClasses['SMWImportValue'] = $smwgIP . '/includes/SMW_DV_Import.php'; |
139 | 150 | //// export |
140 | 151 | $wgAutoloadClasses['SMWExporter'] = $smwgIP . '/includes/export/SMW_Exporter.php'; |
141 | 152 | $wgAutoloadClasses['SMWExpData'] = $smwgIP . '/includes/export/SMW_Exp_Data.php'; |
— | — | @@ -216,22 +227,8 @@ |
217 | 228 | */ |
218 | 229 | function smwfSetupExtension() { |
219 | 230 | wfProfileIn('smwfSetupExtension (SMW)'); |
220 | | - global $smwgIP, $smwgStoreActive, $wgHooks, $wgParser, $wgExtensionCredits, $smwgEnableTemplateSupport, $smwgMasterStore, $smwgIQRunningNumber, $wgLanguageCode, $wgVersion, $smwgToolboxBrowseLink; |
| 231 | + global $smwgIP, $wgHooks, $wgParser, $wgExtensionCredits, $smwgEnableTemplateSupport, $smwgMasterStore, $smwgIQRunningNumber, $wgLanguageCode, $wgVersion, $smwgToolboxBrowseLink; |
221 | 232 | |
222 | | - /** |
223 | | - * Setting this to false prevents any new data from being stored in |
224 | | - * the static SMWSemanticData store, and disables printing of the |
225 | | - * factbox, and clearing of the existing data. |
226 | | - * This is a hack to enable parsing of included articles in a save |
227 | | - * way without importing their annotations. Unfortunately, there |
228 | | - * appears to be no way for finding out whether the current parse |
229 | | - * is the "main" parse, or whether some intro, docu, or whatever |
230 | | - * text is parsed. Using the hook mechanism, we have to rely on |
231 | | - * globals/static fields -- so we cannot somehow differentiate this |
232 | | - * store between parsers. |
233 | | - */ |
234 | | - $smwgStoreActive = true; |
235 | | - |
236 | 233 | $smwgMasterStore = NULL; |
237 | 234 | smwfInitContentLanguage($wgLanguageCode); // this really could not be done in enableSemantics() |
238 | 235 | wfLoadExtensionMessages('SemanticMediaWiki'); /// TODO: this is extremely slow; up to 10% of page display time (on a page with queries!) are consumed by loading unnecessary messages from a large file ... |
— | — | @@ -347,7 +344,6 @@ |
348 | 345 | // The global $smwgConceptText is used to pass information to the MW hooks for storing it, |
349 | 346 | // $smwgPreviousConcept is used to detect if we already have a concept defined for this page. |
350 | 347 | $title = $parser->getTitle(); |
351 | | - SMWFactbox::initStorage($title); // make sure we have the right title |
352 | 348 | if ($title->getNamespace() != SMW_NS_CONCEPT) { |
353 | 349 | return smwfEncodeMessages(array(wfMsgForContent('smw_no_concept_namespace'))); |
354 | 350 | } elseif (isset($smwgPreviousConcept) && ($smwgPreviousConcept == $title->getText())) { |
— | — | @@ -366,8 +362,8 @@ |
367 | 363 | |
368 | 364 | $dv = SMWDataValueFactory::newSpecialValue(SMW_SP_CONCEPT_DESC); |
369 | 365 | $dv->setValues($concept_text, $concept_docu, $query->getDescription()->getQueryFeatures(), $query->getDescription()->getSize(), $query->getDescription()->getDepth()); |
370 | | - if (SMWFactbox::$semdata !== NULL) { |
371 | | - SMWFactbox::$semdata->addSpecialValue(SMW_SP_CONCEPT_DESC,$dv); |
| 366 | + if (SMWParseData::getSMWData($parser) !== NULL) { |
| 367 | + SMWParseData::getSMWData($parser)->addSpecialValue(SMW_SP_CONCEPT_DESC,$dv); |
372 | 368 | } |
373 | 369 | |
374 | 370 | // display concept box: |
— | — | @@ -457,9 +453,8 @@ |
458 | 454 | * (2) Fetch category information and other final settings from parser output. |
459 | 455 | */ |
460 | 456 | function smwfParserAfterTidy(&$parser, &$text) { |
461 | | - global $smwgHeadItems, $smwgStoreActive; |
462 | | - SMWFactbox::initStorage($parser->getTitle()); // be sure we have our title, strange things happen in parsing |
463 | | - if (!$smwgStoreActive || (SMWFactbox::$semdata === NULL)) return true; // avoid doing this in SMW-generated sub-parsers |
| 457 | + global $smwgHeadItems; |
| 458 | + if (SMWParseData::getSMWData($parser) === NULL) return true; |
464 | 459 | // make HTML header |
465 | 460 | foreach ($smwgHeadItems as $key => $item) { |
466 | 461 | $parser->mOutput->addHeadItem("\t\t" . $item . "\n", $key); |
— | — | @@ -470,13 +465,13 @@ |
471 | 466 | foreach ($categories as $name) { |
472 | 467 | $dv = SMWDataValueFactory::newSpecialValue(SMW_SP_INSTANCE_OF); |
473 | 468 | $dv->setValues($name,NS_CATEGORY); |
474 | | - SMWFactbox::$semdata->addSpecialValue(SMW_SP_INSTANCE_OF,$dv); |
475 | | - if (SMWFactbox::$semdata->getSubject()->getNamespace() == NS_CATEGORY) { |
476 | | - SMWFactbox::$semdata->addSpecialValue(SMW_SP_SUBCLASS_OF,$dv); |
| 469 | + SMWParseData::getSMWData($parser)->addSpecialValue(SMW_SP_INSTANCE_OF,$dv); |
| 470 | + if (SMWParseData::getSMWData($parser)->getSubject()->getNamespace() == NS_CATEGORY) { |
| 471 | + SMWParseData::getSMWData($parser)->addSpecialValue(SMW_SP_SUBCLASS_OF,$dv); |
477 | 472 | } |
478 | 473 | } |
479 | | - $sortkey = ($parser->mDefaultSort?$parser->mDefaultSort:SMWFactbox::$semdata->getSubject()->getText()); |
480 | | - SMWFactbox::$semdata->getSubject()->setSortkey($sortkey); |
| 474 | + $sortkey = ($parser->mDefaultSort?$parser->mDefaultSort:SMWParseData::getSMWData($parser)->getSubject()->getText()); |
| 475 | + SMWParseData::getSMWData($parser)->getSubject()->setSortkey($sortkey); |
481 | 476 | return true; |
482 | 477 | } |
483 | 478 | |
— | — | @@ -487,8 +482,7 @@ |
488 | 483 | * output (exploiting parser caching). |
489 | 484 | */ |
490 | 485 | function smwfAddHTMLHeadersOutput(&$out) { |
491 | | - global $smwgHeadItems, $smwgStoreActive; |
492 | | - if (!$smwgStoreActive) return true; // avoid doing this in SMW-generated sub-parsers |
| 486 | + global $smwgHeadItems; |
493 | 487 | // Add scripts to output if not done already (should happen only if we are |
494 | 488 | // not using a parser, e.g on special pages). |
495 | 489 | foreach ($smwgHeadItems as $key => $item) { |
Index: trunk/extensions/SemanticMediaWiki/includes/SMW_TemplateDeclare.php |
— | — | @@ -61,19 +61,16 @@ |
62 | 62 | $objects = $matches[1]; |
63 | 63 | if (count($objects) == 0) { |
64 | 64 | if (trim($valuestring) != '') { |
65 | | - if (!SMWFactbox::$semdata) SMWFactBox::initStorage($parser->getTitle()); |
66 | | - SMWFactbox::addProperty( $propertystring, $valuestring, false, true ); |
| 65 | + SMWParseData::addProperty( $propertystring, $valuestring, false, $parser, true ); |
67 | 66 | } |
68 | 67 | } else { |
69 | 68 | foreach ($objects as $object) { |
70 | | - if (!SMWFactbox::$semdata) SMWFactBox::initStorage($parser->getTitle()); |
71 | | - SMWFactbox::addProperty( $propertystring, $object, false, true ); |
| 69 | + SMWParseData::addProperty( $propertystring, $object, false, $parser, true ); |
72 | 70 | } |
73 | 71 | } |
74 | 72 | } else { |
75 | 73 | if (trim($valuestring) != '') { |
76 | | - if (!SMWFactbox::$semdata) SMWFactBox::initStorage($parser->getTitle()); |
77 | | - SMWFactbox::addProperty( $propertystring, $valuestring, false, true ); |
| 74 | + SMWParseData::addProperty( $propertystring, $valuestring, false, $parser, true ); |
78 | 75 | } |
79 | 76 | } |
80 | 77 | $value = SMWDataValueFactory::newPropertyObjectValue($property, $valuestring); |