2017-01-19 6 views
0

Ich habe eine router, securityplugin (for ACL) und notfoundplugin implementiert.Routing-Probleme mit Subcontroller-Struktur in Phalcon

möchte ich meine Website mit einer Subzentrale Struktur aufgebaut werden: Link

Die Website wird in den folgenden Hauptteilen aufgebaut:

  • Index
  • Admin
    • Tickets
  • Konto

Die Fragen, die ich habe:

Beim Aufruf: Domain/admin/actionofadmin

Returns benutzerdefinierte 404: "Die Seite existiert nicht" anstelle des normalen Aktionsergebnis

Beim Aufruf: domain/admin/actionofadmin. (< - etwas dagegen, den Punkt am Ende)

Returns Index Aktion von Index-Controller statt der normalen Aktion Ergebnis

Warum funktioniert die Router Rückkehr Thesen Ergebnisse? Wie können sie behoben werden?

Zusätzliche Fragen:

  • Wie weiß Phalcon wo eine Ansicht zu finden und es auf den richtigen Controller verbinden? Beispiel: Ein DashboardController befindet sich in einem Ordner "admin" im Ordner "controllers".

  • Woher weiß Phalcon, dass in der SecurityPlugin-ACL nach dem richtigen Controller gesucht werden muss, obwohl kein Namespace vorhanden ist? Beispiel: Wenn ich zulassen möchte, dass Controller-Tickets mit Namespace-App \ controllers \ admin nur von Administratoren angezeigt werden.

Zusätzliche Informationen:

  • Phalcon 3.0.3
  • PHP 5,6

Lassen Sie mich wissen, wenn Sie weitere Informationen/Dateien benötigen, oder wenn ich poste sollte es woanders zum leichteren Lesen.

Dateien:

/app/controllers/Admincontroller.php

<?php 

namespace Ontrack\Controllers; 

class AdminController extends ControllerBase 
{ 

    public function indexAction(){ 

    } 

    public function testAction(){ 
     echo "test"; 
    } 

} 

/app/config/services.phpAuszug

//This makes sure the routes are correctly handled for authorized/unauthorized 
/** 
* MVC dispatcher 
*/ 
$di->set("dispatcher", function() use ($di) { 
    // Create an events manager 
    $eventsManager = $di->getShared('eventsManager'); 

    /** 
    *Check if the user is allowed to access certain action using the SecurityPlugin 
    *Listen for events produced in the dispatcher using the Security plugin 
    */ 
    $eventsManager->attach("dispatch:beforeDispatch", new SecurityPlugin()); 

    // Handle exceptions and not-found exceptions using NotFoundPlugin 
    $eventsManager->attach("dispatch:beforeException", new NotFoundPlugin()); 

    $dispatcher = new Dispatcher(); 
    $dispatcher->setDefaultNamespace('Ontrack\Controllers'); 

    // Assign the events manager to the dispatcher 
    $dispatcher->setEventsManager($eventsManager); 

    return $dispatcher; 
    } 
); 

/app/config/loader.php

<?php 

$loader = new \Phalcon\Loader(); 

/** 
* We're a registering a set of directories taken from the configuration file 
*/ 
$loader->registerDirs(
    [ 
     $config->application->controllersDir, 
     $config->application->modelsDir, 
     $config->application->pluginsDir 
    ] 
)->register(); 

$loader->registerNamespaces(
    [ 
     'Ontrack\Controllers' => APP_PATH . '/controllers/', 
     'Ontrack\Controllers\Admin' => APP_PATH . '/controllers/admin', 
     'Ontrack\Models' => APP_PATH . '/models/' 
    ] 
)->register(); 

/app/config/routes.php

