[commits] [Wiki] changed: Doc/Dev/Horde_Controller

Wiki Guest wikiguest at horde.org
Thu May 9 21:24:03 UTC 2019


guest [24.134.26.253]  Thu, 09 May 2019 21:24:03 +0000

Modified page: https://wiki.horde.org/Doc/Dev/Horde_Controller
New Revision:  5
Change log:  Add example on rendering a full page through controllers

@@ -1,14 +1,15 @@
  [[toc]]

  + Horde_Controller

-Documentation on using Horde_Controller
+Documentation on using Horde_Controller Framework

  ++ General Info

  Horde uses a lot of behind-the-scenes magic to glue together  
controller based request processing. In normal cases, the application  
developer only needs to create a routes configuration file entry and a  
controller class, horde will handle the rest.
  To add custom pre and post filters to a controller, just add the  
corresponding $app_$controller_SettingsExporter class to the  
app/settings dir.
+
  On this page, developers of specialised endpoints (RPC, REST, etc)  
can read up on how the pieces work together.

  ++ General flow of processing

@@ -29,32 +30,32 @@
  The first path component after the horde base app's webroot will be  
interpreted as the app name.
  The remaining parts of the request uri are interpreted relative to  
the identified app's web root.
  The requestMapper in turn will get a list of routes to match from  
app fileroot/config/routes.php
  If no defined route matches, a default  
Horde_Core_Controller_NotFound is returned
-
+
  Otherwise, a controller class name is found and the identified app's  
context is loaded ($registry->pushApp())
  The controller class found is added to the RequestConfiguration.
  The SettingsFinder looks for an $app_$controller_SettingsExporter  
class, otherwise it adds the Horde_Controller_SettingsExporter_Default  
to the config - which exports no filters or bindings to the runner
-
-
+
+
  Let the runner create a $response = $runner->execute($injector,  
$request, $config);


  Finally, get a responseWriter (_Web is the default) and render the  
response object to the output

  ++ How to use Horde_Controllers in Horde Core Apps

-Horde Controllers are independent from the Horde Ajax Framework.  
Controllers need Horde_Routes and need rewrite rules.
-
+Horde Controllers are independent from the Horde Ajax Framework.  
Controllers need Horde_Routes and need rewrite rules.
+
  Ajax application controllers do not live in {{lib/}} but in  
{{$app/app/controllers/}}

  Example:

  Class {{Nag_CompleteTask_Controller}} in  
{{nag/app/controllers/!CompleteTask.php}}
  <code type="php">
  <?php
  class Nag_CompleteTask_Controller extends Horde_Controller_Base
-{
+{
      public function processRequest(Horde_Controller_Request  
$request, Horde_Controller_Response $response)
      {
          /* Toggle the task's completion status if we're provided with a
           * valid task ID. */
@@ -63,41 +64,118 @@
              $nag_task = new Nag_CompleteTask();
              $result = $nag_task->result($requestVars['task'],  
$requestVars['tasklist']);
          } else {
              $result = array('error' => 'missing parameters');
-        }
+        }

          $requestVars = $request->getGetVars();
          if (!empty($requestVars['format']) &&
              $requestVars['format'] == 'json') {
              $response->setContentType('application/json');
              $response->setBody(json_encode($result));
          } elseif ($requestVars['url']) {
              $response->setRedirectUrl($requestVars['url']);
-        }
-    }
-}
-?>
-</code>
-
-
+        }
+    }
+}
+?>
+</code>
+
+
  A Horde Controller based app needs a {{config/routes.php}} file.
-
+
  For example
  <code type="php">
  <?php
  /**
   * Setup default routes
   */
-$mapper->connect('/t/complete',
+$mapper->connect('/t/complete',
+    array(
+        'controller' => 'CompleteTask',
+    ));
+?>
+</code>
+
+defines a route for a call like www.example.com/nag/t/complete to be  
handled by the !CompleteTask controller seen above.
+
+The endpoint script is horde/rampage.php  - At the moment, only  
authenticated calls are supported
+The controller is passed the request (in this case, a json request)  
and handles it (with a json answer in this case)
+
+++ Usage for UI
+
++++ Example: Output buffering for Horde_PageOutput
+
+Render a complete page with Horde_PageOutput by capturing any html in  
an output buffer and handing it to the response object.
+
+The Route in config/routes.php
+<code>
+<?php
+/**
+ * Setup default routes
+ */
+$user = $registry->getAuth();
+$dt = new Horde_Date(mktime());
+
+$mapper->connect('EnterTimes', '/enter/:year/:month/:user/',
      array(
-        'controller' => 'CompleteTask',
+        'controller' => 'EnterTimes',
+        'action' => 'view',
+        'user' => $user,
+        'year' => $dt->year,
+        'month' => sprintf('%02d', $dt->month),
+        'conditions' => array('method' => array('GET')),
+        'requirements' => array('month' => '\d{1,2}')
      ));
-?>
+
+</code>
+
+NOTE: The method conditions are currently ignored by production Horde.
+You need a patched Horde_Core for this to work
+
+The Controller in $app/app/controller/EnterTimes.php
+<code>
+<?php
+class Timetool_EnterTimes_Controller extends Horde_Controller_Base
+{
+    /**
+     * Get variables from routes matching
+     */
+    protected $_matchDict;
+
+    public function processRequest(Horde_Controller_Request $request,  
Horde_Controller_Response $response)
+    {
+        /* obtain a Routes mapper to fit the Horde_Routes defined in  
config/routes.php */
+        $this->_mapper =  
$this->getInjector()->getInstance('Horde_Routes_Mapper');
+        /* get the dictionary */
+        $this->_matchDict = new  
Horde_Support_Array($this->_mapper->match($request->getPath()));
+
+        switch ($this->_matchDict->action) {
+        case "view":
+            return $this->view($request, $response);
+            break;
+        }
+    }
+
+    public function view($request, $response)
+    {
+        $vars = Horde_Variables::getDefaultVariables();
+        $injector = $this->getInjector();
+        // Start a buffer to prevent PageOutput from
+        // engaging the output buffer, circumventing the response
+        // object and any potential post filters
+        ob_start();
+        $page_output = $injector->getInstance("Horde_PageOutput");
+        $page_output->header(array("title" => _("Enter Timesheet")));
+        // Bug: The sidebar is not correctly rendered if the main  
screen does not contain anything
+        echo "something";
+        $page_output->footer();
+        // Feed any output to the response body and close the buffer
+        $response->setBody(ob_get_contents());
+        ob_end_clean();
+    }
+}
+
  </code>

-defines a route for a call like www.example.com/nag/t/complete to be  
handled by the !CompleteTask controller seen above.
-
-The endpoint script is horde/rampage.php  - rampage.php currently  
seems to handle only authenticated calls.
-
-The controller is passed the request (in this case, a json request)  
and handles it (with a json answer in this case)
++++ Example: Generating URLs from Routes inside the controller




More information about the commits mailing list