Changeset 11868

Show
Ignore:
Timestamp:
08/30/07 15:12:46 (1 year ago)
Author:
bergie
Message:

Rewritten URL parsing infrastructure, refs #1 and refs #102

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/midcom/midcom.core/midcom/application.php

    r11865 r11868  
    173173     * The URL parser. 
    174174     * 
    175      * @var midcom_helper_urlparser 
     175     * @var midcom_core_service_urlparser 
    176176     * @access private 
    177177     */ 
     
    414414        $this->_prefix = $GLOBALS['midcom_config']['midcom_prefix']; 
    415415 
    416         $this->midgard = $this->get_midgard(); 
     416        //$this->midgard = $this->get_midgard(); 
    417417 
    418418        $this->_status = MIDCOM_STATUS_PREPARE; 
     
    420420        // Load the services that are always needed, including the serviceloader 
    421421        $this->_load_core_services(); 
     422         
     423        // Start-up some of the services 
     424        $this->auth->initialize(); 
     425        $this->dbclassloader->load_classes('midcom', 'legacy_classes.inc'); 
     426        $this->dbclassloader->load_classes('midcom', 'core_classes.inc'); 
    422427 
    423428        $this->componentloader->load_all_manifests(); 
     
    444449            // This will exit. 
    445450        } 
    446  
     451         
    447452        // Initialize Context Storage 
    448         $this->_context = Array(); 
    449         $this->_create_context(0); 
    450         $this->_currentcontext = 0; 
    451         $this->_context[0][MIDCOM_CONTEXT_ROOTTOPIC] = $root_topic; 
     453        $this->_currentcontext = $this->_create_context(0, $root_topic); 
    452454 
    453455        // Populate browser information 
     
    476478        $this->componentloader = new midcom_helper__componentloader(); 
    477479        $this->dbclassloader = new midcom_services_dbclassloader(); 
    478         $this->dbclassloader->load_classes('midcom', 'legacy_classes.inc'); 
    479         $this->dbclassloader->load_classes('midcom', 'core_classes.inc'); 
    480480        $this->dbfactory = new midcom_helper__dbfactory(); 
    481481        $this->style = new midcom_helper__styleloader(); 
    482482        $this->auth = new midcom_services_auth(); 
    483         $this->auth->initialize(); 
    484483         
    485484        // These can be refactored behind serviceloader 
     
    545544    public function codeinit()  
    546545    { 
    547         $oldcontext = $this->_currentcontext; 
    548         $this->_currentcontext = 0; 
    549  
    550         // Initialize the UI message stack from session 
    551         $this->uimessages->initialize(); 
    552  
    553         $topic = $this->get_context_data(MIDCOM_CONTEXT_ROOTTOPIC); 
    554         $this->_parser = new midcom_helper_urlparser($topic->id); 
    555  
     546        if ($this->get_current_context() == 0) 
     547        {     
     548            // Initialize the UI message stack from session 
     549            $this->uimessages->initialize(); 
     550        } 
     551 
     552        // Parse the URL 
     553        $this->_parser = $this->serviceloader->load('midcom_core_service_urlparser'); 
     554        $this->_parser->parse($_MIDGARD['argv']); 
     555         
    556556        if (!$this->_parser)  
    557557        { 
     
    563563 
    564564        $this->_process(); 
    565  
    566         $this->_codeinit = false; 
    567  
    568         $this->_currentcontext = $oldcontext; 
    569565         
    570         // Let metadata service add its meta tags 
    571         $this->metadata->populate_meta_head(); 
     566        if ($this->get_current_context() == 0) 
     567        { 
     568            // Let metadata service add its meta tags 
     569            $this->metadata->populate_meta_head(); 
     570        } 
    572571    } 
    573572 
     
    702701        // Determine new Context ID and set $this->_currentcontext, 
    703702        // enter that context and prepare its data structure. 
    704         $context = $this->_create_context(); 
     703        $context = $this->_create_context(null, $_MIDCOM->get_context_data(MIDCOM_CONTEXT_ROOTTOPIC)); 
    705704        $oldcontext = $this->_currentcontext; 
    706705        $this->_currentcontext = $context; 
    707706 
    708         $this->_context[$context][MIDCOM_CONTEXT_REQUESTTYPE] = $type; 
    709         $this->_context[$context][MIDCOM_CONTEXT_CONTENTTOPIC] = null; 
    710         $this->_context[$context][MIDCOM_CONTEXT_COMPONENT] = null; 
    711         $this->_context[$context][MIDCOM_CONTEXT_ROOTTOPIC] = $this->_context[0][MIDCOM_CONTEXT_ROOTTOPIC]; 
    712         $this->_context[$context][MIDCOM_CONTEXT_OUTPUT] = null; 
    713         $this->_context[$context][MIDCOM_CONTEXT_NAP] = null; 
    714         $this->_context[$context][MIDCOM_CONTEXT_PAGETITLE] = ""; 
    715         $this->_context[$context][MIDCOM_CONTEXT_CUSTOMDATA] = Array(); 
    716  
    717707        // Parser Init: Generate arguments and instantinate it. 
    718  
    719         if (   $url == "" 
    720             || $url == "/") 
    721         { 
    722             $argv = array(); 
    723         } 
    724         else 
    725         { 
    726             if (strpos($url,"/") === 0) 
    727             { 
    728                 $url = substr($url,1); 
    729             } 
    730             if (substr($url,-1) == "/") 
    731             { 
    732                 $url = substr($url,0,-1); 
    733             } 
    734             $argv = explode ("/", $url); 
    735         } 
    736  
    737708        $topic = $this->get_context_data(MIDCOM_CONTEXT_ROOTTOPIC); 
    738         $this->_parser = new midcom_helper_urlparser($topic->id, $argv); 
     709        $this->_parser = $this->serviceloader->load('midcom_core_service_urlparser'); 
     710        $argv = $this->_parser->tokenize($url); 
     711        $this->_parser->parse($argv); 
    739712 
    740713        if (!$this->_parser) 
     
    851824        $substyle = ""; 
    852825 
    853         while (($tmp = $this->_parser->fetch_variable("midcom")) !== false) 
    854         { 
    855             switch ($tmp[MIDCOM_HELPER_URLPARSER_KEY]
     826        while (($tmp = $this->_parser->get_variable('midcom')) !== false) 
     827        { 
     828            foreach ($tmp as $key => $value
    856829            { 
    857                 case "substyle": 
    858                     $substyle = $tmp[MIDCOM_HELPER_URLPARSER_VALUE]; 
    859                     debug_add("Substyle '$substyle' selected", MIDCOM_LOG_INFO); 
    860                     break; 
    861  
    862                 case "serveattachmentguid": 
    863                 case "serveattachment": 
    864                     if ($this->_parser->argc > 1) 
    865                     { 
    866                         debug_add("Too many arguments remaining for serve_attachment.", MIDCOM_LOG_ERROR); 
    867                         debug_print_r("Parser object:", $this->_parser); 
    868                     } 
    869                     debug_add("Trying to serve Attachment with (GU)ID {$tmp[MIDCOM_HELPER_URLPARSER_VALUE]}", MIDCOM_LOG_INFO); 
    870                     $attachment = new midcom_baseclasses_database_attachment($tmp[MIDCOM_HELPER_URLPARSER_VALUE]); 
    871                     if (! $attachment) 
    872                     { 
    873                         $this->generate_error(MIDCOM_ERRNOTFOUND, 'Failed to access attachment: ' . mgd_errstr()); 
    874                     } 
    875                     if (! $attachment->can_do('midgard:autoserve_attachment')) 
    876                     { 
    877                         $this->generate_error(MIDCOM_ERRNOTFOUND, 'Failed to access attachment: Autoserving denied.'); 
    878                     } 
    879                     $this->serve_attachment($attachment); 
    880                     $this->finish(); 
    881                     exit(); 
    882  
    883                 case "servesnippet": 
    884                     if ($this->_parser->argc > 1) { 
    885                         debug_add("Too many arguments remaining for serve_snippet.", MIDCOM_LOG_ERROR); 
    886                         debug_print_r("Parser object:", $this->_parser); 
    887                         $this->generate_error(MIDCOM_ERRNOTFOUND, "Failed to access snippet: Too many arguments for serve_snippet"); 
    888                     } 
    889                     debug_add("Trying to serve snippet with ID " . $tmp[MIDCOM_HELPER_URLPARSER_VALUE], MIDCOM_LOG_INFO); 
    890                     $snippet = new midcom_baseclasses_database_snippet($tmp[MIDCOM_HELPER_URLPARSER_VALUE]); 
    891                     if (!$snippet)  
    892                     { 
    893                         debug_add("Failed to access snippet: " . mgd_errstr(), MIDCOM_LOG_ERROR); 
    894                         $this->generate_error(MIDCOM_ERRNOTFOUND, "Failed to access snippet: " . mgd_errstr()); 
    895                     } 
    896                     $this->serve_snippet($snippet); 
    897                     $this->finish(); 
    898                     exit(); 
    899  
    900                 case "servesnippetguid": 
    901                     if ($this->_parser->argc > 1) { 
    902                         debug_add("Too many arguments remaining for serve_snippet.", MIDCOM_LOG_ERROR); 
    903                         debug_print_r("Parser object:", $this->_parser); 
    904                         $this->generate_error(MIDCOM_ERRNOTFOUND, "Failed to access snippet: Too many arguments for serve_snippet"); 
    905                     } 
    906                     debug_add("Trying to serve snippet with GUID " . $tmp[MIDCOM_HELPER_URLPARSER_VALUE], MIDCOM_LOG_INFO); 
    907                     $snippet = new midcom_baseclasses_database_snippet($tmp[MIDCOM_HELPER_URLPARSER_VALUE]); 
    908                     if (!$snippet)  
    909                     { 
    910                         debug_add("Failed to access snippet: " . mgd_errstr(), MIDCOM_LOG_ERROR); 
    911                         $this->generate_error(MIDCOM_ERRNOTFOUND, "Failed to access snippet: " . mgd_errstr()); 
    912                     } 
    913                     $this->serve_snippet($snippet); 
    914                     $this->finish(); 
    915                     exit(); 
    916  
    917                 case "cache": 
    918                     if ($tmp[MIDCOM_HELPER_URLPARSER_VALUE] == "invalidate") 
    919                     { 
    920                         $this->cache->content->enable_live_mode(); 
    921                         $this->cache->invalidate_all(); 
    922                         $this->uimessages->add($_MIDCOM->i18n->get_string('MidCOM', 'midcom'), "Cache invalidation successful.", 'info'); 
    923                     } 
    924                     else if ($tmp[MIDCOM_HELPER_URLPARSER_VALUE] == "nocache") 
    925                     { 
     830                switch ($key) 
     831                { 
     832                    case 'substyle': 
     833                        $substyle = $value; 
     834                        debug_add("Substyle '$substyle' selected", MIDCOM_LOG_INFO); 
     835                        break; 
     836     
     837                    case 'serveattachmentguid': 
     838                    case 'serveattachment': 
     839                        if ($this->_parser->argc > 1) 
     840                        { 
     841                            debug_add('Too many arguments remaining for serve_attachment.', MIDCOM_LOG_ERROR); 
     842                        } 
     843                         
     844                        debug_add("Trying to serve Attachment with GUID {$value}", MIDCOM_LOG_INFO); 
     845                         
     846                        $attachment = new midcom_baseclasses_database_attachment($value); 
     847                        if (   !$attachment 
     848                            && !$attachment->guid) 
     849                        { 
     850                            $this->generate_error(MIDCOM_ERRNOTFOUND, 'Failed to access attachment: ' . mgd_errstr()); 
     851                        } 
     852                         
     853                        if (!$attachment->can_do('midgard:autoserve_attachment')) 
     854                        { 
     855                            $this->generate_error(MIDCOM_ERRNOTFOUND, 'Failed to access attachment: Autoserving denied.'); 
     856                        } 
     857                         
     858                        $this->serve_attachment($attachment); 
     859                        $this->finish(); 
     860                        exit(); 
     861                         
     862                    case 'permalink': 
     863                        $guid = $tmp[MIDCOM_HELPER_URLPARSER_VALUE]; 
     864                        $destination = $this->permalinks->resolve_permalink($guid); 
     865                        if ($destination === null) 
     866                        { 
     867                            $this->generate_error(MIDCOM_ERRNOTFOUND, "This Permalink is unknown."); 
     868                            // This will exit; 
     869                        } 
     870     
     871                        // We use "302 Found" here so that search engines and others will keep using the PermaLink instead of the temporary 
     872                        $this->header("Location: {$destination}", 302); 
     873                        $this->finish(); 
     874                        exit(); 
     875     
     876                    case 'cache': 
     877                        if ($value == 'invalidate') 
     878                        { 
     879                            $this->cache->content->enable_live_mode(); 
     880                            $this->cache->invalidate_all(); 
     881                            $this->uimessages->add($_MIDCOM->i18n->get_string('MidCOM', 'midcom'), "Cache invalidation successful.", 'info'); 
     882                            $_MIDCOM->relocate(''); 
     883                        } 
     884                        else if ($value == 'nocache') 
     885                        { 
     886                            $this->cache->content->no_cache(); 
     887                        } 
     888                        break; 
     889 
     890                    case 'logout': 
     891                        // Value is ignored 
    926892                        $this->cache->content->no_cache(); 
    927                     } 
    928                     break; 
    929  
    930                 case "log": 
    931                     if ($this->_parser->argc > 1) { 
    932                         debug_add("Too many arguments remaining for debuglog.", MIDCOM_LOG_ERROR); 
    933                         debug_print_r("Parser object:", $this->_parser); 
    934                         $this->generate_error(MIDCOM_ERRNOTFOUND, "Failed to access debug log: Too many arguments for debuglog"); 
    935                     } 
    936                     $this->_showdebuglog($tmp[MIDCOM_HELPER_URLPARSER_VALUE]); 
    937                     break; 
    938  
    939                 case "permalink": 
    940                     $guid = $tmp[MIDCOM_HELPER_URLPARSER_VALUE]; 
    941                     $destination = $this->permalinks->resolve_permalink($guid); 
    942                     if ($destination === null) 
    943                     { 
    944                         $this->generate_error(MIDCOM_ERRNOTFOUND, "This Permalink is unknown."); 
     893                        $this->auth->logout(); 
    945894                        // This will exit; 
    946                     } 
    947  
    948                     // We use "302 Found" here so that search engines and others will keep using the PermaLink instead of the temporary 
    949                     $this->header("Location: {$destination}", 302); 
    950                     $this->finish(); 
    951                     exit(); 
    952  
    953                 case "exec": 
    954                     $this->_exec_file($tmp[MIDCOM_HELPER_URLPARSER_VALUE]); 
    955                     // This will exit; 
    956  
    957  
    958                 // TODO: Replace login/logout with real-life versions. 
    959                 case "logout": 
    960                     // Value is ignored 
    961                     $this->cache->content->no_cache(); 
    962                     $this->auth->logout(); 
    963                     // This will exit; 
    964  
    965                 case "login": 
    966                     // Value is ignored 
    967                     if ($this->auth->is_valid_user()) 
    968                     { 
    969                         $this->relocate(''); 
     895     
     896                    case 'login': 
     897                        // Value is ignored 
     898                        if ($this->auth->is_valid_user()) 
     899                        { 
     900                            $this->relocate(''); 
     901                            // This will exit; 
     902                        } 
     903                        $this->auth->show_login_page(); 
     904                        // This will exit too; 
     905 
     906                    case 'exec': 
     907                        $this->_exec_file($value); 
    970908                        // This will exit; 
    971                     } 
    972                     $this->auth->show_login_page(); 
    973                     // This will exit too; 
    974  
    975                 default: 
    976                     debug_add("Unknown MidCOM URL Property ignored: " . 
    977                       $tmp[MIDCOM_HELPER_URLPARSER_KEY] . " => " . 
    978                       $tmp[MIDCOM_HELPER_URLPARSER_VALUE], MIDCOM_LOG_WARN); 
    979                     $_MIDCOM->generate_error(MIDCOM_ERRNOTFOUND, "This midcom URL method is unknown."); 
    980                     // This will exit. 
     909 
     910                    case 'log': 
     911                        if ($this->_parser->argc > 1) { 
     912                            debug_add("Too many arguments remaining for debuglog.", MIDCOM_LOG_ERROR); 
     913                            $this->generate_error(MIDCOM_ERRNOTFOUND, "Failed to access debug log: Too many arguments for debuglog"); 
     914                        } 
     915                        $this->_showdebuglog($value); 
     916                        break; 
     917     
     918                    default: 
     919                        debug_add("Unknown MidCOM URL Property ignored: {$key} => {$value}", MIDCOM_LOG_WARN); 
     920                        $_MIDCOM->generate_error(MIDCOM_ERRNOTFOUND, "This MidCOM URL method is unknown."); 
     921                        // This will exit. 
     922                } 
    981923            } 
    982924        } 
     
    984926        $this->_status = MIDCOM_STATUS_CANHANDLE; 
    985927 
    986         do { 
    987             $object = $this->_parser->fetch_object(); 
     928        do  
     929        { 
     930            $object = $this->_parser->get_current_object(); 
    988931 
    989932            if (!is_a($object,'midcom_db_topic')) 
     
    1011954                // Strip all midcom-*-* URL Parameters out of the prefix. 
    1012955 
    1013                 $prefix = $this->_parser->fetch_URL(); 
     956                $prefix = $this->_parser->get_url(); 
    1014957                $prefix = preg_replace ("|midcom-[^-]*-[^/]*/|i","",$prefix); 
    1015958 
     
    1028971            } 
    1029972 
    1030         } while ($this->_parser->fetch_topic() !== false); 
     973        } while ($this->_parser->get_object() !== false); 
    1031974 
    1032975        if (! $success) 
     
    1039982            } 
    1040983 
     984            /* 
    1041985            // Check if there is an Attachment, if yes, serve it and exit 
    1042  
    1043986            if ($this->_parser->fetch_attachment()) 
    1044987            { 
    1045                 $this->serve_attachment($this->_parser->fetch_object()); 
     988                $this->serve_attachment($this->_parser->get_object()); 
    1046989                $this->finish(); 
    1047990                exit(); 
    1048991            } 
     992            */ 
    1049993 
    1050994            $this->generate_error(MIDCOM_ERRNOTFOUND, "This page is not available on this server"); 
     
    11121056        $handler =& $this->componentloader->get_interface_class($path); 
    11131057 
    1114         $this->_set_context_data($this->_parser->fetch_object(), MIDCOM_CONTEXT_CONTENTTOPIC); 
    1115  
    1116         if (!$handler->handle($this->_parser->fetch_object(), $this->_parser->argc, $this->_parser->argv, $this->_currentcontext)) 
     1058        $this->_set_context_data($this->_parser->get_current_object(), MIDCOM_CONTEXT_CONTENTTOPIC); 
     1059 
     1060        if (!$handler->handle($this->_parser->get_current_object(), $this->_parser->argc, $this->_parser->argv, $this->_currentcontext)) 
    11171061        { 
    11181062            debug_add("Component $path failed to handle the request:", MIDCOM_LOG_ERROR); 
     
    19331877     * 
    19341878     * @param int id Explicitly specify the ID for context creation (used during construction), this parameter is usually omitted. 
     1879     * @param midcom_db_topic Root topic of the context 
    19351880     * @return int The ID of the newly created component. 
    19361881     * @access private 
    19371882     */ 
    1938     function _create_context($id = null) 
     1883    private function _create_context($id = null, $topic = null) 
    19391884    { 
    19401885        if (is_null($id)) 
     
    19451890        $this->_context[$id][MIDCOM_CONTEXT_ANCHORPREFIX] = ''; 
    19461891        $this->_context[$id][MIDCOM_CONTEXT_REQUESTTYPE] = MIDCOM_REQUEST_CONTENT; 
    1947         $this->_context[$id][MIDCOM_CONTEXT_ROOTTOPIC] = null
     1892        $this->_context[$id][MIDCOM_CONTEXT_ROOTTOPIC] = $topic
    19481893        $this->_context[$id][MIDCOM_CONTEXT_CONTENTTOPIC] = null; 
    19491894        $this->_context[$id][MIDCOM_CONTEXT_COMPONENT] = null; 
  • trunk/midcom/midcom.core/midcom/config/midcom_config.php

    r11854 r11868  
    435435 
    436436// Service implementation defaults 
     437$GLOBALS['midcom_config_default']['service_midcom_core_service_urlparser'] = 'midcom_core_service_implementation_urlparsertopic'; 
    437438$GLOBALS['midcom_config_default']['service_midcom_core_service_urlgenerator'] = 'midcom_core_service_implementation_urlgeneratori18n'; 
    438439 
  • trunk/midcom/midcom.core/midcom/helper/serviceloader.php

    r11278 r11868  
    5757        // Start by checking what implementation is to be used 
    5858        $implementation_class = $this->get_implementation($service); 
    59          
     59 
    6060        if (   is_null($implementation_class) 
    6161            || empty($implementation_class)) 
     
    111111        } 
    112112         
     113        if (!$this->can_load($service)) 
     114        { 
     115            // Service disabled for this site 
     116            $_MIDCOM->generate_error(MIDCOM_ERRCRIT, "Service implementation for {$service} could not be loaded"); 
     117        } 
     118         
    113119        if (!isset($this->instances['service'])) 
    114120        {