eZ Publish  [4.0]
ezrssexport.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Definition of eZRSSExport class
00004 //
00005 // Created on: <18-Sep-2003 11:13:56 kk>
00006 //
00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00008 // SOFTWARE NAME: eZ Publish
00009 // SOFTWARE RELEASE: 4.0.x
00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00011 // SOFTWARE LICENSE: GNU General Public License v2.0
00012 // NOTICE: >
00013 //   This program is free software; you can redistribute it and/or
00014 //   modify it under the terms of version 2.0  of the GNU General
00015 //   Public License as published by the Free Software Foundation.
00016 //
00017 //   This program is distributed in the hope that it will be useful,
00018 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //   GNU General Public License for more details.
00021 //
00022 //   You should have received a copy of version 2.0 of the GNU General
00023 //   Public License along with this program; if not, write to the Free
00024 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00025 //   MA 02110-1301, USA.
00026 //
00027 //
00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00029 //
00030 
00031 /*! \file ezrssexport.php
00032 */
00033 
00034 /*!
00035   \class eZRSSExport ezrssexport.php
00036   \brief Handles RSS Export in eZ Publish
00037 
00038   RSSExport is used to create RSS feeds from published content. See kernel/rss for more files.
00039 */
00040 
00041 //include_once( 'kernel/classes/ezpersistentobject.php' );
00042 //include_once( 'kernel/classes/ezrssexportitem.php' );
00043 //include_once( "lib/ezdb/classes/ezdb.php" );
00044 
00045 class eZRSSExport extends eZPersistentObject
00046 {
00047     const STATUS_VALID = 1;
00048     const STATUS_DRAFT = 0;
00049 
00050     /*!
00051      Initializes a new RSSExport.
00052     */
00053     function eZRSSExport( $row )
00054     {
00055         $this->eZPersistentObject( $row );
00056     }
00057 
00058     /*!
00059      \reimp
00060     */
00061     static function definition()
00062     {
00063         return array( "fields" => array( "id" => array( 'name' => 'ID',
00064                                                         'datatype' => 'integer',
00065                                                         'default' => 0,
00066                                                         'required' => true ),
00067                                          'title' => array( 'name' => 'Title',
00068                                                            'datatype' => 'string',
00069                                                            'default' => ezi18n( 'kernel/rss', 'New RSS Export' ),
00070                                                            'required' => true ),
00071                                          'url' => array( 'name' => 'URL',
00072                                                          'datatype' => 'string',
00073                                                          'default' => '',
00074                                                          'required' => true ),
00075                                          'site_access' => array( 'name' => 'SiteAccess',
00076                                                                  'datatype' => 'string',
00077                                                                  'default' => '',
00078                                                                  'required' => true ),
00079                                          'modified' => array( 'name' => 'Modified',
00080                                                               'datatype' => 'integer',
00081                                                               'default' => 0,
00082                                                               'required' => true ),
00083                                          'modifier_id' => array( 'name' => 'ModifierID',
00084                                                               'datatype' => 'integer',
00085                                                               'default' => 0,
00086                                                               'required' => true,
00087                                                                  'foreign_class' => 'eZUser',
00088                                                                  'foreign_attribute' => 'contentobject_id',
00089                                                                  'multiplicity' => '1..*' ),
00090                                          'created' => array( 'name' => 'Created',
00091                                                               'datatype' => 'integer',
00092                                                               'default' => 0,
00093                                                               'required' => true ),
00094                                          'creator_id' => array( 'name' => 'CreatorID',
00095                                                               'datatype' => 'integer',
00096                                                               'default' => 0,
00097                                                               'required' => true,
00098                                                                 'foreign_class' => 'eZUser',
00099                                                                 'foreign_attribute' => 'contentobject_id',
00100                                                                 'multiplicity' => '1..*' ),
00101                                          'description' => array( 'name' => 'Description',
00102                                                                  'datatype' => 'string',
00103                                                                  'default' => '',
00104                                                                  'required' => false ),
00105                                          'image_id' => array( 'name' => 'ImageID',
00106                                                               'datatype' => 'integer',
00107                                                               'default' => 0,
00108                                                               'required' => false ),
00109                                          'rss_version' => array( 'name' => 'RSSVersion',
00110                                                                  'datatype' => 'string',
00111                                                                  'default' => 0,
00112                                                                  'required' => true ),
00113                                          'active' => array( 'name' => 'Active',
00114                                                             'datatype' => 'integer',
00115                                                             'default' => 0,
00116                                                             'required' => true ),
00117                                          'status' => array( 'name' => 'Status',
00118                                                             'datatype' => 'integer',
00119                                                             'default' => 0,
00120                                                             'required' => true ),
00121                                          'access_url' => array( 'name' => 'AccessURL',
00122                                                                 'datatype' => 'string',
00123                                                                 'default' => 'rss_feed',
00124                                                                 'required' => false ),
00125                                          'number_of_objects' => array( 'name' => 'NumberOfObjects',
00126                                                                        'datatype' => 'integer',
00127                                                                        'default' => 0,
00128                                                                        'required' => true ),
00129                                          'main_node_only' => array( 'name' => 'MainNodeOnly',
00130                                                                     'datatype' => 'integer',
00131                                                                     'default' => 0,
00132                                                                     'required' => true ) ),
00133                       "keys" => array( "id", 'status' ),
00134                       'function_attributes' => array( 'item_list' => 'itemList',
00135                                                       'modifier' => 'modifier',
00136                                                       'rss-xml' => 'rssXml',
00137                                                       'image_path' => 'imagePath',
00138                                                       'image_node' => 'imageNode' ),
00139                       "increment_key" => "id",
00140                       "sort" => array( "title" => "asc" ),
00141                       "class_name" => "eZRSSExport",
00142                       "name" => "ezrss_export" );
00143 
00144     }
00145 
00146     /*!
00147      \static
00148      Creates a new RSS Export
00149      \param User ID
00150 
00151      \return the URL alias object
00152     */
00153     static function create( $user_id )
00154     {
00155         $config = eZINI::instance( 'site.ini' );
00156         $dateTime = time();
00157         $row = array( 'id' => null,
00158                       'title' => ezi18n( 'kernel/classes', 'New RSS Export' ),
00159                       'site_access' => '',
00160                       'modifier_id' => $user_id,
00161                       'modified' => $dateTime,
00162                       'creator_id' => $user_id,
00163                       'created' => $dateTime,
00164                       'status' => 0,
00165                       'url' => 'http://'. $config->variable( 'SiteSettings', 'SiteURL' ),
00166                       'description' => '',
00167                       'image_id' => 0,
00168                       'active' => 1,
00169                       'access_url' => '' );
00170         return new eZRSSExport( $row );
00171     }
00172 
00173     /*!
00174      Store Object to database
00175      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00176      the calls within a db transaction; thus within db->begin and db->commit.
00177     */
00178     function store( $storeAsValid = false )
00179     {
00180         //include_once( "kernel/classes/datatypes/ezuser/ezuser.php" );
00181         $dateTime = time();
00182         $user = eZUser::currentUser();
00183         if (  $this->ID == null )
00184         {
00185             eZPersistentObject::store();
00186             return;
00187         }
00188 
00189         $db = eZDB::instance();
00190         $db->begin();
00191         if ( $storeAsValid )
00192         {
00193             $oldStatus = $this->attribute( 'status' );
00194             $this->setAttribute( 'status', eZRSSExport::STATUS_VALID );
00195         }
00196         $this->setAttribute( 'modified', $dateTime );
00197         $this->setAttribute( 'modifier_id', $user->attribute( "contentobject_id" ) );
00198         eZPersistentObject::store();
00199         $db->commit();
00200         if ( $storeAsValid )
00201         {
00202             $this->setAttribute( 'status', $oldStatus );
00203         }
00204     }
00205 
00206     /*!
00207      Remove the RSS Export.
00208      \note Transaction unsafe. If you call several transaction unsafe methods you must enclose
00209      the calls within a db transaction; thus within db->begin and db->commit.
00210     */
00211     function removeThis()
00212     {
00213         $exportItems = $this->fetchItems();
00214 
00215         $db = eZDB::instance();
00216         $db->begin();
00217         foreach ( $exportItems as $item )
00218         {
00219             $item->remove();
00220         }
00221         eZPersistentObject::remove();
00222         $db->commit();
00223     }
00224 
00225     /*!
00226      \static
00227       Fetches the RSS Export by ID.
00228 
00229      \param RSS Export ID
00230     */
00231     static function fetch( $id, $asObject = true, $status = eZRSSExport::STATUS_VALID )
00232     {
00233         return eZPersistentObject::fetchObject( eZRSSExport::definition(),
00234                                                 null,
00235                                                 array( "id" => $id,
00236                                                        'status' => $status ),
00237                                                 $asObject );
00238     }
00239 
00240     /*!
00241      \static
00242       Fetches the RSS Export by feed access url and is active.
00243 
00244      \param RSS Export access url
00245     */
00246     static function fetchByName( $access_url, $asObject = true )
00247     {
00248         return eZPersistentObject::fetchObject( eZRSSExport::definition(),
00249                                                 null,
00250                                                 array( 'access_url' => $access_url,
00251                                                        'active' => 1,
00252                                                        'status' => 1 ),
00253                                                 $asObject );
00254     }
00255 
00256     /*!
00257      \static
00258       Fetches complete list of RSS Exports.
00259     */
00260     static function fetchList( $asObject = true )
00261     {
00262         return eZPersistentObject::fetchObjectList( eZRSSExport::definition(),
00263                                                     null, array( 'status' => 1 ), null, null,
00264                                                     $asObject );
00265     }
00266 
00267     function itemList()
00268     {
00269         return $this->fetchItems();
00270     }
00271 
00272     function imageNode()
00273     {
00274         if ( isset( $this->ImageID ) and $this->ImageID )
00275         {
00276             //include_once( "kernel/classes/ezcontentobjecttreenode.php" );
00277             return eZContentObjectTreeNode::fetch( $this->ImageID );
00278         }
00279         return null;
00280     }
00281 
00282     function imagePath()
00283     {
00284         if ( isset( $this->ImageID ) and $this->ImageID )
00285         {
00286             //include_once( "kernel/classes/ezcontentobjecttreenode.php" );
00287             $objectNode = eZContentObjectTreeNode::fetch( $this->ImageID );
00288             if ( isset( $objectNode ) )
00289             {
00290                 $retValue = '';
00291                 $path_array = $objectNode->attribute( 'path_array' );
00292                 for ( $i = 0; $i < count( $path_array ); $i++ )
00293                 {
00294                     $treenode = eZContentObjectTreeNode::fetch( $path_array[$i], false, false );
00295 
00296                     if( $i != 0 )
00297                     {
00298                         $retValue .= '/';
00299                     }
00300 
00301                     $retValue .= array_key_exists( 'name', $treenode ) ? $treenode['name'] : '';
00302                 }
00303                 return $retValue;
00304             }
00305         }
00306         return null;
00307 
00308     }
00309 
00310     function modifier()
00311     {
00312         if ( isset( $this->ModifierID ) and $this->ModifierID )
00313         {
00314             //include_once( "kernel/classes/datatypes/ezuser/ezuser.php" );
00315             return eZUser::fetch( $this->ModifierID );
00316         }
00317         return null;
00318     }
00319 
00320     function rssXml()
00321     {
00322         switch( $this->attribute( 'rss_version' ) )
00323         {
00324             case '1.0':
00325             {
00326                 return $this->fetchRSS1_0();
00327             } break;
00328 
00329             case '2.0':
00330             {
00331                 return $this->fetchRSS2_0();
00332             } break;
00333 
00334             default:
00335             {
00336                 return null;
00337             } break;
00338         }
00339 
00340         return null;
00341     }
00342 
00343     /*!
00344       Fetches RSS Items related to this RSS Export. The RSS Export Items contain information about which nodes to export information from
00345 
00346       \param RSSExport ID (optional). Uses current RSSExport's ID as default
00347 
00348       \return RSSExportItem list. null if no RSS Export items found
00349     */
00350     function fetchItems( $id = false, $status = eZRSSExport::STATUS_VALID )
00351     {
00352         if ( $id === false )
00353         {
00354             if ( isset( $this ) )
00355             {
00356                 $id = $this->ID;
00357                 $status = $this->Status;
00358             }
00359             else
00360             {
00361                 $itemList = null;
00362                 return $itemList;
00363             }
00364         }
00365         if ( $id !== null )
00366             $itemList = eZRSSExportItem::fetchFilteredList( array( 'rssexport_id' => $id, 'status' => $status ) );
00367         else
00368             $itemList = null;
00369         return $itemList;
00370     }
00371 
00372     function getObjectListFilter()
00373     {
00374         if ( $this->MainNodeOnly == 1 )
00375         {
00376             $this->MainNodeOnly = true;
00377         }
00378         else
00379         {
00380             $this->MainNodeOnly = false;
00381         }
00382 
00383         return array( 'number_of_objects' => intval($this->NumberOfObjects),
00384                       'main_node_only'    => $this->MainNodeOnly
00385                      );
00386     }
00387 
00388     /*!
00389      Get a RSS xml document based on the RSS 2.0 standard based on the RSS Export settings defined by this object
00390 
00391      \param
00392 
00393      \return RSS 2.0 XML document
00394     */
00395     function fetchRSS2_0( $id = null )
00396     {
00397         if ( $id != null )
00398         {
00399             $rssExport = eZRSSExport::fetch( $id );
00400             return $rssExport->fetchRSS2_0();
00401         }
00402 
00403         $locale = eZLocale::instance();
00404 
00405         // Get URL Translation settings.
00406         $config = eZINI::instance();
00407         if ( $config->variable( 'URLTranslator', 'Translation' ) == 'enabled' )
00408         {
00409             $useURLAlias = true;
00410         }
00411         else
00412         {
00413             $useURLAlias = false;
00414         }
00415 
00416         if ( $this->attribute( 'url' ) == '' )
00417         {
00418             //include_once( 'lib/ezutils/classes/ezuri.php' );
00419             $baseItemURL = '';
00420             eZURI::transformURI( $baseItemURL, false, 'full' );
00421             $baseItemURL .= '/';
00422         }
00423         else
00424         {
00425             $baseItemURL = $this->attribute( 'url' ).'/'; //.$this->attribute( 'site_access' ).'/';
00426         }
00427 
00428         $doc = new DOMDocument( '1.0', 'utf-8' );
00429         $doc->formatOutput = true;
00430         $root = $doc->createElement( 'rss' );
00431         $root->setAttribute( 'version', '2.0' );
00432         $root->setAttribute( 'xmlns:atom', 'http://www.w3.org/2005/Atom' );
00433         $doc->appendChild( $root );
00434 
00435         $channel = $doc->createElement( 'channel' );
00436         $root->appendChild( $channel );
00437 
00438         $atomLink = $doc->createElement( 'atom:link' );
00439         $atomLink->setAttribute( 'href', $baseItemURL . "rss/feed/" . $this->attribute( 'access_url' ) );
00440         $atomLink->setAttribute( 'rel', 'self' );
00441         $atomLink->setAttribute( 'type', 'application/rss+xml' );
00442         $channel->appendChild( $atomLink );
00443 
00444         $channelTitle = $doc->createElement( 'title' );
00445         $channelTitle->appendChild( $doc->createTextNode( $this->attribute( 'title' ) ) );
00446         $channel->appendChild( $channelTitle );
00447 
00448         $channelLink = $doc->createElement( 'link' );
00449         $channelLink->appendChild( $doc->createTextNode( $this->attribute( 'url' ) ) );
00450         $channel->appendChild( $channelLink );
00451 
00452         $channelDescription = $doc->createElement( 'description' );
00453         $channelDescription->appendChild( $doc->createTextNode( $this->attribute( 'description' ) ) );
00454         $channel->appendChild( $channelDescription );
00455 
00456         $channelLanguage = $doc->createElement( 'language' );
00457         $channelLanguage->appendChild( $doc->createTextNode( $locale->httpLocaleCode() ) );
00458         $channel->appendChild( $channelLanguage );
00459 
00460         $imageURL = $this->fetchImageURL();
00461         if ( $imageURL !== false )
00462         {
00463             $image = $doc->createElement( 'image' );
00464 
00465             $imageUrlNode = $doc->createElement( 'url' );
00466             $imageUrlNode->appendChild( $doc->createTextNode( $imageURL ) );
00467             $image->appendChild( $imageUrlNode );
00468 
00469             $imageTitle = $doc->createElement( 'title' );
00470             $imageTitle->appendChild( $doc->createTextNode( $this->attribute( 'title' ) ) );
00471             $image->appendChild( $imageTitle );
00472 
00473             $imageLink = $doc->createElement( 'link' );
00474             $imageLink->appendChild( $doc->createTextNode( $this->attribute( 'url' ) ) );
00475             $image->appendChild( $imageLink );
00476 
00477             $channel->appendChild( $image );
00478         }
00479 
00480         $cond = array(
00481                     'rssexport_id'  => $this->ID,
00482                     'status'        => $this->Status
00483                     );
00484         $rssSources = eZRSSExportItem::fetchFilteredList( $cond );
00485 
00486         $nodeArray = eZRSSExportItem::fetchNodeList( $rssSources, $this->getObjectListFilter() );
00487 
00488         if ( is_array( $nodeArray ) && count( $nodeArray ) )
00489         {
00490             $attributeMappings = eZRSSExportItem::getAttributeMappings( $rssSources );
00491 
00492             foreach ( $nodeArray as $node )
00493             {
00494                 $object = $node->attribute( 'object' );
00495                 $dataMap = $object->dataMap();
00496                 if ( $useURLAlias === true )
00497                 {
00498                     $nodeURL = $this->urlEncodePath( $baseItemURL . $node->urlAlias() );
00499                 }
00500                 else
00501                 {
00502                     $nodeURL = $baseItemURL . 'content/view/full/' . $node->attribute( 'node_id' );
00503                 }
00504 
00505                 // keep track if there's any match
00506                 $doesMatch = false;
00507                 // start mapping the class attribute to the respective RSS field
00508                 foreach ( $attributeMappings as $attributeMapping )
00509                 {
00510                     // search for correct mapping by path
00511                     if ( $attributeMapping[0]->attribute( 'class_id' ) == $object->attribute( 'contentclass_id' ) and
00512                          in_array( $attributeMapping[0]->attribute( 'source_node_id' ), $node->attribute( 'path_array' ) ) )
00513                     {
00514                         // found it
00515                         $doesMatch = true;
00516                         // now fetch the attributes
00517                         $title =  $dataMap[$attributeMapping[0]->attribute( 'title' )];
00518                         $description =  $dataMap[$attributeMapping[0]->attribute( 'description' )];
00519                         break;
00520                     }
00521                 }
00522 
00523                 if( !$doesMatch )
00524                 {
00525                     // no match
00526                     eZDebug::writeWarning( __METHOD__ . ': Cannot find matching RSS source node for content object in '.__FILE__.', Line '.__LINE__ );
00527                     $retValue = null;
00528                     return $retValue;
00529                 }
00530 
00531                 $item = $doc->createElement( 'item' );
00532 
00533                 // title RSS element with respective class attribute content
00534                 $titleContent =  $title->attribute( 'content' );
00535                 if ( $titleContent instanceof eZXMLText )
00536                 {
00537                     $outputHandler = $titleContent->attribute( 'output' );
00538                     $itemTitleText = $outputHandler->attribute( 'output_text' );
00539                 }
00540                 else
00541                 {
00542                     $itemTitleText = $titleContent;
00543                 }
00544 
00545                 $itemTitle = $doc->createElement( 'title' );
00546                 $itemTitle->appendChild( $doc->createTextNode( $itemTitleText ) );
00547                 $item->appendChild( $itemTitle );
00548 
00549                 $itemLink = $doc->createElement( 'link' );
00550                 $itemLink->appendChild( $doc->createTextNode( $nodeURL ) );
00551                 $item->appendChild( $itemLink );
00552 
00553                 $itemGuid = $doc->createElement( 'guid' );
00554                 $itemGuid->appendChild( $doc->createTextNode( $nodeURL ) );
00555                 $item->appendChild( $itemGuid );
00556 
00557                 // description RSS element with respective class attribute content
00558                 $descriptionContent =  $description->attribute( 'content' );
00559                 if ( $descriptionContent instanceof eZXMLText )
00560                 {
00561                     $outputHandler =  $descriptionContent->attribute( 'output' );
00562                     $itemDescriptionText = $outputHandler->attribute( 'output_text' );
00563                 }
00564                 else
00565                 {
00566                     $itemDescriptionText = $descriptionContent;
00567                 }
00568 
00569                 $itemDescription = $doc->createElement( 'description' );
00570                 $itemDescription->appendChild( $doc->createTextNode( $itemDescriptionText ) );
00571                 $item->appendChild( $itemDescription );
00572 
00573                 $itemPubDate = $doc->createElement( 'pubDate' );
00574                 $itemPubDate->appendChild( $doc->createTextNode( gmdate( 'D, d M Y H:i:s', $object->attribute( 'published' ) ) .' GMT' ) );
00575 
00576                 $item->appendChild( $itemPubDate );
00577 
00578                 $channel->appendChild( $item );
00579             }
00580         }
00581 
00582         return $doc;
00583     }
00584 
00585     /*!
00586      Get a RSS xml document based on the RSS 1.0 standard based on the RSS Export settings defined by this object
00587 
00588      \param object ID
00589 
00590      \return RSS 1.0 XML document
00591     */
00592     function fetchRSS1_0( $id = null )
00593     {
00594         if ( $id != null )
00595         {
00596             $rssExport = eZRSSExport::fetch( $id );
00597             return $rssExport->fetchRSS1_0();
00598         }
00599 
00600         $imageURL = $this->fetchImageURL();
00601 
00602         // Get URL Translation settings.
00603         $config = eZINI::instance( 'site.ini' );
00604         if ( $config->variable( 'URLTranslator', 'Translation' ) == 'enabled' )
00605         {
00606             $useURLAlias = true;
00607         }
00608         else
00609         {
00610             $useURLAlias = false;
00611         }
00612 
00613         if ( $this->attribute( 'url' ) == '' )
00614         {
00615             //include_once( 'lib/ezutils/classes/ezuri.php' );
00616             $baseItemURL = '';
00617             eZURI::transformURI( $baseItemURL, false, 'full' );
00618             $baseItemURL .= '/';
00619         }
00620         else
00621         {
00622             $baseItemURL = $this->attribute( 'url' ).'/'; //.$this->attribute( 'site_access' ).'/';
00623         }
00624 
00625         $doc = new DOMDocument( '1.0', 'utf-8' );
00626         $root = $doc->createElementNS( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf:RDF' );
00627         $doc->appendChild( $root );
00628 
00629         $channel = $doc->createElementNS( 'http://purl.org/rss/1.0/', 'channel' );
00630         $channel->setAttributeNS( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf:about', $this->attribute( 'url' ) );
00631         $root->appendChild( $channel );
00632 
00633         $channelTitle = $doc->createElement( 'title' );
00634         $channelTitle->appendChild( $doc->createTextNode( $this->attribute( 'title' ) ) );
00635         $channel->appendChild( $channelTitle );
00636 
00637         $channelUrl = $doc->createElement( 'link' );
00638         $channelUrl->appendChild( $doc->createTextNode( $this->attribute( 'url' ) ) );
00639         $channel->appendChild( $channelUrl );
00640 
00641         $channelDescription = $doc->createElement( 'description' );
00642         $channelDescription->appendChild( $doc->createTextNode( $this->attribute( 'description' ) ) );
00643         $channel->appendChild( $channelDescription );
00644 
00645         if ( $imageURL !== false )
00646         {
00647             $channelImage = $doc->createElement( 'image' );
00648             $channelImage->setAttributeNS( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf:resource', $imageURL );
00649             $channel->appendChild( $channelImage );
00650 
00651             $image = $doc->createElement( 'image' );
00652             $image->setAttributeNS( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf:about', $imageURL );
00653 
00654             $imageTitle = $doc->createElement( 'title' );
00655             $imageTitle->appendChild( $doc->createTextNode( $this->attribute( 'title' ) ) );
00656             $image->appendChild( $imageTitle );
00657 
00658             $imageLink = $doc->createElement( 'link' );
00659             $imageLink->appendChild( $doc->createTextNode( $this->attribute( 'url' ) ) );
00660             $image->appendChild( $imageLink );
00661 
00662             $imageUrlNode = $doc->createElement( 'url' );
00663             $imageUrlNode->appendChild( $doc->createTextNode( $imageURL ) );
00664             $image->appendChild( $imageUrlNode );
00665 
00666             $root->appendChild( $image );
00667         }
00668 
00669         $items = $doc->createElement( 'items' );
00670         $channel->appendChild( $items );
00671 
00672         $rdfSeq = $doc->createElementNS( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf:Seq' );
00673         $items->appendChild( $rdfSeq );
00674 
00675         $cond = array(
00676                     'rssexport_id'  => $this->ID,
00677                     'status'        => $this->Status
00678                     );
00679         $rssSources = eZRSSExportItem::fetchFilteredList( $cond );
00680 
00681         $nodeArray = eZRSSExportItem::fetchNodeList( $rssSources, $this->getObjectListFilter() );
00682 
00683         if ( is_array( $nodeArray ) && count( $nodeArray ) )
00684         {
00685             $attributeMappings = eZRSSExportItem::getAttributeMappings( $rssSources );
00686 
00687             foreach ( $nodeArray as $node )
00688             {
00689                 $object = $node->attribute( 'object' );
00690                 $dataMap = $object->dataMap();
00691                 if ( $useURLAlias === true )
00692                 {
00693                     $nodeURL = $this->urlEncodePath( $baseItemURL . $node->urlAlias() );
00694                 }
00695                 else
00696                 {
00697                     $nodeURL = $baseItemURL . 'content/view/full/' . $node->attribute( 'node_id' );
00698                 }
00699 
00700                 $rdfSeqLi = $doc->createElementNS( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf:li' );
00701                 $rdfSeqLi->setAttributeNS( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf:resource', $nodeURL );
00702                 $rdfSeq->appendChild( $rdfSeqLi );
00703 
00704                 // keep track if there's any match
00705                 $doesMatch = false;
00706                 // start mapping the class attribute to the respective RSS field
00707                 foreach ( $attributeMappings as $attributeMapping )
00708                 {
00709                     // search for correct mapping by path
00710                     if ( $attributeMapping[0]->attribute( 'class_id' ) == $object->attribute( 'contentclass_id' ) and
00711                          in_array( $attributeMapping[0]->attribute( 'source_node_id' ), $node->attribute( 'path_array' ) ) )
00712                     {
00713                         // found it
00714                         $doesMatch = true;
00715                         // now fetch the attributes
00716                         $title =  $dataMap[$attributeMapping[0]->attribute( 'title' )];
00717                         $description =  $dataMap[$attributeMapping[0]->attribute( 'description' )];
00718                         break;
00719                     }
00720                 }
00721 
00722                 if( !$doesMatch )
00723                 {
00724                     // no match
00725                     eZDebug::writeWarning( __METHOD__ . ': Cannot find matching RSS source node for content object in '.__FILE__.', Line '.__LINE__ );
00726                     $retValue = null;
00727                     return $retValue;
00728                 }
00729 
00730                 // title RSS element with respective class attribute content
00731                 $titleContent =  $title->attribute( 'content' );
00732                 if ( $titleContent instanceof eZXMLText )
00733                 {
00734                     $outputHandler =  $titleContent->attribute( 'output' );
00735                     $itemTitleText = $outputHandler->attribute( 'output_text' );
00736                 }
00737                 else
00738                 {
00739                     $itemTitleText = $titleContent;
00740                 }
00741 
00742                 $itemTitle = $doc->createElement( 'title' );
00743                 $itemTitle->appendChild( $doc->createTextNode( $itemTitleText ) );
00744 
00745                 // description RSS element with respective class attribute content
00746                 $descriptionContent =  $description->attribute( 'content' );
00747                 if ( $descriptionContent instanceof eZXMLText )
00748                 {
00749                     $outputHandler =  $descriptionContent->attribute( 'output' );
00750                     $itemDescriptionText = $outputHandler->attribute( 'output_text' );
00751                 }
00752                 else
00753                 {
00754                     $itemDescriptionText = $descriptionContent;
00755                 }
00756 
00757                 $itemDescription = $doc->createElement( 'description' );
00758                 $itemDescription->appendChild( $doc->createTextNode( $itemDescriptionText ) );
00759 
00760                 $itemLink = $doc->createElement( 'link' );
00761                 $itemLink->appendChild( $doc->createTextNode( $nodeURL ) );
00762 
00763                 $item = $doc->createElementNS( 'http://purl.org/rss/1.0/', 'item' );
00764                 $item->setAttributeNS( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'rdf:about', $nodeURL );
00765 
00766                 $item->appendChild( $itemTitle );
00767                 $item->appendChild( $itemLink );
00768                 $item->appendChild( $itemDescription );
00769 
00770                 $root->appendChild( $item );
00771             }
00772         }
00773 
00774         return $doc;
00775     }
00776 
00777     /*!
00778      \private
00779 
00780      Fetch Image from current ezrss export object. If non exist, or invalid, return false
00781 
00782      \return valid image url
00783     */
00784     function fetchImageURL()
00785     {
00786 
00787         $imageNode =  $this->attribute( 'image_node' );
00788         if ( !$imageNode )
00789             return false;
00790 
00791         $imageObject =  $imageNode->attribute( 'object' );
00792         if ( !$imageObject )
00793             return false;
00794 
00795         $dataMap =  $imageObject->attribute( 'data_map' );
00796         if ( !$dataMap )
00797             return false;
00798 
00799         $imageAttribute =  $dataMap['image'];
00800         if ( !$imageAttribute )
00801             return false;
00802 
00803         $imageHandler =  $imageAttribute->attribute( 'content' );
00804         if ( !$imageHandler )
00805             return false;
00806 
00807         $imageAlias =  $imageHandler->imageAlias( 'rss' );
00808         if( !$imageAlias )
00809             return false;
00810 
00811         $url = eZSys::hostname() . eZSys::wwwDir() .'/'. $imageAlias['url'];
00812         $url = preg_replace( "#^(//)#", "/", $url );
00813 
00814         return 'http://'.$url;
00815     }
00816 
00817     /*!
00818      \private
00819 
00820      Performs rawurlencode() on the path part of the URL. The rest is not touched.
00821 
00822      \return partially encoded url
00823     */
00824     function urlEncodePath( $url )
00825     {
00826         // Raw encode the path part of the URL
00827         $urlComponents = parse_url( $url );
00828         $pathParts = explode( '/', $urlComponents['path'] );
00829         foreach ( $pathParts as $key => $pathPart )
00830         {
00831             $pathParts[$key] = rawurlencode( $pathPart );
00832         }
00833         $encodedPath = implode( '/', $pathParts );
00834 
00835         // Rebuild the URL again, like this: scheme://user:pass@host/path?query#fragment
00836         $encodedUrl = $urlComponents['scheme'] . '://';
00837 
00838         if ( isset( $urlComponents['user'] ) )
00839         {
00840             $encodedUrl .= $urlComponents['user'];
00841             if ( isset( $urlComponents['pass'] ) )
00842             {
00843                 $encodedUrl .= ':' . $urlComponents['pass'];
00844             }
00845             $encodedUrl .= '@';
00846         }
00847 
00848         $encodedUrl .= $urlComponents['host'];
00849         if ( isset( $urlComponents['port'] ) )
00850         {
00851             $encodedUrl .= ':' . $urlComponents['port'];
00852         }
00853         $encodedUrl .= $encodedPath;
00854 
00855         if ( isset( $urlComponents['query'] ) )
00856         {
00857             $encodedUrl .= '?' . $urlComponents['query'];
00858         }
00859 
00860         if ( isset( $urlComponents['fragment'] ) )
00861         {
00862             $encodedUrl .= '#' . $urlComponents['fragment'];
00863         }
00864 
00865         return $encodedUrl;
00866     }
00867 }
00868 ?>