簡體   English   中英

Phalcon中子控制器結構的路由問題

[英]Routing issues with subcontroller structure in Phalcon

我已經實現了一個routersecurityplugin (for ACL)notfoundplugin

我希望使用子控制器結構來設置我的網站: 鏈接

該網站分為以下主要部分:

  • 指數
  • 管理員
    • 門票
  • 帳戶

我遇到的問題:

致電時:domain / admin / actionofadmin

返回自定義404:“頁面不存在”,而不是常規操作結果

調用時:domain / admin / actionofadmin。 (<-注意結尾處的點)

返回索引控制器的索引操作,而不是正常操作結果

路由器為什么返回這些結果? 如何解決?

額外問題:

  • Phalcon如何知道在哪里可以找到視圖並將其鏈接到正確的控制器? 示例:dashboardController駐留在文件夾“ controllers”內的文件夾“ admin”中。

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

額外的信息:

  • 菲爾康3.0.3
  • PHP 5.6

讓我知道您是否需要更多信息/文件,或者是否應該將其張貼在其他地方以便於閱讀。

檔案:

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

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

致電時: domain/admin/actionofadmin (據我所知,域是例如www.google.pl ),Phalcon希望根據您的路線選擇ActionofadminController 您確定有這樣的控制器嗎? 不確定為什么使用dot會打中索引控制器和索引動作。

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應用程序如果不渲染視圖,您的自身就是隱式的自動渲染。 檢查此源: https : //github.com/phalcon/cphalcon/blob/master/phalcon/mvc/application.zep#L348和其他視圖類。

關於Acl插件-它根本不檢查名稱空間。 因此,如果您有兩個名稱相同但名稱空間不同的控制器,則顯然會引起問題。 您只需要更改安全性插件即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM