Global.php not being called in Album tutorial application

General discussion forum for the Zend Server

Global.php not being called in Album tutorial application

Postby rgrodgers on Tue Jan 08, 2013 4:06 pm

I am using ZendServer-CE-php-5.3.14-5.6.0-SP2-Windows_x86 and am building the Album tutorial. I am receving errors (unable to create zend\db\adapter\adapter) that showed that global.php was not being called or merged with module.config.php. I have definitely checked my directory structure and ensured all code is per the tutorial. To bypass this problem, I copied both global.php and local.php into module.config.php manually. That worked. However, it is a very poor solution.

What would cause global.php to not be called or merged? I have also tried other names like myconfig.global.php to ensure it matched the criteria. I'll provide pertinent code here.

global.php (or myconfig.global.php) (also, I merged in local.php at this point too) is in config\autoload and is:
Code: Select all
<?php
echo PHP_EOL . "Global.php executed." . PHP_EOL;
return array(
    'db' => array(
        'driver'        => 'Pdo',
        'dsn'           => 'mysql:dbname=zf2tutorial;host=localhost',
        'username'      => 'deleted',
        'password'      => 'deleted',
        'driver_options' => array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
        ),
    ),
    'service_manager' => array(
        'factories' => array(
            'Zend\Db\Adapter\Adapter'
                    => 'Zend\Db\Adapter\AdapterServiceFactory',
        ),
    ),
);
?>



application.config.php is:
Code: Select all
<?php
echo PHP_EOL . "Application.config.php executed." . PHP_EOL;
return array(
    'modules' => array(
        'Album',                  // <-- Add this line
    ),
    'module_listener_options' => array(
        'config_glob_paths'    => array(
            'config/autoload/{,*.}{global,local}.php',
        ),
        'module_paths' => array(
            './module',
            './vendor',
        ),
    ),
);
?>


testconfig.php.dist is:
Code: Select all
<?php

echo PHP_EOL . "TestConfig.php.dist executed." . PHP_EOL;
return array(
    'modules' => array(
        'Album', // <-- Add this line
    ),
    'module_listener_options' => array(
        'config_glob_paths' => array(
            'config/autoload/{,*.}{global,local}.php',
        ),
        'module_paths' => array(
            './module',
            './vendor',
        ),
    ),
);
?>


module.config.php is: (this includes the code I manually copied from global.php and local.php)
Code: Select all
<?php
echo PHP_EOL . "Module.config.php executed." . PHP_EOL;
return array(
    'db' => array(
        'driver'        => 'Pdo',
        'dsn'           => 'mysql:dbname=zf2tutorial;host=localhost',
        'username'      => 'deleted',
        'password'      => 'deleted',
        'driver_options' => array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
        ),
    ),
    'service_manager' => array(
        'factories' => array(
            'Zend\Db\Adapter\Adapter'
                    => 'Zend\Db\Adapter\AdapterServiceFactory',
        ),
    ),
    'controllers' => array(
        'invokables' => array(
            'Album\Controller\Album' => 'Album\Controller\AlbumController',
        ),
    ),

    // The following section is new and should be added to your file
    'router' => array(
        'routes' => array(
            'album' => array(
                'type'    => 'segment',
                'options' => array(
                    'route'    => '/album[/:action][/:id]',
                    'constraints' => array(
                        'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                        'id'     => '[0-9]+',
                    ),
                    'defaults' => array(
                        'controller' => 'Album\Controller\Album',
                        'action'     => 'index',
                    ),
                ),
            ),
        ),
    ),

    'view_manager' => array(
        'template_path_stack' => array(
            'album' => __DIR__ . '/../view',
        ),
    ),
);
?>


