Changeset 11037

Show
Ignore:
Timestamp:
06/27/07 09:44:12 (3 years ago)
Author:
rambo
Message:

Some sanity checking to the automatiuc request_switch generation
Basic feed outputs seem to work, now just to get the media tags
working properly (and calls to add_link_head to supported handler to
add the rel=alternate links)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/MidCOM_2_8/org.routamc.photostream/handler/feed.php

    r11036 r11037  
    1010class org_routamc_photostream_handler_feed extends org_routamc_photostream_handler_list 
    1111{ 
     12    var $_feed; 
     13 
     14    /** 
     15     * Array of normalized file basenames (with extension removed) pointing 
     16     * to de.bitfolge.feedcreator creator types 
     17     */ 
     18    var $_supported_types = array 
     19    ( 
     20        'rss' => 'RSS2.0', 
     21        'rss1' => 'RSS1.0', 
     22        'rss091' => 'RSS0.91', 
     23        'atom' => 'ATOM', 
     24    ); 
     25 
    1226    /** 
    1327     * Simple default constructor. 
     
    1933 
    2034    /** 
    21      * Overloaded since we really dont' need those 
     35     * We override this to avoid unneccessary controller creations 
    2236     */ 
    2337    function _prepare_ajax_controllers() 
    2438    { 
    25         // No need for these in the feed... 
    26         return; 
     39        // No need for ajax stuff here 
    2740    } 
    2841 
     
    3548    { 
    3649        debug_push_class(__CLASS__, __FUNCTION__); 
    37         $parent_handler_id = preg_replace('/^feed:/', '', $handler_id); 
    38         if (!isset($data['request_switch'][$parent_handler_id])) 
     50        // This is required and will throw error if we can't load it 
     51        $_MIDCOM->load_library('de.bitfolge.feedcreator'); 
     52        if ($GLOBALS['midcom_config']['positioning_enable']) 
     53        { 
     54            // Silently try to load this library if possible 
     55            $_MIDCOM->componentloader->load_graceful('org.routamc.positioning'); 
     56        } 
     57 
     58        $data['parent_handler_id'] = preg_replace('/^feed[0-9]*:/', '', $handler_id); 
     59        if (!isset($data['request_switch'][$data['parent_handler_id']])) 
    3960        { 
    4061            // Fatal, cannot solve haandler to use to get the actual data 
    41             debug_add("Cannot find handler_id '{$parent_handler_id}'", MIDCOM_LOG_ERROR); 
    42             debug_pop(); 
    43             return false; 
    44         } 
    45         $parent_method = "_handler_{$data['request_switch'][$parent_handler_id]['handler'][1]}"; 
     62            debug_add("Cannot find handler_id '{$data['parent_handler_id']}'", MIDCOM_LOG_ERROR); 
     63            debug_pop(); 
     64            return false; 
     65        } 
     66        $parent_method = "_handler_{$data['request_switch'][$data['parent_handler_id']]['handler'][1]}"; 
    4667        debug_add("Resolved parent method to '{$parent_method}'"); 
     68 
     69        if (!is_callable(array($this, $parent_method))) 
     70        { 
     71            // Fatal, parent method is not callable 
     72            debug_add("Handler method \$this->{$parent_method} is not callable", MIDCOM_LOG_ERROR); 
     73            debug_pop(); 
     74            return false; 
     75        } 
     76        // Use array_pop so we can pass the args on to the parent handler and it will not get confused by too long argument list 
     77        $feed_type_arg = array_pop($args); 
     78 
     79        // This will also do some validations 
     80        $this->_normalize_feed_type($feed_type_arg); 
     81        $this->_resolve_feed_urls($args); 
     82         
     83        debug_add("Calling \$this->{$parent_method}('{$data['parent_handler_id']}', \$args, \$data)"); 
     84        if (!$this->$parent_method($data['parent_handler_id'], $args, $data)) 
     85        { 
     86            debug_add("\$this->{$parent_method}('{$data['parent_handler_id']}', \$args, \$data) returned false", MIDCOM_LOG_ERROR); 
     87            debug_pop(); 
     88            return false; 
     89        } 
     90        if (!isset($data['photos'])) 
     91        { 
     92            debug_add("\$data['photos'] is not set, most probably we hit a method ('{$parent_method}') in the list handler that does not populate it", MIDCOM_LOG_WARN); 
     93            debug_pop(); 
     94            return false; 
     95        } 
     96        $this->_create_feed(); 
     97 
    4798        // Now that we have all that we need, we can remove this reference from cluttering our world 
    4899        unset($data['request_switch']); 
    49100 
    50         if (!is_callable(array($this, $parent_method))) 
    51         { 
    52             // Fatal, parent method is not callable 
    53             debug_add("Handler method \$this->{$parent_method} is not callable", MIDCOM_LOG_ERROR); 
    54             debug_pop(); 
    55             return false; 
    56         } 
    57         // Use array_pop so we can pass the args on to the parent handler and it will not get confused by too long argument list 
    58         $data['feed_type_arg'] = array_pop($args); 
    59          
    60         // TODO: Validate feed type before continuing 
    61          
    62         debug_add("Calling \$this->{$parent_method}('{$parent_handler_id}', \$args, \$data)"); 
    63         if (!$this->$parent_method($parent_handler_id, $args, $data)) 
    64         { 
    65             debug_add("\$this->{$parent_method}('{$parent_handler_id}', \$args, \$data) returned false", MIDCOM_LOG_ERROR); 
    66             debug_pop(); 
    67             return false; 
    68         } 
    69         if (!isset($data['photos'])) 
    70         { 
    71             debug_add("\$data['photos'] is not set, most probably we hit a method ('{$parent_method}') in the list handler that does not populate it", MIDCOM_LOG_WARN); 
    72             debug_pop(); 
    73             /* TODO: Check if this is correct way 
    74             $_MIDCOM->generate_error(MIDCOM_ERR_NOTFOUND); 
    75             // This will exit 
    76             */ 
    77             return false; 
    78         } 
     101 
     102        $this->_datamanager = new midcom_helper_datamanager2_datamanager($this->_request_data['schemadb']); 
     103 
     104        // No failures thus far, set content type etc 
     105        $_MIDCOM->cache->content->content_type("text/xml"); 
     106        $_MIDCOM->header("Content-type: text/xml; charset=UTF-8"); 
     107        $_MIDCOM->skip_page_style = true; 
    79108 
    80109        debug_pop(); 
     
    82111    } 
    83112 
     113    /** 
     114     * Reolves sane URL for both the HTML view and the feed 
     115     */ 
     116    function _resolve_feed_urls($args) 
     117    { 
     118        $data =& $this->_request_data; 
     119        $data['prefix'] = $_MIDCOM->get_context_data(MIDCOM_CONTEXT_ANCHORPREFIX); 
     120        $parent_switch =& $data['request_switch'][$data['parent_handler_id']]; 
     121        $data['list_url'] = $data['prefix'] . implode('/', $parent_switch['fixed_args']) . '/'. implode('/', $args) . '/'; 
     122        $data['feed_url'] = "{$data['prefix']}feed/" . implode('/', $parent_switch['fixed_args']) . '/'. implode('/', $args) . "/{$data['feed_filename']}"; 
     123    } 
     124 
     125    /** 
     126     * Resolves and sanity-checks the feed type from the filename given as last argument to the dispatcher 
     127     */ 
     128    function _normalize_feed_type($type_str) 
     129    { 
     130        debug_push_class(__CLASS__, __FUNCTION__); 
     131        $data =& $this->_request_data; 
     132        $type = preg_replace('/\..*$/', '', strtolower($type_str)); 
     133        debug_add("normalized '{$type_str}' to '{$type}'"); 
     134        if (   !isset($this->_supported_types[$type]) 
     135            || empty($this->_supported_types[$type])) 
     136        { 
     137            debug_add("Feed type '{$type}' is not supported", MIDCOM_LOG_ERROR); 
     138            debug_pop(); 
     139            $_MIDCOM->generate_error(MIDCOM_ERRNOTFOUND, "Feed type '{$type}' is not supported"); 
     140            // This will exit() 
     141        } 
     142        $data['feed_type'] = $this->_supported_types[$type]; 
     143        $data['feed_filename'] = "{$type}.xml"; 
     144    } 
     145 
     146    /** 
     147     * Instantiate the feed object and set base value 
     148     */ 
     149    function _create_feed() 
     150    { 
     151        $data =& $this->_request_data; 
     152        $this->_feed = new UniversalFeedCreator(); 
     153        $this->_feed->cssStyleSheet = false; 
     154        if (   isset($data['view_title']) 
     155            && !empty($data['view_title'])) 
     156        { 
     157            $this->_feed->title = $data['view_title']; 
     158        } 
     159        else 
     160        { 
     161            $this->_feed->title = $this->_topic->extra; 
     162        } 
     163        $this->_feed->language = $this->_config->get('rss_language'); 
     164        $this->_feed->editor = $this->_config->get('rss_webmaster'); 
     165        $this->_feed->link = $data['list_url']; 
     166        $this->_feed->syndicationURL = $data['feed_url']; 
     167    } 
     168 
     169    /** 
     170     * Add each photo as item to the feed then creates the XML and 
     171     * finally calls an element if one wishes to mangle the raw feed data 
     172     */ 
    84173    function _show_dispatcher($handler_id, &$data) 
    85174    { 
    86         echo "<p>Handler '{$handler_id}' says: Hello world!</p>"; 
    87         /* 
    88         echo "request_data: <pre>\n"; 
    89         print_r($data); 
    90         echo "</pre>\n"; 
    91         */ 
     175        foreach($data['photos'] as $photo) 
     176        { 
     177            $this->_add_photo_to_feed($photo); 
     178        } 
     179        $data['feed_data'] = $this->_feed->createFeed($data['feed_type']); 
     180        ob_start(); 
     181        midcom_show_style('mangle_feed_data'); 
     182        ob_end_clean(); 
     183        echo $data['feed_data']; 
     184        unset($data['feed_data']); 
     185    } 
     186 
     187    /** 
     188     * This method creates a feed item for a photo object given 
     189     * It uses the style-engine to render the description and to 
     190     * allow custom hacks to mangle the item data 
     191     */ 
     192    function _add_photo_to_feed(&$photo) 
     193    { 
     194        $data =& $this->_request_data; 
     195        $item = new FeedItem(); 
     196        $item->title = $photo->title; 
     197        $item->link = "{$data['prefix']}photo/{$photo->guid}/"; 
     198        $item->date = $photo->taken; 
     199        $data['item'] =& $item; 
     200 
     201        if (!$this->_datamanager->autoset_storage($photo)) 
     202        { 
     203            return false; 
     204        } 
     205        $data['datamanager'] =& $this->_datamanager; 
     206        $data['photo'] =& $photo; 
     207        $data['photo_view'] = $this->_datamanager->get_content_html(); 
     208        $thumbnail = false; 
     209        if (   isset($data['datamanager']->types['photo']) 
     210            && isset($data['datamanager']->types['photo']->attachments_info['thumbnail'])) 
     211        { 
     212            $thumbnail = $data['datamanager']->types['photo']->attachments_info['thumbnail']; 
     213        } 
     214        if ($thumbnail) 
     215        { 
     216            $item->thumb = $thumbnail['url']; 
     217        } 
     218        $tags = net_nemein_tag_handler::get_object_tags($photo); 
     219        if (!empty($tags)) 
     220        { 
     221            // Use first tag as category 
     222            $item->category = array_shift($tags); 
     223        } 
     224 
     225        ob_start(); 
     226        midcom_show_style('render_feed_item'); 
     227        $item->description = ob_get_contents(); 
     228        ob_end_clean(); 
     229 
     230        if (class_exists('org_routamc_positioning_object')) 
     231        { 
     232            // Attach coordinates to the item if available 
     233            $object_position = new org_routamc_positioning_object($photo); 
     234            $coordinates = $object_position->get_coordinates(); 
     235            if (!is_null($coordinates)) 
     236            { 
     237                $item->lat = $coordinates['latitude']; 
     238                $item->long = $coordinates['longitude']; 
     239            } 
     240        } 
     241        // Replace links, TODO: This should be a feature of feedcreator... 
     242        $item->description = preg_replace(',<(a|link|img|script|form|input)([^>]+)(href|src|action)="/([^>"\s]+)",ie', '"<\1\2\3=\"' . $_MIDCOM->get_host_name() . '/\4\""', $item->description); 
     243 
     244        ob_start(); 
     245        midcom_show_style('mangle_feed_item'); 
     246        ob_end_clean(); 
     247        $this->_feed->addItem($item); 
    92248    } 
    93249} 
  • branches/MidCOM_2_8/org.routamc.photostream/viewer.php

    r11036 r11037  
    348348            } 
    349349            $new_id = "feed:{$handler_id}"; 
     350            if (isset($this->_request_switch[$new_id])) 
     351            { 
     352                debug_add("Not reating new switch '{$new_id}', it already exists", MIDCOM_LOG_INFO); 
     353                continue; 
     354            } 
    350355            debug_add("Creating new switch with id '{$new_id}'"); 
    351356            // PHP5-TODO: Must be copy-by-value 
     
    360365            $new_switch['variable_args']++; 
    361366             
    362             /* OTOH the variable_args increment server the same purpose and it's easier to just add rss.xml/atom.xml to the url... 
    363             // Prepend /feed/ to list fixed args 
    364             array_unshift($new_switch['fixed_args'], 'feed'); 
    365             */ 
    366  
     367            if (!$this->_sanity_check_switch($new_switch)) 
     368            { 
     369                // ULR-space clash, prepend /feed/ to list fixed args 
     370                debug_add("Prepending 'feed' to fixed_args"); 
     371                array_unshift($new_switch['fixed_args'], 'feed'); 
     372            } 
     373            if (!$this->_sanity_check_switch($new_switch)) 
     374            { 
     375                // URL-space still clashes 
     376                debug_add("New switch '{$new_id}' would never be match  ed, not adding", MIDCOM_LOG_WARN); 
     377                continue; 
     378            } 
    367379            // Add the new switch 
    368380            debug_print_r("Setting \$this->_request_switch['{$new_id}'] to: ", $new_switch); 
    369381            $this->_request_switch[$new_id] = $new_switch; 
     382 
     383            // If we were not forced to use the feed url space earlier add it anyway so we have at least one consistent interface 
     384            if ($new_switch['fixed_args'][0] !== 'feed') 
     385            { 
     386                array_unshift($new_switch['fixed_args'], 'feed'); 
     387                $new_id = "feed2:{$handler_id}"; 
     388                debug_print_r("Setting \$this->_request_switch['{$new_id}'] to: ", $new_switch); 
     389                $this->_request_switch[$new_id] = $new_switch; 
     390            } 
     391 
    370392            unset($new_id, $new_switch); 
    371393        } 
     
    373395        debug_print_r('$this->_request_switch is now: ', $this->_request_switch); 
    374396        debug_pop(); 
     397    } 
     398 
     399    function _sanity_check_switch(&$new_switch) 
     400    { 
     401        debug_push_class(__CLASS__, __FUNCTION__); 
     402        foreach ($this->_request_switch as $handler_id => $switch_data) 
     403        { 
     404            debug_add("Comparing with handler '{$handler_id}'"); 
     405            switch(true) 
     406            { 
     407                case (   !isset($switch_data['fixed_args']) 
     408                      && isset($new_switch['fixed_args'])): 
     409                    debug_add('existing switch has not-set fixed_args and new_switch has'); 
     410                    $fixed_diff = true; 
     411                    break; 
     412                case (   !isset($new_switch['fixed_args']) 
     413                      && isset($switch_data['fixed_args'])): 
     414                    debug_add('new_switch has not-set fixed_args and existing switch has'); 
     415                    $fixed_diff = true; 
     416                    break; 
     417                case (   !is_array($switch_data['fixed_args']) 
     418                      && is_array($new_switch['fixed_args'])): 
     419                    debug_add('existing switch fixed_args is not array, new_switch fixed_args is'); 
     420                    $fixed_diff = true; 
     421                    break; 
     422                case (   !is_array($new_switch['fixed_args']) 
     423                      && is_array($switch_data['fixed_args'])): 
     424                    debug_add('new_switch fixed_args is not array, existing switch fixed_args is'); 
     425                    $fixed_diff = true; 
     426                    break; 
     427                case (   is_array($switch_data['fixed_args']) 
     428                      && is_array($new_switch['fixed_args'])): 
     429                    debug_add('new_switch and existing switch fixed_args are both arrays, calling array_diff'); 
     430                    $fixed_diff = array_diff($switch_data['fixed_args'], $new_switch['fixed_args']); 
     431                    if (empty($fixed_diff)) 
     432                    { 
     433                        /** 
     434                         * array_diff() returns an array consisting of all elements in $array1 that are not in $array2, 
     435                         * NOT a true diff, thus we need to check again with reversed order 
     436                         */  
     437                        $fixed_diff = array_diff($new_switch['fixed_args'], $switch_data['fixed_args']); 
     438                    } 
     439                    break; 
     440                default: 
     441                    debug_add('defaulting fixed_diff to false'); 
     442                    $fixed_diff = false; 
     443            } 
     444            debug_print_r('$fixed_diff: ', $fixed_diff); 
     445            if (!empty($fixed_diff)) 
     446            { 
     447                // Fixed args differ 
     448                continue; 
     449            } 
     450            if (   !isset($switch_data['variable_args']) 
     451                || !isset($new_switch['variable_args']) 
     452                || $switch_data['variable_args'] < $new_switch['variable_args']) 
     453            { 
     454                // Variable args do not overlap 
     455                continue; 
     456            } 
     457            debug_add("handler '{$handler_id}' already implements the url space", MIDCOM_LOG_INFO); 
     458            debug_print_r('$new_switch was: ', $new_switch, MIDCOM_LOG_INFO); 
     459            debug_print_r("\$this->_request_switch['{$handler_id}'] was: ", $switch_data, MIDCOM_LOG_INFO); 
     460            debug_pop(); 
     461            return false; 
     462        } 
     463        debug_pop(); 
     464        return true;         
    375465    } 
    376466