繁体   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