getServiceLocator returning Null under PHPUnittests - php

I'm trying to test a simple controller that authenticates a user using the LdapAdapter and using the 'ldap' array from the configuration of the Application, but phpunit is returning the following error:
Fatal error: Uncaught Error: Call to a member function get() on null in /var/www/html/app/module/Auth/src/Auth/Controller/AuthController.php:53
Stack trace:
#0 /var/www/html/app/module/Auth/test/AuthTest/Controller/AuthControllerTest.php(37): Auth\Controller\AuthController->authenticate('myuser', 'mypassword')
#1 [internal function]: AuthTest\Controller\AlbumControllerTest->testLoginAction()
#2 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php(863): ReflectionMethod->invokeArgs(Object(AuthTest\Controller\AlbumControllerTest), Array)
#3 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php(741): PHPUnit_Framework_TestCase->runTest()
#4 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestResult.php(608): PHPUnit_Framework_TestCase->runBare()
#5 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestCase.php(697): PHPUnit_Framework_TestResult->run(Object(AuthTest\Controller\AlbumControllerTest))
#6 /var/www/html/vendor/phpunit/phpunit/src/Framework/TestSuite.php(733): PHPUnit_Framework_TestCase- in /var/www/html/app/module/Auth/src/Auth/Controller/AuthController.php on line 53
My Controller is the following:
<?php
namespace Auth\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Authentication\Adapter\Ldap as AuthAdapter;
use Zend\Authentication\AuthenticationService;
use Zend\Authentication\Result;
use Auth\Form\AuthForm;
use Auth\Model\Auth;
class AuthController extends AbstractActionController
{
public function loginAction()
{
$form = new AuthForm();
$request = $this->getRequest();
if ($request->isPost()) {
$auth = new Auth();
$form->setInputFilter($auth->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()){
$auth->exchangeArray($form->getData());
$values = $form->getData();
$result = $this->authenticate($values['username'], $values['password']);
switch($result->getCode()) {
case Result::SUCCESS:
return $this->redirect()->toRoute('home');
break;
case Result::FAILURE:
break;
}
}
}
return array('form' => $form);
}
public function authenticate($username, $password){
$options = $this->getServiceLocator()->get('Config');
$authAdapter = new AuthAdapter($options['ldap'],
'username',
'password');
$authAdapter
->setIdentity($username)
->setCredential($password);
$auth = new AuthenticationService();
$result = $auth->authenticate($authAdapter);
return $result;
}
private function debug($var){
echo '<pre>';
var_dump($var);
echo '</pre>';
exit();
}
}
The TestCase:
namespace AuthTest\Controller;
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
use Zend\Authentication\AuthenticationService;
use Auth\Controller\AuthController;
class AuthControllerTest extends AbstractHttpControllerTestCase
{
protected $traceError = true;
public function setUp()
{
$this->setApplicationConfig(
include '/var/www/html/app/config/application.config.php'
);
parent::setUp();
}
public function testLoginAction()
{
#Basic Access to the page
$this->dispatch('/login');
$this->assertResponseStatusCode(200);
$data = array(
'identity' => 'myuser',
'credential' => 'mypassword',
);
$auth = new AuthController();
$auth->authenticate($data['identity'], $data['credential']);
$identity = new AuthenticationService();
$this->assertEquals($data['identity'], $identity->getIdentity());
}
}
PHPUnittest's BootStrap:
<?php
namespace AuthTest;
use Zend\Loader\AutoloaderFactory;
use Zend\Mvc\Service\ServiceManagerConfig;
use Zend\ServiceManager\ServiceManager;
use RuntimeException;
error_reporting(E_ALL | E_STRICT);
chdir(__DIR__);
/**
* Test bootstrap, for setting up autoloading
*/
class Bootstrap
{
protected static $serviceManager;
public static function init()
{
$zf2ModulePaths = array(dirname(dirname(__DIR__)));
if (($path = static::findParentPath('vendor'))) {
$zf2ModulePaths[] = $path;
}
if (($path = static::findParentPath('module')) !== $zf2ModulePaths[0]) {
$zf2ModulePaths[] = $path;
}
static::initAutoloader();
// use ModuleManager to load this module and it's dependencies
$config = array(
'module_listener_options' => array(
'module_paths' => $zf2ModulePaths,
),
'modules' => array(
'Auth'
)
);
$serviceManager = new ServiceManager(new ServiceManagerConfig());
$serviceManager->setService('ApplicationConfig', $config);
$serviceManager->get('ModuleManager')->loadModules();
static::$serviceManager = $serviceManager;
}
public static function chroot()
{
$rootPath = dirname(static::findParentPath('module'));
chdir($rootPath);
}
public static function getServiceManager()
{
return static::$serviceManager;
}
protected static function initAutoloader()
{
$vendorPath = static::findParentPath('vendor');
if (file_exists($vendorPath.'/autoload.php')) {
include $vendorPath.'/autoload.php';
}
if (! class_exists('Zend\Loader\AutoloaderFactory')) {
throw new RuntimeException(
'Unable to load ZF2. Run `php composer.phar install`'
);
}
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();
Bootstrap::chroot();
In the functional tests it works as expected, but on php unittests the error occurs in the line 53 '$options = $this->getServiceLocator()->get('Config');'.
So, how can use or set ServiceLocator to work with phpunittests?

After so much struggling on this doubt and other tests which a controller that uses an ServiceLocator, I figure that the correct way to test a controllers Action is to Mock the object or/and his methods.
I don't feel totally comfortable with this solution, but for now, this is what it is.
An other feel is that mocking an behaviour of the code is something like that breaks the DRY principle: instead of use the real code I just create a mock that half behaves like it :S
Anyway, the following code does the job for me:
$authControllerMock = $this->getMockBuilder('Auth\Controller\AuthController')
->disableOriginalConstructor()
->getMock();
$authControllerMock->expects($this->any())
->method('authenticate')
->will($this->returnValue(true);
$serviceManager = $this->getApplicationServiceLocator();
$serviceManager->setAllowOverride(true);
$serviceManager->setService('Auth\Controller\Auth', $authControllerMock);
$this->dispatch('/usermgr');
self::assertMatchedRouteName('usermgr');
self::assertControllerClass('AuthController');
self::assertControllerName('auth\controller\auth');
self::assertResponseStatusCode('200');

Related

Class 'BaseController' not found in 'RouteController.php'

I started writing a site and encountered this problem. I created RouteController, which serves for address bar parsing, and created an inherited class to have a binding:
protected $controller;
protected $inputMethod;
protected $outputMethod;
protected $parameters;
Well, generally speaking, the base class, which is inherited by RouteController. But when I just added "extends BaseController" to "class RouteController", it immediately started crashing and outputted the following error:
PHP Fatal error: Uncaught Error: Class 'Core\Base\Controllers\BaseController' not found in /var/www/Artemiys_Shop/Core/Base/Controllers/RouteController. php:10 Stack trace: #0 {main} thrown in /var/www/Artemiys_Shop/Core/Base/Controllers/RouteController.php on line 10
Does anyone know where I might have made a mistake or done something wrong? I've never had a problem with this before.
RouteController.php
<?php
namespace Core\Base\Controllers;
use Core\Base\Exceptions\RouteException;
use Core\Base\Settings\Settings;
use Core\Base\Settings\ShopSettings;
class RouteController extends BaseController
{
static private $_instance;
protected $routes;
private function _clone()
{
}
static public function getInstance()
{
if(self::$_instance instanceof self){
return self::$_instance;
}
return self::$_instance = new self;
}
/**
* #throws RouteException
*/
private function _construct()
{
$address_str = $_SERVER['REQUEST_URI'];
if(strpos($address_str, '/') === strlen($address_str) - 1 && strpos($address_str, '/') !== 0){
$this->redirect(rtrim($address_str, '/'), 301);
}
$path = substr($_SERVER['PHP_SELF'], 0, strpos($_SERVER['PHP_SELF'], 'index.php'));
if($path === PATH){
$this->routes = Settings::get('routes');
if(!$this->routes) throw new RouteException('Website is under maintenance');
$url = explode('/', substr($address_str, strlen(PATH)));
if($url[0] && $url[0] === $this->routes['admin']['alias']){
array_shift($url);
if($url[0] && is_dir($_SERVER['DOCUMENT_ROOT'] . PATH . $this->routes['plugins']['path'] . $url[0])){
$plugin = array_shift($url);
$pluginSettings = $this->routes['settings']['path'] . ucfirst($plugin . 'Settings');
if(file_exists($_SERVER['DOCUMENT_ROOT'] . PATH . $pluginSettings . '.php')){
$pluginSettings = str_replace('/', '\\', $pluginSettings);
$this->routes = $pluginSettings::get('routes');
}
$dir = $this->routes['plugins']['dir'] ? '/' . $this->routes['plugins']['dir'] . '/' : '/';
$dir = str_replace('//', '/', $dir);
$this->controller = $this->routes['plugins']['path'] . $plugin . $dir;
$hrUrl = $this->routes['plugins']['hrUrl'];
$route = 'plugins';
}else{
$this->controller = $this->routes['admin']['path'];
$hrUrl = $this->routes['admin']['hrUrl'];
$route = 'admin';
}
}else{
$hrUrl = $this->routes['user']['hrUrl'];
$this->controller = $this->routes['user']['path'];
$route = 'user';
}
$this->createRoute($route, $url);
if($url[1]){
$count = count($url);
$key = '';
if(!$hrUrl){
$i = 1;
}else{
$this->parameters['alias'] = $url[1];
$i = 2;
}
for( ; $i < $count; $i++){
if(!$key){
$key = $url[$i];
$this->parameters[$key] = '';
}else{
$this->parameters[$key] = $url[$i];
$key = '';
}
}
}
exit();
}else{
try{
throw new \Exception('Incorrect directory');
}
catch (\Exception $e){
exit($e->getMessage());
}
}
}
private function createRoute($var, $arr){
$route = [];
if(!empty($arr[0])){
if($this->routes[$var]['routes'][$arr[0]]){
$route = explode('/', $this->routes[$var]['routes'][$arr[0]]);
$this->controller .= ucfirst($route[0]. 'Controller');
}else{
$this->controller .= ucfirst($arr[0]. 'Controller');
}
}else{
$this->controller .= $this->routes['default']['controller'];
}
$this->inputMethod = $route[1] ? $route[1] : $this->routes['default']['inputMethod'];
$this->outputMethod = $route[2] ? $route[2] : $this->routes['default']['outputMethod'];
return;
}
}
BaseController.php
<?php
namespace Core\Base\Controllers;
use Core\Base\Exceptions\RouteException;
abstract class BaseController
{
protected $controller;
protected $inputMethod;
protected $outputMethod;
protected $parameters;
/**
* #throws RouteException
*/
public function route() {
$controller = str_replace('/', '\\', $this->controller);
try {
$object = new \ReflectionMethod($controller, 'request');
$args = [
'parameters' => $this->parameters,
'inputMethod' => $this->inputMethod,
'outputMethod' => $this->outputMethod
];
$object->invoke(new $controller, $args);
}
catch (\ReflectionException $e){
throw new RouteException($e->getMessage());
}
}
public function request($args){
}
}
Index.php
<?php
define ('VG_ACCESS', true);
header('Content-Type:text/html;charset=utf-8');
session_start();
require_once 'config.php';
require_once 'Core/Base/Settings/internal_settings.php';
use Core\Base\Exceptions\RouteException;
use Core\Base\Controllers\RouteController;
try{
RouteController::getInstance()->route();
}
catch (RouteException $e) {
exit($e->getMessage());
}
Setting.php
<?php
namespace Core\Base\Settings;
class Settings
{
static private $_instance;
private array $routes = [
'admin' => [
'alias' => 'admin',
'path' => 'Core/Admin/Controllers/',
'hrUrl' => false
],
'settings' => [
'path' => 'Core/Base/Settings/'
],
'plugins' => [
'path' => 'Core/Plugins/',
'hrUrl' => false,
'dir' => false
],
'user' => [
'path' => 'Core/User/Controllers/',
'hrUrl' => true,
'routes' => [
]
],
'default' => [
'controller' => 'IndexController',
'inputMethod' => 'inputData',
'outputMethod' => 'outputData'
]
];
And i would like to know, why is this error showing up?

Deprecated: call_user_func_array() should not be called statically in Symfony Router Component

I work with symfony router component like this:
index.php
require '../application/core/Core.php';
$request = Request::createFromGlobals();
// Our framework is now handling itself the request
$app = new Framework\Core();
$response = $app->handle($request);
$response->send();
Core.php
namespace Framework;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
class Core implements HttpKernelInterface
{
/** #var RouteCollection */
protected $routes;
public function __construct()
{
$this->routes = new RouteCollection();
}
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
// Load routes from the yaml file
$fileLocator = new FileLocator(array(__DIR__));
$loader = new YamlFileLoader($fileLocator);
$routes = $loader->load('routes.yaml');
// create a context using the current request
$context = new RequestContext();
$context->fromRequest($request);
$matcher = new UrlMatcher($routes, $context);
try {
$attributes = $matcher->match($request->getPathInfo());
print_r($attributes);
$controller = $attributes['_controller'];
$response = call_user_func_array($controller, $attributes);
} catch (ResourceNotFoundException $e) {
$response = new Response('Not found!', Response::HTTP_NOT_FOUND);
}
return $response;
}
public function map($path, $controller) {
$this->routes->add($path, new Route(
$path,
array('controller' => $controller)
));
}
}
In routes.yaml I add:
index:
path: /test/foo
methods: GET
controller: 'App\Catalog\Controller\Home\IndexController::index'
And I have this Index Controller:
namespace App\Catalog\Controller\Home;
class IndexController extends \App\Core\Controller
{
public function index()
{
$this->Language->load('common/home');
$data['url'] = Config::get('URL');
$data['title'] = $this->Language->get('text_title');
//$data['Csrf_Token'] = Csrf::generate('csrf_token');
$this->templates->addData($data, 'common/header');
$headerData['scripts'] = $this->Document->getScripts('header');
$headerData['data'] = $this->loadController('Common\HeaderController')->index();
$this->templates->addData($headerData, 'common/header');
echo $this->templates->render('index/index', $data);
}
}
Now in action when I load this uri: test/foo in browser I see this error:
>
Deprecated: call_user_func_array() expects parameter 1 to be a valid callback, non-static method App\Catalog\Controller\Home\IndexController::index() should not be called statically in /Applications/MAMP/htdocs/test/application/core/Core.php on line 42
Fatal error: Uncaught Error: Using $this when not in object context in /Applications/MAMP/htdocs/test/application/Catalog/Controller/Home/IndexController.php:16 Stack trace: #0 [internal function]: App\Catalog\Controller\Home\IndexController::index('App\Catalog\Con...', 'index') #1 /Applications/MAMP/htdocs/test/application/core/Core.php(42): call_user_func_array('App\Catalog\Con...', Array) #2 /Applications/MAMP/htdocs/test/public/index.php(98): Framework\Core->handle(Object(Symfony\Component\HttpFoundation\Request)) #3 {main} thrown in /Applications/MAMP/htdocs/test/application/Catalog/Controller/Home/IndexController.php on line 16
Line 42 in Core.php File is:
$response = call_user_func_array($controller, $attributes);
How do can i fix this error?!
Fix:
$controllerResolver = new HttpKernel\Controller\ControllerResolver();
$argumentResolver = new HttpKernel\Controller\ArgumentResolver();
try {
$request->attributes->add($matcher->match($request->getPathInfo()));
$controller = $controllerResolver->getController($request);
$arguments = $argumentResolver->getArguments($request, $controller);
$response = call_user_func_array($controller, $arguments);
} catch (ResourceNotFoundException $e) {
$response = new Response('Not found!', Response::HTTP_NOT_FOUND);
}

Allow SVN commit with existing PreCommit hook warnings

I am using SVN precommit hooks to validate my code standard (PSR2) before being able to commit. This works perfectly with just one exception. My unit test (PHPUnit) files exist of my bootstrap class existing of all static unit test functions, but also enables error messages above the bootstrap class definition.
The PSR2 standard will give a warning when trying to commit this, because you cannot have code that is not in a class or function in a file that contains a class definition.
Does anyone have either a way to exclude this error in my codesniffer or a way to make my code valid (without putting the code to enable my error messages in each static function of the bootstrap class)?
Here's the file:
<?php
namespace AlbumTest;
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();
How does your precommit-hook look like? Could you just remove the first few lines dynamically before sending the to the Codesniffer?
Another solution would be to set the error_reporting in the init of your bootstrap

Zend_Log_Writer_Db - Call to undefined method Zend_Config::insert()

I am running php 5.2.12 and Zend Framework 5.0.2
In my Bootstrap.php, I initialize our database connection, and initialize our logger... placing both in the registry.
However, when I try to log info in the IndexController.php, it gives the following message:
"*Fatal error: Call to undefined method Zend_Config::insert() in /usr/local/zendsvr/share/ZendFramework/library/Zend/Log/Writer/Db.php on line 137*"
At the bottom of this post, you will find the Zend Framework's class file, db.php , and the _write function being called.
I believe the problem is that I am getting the database connection options from my application.ini... and there is no insert() function defined in my application.ini for the database. But I dont really know how to add one to the config, or how I should be doing this.
Bootstrap.php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initConfig()
{
Zend_Registry::set('config', new Zend_Config($this->getOptions()));
}
protected function _initDatabases()
{
$this->bootstrap('multidb');
$resource = $this->getPluginResource('multidb');
$databases = Zend_Registry::get('config')->resources->multidb;
foreach ($databases as $name => $adapter)
{
$db_adapter = $resource->getDb($name);
Zend_Registry::set($name, $db_adapter);
}
}
protected function _initLog()
{
$db = Zend_Registry::get('config')->resources->multidb->as400;
$columnMapping = array('ILGID' => 'id', //1 numeric
'ILGLVL' => 'priority', //2 numeric
'ILGDTE' => 'date', //yymmdd
'ILGTME' => 'time', //hhmmss
'ILGPGM' => 'program', //40 alnum
'ILGURL' => 'url', //2100
'ILGUSR' => 'user', //30
'ILGMSG' => 'message'); //1000
$writer = new Zend_Log_Writer_Db($db, 'dwhlib.intralog', $columnMapping);
$logger = new Zend_Log($writer);
$date = new Zend_Date();
date_default_timezone_set('America/Chicago');
$logger->setEventItem('id' , 1);
$logger->setEventItem('date' , $date->get('Ymd'));
$logger->setEventItem('time' , $date->get('Hms'));
$logger->setEventItem('program' , 'testProgramName'); $logger->setEventItem('url' , $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
$logger->setEventItem('user' , gethostbyaddr($_SERVER['REMOTE_ADDR']));
Zend_Registry::set('logger', $logger);
}
}
application.ini
resources.multidb.as400.adapter = "db2"
resources.multidb.as400.host = "i5"
resources.multidb.as400.username = "removedUsername"
resources.multidb.as400.password = "removedPassword"
resources.multidb.as400.dbname = "*LOCAL"
resources.multidb.as400.default = true
IndexController.php
include("/www/zendserver/htdocs/development/application/models/as400.php");
class IndexController extends Zend_Controller_Action
{
public function init()
{
Zend_Registry::get('logger')->info("this is a test message");
}
public function indexAction()
{
// action body
}
}
as400.php
Class default_Model_As400 extends Zend_Db {
public static function ExecuteSelect($sql, $mode = Zend_Db::FETCH_ASSOC, $log = false)
{
$stmt = self::getStmt($sql);
$stmt->setFetchMode($mode);
$stmt->execute();
if($log === true) {
Zend_Registry::get('logger')->info($sql);
}
$rows = $stmt->fetchAll();
return $rows;
}
private static function getStmt($sql){
$db = Zend_Registry::get('config')->resources->multidb->as400;
$abstractAdapter = new Zend_Db_Adapter_Db2($db);
return new Zend_Db_Statement_DB2($abstractAdapter, $sql);
}
public function insert($libAndFile, $arrData){
echo "this was hit!!";
}
}
db.php
class Zend_Log_Writer_Db extends Zend_Log_Writer_Abstract
{
public function __construct($db, $table, $columnMap = null)
{
$this->_db = $db;
$this->_table = $table;
$this->_columnMap = $columnMap;
}
protected function _write($event)
{
if ($this->_db === null) {
require_once 'Zend/Log/Exception.php';
throw new Zend_Log_Exception('Database adapter is null');
}
if ($this->_columnMap === null) {
$dataToInsert = $event;
} else {
$dataToInsert = array();
foreach ($this->_columnMap as $columnName => $fieldKey) {
$dataToInsert[$columnName] = $event[$fieldKey];
}
}
$this->_db->insert($this->_table, $dataToInsert);
}
}
What is happening: you are calling a method called insert() on a Zend_Config instance.
What you want: call a method insert() through a Zend_Db_Adapter.
There is something wrong in your _initLog() bootstrap method:
$db = Zend_Registry::get('config')->resources->multidb->as400;
$writer = new Zend_Log_Writer_Db($db, 'dwhlib.intralog', $columnMapping);
Zend_Log_Writer_Db expects a Zend_Db adapter as a first constructor parameter. To fix this, since you already registered your database adapter in the registry, you should do something like this :
$dbName = Zend_Registry::get('config')->resources->multidb->as400;
$db = Zend_Registry::get($dbName);
$writer = new Zend_Log_Writer_Db($db, 'dwhlib.intralog', $columnMapping);

Issue with Zend framework controller

I am a newbie to the Zend framework.
I am getting an error while loading my index controller:
Fatal error: Class 'Places' not found in C:\xampp\htdocs\zend\book\application\controllers\IndexController.php on line 36
My bootstrapper code is
<?php
class Bootstrap
{
public function __construct($configSection)
{
$rootDir = dirname(dirname(__FILE__));
define('ROOT_DIR', $rootDir);
set_include_path(get_include_path(). PATH_SEPARATOR . ROOT_DIR . '/library/'. PATH_SEPARATOR . ROOT_DIR .
'/application/models/');
require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
// Load configuration
Zend_Registry::set('configSection',$configSection);
$config = new Zend_Config_Ini(ROOT_DIR.'/application/config.ini',$configSection);
Zend_Registry::set('config', $config);
date_default_timezone_set($config->date_default_timezone);
// configure database and store to the registry
$db = Zend_Db::factory($config->db);
Zend_Db_Table_Abstract::setDefaultAdapter($db);
Zend_Registry::set('db', $db);
}
public function configureFrontController()
{
$frontController = Zend_Controller_Front::getInstance();
$frontController->setControllerDirectory(ROOT_DIR .'/application/controllers');
}
public function runApp()
{
$this->configureFrontController();
// run!
$frontController = Zend_Controller_Front::getInstance();
$frontController->dispatch();
}
}
I have a model:
<?php
class Places extends Zend_Db_Table
{
protected $_name = 'places'; //table name
function fetchLatest($count = 10)
{
return $this->fetchAll(null,'date_created DESC', $count);
}
}
My index controller code is:
class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
$this->view->title = 'Welcome';
$placesFinder = new Places();
$this->view->places = $places->fetchLatest();
}
}
I am using ZF version 1.10.4
There is a good chance you are missing somethign in your class declaration
try:
<?php
class Models_Places extends Zend_Db_Table
{
protected $_name = 'places'; //table name
function fetchLatest($count = 10)
{
return $this->fetchAll(null,'date_created DESC', $count);
}
}
The Zend autoloader class will look into Models/places.php for your class.
Also you could initialise the models and default module in bootstrap with:
protected function _initAutoload() {
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => dirname(__FILE__),
));
$autoloader->addResourceType('models', 'models/', 'Models');
return $autoloader;
}
After having done that your class should be named Models_Places.
Check out the docs about autoloading.
Well, personally, I use extended controllers which contain few util methods I use very often. Here is a snippet of my extended controller:
<?php
class My_MyController extends Zend_Controller_Action
{
protected $_tables = array();
protected function _getTable($table)
{
if (false === array_key_exists($table, $this->_tables)) {
include APPLICATION_PATH . '/modules/'
. $this->_request->getModuleName() . '/models/' . $table . '.php';
$this->_tables[$table] = new $table();
}
return $this->_tables[$table];
}
}
You just need to define the APPLICATION_PATH in index.php. Then your controller could look like this:
<?php
class IndexController extends My_MyController
{
public function indexAction()
{
// get model
$model = $this->_getTable('ModelName');
}
}
Path where you store the My_Controller must also be in your include path.

Categories