|
eZ Publish
[trunk]
|
00001 <?php 00002 /** 00003 * File containing the eZXMLTextType class. 00004 * 00005 * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved. 00006 * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2 00007 * @version //autogentag// 00008 * @package kernel 00009 */ 00010 00011 /*! 00012 \class eZXMLTextType ezxmltexttype 00013 \ingroup eZDatatype 00014 \brief The class eZXMLTextType haneles XML formatted datatypes 00015 00016 The formatted datatypes store the data in XML. A typical example of this is shown below: 00017 \code 00018 <?xml version="1.0" encoding="utf-8" ?> 00019 <section xmlns:image="http://ez.no/namespaces/ezpublish3/image/" 00020 xmlns:xhtml="http://ez.no/namespaces/ezpublish3/xhtml/"> 00021 <header>This is a level one header</header> 00022 <paragraph> 00023 This is a <emphasize>block</emphasize> of text. 00024 </paragraph> 00025 <section> 00026 <header class="foo">This is a level two header has classification "foo"</header> 00027 <paragraph> 00028 This is the second paragraph with <bold class="foo">bold text which has classification "foo"</bold> 00029 </paragraph> 00030 <header>This is a level two header</header> 00031 <paragraph> 00032 <line>Paragraph can have table</line> 00033 <table class="foo" border='1' width='100%'> 00034 <tr> 00035 <th class="foo"><paragraph>table header of class "foo"</paragraph></th> 00036 <td xhtml:width="66" xhtml:colspan="2" xhtml:rowspan="2"> 00037 <paragraph>table cell text</paragraph> 00038 </td> 00039 </tr> 00040 </table> 00041 </paragraph> 00042 <paragraph> 00043 <line>This is the first line with <anchor name="first">anchor</anchor></line> 00044 <line>This is the second line with <link target="_self" id="1">link</link></line> 00045 <line>This is the third line.</line> 00046 </paragraph> 00047 <paragraph> 00048 <ul class="foo"> 00049 <li>List item 1</li> 00050 <li>List item 2</li> 00051 </ul> 00052 </paragraph> 00053 <paragraph> 00054 <ol> 00055 <li>Ordered list item 1</li> 00056 <li>ordered list item 2</li> 00057 </ol> 00058 </paragraph> 00059 <paragraph> 00060 <line>Paragraph can have both inline custom tag <custom name="myInlineTag">text</custom> and block custom tag</line> 00061 <custom name="myBlockTag"> 00062 <paragraph> 00063 block text 00064 </paragraph> 00065 </custom> 00066 </paragraph> 00067 <paragraph> 00068 Paragraph can have image object with link <object id="55" size="large" align="center" image:ezurl_id="4" /> 00069 </paragraph> 00070 <paragraph> 00071 You can use literal tag to write html code if you have done some changes in override system. 00072 <literal class="html"><font color="red">red text</font></literal> 00073 </paragraph> 00074 <header>This is a level two header</header> 00075 </section> 00076 </section> 00077 00078 \endcode 00079 00080 */ 00081 00082 class eZXMLTextType extends eZDataType 00083 { 00084 const DATA_TYPE_STRING = "ezxmltext"; 00085 const COLS_FIELD = 'data_int1'; 00086 const COLS_VARIABLE = '_ezxmltext_cols_'; 00087 00088 // Tag support preset 00089 const TAG_PRESET_FIELD = 'data_text2'; 00090 const TAG_PRESET_VARIABLE = '_ezxmltext_tagpreset_'; 00091 00092 // The timestamp of the format for eZ Publish 3.0. 00093 const VERSION_30_TIMESTAMP = 1045487555; 00094 // Contains the timestamp of the current xml format, if the stored 00095 // timestamp is less than this it needs to be upgraded until it is correct. 00096 const VERSION_TIMESTAMP = 1045487555; // AS 21-09-2007: should be the same as VERSION_30_TIMESTAMP 00097 00098 function eZXMLTextType() 00099 { 00100 $this->eZDataType( self::DATA_TYPE_STRING, ezpI18n::tr( 'kernel/classes/datatypes', "XML block", 'Datatype name' ), 00101 array( 'serialize_supported' => true ) ); 00102 } 00103 00104 /*! 00105 Set class attribute value for template version 00106 */ 00107 function initializeClassAttribute( $classAttribute ) 00108 { 00109 if ( $classAttribute->attribute( self::COLS_FIELD ) == null ) 00110 $classAttribute->setAttribute( self::COLS_FIELD, 10 ); 00111 $classAttribute->store(); 00112 } 00113 00114 /*! 00115 Sets the default value. 00116 */ 00117 function initializeObjectAttribute( $contentObjectAttribute, $currentVersion, $originalContentObjectAttribute ) 00118 { 00119 if ( $currentVersion != false ) 00120 { 00121 $xmlText = eZXMLTextType::rawXMLText( $originalContentObjectAttribute ); 00122 $contentObjectAttribute->setAttribute( "data_text", $xmlText ); 00123 } 00124 else 00125 { 00126 $parser = new eZXMLInputParser(); 00127 $doc = $parser->createRootNode(); 00128 $xmlText = eZXMLTextType::domString( $doc ); 00129 $contentObjectAttribute->setAttribute( "data_text", $xmlText ); 00130 } 00131 } 00132 00133 /** 00134 * Method triggered on publish for xml text datatype 00135 * 00136 * This method makes sure that links from all translations of an xml text 00137 * are registered in the ezurl_object_link table, and thus retained, if 00138 * previous versions of an object are removed. 00139 * 00140 * @param eZContentObjectAttribute $contentObjectAttribute 00141 * @param eZContentObject $object 00142 * @param array $publishedNodes 00143 * @return boolean 00144 */ 00145 function onPublish( $contentObjectAttribute, $object, $publishedNodes ) 00146 { 00147 $currentVersion = $object->currentVersion(); 00148 $langMask = $currentVersion->attribute( 'language_mask' ); 00149 00150 // We find all translations present in the current version. We calculate 00151 // this from the language mask already present in the fetched version, 00152 // so no further round-trip to the DB is required. 00153 $languageList = eZContentLanguage::decodeLanguageMask( $langMask, true ); 00154 $languageList = $languageList['language_list']; 00155 00156 // We want to have the class attribute identifier of the attribute 00157 // containing the current ezxmltext, as we then can use the more efficient 00158 // eZContentObject->fetchAttributesByIdentifier() to get the data 00159 $identifier = $contentObjectAttribute->attribute( 'contentclass_attribute_identifier' ); 00160 00161 $attributeArray = $object->fetchAttributesByIdentifier( array( $identifier ), 00162 $currentVersion->attribute( 'version' ), 00163 $languageList ); 00164 00165 foreach ( $attributeArray as $attr ) 00166 { 00167 $xmlText = eZXMLTextType::rawXMLText( $attr ); 00168 $dom = new DOMDocument( '1.0', 'utf-8' ); 00169 $success = $dom->loadXML( $xmlText ); 00170 00171 if ( !$success ) 00172 { 00173 continue; 00174 } 00175 00176 $linkNodes = $dom->getElementsByTagName( 'link' ); 00177 $urlIdArray = array(); 00178 00179 foreach ( $linkNodes as $link ) 00180 { 00181 // We are looking for external 'http://'-style links, not the internal 00182 // object or node links. 00183 if ( $link->hasAttribute( 'url_id' ) ) 00184 { 00185 $urlIdArray[] = $link->getAttribute( 'url_id' ); 00186 } 00187 } 00188 00189 if ( count( $urlIdArray ) > 0 ) 00190 { 00191 eZSimplifiedXMLInput::updateUrlObjectLinks( $attr, $urlIdArray ); 00192 } 00193 } 00194 } 00195 00196 /*! 00197 Validates the input and returns true if the input was 00198 valid for this datatype. 00199 */ 00200 function validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute ) 00201 { 00202 /// Get object for input validation 00203 // To do: only validate, not save data 00204 $xmlText = $this->objectAttributeContent( $contentObjectAttribute ); 00205 $input = $xmlText->attribute( 'input' ); 00206 $isValid = $input->validateInput( $http, $base, $contentObjectAttribute ); 00207 00208 return $isValid; 00209 } 00210 00211 function fetchClassAttributeHTTPInput( $http, $base, $classAttribute ) 00212 { 00213 $column = $base . self::COLS_VARIABLE . $classAttribute->attribute( 'id' ); 00214 $tagPreset = $base . self::TAG_PRESET_VARIABLE . $classAttribute->attribute( 'id' ); 00215 if ( $http->hasPostVariable( $column ) ) 00216 { 00217 $columnValue = $http->postVariable( $column ); 00218 $classAttribute->setAttribute( self::COLS_FIELD, $columnValue ); 00219 if ( $http->hasPostVariable( $tagPreset ) ) 00220 { 00221 $tagPresetValue = $http->postVariable( $tagPreset ); 00222 $classAttribute->setAttribute( self::TAG_PRESET_FIELD, $tagPresetValue ); 00223 } 00224 return true; 00225 } 00226 return false; 00227 } 00228 00229 /*! 00230 Fetches the http post var string input and stores it in the data instance. 00231 */ 00232 function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute ) 00233 { 00234 // To do: Data should be saved here. 00235 /*$xmlText = $this->objectAttributeContent( $contentObjectAttribute ); 00236 $input = $xmlText->attribute( 'input' ); 00237 $isValid = $input->validateInput( $http, $base, $contentObjectAttribute );*/ 00238 return true; 00239 } 00240 00241 /*! 00242 Initializes the object attribute with some data after object attribute is already stored. 00243 It means that for initial version you allready have an attribute_id and you can store data somewhere using this id. 00244 \note Default implementation does nothing. 00245 */ 00246 function postInitializeObjectAttribute( $objectAttribute, $currentVersion, $originalContentObjectAttribute ) 00247 { 00248 } 00249 00250 /*! 00251 Store the content. 00252 */ 00253 function storeObjectAttribute( $attribute ) 00254 { 00255 $attribute->setAttribute( 'data_int', self::VERSION_TIMESTAMP ); 00256 } 00257 00258 function viewTemplate( $contentobjectAttribute ) 00259 { 00260 $template = $this->DataTypeString; 00261 $suffix = $this->viewTemplateSuffix( $contentobjectAttribute ); 00262 if ( $suffix ) 00263 { 00264 $template .= '_' . $suffix; 00265 } 00266 return $template; 00267 } 00268 00269 function editTemplate( $contentobjectAttribute ) 00270 { 00271 $template = $this->DataTypeString; 00272 $suffix = $this->editTemplateSuffix( $contentobjectAttribute ); 00273 if ( $suffix ) 00274 $template .= '_' . $suffix; 00275 return $template; 00276 } 00277 00278 function informationTemplate( $contentobjectAttribute ) 00279 { 00280 $template = $this->DataTypeString; 00281 $suffix = $this->informationTemplateSuffix( $contentobjectAttribute ); 00282 if ( $suffix ) 00283 $template .= '_' . $suffix; 00284 return $template; 00285 } 00286 00287 function viewTemplateSuffix( &$contentobjectAttribute ) 00288 { 00289 $content = $this->objectAttributeContent( $contentobjectAttribute ); 00290 $outputHandler = $content->attribute( 'output' ); 00291 return $outputHandler->viewTemplateSuffix( $contentobjectAttribute ); 00292 } 00293 00294 function editTemplateSuffix( &$contentobjectAttribute ) 00295 { 00296 $content = $this->objectAttributeContent( $contentobjectAttribute ); 00297 $inputHandler = $content->attribute( 'input' ); 00298 return $inputHandler->editTemplateSuffix( $contentobjectAttribute ); 00299 } 00300 00301 function informationTemplateSuffix( &$contentobjectAttribute ) 00302 { 00303 $content = $this->objectAttributeContent( $contentobjectAttribute ); 00304 $inputHandler = $content->attribute( 'input' ); 00305 return $inputHandler->informationTemplateSuffix( $contentobjectAttribute ); 00306 } 00307 00308 /*! 00309 \return the RAW XML text from the attribute \a $contentobjectAttribute. 00310 If the XML format is older than the current one it will 00311 be upgraded to the current before being returned. 00312 */ 00313 static function rawXMLText( $contentObjectAttribute ) 00314 { 00315 $text = $contentObjectAttribute->attribute( 'data_text' ); 00316 $timestamp = $contentObjectAttribute->attribute( 'data_int' ); 00317 if ( $timestamp < self::VERSION_30_TIMESTAMP ) 00318 { 00319 $charset = 'UTF-8'; 00320 $codec = eZTextCodec::instance( false, $charset ); 00321 $text = $codec->convertString( $text ); 00322 $timestamp = self::VERSION_30_TIMESTAMP; 00323 } 00324 return $text; 00325 } 00326 00327 /*! 00328 \static 00329 \return the XML structure in \a $domDocument as text. 00330 It will take of care of the necessary charset conversions 00331 for content storage. 00332 */ 00333 static function domString( $domDocument ) 00334 { 00335 return $domDocument->saveXML(); 00336 } 00337 00338 /*! 00339 Returns the content. 00340 */ 00341 function objectAttributeContent( $contentObjectAttribute ) 00342 { 00343 $xmlText = new eZXMLText( eZXMLTextType::rawXMLText( $contentObjectAttribute ), $contentObjectAttribute ); 00344 return $xmlText; 00345 } 00346 00347 /*! 00348 Returns the meta data used for storing search indeces. 00349 */ 00350 function metaData( $contentObjectAttribute ) 00351 { 00352 $metaData = ""; 00353 00354 $dom = new DOMDocument( '1.0', 'utf-8' ); 00355 $text = eZXMLTextType::rawXMLText( $contentObjectAttribute ); 00356 if ( trim( $text ) == '' ) 00357 { 00358 return $metaData; 00359 } 00360 $success = $dom->loadXML( $text ); 00361 00362 if ( $success ) 00363 { 00364 $metaData = trim( eZXMLTextType::concatTextContent( $dom->documentElement ) ); 00365 } 00366 return $metaData; 00367 } 00368 00369 /** 00370 * Recursively drills down in the xml tree in $node and 00371 * concatenates text content from the DOMNodes with a space 00372 * in-between to make sure search words from two different lines 00373 * are merged. 00374 * 00375 * @param DOMNode $node 00376 * @return string 00377 */ 00378 static function concatTextContent( $node ) 00379 { 00380 $retString = ''; 00381 if ( !( $node instanceof DOMNode ) ) 00382 { 00383 return $retString; 00384 } 00385 if ( $node->hasChildNodes() ) 00386 { 00387 $childArray = $node->childNodes; 00388 foreach ( $childArray as $child ) 00389 { 00390 $retString .= eZXMLTextType::concatTextContent( $child ); 00391 } 00392 } 00393 elseif ( $node->nodeType === XML_TEXT_NODE ) 00394 { 00395 return $node->textContent . ' '; 00396 } 00397 return $retString; 00398 } 00399 00400 /*! 00401 \return string representation of an contentobjectattribute data for simplified export 00402 00403 */ 00404 function toString( $contentObjectAttribute ) 00405 { 00406 return $contentObjectAttribute->attribute( 'data_text' ); 00407 } 00408 00409 function fromString( $contentObjectAttribute, $string ) 00410 { 00411 return $contentObjectAttribute->setAttribute( 'data_text', $string ); 00412 } 00413 00414 00415 /*! 00416 Returns the text. 00417 */ 00418 function title( $contentObjectAttribute, $value = null ) 00419 { 00420 $text = eZXMLTextType::rawXMLText( $contentObjectAttribute ); 00421 00422 $dom = new DOMDocument( '1.0', 'utf-8' ); 00423 $success = $dom->loadXML( $text ); 00424 00425 // Get first text element of xml 00426 if ( !$success ) 00427 { 00428 return $text; 00429 } 00430 00431 $root = $dom->documentElement; 00432 $section = $root->firstChild; 00433 $textDom = false; 00434 if ( $section ) 00435 { 00436 $textDom = $section->firstChild; 00437 } 00438 00439 if ( $textDom and $textDom->hasChildNodes ) 00440 { 00441 $text = $textDom->firstChild->textContent; 00442 } 00443 elseif ( $textDom ) 00444 { 00445 $text = $textDom->textContent; 00446 } 00447 00448 return $text; 00449 } 00450 00451 function hasObjectAttributeContent( $contentObjectAttribute ) 00452 { 00453 $content = $this->objectAttributeContent( $contentObjectAttribute ); 00454 if ( is_object( $content ) and 00455 !$content->attribute( 'is_empty' ) ) 00456 return true; 00457 return false; 00458 } 00459 00460 function isIndexable() 00461 { 00462 return true; 00463 } 00464 00465 function isInformationCollector() 00466 { 00467 return false; 00468 } 00469 00470 /*! 00471 Makes sure content/datatype/.../ezxmltags/... are included. 00472 */ 00473 function templateList() 00474 { 00475 return array( array( 'regexp', 00476 '#^content/datatype/[a-zA-Z]+/ezxmltags/#' ) ); 00477 } 00478 00479 function serializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode ) 00480 { 00481 $textColumns = $classAttribute->attribute( self::COLS_FIELD ); 00482 $dom = $attributeParametersNode->ownerDocument; 00483 $textColumnCountNode = $dom->createElement( 'text-column-count' ); 00484 $textColumnCountNode->appendChild( $dom->createTextNode( $textColumns ) ); 00485 $attributeParametersNode->appendChild( $textColumnCountNode ); 00486 } 00487 00488 function unserializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode ) 00489 { 00490 $textColumns = $attributeParametersNode->getElementsByTagName( 'text-column-count' )->item( 0 )->textContent; 00491 $classAttribute->setAttribute( self::COLS_FIELD, $textColumns ); 00492 } 00493 00494 function customObjectAttributeHTTPAction( $http, $action, $contentObjectAttribute, $parameters ) 00495 { 00496 $content = $this->objectAttributeContent( $contentObjectAttribute ); 00497 $inputHandler = $content->attribute( 'input' ); 00498 $inputHandler->customObjectAttributeHTTPAction( $http, $action, $contentObjectAttribute ); 00499 } 00500 00501 /*! 00502 \return a DOM representation of the content object attribute 00503 */ 00504 function serializeContentObjectAttribute( $package, $objectAttribute ) 00505 { 00506 00507 $DOMNode = $this->createContentObjectAttributeDOMNode( $objectAttribute ); 00508 $xmlString = $objectAttribute->attribute( 'data_text' ); 00509 00510 if ( $xmlString != '' ) 00511 { 00512 $doc = new DOMDocument( '1.0', 'utf-8' ); 00513 $success = $doc->loadXML( $xmlString ); 00514 00515 /* For all links found in the XML, do the following: 00516 * - add "href" attribute fetching it from ezurl table. 00517 * - remove "id" attribute. 00518 */ 00519 00520 $links = $doc->getElementsByTagName( 'link' ); 00521 $embeds = $doc->getElementsByTagName( 'embed' ); 00522 $objects = $doc->getElementsByTagName( 'object' ); 00523 $embedsInline = $doc->getElementsByTagName( 'embed-inline' ); 00524 00525 eZXMLTextType::transformLinksToRemoteLinks( $links ); 00526 eZXMLTextType::transformLinksToRemoteLinks( $embeds ); 00527 eZXMLTextType::transformLinksToRemoteLinks( $objects ); 00528 eZXMLTextType::transformLinksToRemoteLinks( $embedsInline ); 00529 00530 $importedRootNode = $DOMNode->ownerDocument->importNode( $doc->documentElement, true ); 00531 $DOMNode->appendChild( $importedRootNode ); 00532 } 00533 00534 return $DOMNode; 00535 } 00536 00537 static function transformLinksToRemoteLinks( DOMNodeList $nodeList ) 00538 { 00539 foreach ( $nodeList as $node ) 00540 { 00541 $linkID = $node->getAttribute( 'url_id' ); 00542 $isObject = ( $node->localName == 'object' ); 00543 $objectID = $isObject ? $node->getAttribute( 'id' ) : $node->getAttribute( 'object_id' ); 00544 $nodeID = $node->getAttribute( 'node_id' ); 00545 00546 if ( $linkID ) 00547 { 00548 $urlObj = eZURL::fetch( $linkID ); 00549 if ( !$urlObj ) // an error occured 00550 { 00551 continue; 00552 } 00553 $url = $urlObj->attribute( 'url' ); 00554 $node->setAttribute( 'href', $url ); 00555 $node->removeAttribute( 'url_id' ); 00556 } 00557 elseif ( $objectID ) 00558 { 00559 $object = eZContentObject::fetch( $objectID, false ); 00560 if ( is_array( $object ) ) 00561 { 00562 $node->setAttribute( 'object_remote_id', $object['remote_id'] ); 00563 } 00564 00565 if ( $isObject ) 00566 { 00567 $node->removeAttribute( 'id' ); 00568 } 00569 else 00570 { 00571 $node->removeAttribute( 'object_id' ); 00572 } 00573 } 00574 elseif ( $nodeID ) 00575 { 00576 $nodeData = eZContentObjectTreeNode::fetch( $nodeID, false, false ); 00577 if ( is_array( $nodeData ) ) 00578 { 00579 $node->setAttribute( 'node_remote_id', $nodeData['remote_id'] ); 00580 } 00581 $node->removeAttribute( 'node_id' ); 00582 } 00583 } 00584 } 00585 00586 /*! 00587 \param contentobject attribute object 00588 \param domnode object 00589 */ 00590 function unserializeContentObjectAttribute( $package, $objectAttribute, $attributeNode ) 00591 { 00592 /* For all links found in the XML, do the following: 00593 * Search for url specified in 'href' link attribute (in ezurl table). 00594 * If the url not found then create a new one. 00595 * Then associate the found (or created) URL with the object attribute by creating new url-object link. 00596 * After that, remove "href" attribute, add new "id" attribute. 00597 * This new 'id' will always refer to the existing url object. 00598 */ 00599 $linkNodes = $attributeNode->getElementsByTagName( 'link' ); 00600 00601 foreach ( $linkNodes as $linkNode ) 00602 { 00603 $href = $linkNode->getAttribute( 'href' ); 00604 if ( !$href ) 00605 continue; 00606 $urlObj = eZURL::urlByURL( $href ); 00607 00608 if ( !$urlObj ) 00609 { 00610 $urlObj = eZURL::create( $href ); 00611 $urlObj->store(); 00612 } 00613 00614 $linkNode->removeAttribute( 'href' ); 00615 $linkNode->setAttribute( 'url_id', $urlObj->attribute( 'id' ) ); 00616 $urlObjectLink = eZURLObjectLink::create( $urlObj->attribute( 'id' ), 00617 $objectAttribute->attribute( 'id' ), 00618 $objectAttribute->attribute( 'version' ) ); 00619 $urlObjectLink->store(); 00620 } 00621 00622 foreach ( $attributeNode->childNodes as $childNode ) 00623 { 00624 if ( $childNode->nodeType == XML_ELEMENT_NODE ) 00625 { 00626 $xmlString = $childNode->ownerDocument->saveXML( $childNode ); 00627 $objectAttribute->setAttribute( 'data_text', $xmlString ); 00628 break; 00629 } 00630 } 00631 } 00632 00633 function postUnserializeContentObjectAttribute( $package, $objectAttribute ) 00634 { 00635 $xmlString = $objectAttribute->attribute( 'data_text' ); 00636 $doc = new DOMDocument( '1.0', 'utf-8' ); 00637 $success = $doc->loadXML( $xmlString ); 00638 00639 if ( !$success ) 00640 { 00641 return false; 00642 } 00643 00644 $links = $doc->getElementsByTagName( 'link' ); 00645 $objects = $doc->getElementsByTagName( 'object' ); 00646 $embeds = $doc->getElementsByTagName( 'embed' ); 00647 $embedsInline = $doc->getElementsByTagName( 'embed-inline' ); 00648 00649 $modified = array(); 00650 $modified[] = eZXMLTextType::transformRemoteLinksToLinks( $links, $objectAttribute ); 00651 $modified[] = eZXMLTextType::transformRemoteLinksToLinks( $objects, $objectAttribute ); 00652 $modified[] = eZXMLTextType::transformRemoteLinksToLinks( $embeds, $objectAttribute ); 00653 $modified[] = eZXMLTextType::transformRemoteLinksToLinks( $embedsInline, $objectAttribute ); 00654 00655 if ( in_array( true, $modified ) ) 00656 { 00657 $objectAttribute->setAttribute( 'data_text', eZXMLTextType::domString( $doc ) ); 00658 return true; 00659 } 00660 else 00661 { 00662 return false; 00663 } 00664 } 00665 00666 static function transformRemoteLinksToLinks( DOMNodeList $nodeList, $objectAttribute ) 00667 { 00668 $modified = false; 00669 00670 $contentObject = $objectAttribute->attribute( 'object' ); 00671 foreach ( $nodeList as $node ) 00672 { 00673 $objectRemoteID = $node->getAttribute( 'object_remote_id' ); 00674 $nodeRemoteID = $node->getAttribute( 'node_remote_id' ); 00675 if ( $objectRemoteID ) 00676 { 00677 $objectArray = eZContentObject::fetchByRemoteID( $objectRemoteID, false ); 00678 if ( !is_array( $objectArray ) ) 00679 { 00680 eZDebug::writeWarning( "Can't fetch object with remoteID = $objectRemoteID", __METHOD__ ); 00681 continue; 00682 } 00683 00684 $objectID = $objectArray['id']; 00685 if ( $node->localName == 'object' ) 00686 $node->setAttribute( 'id', $objectID ); 00687 else 00688 $node->setAttribute( 'object_id', $objectID ); 00689 $node->removeAttribute( 'object_remote_id' ); 00690 $modified = true; 00691 00692 // add as related object 00693 if ( $contentObject ) 00694 { 00695 $relationType = $node->localName == 'link' ? eZContentObject::RELATION_LINK : eZContentObject::RELATION_EMBED; 00696 $contentObject->addContentObjectRelation( $objectID, $objectAttribute->attribute( 'version' ), 0, $relationType ); 00697 } 00698 } 00699 elseif ( $nodeRemoteID ) 00700 { 00701 $nodeArray = eZContentObjectTreeNode::fetchByRemoteID( $nodeRemoteID, false ); 00702 if ( !is_array( $nodeArray ) ) 00703 { 00704 eZDebug::writeWarning( "Can't fetch node with remoteID = $nodeRemoteID", __METHOD__ ); 00705 continue; 00706 } 00707 00708 $node->setAttribute( 'node_id', $nodeArray['node_id'] ); 00709 $node->removeAttribute( 'node_remote_id' ); 00710 $modified = true; 00711 00712 // add as related object 00713 if ( $contentObject ) 00714 { 00715 $relationType = $node->nodeName == 'link' ? eZContentObject::RELATION_LINK : eZContentObject::RELATION_EMBED; 00716 $contentObject->addContentObjectRelation( $nodeArray['contentobject_id'], $objectAttribute->attribute( 'version' ), 0, $relationType ); 00717 } 00718 } 00719 } 00720 00721 return $modified; 00722 } 00723 00724 /*! 00725 Delete stored object attribute, this will clean up the ezurls and ezobjectlinks 00726 */ 00727 function deleteStoredObjectAttribute( $contentObjectAttribute, $version = null ) 00728 { 00729 $contentObjectAttributeID = $contentObjectAttribute->attribute( "id" ); 00730 00731 $db = eZDB::instance(); 00732 00733 /* First we remove the link between the keyword and the object 00734 * attribute to be removed */ 00735 if ( $version == null ) 00736 { 00737 eZPersistentObject::removeObject( eZURLObjectLink::definition(), 00738 array( 'contentobject_attribute_id' => $contentObjectAttributeID ) ); 00739 00740 } 00741 else 00742 { 00743 eZPersistentObject::removeObject( eZURLObjectLink::definition(), 00744 array( 'contentobject_attribute_id' => $contentObjectAttributeID, 00745 'contentobject_attribute_version' => $version ) ); 00746 } 00747 00748 /* Here we figure out which which URLs are not in use at all */ 00749 if ( $db->databaseName() == 'oracle' ) 00750 { 00751 $res = $db->arrayQuery( "SELECT DISTINCT id 00752 FROM ezurl, ezurl_object_link 00753 WHERE ezurl.id = ezurl_object_link.url_id(+) 00754 AND url_id IS NULL" ); 00755 } 00756 else 00757 { 00758 $res = $db->arrayQuery(" SELECT DISTINCT id 00759 FROM ezurl LEFT JOIN ezurl_object_link ON (ezurl.id = ezurl_object_link.url_id) 00760 WHERE url_id IS NULL" ); 00761 } 00762 00763 /* And if there are some, we delete them */ 00764 if ( count( $res ) ) 00765 { 00766 $unusedUrlIDs = array(); 00767 foreach ( $res as $record ) 00768 $unusedUrlIDs[] = $record['id']; 00769 $unusedUrlIDString = implode( ', ', $unusedUrlIDs ); 00770 00771 $db->query( "DELETE FROM ezurl WHERE id IN ($unusedUrlIDString)" ); 00772 } 00773 } 00774 00775 function diff( $old, $new, $options = false ) 00776 { 00777 $diff = new eZDiff(); 00778 $diff->setDiffEngineType( $diff->engineType( 'xml' ) ); 00779 $diff->initDiffEngine(); 00780 $diffObject = $diff->diff( $old, $new ); 00781 return $diffObject; 00782 } 00783 00784 function supportsBatchInitializeObjectAttribute() 00785 { 00786 return true; 00787 } 00788 00789 function batchInitializeObjectAttributeData( $classAttribute ) 00790 { 00791 $parser = new eZXMLInputParser(); 00792 $doc = $parser->createRootNode(); 00793 $xmlText = eZXMLTextType::domString( $doc ); 00794 $db = eZDB::instance(); 00795 $xmlText = "'" . $db->escapeString( $xmlText ) . "'"; 00796 return array( 'data_text' => $xmlText ); 00797 } 00798 } 00799 00800 eZDataType::register( eZXMLTextType::DATA_TYPE_STRING, "eZXMLTextType" ); 00801 00802 ?>