<?php 
$router = new Phalcon\Mvc\Router(false); 
$router->setDefaults(
    [ 
     "controller" => "index", 
     "action"  => "index", 
    ] 
); 
$router->add('/:controller/:action/:params', [ 
    'namespace' => 'Ontrack\Controllers', 
    'controller' => 1, 
    'action'  => 2, 
    'params'  => 3, 
]); 
$router->add('/:controller/:action', [ 
    'namespace' => 'Ontrack\Controllers', 
    'controller' => 1, 
    'action'  => 2, 
]); 
$router->add('/:controller', [ 
    'namespace' => 'Ontrack\Controllers', 
    'controller' => 1, 
]); 
$router->add('/admin/:controller/:action/:params', [ 
    'namespace' => 'Ontrack\Controllers\Admin', 
    'controller' => 1, 
    'action'  => 2, 
    'params'  => 3, 
]); 
$router->add('/admin/:controller/:action', [ 
    'namespace' => 'Ontrack\Controllers\Admin', 
    'controller' => 1, 
    'action'  => 2, 
]); 
$router->add('/admin/:controller', [ 
    'namespace' => 'Ontrack\Controllers\Admin', 
    'controller' => 1, 
]); 
$router->removeExtraSlashes(true); 
return $router; 

/app/plugins/SecurityPlugin.php

<?php 

use Phalcon\Acl; 
use Phalcon\Acl\Role; 
use Phalcon\Acl\Adapter\Memory as AclList; 
use Phalcon\Acl\Resource; 
use Phalcon\Events\Event; 
use Phalcon\Mvc\User\Plugin; 
use Phalcon\Mvc\Dispatcher; 

class SecurityPlugin extends Plugin 
{ 

    /** 
    * Returns an existing or new access control list 
    * 
    * @returns AclList 
    */ 
    public function getAcl() 
    { 
     if (!isset($this->persistent->acl)) { 
      $acl = new AclList(); 
      $acl->setDefaultAction(Acl::DENY); 

      // Register roles 
      $roles = [ 
     'admins' => new Role(
      'admins', 
      'Website administrators' 
     ), 
       'users' => new Role(
        'users', 
        'Member privileges, granted after sign in.' 
       ), 
       'guests' => new Role(
        'guests', 
        'Anyone browsing the site who is not signed in is considered to be a "Guest".' 
       ) 
      ]; 
      foreach ($roles as $role) { 
       $acl->addRole($role); 
      } 

      //Private area resources 
      $privateResources = array(
       'account' => array('*') 
      ); 

     $privateResourcesAdmin = array(
       'admin'  => array('*'), 
       'tickets'  => array('*') 
      ); 

     //Public area resources 
      $publicResources = array(
       'index'  => array('*'), 
       'register' => array('*'), 
       'errors'  => array('show401', 'show404', 'show500'), 
       'register' => array('*'), 
       'login'  => array('*'), 
       'logout'   => array('*') 
      ); 

      foreach ($privateResources as $resource => $actions) { 
       $acl->addResource(new Resource($resource), $actions); 
      } 

     foreach ($privateResourcesAdmin as $resource => $actions) { 
     $acl->addResource(new Resource($resource), $actions); 
     } 

      foreach ($publicResources as $resource => $actions) { 
       $acl->addResource(new Resource($resource), $actions); 
      } 

      //Grant access to public areas to users, admins and guests 
      foreach ($roles as $role) { 
       foreach ($publicResources as $resource => $actions) { 
        foreach ($actions as $action){ 
         $acl->allow($role->getName(), $resource, $action); 
        } 
       } 
      } 

      //Grant access to private area to role Users 
      foreach ($privateResources as $resource => $actions) { 
       foreach ($actions as $action){ 
        $acl->allow('users', $resource, $action); 
       } 
      } 

     foreach ($privateResourcesAdmin as $resource => $actions) { 
       foreach ($actions as $action){ 
        $acl->allow('admins', $resource, $action); 
       } 
      } 

      //The acl is stored in session, APC would be useful here too 
      $this->persistent->acl = $acl; 
     } 
     return $this->persistent->acl; 
    } 