module.php is where the error occurs attempting to create the adapter: (line:$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');)
Code: Select all
<?php

namespace Album;

use Album\Model\Album;
use Album\Model\AlbumTable;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Zend\ModuleManager\Feature\ServiceProviderInterface;

class Module implements ServiceProviderInterface {

    public function getAutoloaderConfig() {
        return array(
            'Zend\Loader\ClassMapAutoloader' => array(
                __DIR__ . '/autoload_classmap.php',
            ),
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }

    public function getConfig() {
        return include __DIR__ . '/config/module.config.php';
    }

    // Add this method:
    public function getServiceConfig() {
        return array(
            'factories' => array(
                'Album\Model\AlbumTable' => function($sm) {
                    echo PHP_EOL . "SM AlbumTable executed." . PHP_EOL;
                    $tableGateway = $sm->get('AlbumTableGateway');
                    $table = new AlbumTable($tableGateway);
                    return $table;
                },
                'AlbumTableGateway' => function ($sm) {
                    echo PHP_EOL . "SM AlbumTableGateway executed." . PHP_EOL;
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Album());
                    return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
                },
            ),
        );
    }

}
?>


And AlbumTableTest.php is my testing module:
Code: Select all
<?php

namespace AlbumTest\Model;

use Album\Model\AlbumTable;
use Album\Model\Album;
use Zend\Db\ResultSet\ResultSet;

use AlbumTest\Bootstrap;
use Album\Controller\AlbumController;
use Zend\Http\Request;
use Zend\Http\Response;
use Zend\Mvc\MvcEvent;
use Zend\Mvc\Router\RouteMatch;
use Zend\Mvc\Router\Http\TreeRouteStack as HttpRouter;
use PHPUnit_Framework_TestCase;


class AlbumTableTest extends PHPUnit_Framework_TestCase {
   
    protected $controller;
    protected $request;
    protected $response;
    protected $routeMatch;
    protected $event;

    protected function setUp()
    {
        $serviceManager = Bootstrap::getServiceManager();
        $this->controller = new AlbumController();
        $this->request    = new Request();
        $this->routeMatch = new RouteMatch(array('controller' => 'index'));
        $this->event      = new MvcEvent();
        $config = $serviceManager->get('Config');
        $routerConfig = isset($config['router']) ? $config['router'] : array();
        $router = HttpRouter::factory($routerConfig);
        $this->event->setRouter($router);
        $this->event->setRouteMatch($this->routeMatch);
        $this->controller->setEvent($this->event);
        $this->controller->setServiceLocator($serviceManager);
    }

    public function testFetchAllReturnsAllAlbums() {
        $resultSet = new ResultSet();
        $mockTableGateway = $this->getMock('Zend\Db\TableGateway\TableGateway', array('select'), array(), '', false);
        $mockTableGateway->expects($this->once())
                ->method('select')
                ->with()
                ->will($this->returnValue($resultSet));

        $albumTable = new AlbumTable($mockTableGateway);

        $this->assertSame($resultSet, $albumTable->fetchAll());
    }

    public function testCanRetrieveAnAlbumByItsId() {
        $album = new Album();
        $album->exchangeArray(array('id' => 123,
            'artist' => 'The Military Wives',
            'title' => 'In My Dreams'));

        $resultSet = new ResultSet();
        $resultSet->setArrayObjectPrototype(new Album());
        $resultSet->initialize(array($album));

        $mockTableGateway = $this->getMock('Zend\Db\TableGateway\TableGateway', array('select'), array(), '', false);
        $mockTableGateway->expects($this->once())
                ->method('select')
                ->with(array('id' => 123))
                ->will($this->returnValue($resultSet));

        $albumTable = new AlbumTable($mockTableGateway);

        $this->assertSame($album, $albumTable->getAlbum(123));
    }

    public function testCanDeleteAnAlbumByItsId() {
        $mockTableGateway = $this->getMock('Zend\Db\TableGateway\TableGateway', array('delete'), array(), '', false);
        $mockTableGateway->expects($this->once())
                ->method('delete')
                ->with(array('id' => 123));

        $albumTable = new AlbumTable($mockTableGateway);
        $albumTable->deleteAlbum(123);
    }

    public function testSaveAlbumWillInsertNewAlbumsIfTheyDontAlreadyHaveAnId() {
        $albumData = array('artist' => 'The Military Wives', 'title' => 'In My Dreams');
        $album = new Album();
        $album->exchangeArray($albumData);

        $mockTableGateway = $this->getMock('Zend\Db\TableGateway\TableGateway', array('insert'), array(), '', false);
        $mockTableGateway->expects($this->once())
                ->method('insert')
                ->with($albumData);

        $albumTable = new AlbumTable($mockTableGateway);
        $albumTable->saveAlbum($album);
    }

    public function testSaveAlbumWillUpdateExistingAlbumsIfTheyAlreadyHaveAnId() {
        $albumData = array('id' => 123, 'artist' => 'The Military Wives', 'title' => 'In My Dreams');
        $album = new Album();
        $album->exchangeArray($albumData);

        $resultSet = new ResultSet();
        $resultSet->setArrayObjectPrototype(new Album());
        $resultSet->initialize(array($album));

        $mockTableGateway = $this->getMock('Zend\Db\TableGateway\TableGateway', array('select', 'update'), array(), '', false);
        $mockTableGateway->expects($this->once())
                ->method('select')
                ->with(array('id' => 123))
                ->will($this->returnValue($resultSet));
        $mockTableGateway->expects($this->once())
                ->method('update')
                ->with(array('artist' => 'The Military Wives', 'title' => 'In My Dreams'), array('id' => 123));

        $albumTable = new AlbumTable($mockTableGateway);
        $albumTable->saveAlbum($album);
    }

    public function testExceptionIsThrownWhenGettingNonexistentAlbum() {
        $resultSet = new ResultSet();
        $resultSet->setArrayObjectPrototype(new Album());
        $resultSet->initialize(array());

        $mockTableGateway = $this->getMock('Zend\Db\TableGateway\TableGateway', array('select'), array(), '', false);
        $mockTableGateway->expects($this->once())
                ->method('select')
                ->with(array('id' => 123))
                ->will($this->returnValue($resultSet));

        $albumTable = new AlbumTable($mockTableGateway);

        try {
            $albumTable->getAlbum(123);
        } catch (\Exception $e) {
            $this->assertSame('Could not find row 123', $e->getMessage());
            return;
        }

        $this->fail('Expected exception was not thrown');
    }

    public function testGetAlbumTableReturnsAnInstanceOfAlbumTable() {
//        echo PHP_EOL;
//        echo var_dump($this).PHP_EOL;
        $this->assertInstanceOf('Album\Model\AlbumTable', $this->controller->getAlbumTable());
    }

}

?>


Error output is:
Code: Select all

TestConfig.php.dist executed.


Module.config.php executed.
PHPUnit 3.7.10 by Sebastian Bergmann.

Configuration read from D:\PHP\zf2-tutorial\module\Album\test\phpunit.xml.dist

......E
SM AlbumTable executed.

SM AlbumTableGateway executed.


Time: 1 second, Memory: 8.75Mb

There was 1 error:

1) AlbumTest\Model\AlbumTableTest::testGetAlbumTableReturnsAnInstanceOfAlbumTable
Zend\ServiceManager\Exception\ServiceNotCreatedException: An exception was raised while creating "Album\Model\AlbumTable"; no instance returned

