root/ez_publish/myutils/trunk/cronjobs/planet.php

Revision 222, 19.6 kB (checked in by llaumgui, 6 weeks ago)

Ecriture de logs pour planet

Line 
1<?php
2/*
3 * #################### BEGIN LICENSE BLOCK ####################
4 * This file is part of myUtils.
5 * Copyright (c) 2007 Guillaume Kulakowski and contributors.
6 *
7 * MyUtils is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * MyUtils is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15 * the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public
18 * License along with ezipb; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330,
20 * Boston, MA  02111-1307  USA
21 * or visit http://www.gnu.org/licenses/gpl.html
22 * ###################### END LICENSE BLOCK ####################
23 *
24 * planet cronjob.
25 *
26 * @author Guillaume Kulakowski <guillaume_AT_llaumgui_DOT_com>
27 * @version 1.0
28 */
29
30$beginScript = microtime(true);
31
32//include_once( 'kernel/classes/ezrssimport.php' );
33//include_once( 'kernel/classes/ezcontentclass.php' );
34//include_once( 'kernel/classes/ezcontentobject.php' );
35//include_once( 'kernel/classes/ezpersistentobject.php' );
36//include_once( 'kernel/classes/ezcontentobjecttreenode.php' );
37//include_once( 'kernel/classes/ezcontentobjectversion.php' );
38//include_once( 'lib/ezutils/classes/ezoperationhandler.php' );
39//include_once( "lib/ezdb/classes/ezdb.php" );
40//include_once( "lib/ezutils/classes/ezhttptool.php" );
41//include_once( "extension/myutils/classes/myutilsfunction.php" );
42
43global $logInfo;
44
45$iniSite             = eZINI::instance( "site.ini" );
46$iniPlanet             = eZINI::instance( "planet.ini" );
47$bloggeurGID        = $iniPlanet->variable( "PlanetInfo", "UserGroupNodeID" );
48
49$logInfo            = array(
50    'countTotalBillets'        => 0,
51    'countTotalBlogs'        => 0,
52    'blogOK'                => 0,
53    'blogKO'                => 0,
54    'logName'                => $iniPlanet->variable( "PlanetLog", "LogName" ),
55    'logDir'                => $iniSite->variable( "FileSettings", "VarDir" ) . "/log"
56);       
57 
58$rssImportArray     = eZContentObjectTreeNode::fetch( $bloggeurGID );
59$rssImportArray     = $rssImportArray->children ();
60$logInfo['countTotalBlogs']    = count( $rssImportArray );
61
62eZLog::write( "========== BEGIN | " . $logInfo['countTotalBlogs'] . " blogs ==========", $logInfo['logName'],    $logInfo['logDir'] );
63
64
65// Loop through all configured and active rss imports. If something goes wrong while processing them, continue to next import
66foreach ( $rssImportArray as $rssImport )
67{
68    // Get RSSImport object
69       $rssImport                = $rssImport->ContentObject;
70       $rssImportDataMap        = $rssImport->dataMap();
71    $rssSource                = $rssImportDataMap['location_rss']->content();
72   
73    if( empty($rssSource))
74    {
75        if ( !$isQuiet )
76        {
77            $cli->output( 'RSSImport '. $rssImport->attribute( 'name' ) .': Escape.' );
78        }
79        eZLog::write( "====> " . $rssImport->attribute( 'name' ) . " : no RSS feeds", $logInfo['logName'], $logInfo['logDir'] );
80        $logInfo['blogKO']++;
81    }
82    else
83    {
84        $addCount = 0;
85       
86        if ( !$isQuiet )
87        {
88            $cli->output( 'RSSImport '.$rssImport->attribute( 'name' ).': Starting.' );
89        }
90   
91        $xmlData = myUtilsFunctions::getDataByURL( $rssSource );
92        if ( $xmlData === false )
93        {
94            if ( !$isQuiet )
95            {
96                $cli->output( 'RSSImport '.$rssImport->attribute( 'name' ).': Failed to open RSS feed file: '.$rssSource );
97            }
98            eZLog::write( "====> " . $rssImport->attribute( 'name' ) . " : Failed to open RSS feed file", $logInfo['logName'], $logInfo['logDir'] );
99            $logInfo['blogKO']++;
100            continue;
101        }
102   
103        // Create DomDocument from http data
104        $domDocument = new DOMDocument( '1.0', 'utf-8' );
105        $success = $domDocument->loadXML( $xmlData );
106   
107        if ( !$success )
108        {
109            if ( !$isQuiet )
110            {
111                $cli->output( 'RSSImport '.$rssImport->attribute( 'name' ).': Invalid RSS document.' );
112            }
113            eZLog::write( "====> " . $rssImport->attribute( 'name' ) . " : Invalid RSS document", $logInfo['logName'], $logInfo['logDir'] );
114            $logInfo['blogKO']++;
115            continue;
116        }
117   
118        $root = $domDocument->documentElement;
119   
120        switch( $root->getAttribute( 'version' ) )
121        {
122            default:
123            case '1.0':
124            {
125                $version = '1.0';
126            } break;
127   
128            case '0.91':
129            case '0.92':
130            case '2.0':
131            {
132                $version = $root->getAttribute( 'version' );
133            } break;
134        }
135   
136        if ( $version !=  $rssImportDataMap['rss_version']->toString() )
137        {
138            if ( !$isQuiet )
139            {
140                $cli->output( 'RSSImport '.$rssImport->attribute( 'name' ).': Invalid RSS version missmatch. Please reconfigure import.' );
141            }
142            eZLog::write(    $rssImport->attribute( 'name' ) . " : Invalid RSS version missmatch. Please reconfigure import", $logInfo['logName'], $logInfo['logDir'] );
143            $logInfo['blogKO']++;
144            continue;
145        }
146        switch( $root->getAttribute( 'version' ) )
147        {
148            default:
149            case '1.0':
150            {
151                rssImport1( $root, $rssImport, $cli );
152            } break;
153   
154            case '0.91':
155            case '0.92':
156            case '2.0':
157            {
158                rssImport2( $root, $rssImport, $cli );
159            } break;
160        }
161    }
162}
163
164//include_once( 'kernel/classes/ezstaticcache.php' );
165eZStaticCache::executeActions();
166
167$endScript         = microtime(true);
168$executionTime    = round($endScript - $beginScript, 4);
169
170eZLog::write(    "========== END | " . $executionTime . "s | " . $logInfo['countTotalBlogs'] . " blogs : " . $logInfo['blogOK'] . " OK, " . $logInfo['blogKO'] . " KO | " . $logInfo['countTotalBillets'] . " billets ==========\n",
171                $logInfo['logName'],
172                $logInfo['logDir'] );
173
174
175
176
177
178/************************************************************************** Fonction */
179
180/**
181 * Parse RSS 1.0 feed
182 * @param DOM root node
183 * @param RSS Import item
184 * @param cli
185 */
186function rssImport1( $root, $rssImport, $cli )
187{
188    global $isQuiet, $logInfo;
189
190    $addCount = 0;
191
192    // Get all items in rss feed
193    $itemArray = $root->getElementsByTagName( 'item' );
194    $channel = $root->getElementsByTagName( 'channel' )->item( 0 );
195
196    // Loop through all items in RSS feed
197    foreach ( $itemArray as $item )
198    {
199        $addCount += importRSSItem( $item, $rssImport, $cli, $channel, $iniPlanet );
200    }
201
202    if ( !$isQuiet )
203    {
204        $cli->output( 'RSSImport '.$rssImport->attribute( 'name' ).': End. '.$addCount.' objects added' );
205    }
206    eZLog::write(    $rssImport->attribute( 'name' ) . " (RSS1) : $addCount objects added", $logInfo['logName'], $logInfo['logDir'] );
207    $logInfo['countTotalBillets']    += $addCount;
208    $logInfo['blogOK']++;
209}
210
211
212
213/**
214 * Parse RSS 2.0 feed
215 *
216 * @param DOM root node
217 * @param RSS Import item
218 * @param cli
219 */
220function rssImport2( $root, $rssImport, $cli )
221{
222    global $isQuiet, $logInfo;
223
224    $addCount = 0;
225
226    // Get all items in rss feed
227    $channel = $root->getElementsByTagName( 'channel' )->item( 0 );
228
229    // Loop through all items in RSS feed
230    foreach ( $channel->getElementsByTagName( 'item' ) as $item )
231    {
232        $addCount += importRSSItem( $item, $rssImport, $cli, $channel );
233    }
234
235    if ( !$isQuiet )
236    {
237        $cli->output( 'RSSImport '.$rssImport->attribute( 'name' ).': End. '.$addCount.' objects added' );
238    }
239    eZLog::write(    $rssImport->attribute( 'name' ) . " (RSS2) : $addCount objects added", $logInfo['logName'], $logInfo['logDir'] );
240    $logInfo['countTotalBillets']    += $addCount;
241    $logInfo['blogOK']++;
242}
243
244
245
246/**
247 * Import specifiec rss item into content tree
248 *
249 * @param RSS item xml element
250 * @param $rssImport Object
251 * @param cli
252 * @param channel
253 * @return 1 if object added, 0 if not
254 */
255function importRSSItem( $item, $rssImport, $cli, $channel )
256{
257    global $isQuiet;
258   
259    $iniPlanet         = eZINI::instance( "planet.ini" );
260   
261    $rssImportID = $rssImport->attribute( 'id' );
262    $rssOwnerID = $rssImport->attribute( 'object_owner_id' ); // Get owner user id
263    $parentContentObjectTreeNode = eZContentObjectTreeNode::fetch( $iniPlanet->variable( "PlanetInfo", "DestinationNodeID" ) ); // Get parent treenode object
264
265    if ( $parentContentObjectTreeNode == null )
266    {
267        if ( !$isQuiet )
268        {
269            $cli->output( 'RSSImport '.$rssImport->attribute( 'name' ).': Destination tree node seems to be unavailable' );
270        }
271        return 0;
272    }
273
274    $parentContentObject = $parentContentObjectTreeNode->attribute( 'object' ); // Get parent content object
275    $titleElement = $item->getElementsByTagName( 'title' )->item( 0 );
276    $title = is_object( $titleElement ) ? $titleElement->textContent : '';
277
278    // Test for link or guid as unique identifier
279    $link = $item->getElementsByTagName( 'link' )->item( 0 );
280    $guid = $item->getElementsByTagName( 'guid' )->item( 0 );
281    if ( $link->textContent )
282    {
283        $md5Sum = md5( $link->textContent );
284    }
285    elseif ( $guid->textContent )
286    {
287        $md5Sum = md5( $guid->textContent );
288    }
289    else
290    {
291        if ( !$isQuiet )
292        {
293            $cli->output( 'RSSImport '.$rssImport->attribute( 'name' ).': Item has no unique identifier. RSS guid or link missing.' );
294        }
295        return 0;
296    }
297
298    // Try to fetch RSSImport object with md5 sum matching link.
299    $existingObject = eZPersistentObject::fetchObject( eZContentObject::definition(), null,
300                                                       array( 'remote_id' => 'RSSImport_'.$rssImportID.'_'.$md5Sum ) );
301
302    // if object exists, continue to next import item
303    if ( $existingObject != null )
304    {
305        if ( !$isQuiet )
306        {
307            $cli->output( 'RSSImport '.$rssImport->attribute( 'name' ).': Object ( ' . $existingObject->attribute( 'id' ) . ' ) with URL: '.$linkURL.' already exists' );
308        }
309        unset( $existingObject ); // delete object to preserve memory
310        return 0;
311    }
312
313    // Fetch class, and create ezcontentobject from it.
314    $contentClass = eZContentClass::fetch( $iniPlanet->variable( "BilletClass", "ClassID" )  );
315
316    // Instantiate the object with user $rssOwnerID and use section id from parent. And store it.
317    $contentObject = $contentClass->instantiate( $rssImport->ID, $parentContentObject->attribute( 'section_id' ) );
318
319    $db = eZDB::instance();
320    $db->begin();
321    $contentObject->store();
322    $contentObjectID = $contentObject->attribute( 'id' );
323
324    // Create node assignment
325    $nodeAssignment = eZNodeAssignment::create( array( 'contentobject_id' => $contentObjectID,
326                                                       'contentobject_version' => $contentObject->attribute( 'current_version' ),
327                                                       'is_main' => 1,
328                                                       'parent_node' => $parentContentObjectTreeNode->attribute( 'node_id' ) ) );
329    $nodeAssignment->store();
330
331    $version = $contentObject->version( 1 );
332    $version->setAttribute( 'status', eZContentObjectVersion::STATUS_DRAFT );
333    $version->store();
334
335    // Get object attributes, and set their values and store them.
336    $dataMap = $contentObject->dataMap();
337    $importDescription = $iniPlanet->variable( "BilletClass", "ImportDescription" );
338
339    // Set content object attribute values.
340    $classAttributeList = $contentClass->fetchAttributes();
341    foreach( $classAttributeList as $classAttribute )
342    {
343        $classAttributeID         = $classAttribute->attribute( 'id' );
344        $importClassAttributes    = $iniPlanet->variable( "BilletClass", "ClassAttributes" );
345       
346        if ( isset( $importClassAttributes[$classAttributeID] ) )
347        {
348            if ( $importDescription['class_attributes'][$classAttributeID] == '-1' )
349            {
350                continue;
351            }
352
353            $importDescriptionArray = explode( ' - ', $importClassAttributes[$classAttributeID] );
354            if ( count( $importDescriptionArray ) < 1 )
355            {
356                $cli->output( 'RSSImport '.$rssImport->attribute( 'name' ).': Invalid import definition. Please redit.' );
357                break;
358            }
359
360            $elementType = $importDescriptionArray[0];
361            array_shift( $importDescriptionArray );
362            switch( $elementType )
363            {
364                case 'item':
365                {
366                    setObjectAttributeValue( $dataMap[$classAttribute->attribute( 'identifier' )],
367                                             recursiveFindRSSElementValue( $importDescriptionArray,
368                                                                           $item ) ) . "\n";
369                } break;
370
371                case 'channel':
372                {
373                    setObjectAttributeValue( $dataMap[$classAttribute->attribute( 'identifier' )],
374                                             recursiveFindRSSElementValue( $importDescriptionArray,
375                                                                           $channel ) );
376                } break;
377            }
378        }
379    }
380
381    $contentObject->setAttribute( 'remote_id', 'RSSImport_'.$rssImportID.'_'. $md5Sum );
382    $contentObject->store();
383    $db->commit();
384
385    //publish new object
386    $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $contentObject->attribute( 'id' ),
387                                                                                 'version' => 1 ) );
388
389    if ( !isset( $operationResult['status'] ) || $operationResult['status'] != eZModuleOperationInfo::STATUS_CONTINUE )
390    {
391        if ( isset( $operationResult['result'] ) && isset( $operationResult['result']['content'] ) )
392            $failReason = $operationResult['result']['content'];
393        else
394            $failReason = "unknown error";
395        $cli->error( "Publishing failed: $failReason" );
396        unset( $failReason );
397    }
398
399    $db->begin();
400    unset( $contentObject );
401    unset( $version );
402    $contentObject = eZContentObject::fetch( $contentObjectID );
403    $version = $contentObject->attribute( 'current' );
404    // Set object Attributes like modified and published timestamps
405    $objectAttributeDescription = $iniPlanet->variable( "BilletClass", "OjectAttributes" );
406    foreach( $objectAttributeDescription as $identifier => $objectAttributeDefinition )
407    {
408        if ( $objectAttributeDefinition == '-1' )
409        {
410            continue;
411        }
412
413        $importDescriptionArray = explode( ' - ', $objectAttributeDefinition );
414
415        $elementType = $importDescriptionArray[0];
416        array_shift( $importDescriptionArray );
417        switch( $elementType )
418        {
419            default:
420            case 'item':
421            {
422                $domNode = $item;
423            } break;
424
425            case 'channel':
426            {
427                $domNode = $channel;
428            } break;
429        }
430
431        switch( $identifier )
432        {
433            case 'modified':
434            {
435                $dateTime = recursiveFindRSSElementValue( $importDescriptionArray,
436                                                          $domNode );
437                if ( !$dateTime )
438                {
439                    break;
440                }
441                $contentObject->setAttribute( $identifier, strtotime( $dateTime ) );
442                $version->setAttribute( $identifier, strtotime( $dateTime ) );
443            } break;
444
445            case 'published':
446            {
447                $dateTime = recursiveFindRSSElementValue( $importDescriptionArray,
448                                                          $domNode );
449                if ( !$dateTime )
450                {
451                    break;
452                }
453                $contentObject->setAttribute( $identifier, strtotime( $dateTime ) );
454                $version->setAttribute( 'created', strtotime( $dateTime ) );
455            } break;
456        }
457    }
458    $version->store();
459    $contentObject->store();
460    $db->commit();
461
462    if ( !$isQuiet )
463    {
464        $cli->output( 'RSSImport '.$rssImport->attribute( 'name' ).': Object created; ' . $title );
465    }
466
467    return 1;
468}
469
470
471
472/**
473 * Enter description here...
474 *
475 * @param array $importDescriptionArray
476 * @param DOM $xmlDomNode
477 * @return unknown
478 */
479function recursiveFindRSSElementValue( $importDescriptionArray, $xmlDomNode )
480{
481    if ( !is_array( $importDescriptionArray ) )
482    {
483        return false;
484    }
485
486    $valueType = $importDescriptionArray[0];
487    array_shift( $importDescriptionArray );
488    switch( $valueType )
489    {
490        case 'elements':
491        {
492            if ( count( $importDescriptionArray ) == 1 )
493            {
494                $element = $xmlDomNode->getElementsByTagName( $importDescriptionArray[0] )->item( 0 );
495
496                $resultText = is_object( $element ) ? $element->textContent : false;
497                return $resultText;
498            }
499            else
500            {
501                $elementName = $importDescriptionArray[0];
502                array_shift( $importDescriptionArray );
503                return recursiveFindRSSElementValue( $importDescriptionArray, $xmlDomNode->getElementsByTagName( $elementName )->item( 0 ) );
504            }
505        }
506
507        case 'attributes':
508        {
509            return $xmlDomNode->getAttribute( $importDescriptionArray[0] );
510        } break;
511    }
512}
513
514
515
516/**
517 * Enter description here...
518 *
519 * @param unknown_type $objectAttribute
520 * @param unknown_type $value
521 */
522function setObjectAttributeValue( $objectAttribute, $value )
523{
524    if ( $value === false )
525    {
526        return;
527    }
528
529    $dataType = $objectAttribute->attribute( 'data_type_string' );
530    switch( $dataType )
531    {
532        case 'ezxmltext':
533        {
534            setEZXMLAttribute( $objectAttribute, $value );
535        } break;
536
537        case 'ezurl':
538        {
539            $objectAttribute->setContent( $value );
540        } break;
541
542        case 'ezkeyword':
543        {
544            //include_once( 'kernel/classes/datatypes/ezkeyword/ezkeyword.php' );
545            $keyword = new eZKeyword();
546            $keyword->initializeKeyword( $value );
547            $objectAttribute->setContent( $keyword );
548        } break;
549       
550        case 'eztext':
551        {
552            setEZTXTAttribute( $objectAttribute, $value );
553        } break;
554
555        default:
556        {
557            $objectAttribute->setAttribute( 'data_text', $value );
558        } break;
559    }
560
561    $objectAttribute->store();
562}
563
564