/** * Dispatch an URL to the correct handlers. This method does the actual * magic, such as url parsing, matching and command invocation. You can * optionally provide a custom url and tell the dispatcher that some parts * of the url should be skipped when handling this request. * * \param $url * The url to dispatch (optional, defaults to null). Omit this value (or * provide null) to use the current request url. * * \param $skip_path_components * The number of path components to skip when handling this request * (optional, defaults to null). This is useful if you want to skip some * prefix present in all urls, such as ~username. If you don't specify * this parameter the value of <code>$_SERVER['PHP_SELF']</code> will be * used to figure out how many components to skip. */ function dispatch($url = null, $skip_path_components = null) { if (is_null($skip_path_components)) { /* Figure out the current script location. This is most likely * the script living in the document root calling this method. Use * the directory path component of this file to figure out how many * path components should be skipped. */ $dir_url = dirname($_SERVER['PHP_SELF']); if ($dir_url == DIRECTORY_SEPARATOR) { $skip_path_components = 0; } else { $skip_path_components = count(explode('/', str_strip_prefix($dir_url, '/'))); } } /* Initialization */ $get_params = ''; /* Use the current url if no explicit url was given */ if (is_null($url)) { $url = Request::relative_url(); } /* We need to strip off the GET parameters */ $question_mark_pos = strpos($url, '?'); if ($question_mark_pos !== false) { $get_params = substr($url, $question_mark_pos); $url = substr($url, 0, $question_mark_pos); } /* Sanity checks */ assert('is_int($skip_path_components) && $skip_path_components >= 0'); assert('is_string($url)'); /* Force trailing slash for GET requests? */ if (Request::is_get() && $this->_getdefault('force-trailing-slash', true) && $url != '/' && !str_has_suffix($url, '/') && preg_match('/^.*\\/[^.\\/]+$/', $url)) { redirect($url . '/' . $get_params, HTTP_STATUS_MOVED_PERMANENTLY); } /* Store the url so that it can be used later */ $this->_set('url', $url); /* Split the url into smaller pieces */ $url = str_strip_prefix($url, '/'); $url = str_strip_suffix($url, '/'); $components = split('/', $url); /* Skip some components if requested, and store the cut-off part in the * 'base-url' property. */ if (count($components) < $skip_path_components) { $this->_handle_result(HTTP_STATUS_INTERNAL_SERVER_ERROR); } $base_url = sprintf('/%s/', join('/', array_slice($components, 0, $skip_path_components))); $this->_set('base-url', $base_url); $components = array_slice($components, $skip_path_components); /* Special case for top level urls */ if (count($components) == 1 && strlen($components[0]) == 0) { $components = array(); } /* Try all URL maps and see if they match the input url */ $found_map = false; $command_name = null; $parameters = array(); foreach ($this->urlmaps as $urlmap) { list($command_name, $patterns) = $urlmap; /* Check for valid parameters */ $match = $this->_match_inputs_with_patterns($components, $patterns); /* This urlmap didn't match, try next one */ if ($match === false) { continue; /* This urlmap matched! */ } else { $parameters = $match; $found_map = true; break; } } /* No explicit map found, try an implicit map */ if (!$found_map && $this->_getdefault('use-implicit-commands', true)) { $command_name = join('_', $components); $command_name = str_replace('-', '_', $command_name); /* The method must exist */ $command = 'command_' . $command_name; $found_map = method_exists($this, $command); } /* As a last resort try the default handler, if one was set. There's no * need to check the availability of the method; set_default_command() * already did that. */ if (!$found_map && $this->_isset('default-command')) { $command_name = $this->_get('default-command'); $found_map = true; } /* Sanity check: is the method available? */ $command = 'command_' . $command_name; if (!method_exists($this, $command)) { /* FIXME: it's not clear if this is desirable */ /* We found a handler name but the method doesn't exist... */ /* Trying the default handler, but remember which command * we wanted to access. */ if (!$this->_isset('default_command')) { /* We give up. */ $found_map = false; } else { $command = 'command_' . $this->_get('default-command'); } } /* If we still don't have a command, we give up. Too bad... not found */ if (!$found_map) { $this->_handle_result(HTTP_STATUS_NOT_FOUND); return false; } /* Store the command name for use by _handle_result() and possibly * pre_command(). */ $this->_set('command', $command_name); /* If this piece of code is reached, a valid command has been found. Run * the pre-command hook, call the appropriate method and handle the * result. The pre_command() method may return HTTP_STATUS_NOT_FOUND or * HTTP_STATUS_FORBIDDEN as well, so we need to handle the status * carefully. */ $status = $this->pre_command($parameters); /* The pre_command() method is not required to have a return value. If * it doesn't return anything, $status will be null at this point. If * that's the case we assume everything is alright. */ if (is_null($status)) { $status = HTTP_STATUS_OK; } if ($status == HTTP_STATUS_OK) { /* The pre_command() method succeeded. Run the actual command and * keep track of the status. */ $status = $this->{$command}($parameters); } /* Regardless of whether the actual command has been executed, the * result handler is invoked. Note: The post_command() is only invoked * if both the pre_command() and the actual command method return * HTTP_STATUS_OK (there's no danger of calling post_command() if no * real command has been executed). */ $this->_handle_result($status); }
/** * Initialize a new AnewtForm instance. * * Do not forget to call this method when you override the constructor in * a subclass, i.e. call <code>parent::__construct()</code>. */ function __construct() { /* Default values */ $id = sprintf('form-%s', str_strip_suffix(strtolower(get_class($this)), 'form')); $this->_seed(array('id' => $id, 'method' => ANEWT_FORM_METHOD_POST, 'action' => Request::relative_url(), 'description' => null, 'error' => null)); }
$ctx1->draw_filled_rectangle_size(3, 3, 4, 3); $ctx1->set('color', $img->color_from_string('#969')); $ctx1->draw_rectangle(3, 3, 6, 7); $ctx1->draw_filled_rectangle_size(15, 2, 2, 2); $ctx1->draw_filled_rectangle_size(15, 2, -1, -1); $col = $img->color_from_string('#36c'); $ctx1->set('color', $col); $ctx1->draw_filled_rectangle(20, 2, 18, 3); assert('$ctx1->color_at(19, 2) == $col'); /* Blow up so we can count the pixels in the result */ $img->resize_relative(10, false); $img->flush_png(); $img->destroy(); } } $test = AnewtGPC::get_string('test'); if (is_null($test)) { /* Show test chooser */ anewt_include('page'); $p = new AnewtPage(); $p->set('title', 'Choose a test'); $p->append(ax_h1('Choose a test')); foreach (get_class_methods('AnewtImageTestCases') as $name) { $url = URL::unparse(Request::relative_url(), array('test' => $name)); $p->append(ax_p(ax_a_href(sprintf('Test: %s', $name), $url))); } $p->flush(); } else { /* Invoke test function */ AnewtImageTestCases::$test(); }
/** * Dispatch an URL to the correct handlers. See the documentation on * URLDispatcher::dispatch() for more information on the parameters. * * \param $url * The url to dispatch (optional, defaults to null). * * \see URLDispatcher::dispatch */ function dispatch($url = null) { if (is_null($url)) { $url = Request::relative_url(); } assert('is_string($url)'); /* Get the default settings */ $module_name = $this->_getdefault('default-module', null); $class_name = $this->_get('default-class'); $skip_path_components = 0; /* Iterate over the mappings and override the default if the mapping matches */ $test_url = str_strip_prefix($url, '/'); foreach ($this->prefix_to_dispatcher_mapping as $prefix => $mapping) { /* Try to match the prefix. Add a trailing slash, otherwise the url * /newsxyz would also match the /news mapping, which is not * intended behaviour. */ $test_prefix = $prefix . '/'; if (str_has_prefix($test_url, $test_prefix)) { /* The prefix matches the url */ list($module_name, $class_name) = $mapping; $skip_path_components = count(explode('/', $prefix)); break; } } /* Load module (if supplied) */ if (!is_null($module_name)) { $this->load_module($module_name); } /* Create and invoke dispatcher */ $dispatcher =& new $class_name(); $dispatcher->dispatch($url, $skip_path_components); }
/** * Returns the canonical URL for the current request. This includes the * http part, the hostname and (optionally) port number. * * \param $include_query_string * Whether the query string (the part after the question mark in HTTP GET * request should be included (optional, defaults to true) * * \return * The canonical URL for the current request. * * \see Request::relative_url * \see Request::canonical_base_url */ static function canonical_url($include_query_string = true) { $canonical_base_url = Request::canonical_base_url(); $relative_url = Request::relative_url($include_query_string); if ($relative_url[0] != '/') { $relative_url = '/' . $relative_url; } return $canonical_base_url . $relative_url; }