D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:733
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:843
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:487
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:442
D:\PHP\zf2-tutorial\module\Album\Module.php:36
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:726
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:843
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:487
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:442
D:\PHP\zf2-tutorial\module\Album\src\Album\Controller\AlbumController.php:33
D:\PHP\zf2-tutorial\module\Album\test\AlbumTest\Model\AlbumTableTest.php:149

Caused by
Zend\ServiceManager\Exception\ServiceNotCreatedException: An exception was raised while creating "AlbumTableGateway"; no instance returned

D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:733
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:841
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:487
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:442
D:\PHP\zf2-tutorial\module\Album\Module.php:42
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:726
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:843
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:487
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:442
D:\PHP\zf2-tutorial\module\Album\Module.php:36
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:726
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:843
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:487
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:442
D:\PHP\zf2-tutorial\module\Album\src\Album\Controller\AlbumController.php:33
D:\PHP\zf2-tutorial\module\Album\test\AlbumTest\Model\AlbumTableTest.php:149

Caused by
Zend\ServiceManager\Exception\ServiceNotCreatedException: An exception was raised while creating "Zend\Db\Adapter\Adapter"; no instance returned

D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:733
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\Db\Adapter\AdapterServiceFactory.php:32
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:726
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:841
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:487
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:442
D:\PHP\zf2-tutorial\module\Album\Module.php:42
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:726
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:843
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:487
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:442
D:\PHP\zf2-tutorial\module\Album\Module.php:36
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:726
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:843
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:487
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:442
D:\PHP\zf2-tutorial\module\Album\src\Album\Controller\AlbumController.php:33
D:\PHP\zf2-tutorial\module\Album\test\AlbumTest\Model\AlbumTableTest.php:149

Caused by
Undefined index: db

D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\Db\Adapter\AdapterServiceFactory.php:32
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:726
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:841
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:487
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:442
D:\PHP\zf2-tutorial\module\Album\Module.php:42
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:726
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:843
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:487
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:442
D:\PHP\zf2-tutorial\module\Album\Module.php:36
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:726
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:843
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:487
D:\PHP\zf2-tutorial\vendor\zendframework\zendframework\library\Zend\ServiceManager\ServiceManager.php:442
D:\PHP\zf2-tutorial\module\Album\src\Album\Controller\AlbumController.php:33
D:\PHP\zf2-tutorial\module\Album\test\AlbumTest\Model\AlbumTableTest.php:149

FAILURES!
Tests: 7, Assertions: 9, Errors: 1.


phpunit.xml.dist:
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="Bootstrap.php">
   <testsuites>
      <testsuite name="zf2tutorial">
         <directory>./AlbumTest</directory>
      </testsuite>
   </testsuites>
</phpunit>


bootstrap.php:
Code: Select all
<?php
namespace AlbumTest;//Change this namespace for your test

use Zend\Loader\AutoloaderFactory;
use Zend\Mvc\Service\ServiceManagerConfig;
use Zend\ServiceManager\ServiceManager;
use Zend\Stdlib\ArrayUtils;
use RuntimeException;