    /** 
    * This action is executed before execute any action in the application 
    * 
    * @param Event $event 
    * @param Dispatcher $dispatcher 
    * @return bool 
    */ 
    public function beforeDispatch(Event $event, Dispatcher $dispatcher){ 
     $auth = $this->session->has('auth'); 

     if (!$auth){ 
      $role = 'guests'; 
     } else { 
     $authSession = $this->session->get("auth"); 
     if($authSession['account_type'] == 99){ 
     $role = 'admins'; 
     } else { 
     $role = 'users'; 
     } 
     } 

     $controller = $dispatcher->getControllerName(); 
     $action = $dispatcher->getActionName(); 
     $acl = $this->getAcl(); 

     if (!$acl->isResource($controller)) { 
      $dispatcher->forward([ 
       'controller' => 'errors', 
       'action'  => 'show404' 
      ]); 
      return false; 
     } 

     $allowed = $acl->isAllowed($role, $controller, $action); 

     if (!$allowed) { 
      if($controller === 'admin'){ 
       $dispatcher->forward(array(
        'controller' => 'errors', 
        'action'  => 'show404' 
       )); 
      } else { 
       $dispatcher->forward(array(
        'controller' => 'errors', 
        'action'  => 'show401' 
       )); 
      } 
      return false; 
     } 
    } 
} 

/app/plugins/NotFoundPlugin.php

<?php 

use Phalcon\Events\Event; 
use Phalcon\Mvc\User\Plugin; 
use Phalcon\Dispatcher; 
use Phalcon\Mvc\Dispatcher\Exception as DispatcherException; 
use Phalcon\Mvc\Dispatcher as MvcDispatcher; 
/** 
* NotFoundPlugin 
* 
* Handles not-found controller/actions 
*/ 
class NotFoundPlugin extends Plugin 
{ 
    /** 
    * This action is executed before execute any action in the application 
    * 
    * @param Event $event 
    * @param MvcDispatcher $dispatcher 
    * @param Exception $exception 
    * @return boolean 
    */ 
    public function beforeException(Event $event, MvcDispatcher $dispatcher, Exception $exception) 
    { 
     error_log($exception->getMessage() . PHP_EOL . $exception->getTraceAsString()); 
     if ($exception instanceof DispatcherException) { 
      switch ($exception->getCode()) { 
       case Dispatcher::EXCEPTION_HANDLER_NOT_FOUND: 
       case Dispatcher::EXCEPTION_ACTION_NOT_FOUND: 
        $dispatcher->forward(array(
         'controller' => 'errors', 
         'action' => 'show404' 
        )); 
        return false; 
      } 
     } 
     $dispatcher->forward(array(
      'controller' => 'errors', 
      'action'  => 'show500' 
     )); 
     return false; 
    } 
} 

Antwort

1

Beim Aufruf: domain/admin/actionofadmin (als i Domain verstehen ist zum Beispiel www.google.pl) phalcon erwartet ActionofadminController nach Ihren Routen. Sind Sie sicher, dass es einen solchen Controller gibt? Ich bin mir nicht sicher, warum es mit einem Punkt einen Index-Controller und eine Index-Aktion trifft.

How does Phalcon know where to find a view and link it to the correct controller? Example: A dashboardController resides in a folder "admin" inside the folder "controllers".

Es wird diese Informationen von Dispatcher. MVC-Anwendung, wenn Sie nicht sehen, Ihr Selbst ist implizit automatisch Rendering. Überprüfen Sie diese Quelle: https://github.com/phalcon/cphalcon/blob/master/phalcon/mvc/application.zep#L348 Und andere Ansichtsklassen.

Über Acl Plugin - es sucht überhaupt nicht nach Namespace. Wenn Sie also zwei Controller mit demselben Namen, aber einem anderen Namespace haben, wird dies offensichtlich ein Problem verursachen. Sie müssen nur das Sicherheits-Plugin nach Ihren Bedürfnissen ändern.

+0

Vielen Dank für Ihre Antwort. Es gelang mir, mein Problem zu lösen, indem ich Namespaces überprüfte, wann ich an Controller und Aktionen in einer bestimmten URL innerhalb der SecurityPlugin.php-Datei weiterleiten sollte. – Dragon54