2017-01-19 43 views
0

我實現了router,securityplugin (for ACL)notfoundpluginPhalcon中子控制器結構的路由問題

我想我的網站設置了一個子控制器結構:Link

該網站是建立在以下幾個主要部分:

  • 指數
  • 聯繫
    • 門票
  • 帳戶

的問題,我有:

當調用:域/管理/ actionofadmin

返回自定義404: 「頁面不存在」,而不是正常作用的結果

調用時:domain/admin/actionofadmin。 (< - 介意結束點)指數控制器

收益指數的行動,而不是正常的動作結果

爲什麼路由器返回論文的結果嗎?他們如何修復?

額外的問題:

  • 如何爾康知道在哪裏可以找到一個視圖,並將其鏈接到正確的控制器?示例:dashboardController駐留在文件夾「controllers」內的「admin」文件夾中。

  • Phalcon如何知道在SecurityPlugin ACL中,它需要搜索正確的控制器,但它沒有獲得命名空間?示例:當我想允許控制器命名空間app \ controllers \ admin的票證僅由管理員用戶查看時。

的額外信息:

  • 爾康3.0.3
  • PHP 5.6

讓我知道如果你需要更多的信息/文件,或者我應該張貼它在其他地方易於閱讀。

文件:

/應用/控制器/ AdminController。PHP

<?php 

namespace Ontrack\Controllers; 

class AdminController extends ControllerBase 
{ 

    public function indexAction(){ 

    } 

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

} 

/app/config/services.php摘錄

//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(); 

/應用/ 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; 
    } 
} 

回答

1

致電時:domain/admin/actionofadmin(如我明白域例如www.google.pl)phalcon預計ActionofadminController根據您的路線。你確定有這樣的控制器嗎?不知道爲什麼使用點它會觸發索引控制器和索引操作。

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".

這是越來越從調度員這個信息。 Mvc應用程序如果你不渲染視圖你的self是隱式自動渲染。檢查來源:https://github.com/phalcon/cphalcon/blob/master/phalcon/mvc/application.zep#L348和其他視圖類。

關於Acl插件 - 它根本不檢查名稱空間。所以如果你有兩個同名的控制器,但是其他的命名空間,這會造成明顯的問題。您只需要根據需要更改安全插件。

+0

謝謝你的回答。我設法通過檢查名稱空間何時轉發給控制器以及SecurityPlugin.php文件中給定URL中的動作來解決我的問題。 – Dragon54