error_reporting(E_ALL | E_STRICT);
chdir(__DIR__);

class Bootstrap
{
    protected static $serviceManager;
    protected static $config;
    protected static $bootstrap;

    public static function init()
    {
        // Load the user-defined test configuration file, if it exists; otherwise, load
        if (is_readable(__DIR__ . '/TestConfig.php')) {
            $testConfig = include __DIR__ . '/TestConfig.php';
        } else {
            $testConfig = include __DIR__ . '/TestConfig.php.dist';
        }

        $zf2ModulePaths = array();

        if (isset($testConfig['module_listener_options']['module_paths'])) {
            $modulePaths = $testConfig['module_listener_options']['module_paths'];
            foreach ($modulePaths as $modulePath) {
                if (($path = static::findParentPath($modulePath)) ) {
                    $zf2ModulePaths[] = $path;
                }
            }
        }

        $zf2ModulePaths  = implode(PATH_SEPARATOR, $zf2ModulePaths) . PATH_SEPARATOR;
        $zf2ModulePaths .= getenv('ZF2_MODULES_TEST_PATHS') ?: (defined('ZF2_MODULES_TEST_PATHS') ? ZF2_MODULES_TEST_PATHS : '');

        static::initAutoloader();

        // use ModuleManager to load this module and it's dependencies
        $baseConfig = array(
            'module_listener_options' => array(
                'module_paths' => explode(PATH_SEPARATOR, $zf2ModulePaths),
            ),
        );

        $config = ArrayUtils::merge($baseConfig, $testConfig);

        $serviceManager = new ServiceManager(new ServiceManagerConfig());
        $serviceManager->setService('ApplicationConfig', $config);
        $serviceManager->get('ModuleManager')->loadModules();

        static::$serviceManager = $serviceManager;
        static::$config = $config;
    }

    public static function getServiceManager()
    {
        return static::$serviceManager;
    }

    public static function getConfig()
    {
        return static::$config;
    }

    protected static function initAutoloader()
    {
        $vendorPath = static::findParentPath('vendor');

        if (is_readable($vendorPath . '/autoload.php')) {
            $loader = include $vendorPath . '/autoload.php';
        } else {
            $zf2Path = getenv('ZF2_PATH') ?: (defined('ZF2_PATH') ? ZF2_PATH : (is_dir($vendorPath . '/ZF2/library') ? $vendorPath . '/ZF2/library' : false));

            if (!$zf2Path) {
                throw new RuntimeException('Unable to load ZF2. Run `php composer.phar install` or define a ZF2_PATH environment variable.');
            }

            include $zf2Path . '/Zend/Loader/AutoloaderFactory.php';

        }

        AutoloaderFactory::factory(array(
            'Zend\Loader\StandardAutoloader' => array(
                'autoregister_zf' => true,
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/' . __NAMESPACE__,
                ),
            ),
        ));
    }

    protected static function findParentPath($path)
    {
        $dir = __DIR__;
        $previousDir = '.';
        while (!is_dir($dir . '/' . $path)) {
            $dir = dirname($dir);
            if ($previousDir === $dir) return false;
            $previousDir = $dir;
        }
        return $dir . '/' . $path;
    }
}

Bootstrap::init();
?>
rgrodgers
 
Posts: 3
Joined: Tue Jan 08, 2013 3:12 pm

Re: Global.php not being called in Album tutorial applicatio

Postby rgrodgers on Wed Jan 09, 2013 4:50 pm

This problem has been solved. The tutorial states that you should put the global.php and local.php in the Album\config\autoload directory. This is fine when you are running Album\config\application.config.php. However, when you are running ApplicationTableTest, you are under the test directory. So, the files need to be in test\config\autoload, too, given the coding of testconfig.php.dist. However, I would recommend modifying testconfig.php.dist to access the original files in Album\config\autoload and I am working on that now.

Also, both testconfig.php.dist and application.config.php require some higher level node over and above global.php and local.php such as myconfig.global.php and myconfig.local.php.
rgrodgers
 
Posts: 3
Joined: Tue Jan 08, 2013 3:12 pm

Re: Global.php not being called in Album tutorial applicatio

Postby rgrodgers on Wed Jan 09, 2013 5:03 pm

A simple modification to testconfig.php.dist resolved the problem and allowed the system to access the files from Album\config\autoload. I changed one line to traverse up the directory structure one level as follows:

Code: Select all
            '../config/autoload/{,*.}{global,local}.php',
rgrodgers
 
Posts: 3
Joined: Tue Jan 08, 2013 3:12 pm


Return to Zend Server

Who is online

Users browsing this forum: No registered users and 6 guests