views:

71

answers:

1

I have a site I am trying to use two modules. default & api. The website runs off of default and works fine (http://localhost). But I am trying to use the api module like this (http://localhost/api/other-params). But it still loads the website. Two routes I have are setup like this:

        'apiDivisionStandings' => array(
            'type'  => 'Zend_Controller_Router_Route',
            'route' => 'api/division/standings/:userID',
            'defaults' => array(
               'module'     => 'api',
               'controller' => 'division',
               'action'     => 'standings'
            )
         ),

     'defaultSchoolSize' => array(
            'type'  => 'Zend_Controller_Router_Route',
            'route' => ':state/:size/schools',
            'defaults' => array(
               'module'     => 'default',
               'controller' => 'school',
               'action'     => 'size'
            )
         ),

And in my bootstrap file:

    Zend_Date::setOptions(array('format_type' => 'php'));
    Zend_Layout::startMvc(array('layout' => 'website/default' , 'layoutPath' => APPLICATION_PATH . '/default/layouts' , 'contentKey' => 'content'));

    $routes = new Zend_Config(Routes::getRoutes());
    $router = new Zend_Controller_Router_Rewrite();
    $router->addConfig($routes, 'routes');

    $this->bootstrap('frontController');
    $frontController = Zend_Controller_Front::getInstance();
    $frontController->setRouter($router);

    $cOpts = array('lifetime' => 99000 ,'automatic_serialization' => true);
    Zend_Registry::set('cache', Zend_Cache::factory('Core', 'File', $cOpts, array('cache_dir' => '../cache/')));

And in my index.php before I bootstrap()->run();

require_once '../library/Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->setFallbackAutoloader(true);
$loader->suppressNotFoundWarnings(false);
$loader->registerNamespace('Api_');

My application.ini:

[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
resources.frontController.controllerDirectory = APPLICATION_PATH   "/modules/default/controllers"
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"

And finally, part of my DivisionController in the application/modules/api/controllers folder (the website stuff is in application/modules/default; works fine):

class Api_DivisionController extends Zend_Rest_Controller
{

/**
 *  - Class setup
 *      - Tells framework not to render to view
 *      - sets default data type to JSON
 */ 
public function init()
{
    $this->_helper->viewRenderer->setNoRender(true);

    $this->_helper->contextSwitch()
          ->addActionContext('standings', array('xml','json'))
          ->addActionContext('news', array('xml', 'json'))
          ->setAutoJsonSerialization(true)
          ->initContext();   
}

But instead of getting the JSON response on the page I am getting the web page to load with an error message that it can't find the view. What am I missing?

+1  A: 

ZF matches routes in reverse order, so my guess is it's matching http://localhost/api/params to your default route as it checks this first, and the router has no way of knowing that 'api' is not a valid :state. So try switching around the order of your routes so that the API one is the last one (and thus is checked first).

If this doesn't work, try temporarily removing your default route and seeing if the API requests then work. If they don't, then this would indicate a problem with your API route itself.

Tim Fountain
This worked well. Thanks. The code I had above in my init() in the Api_DivisionController did not stop the website from rendering, It tried to continue loading the site. I had to put an exit after my echo json_encode($array); But curious as to why the init() function, knowing it was called when I did a breakpoint in that method, did not stop the ZF from trying to render a page instead of just returning the json response. Thanks!
Hallik
The contextSwitch helper will specifically enable a template with a json.phtml extension, so it's probably overriding the setNoRender call. Sounds like what you're doing is working fine but if you did want to alter this you could move the setNoRender call to after the contextSwitch stuff, and then in your action do something like this: $this->getResponse()->setBody($yourJsonStuff); instead of: echo $yourJsonStuff; exit;
Tim Fountain
Thanks you for your help!
Hallik