Phalcon 中子控制器结构的路由问题

Routing issues with subcontroller structure in Phalcon

我已经实现了 routersecurityplugin (for ACL)notfoundplugin

我希望我的站点设置有子控制器结构:Link

网站主要分为以下几个部分:

我遇到的问题:

When calling: domain/admin/actionofadmin

Returns custom 404: "Page doesn't exist" instead of the normal action result

When calling: domain/admin/actionofadmin. (<-- mind the dot at the end)

Returns index action of index controller instead of the normal action result

为什么路由器会出现return这些结果?如何修复它们?

补充问题:

补充信息:

如果您需要更多信息/文件,或者我是否应该post将它放在其他地方以便于阅读,请告诉我。

文件:

/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。你确定有这样的控制器吗?不确定为什么使用点会影响索引控制器和索引操作。

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 插件 - 它根本不检查名称空间。因此,如果您有两个名称相同但名称空间不同的控制器,这显然会导致问题。您只需要根据需要更改安全插件。