I have this module called 'olo' which handles all our online ordering stuff.
Now I have made a new module called 'olosec' because I wish make a different version with a slight changed flow, and some other changes in some of the controllers.
Is it possible for me to extend a controller in 'olosec' with a controller in 'olo'?
As of now I have tried
class Olosec_CartController extends Olo_CartController
Which throws an error like
Warning: include_once(Olo/CartController.php): failed to open stream:
No such file or directory in /httpdocs/library/Zend/Loader.php on line 146 Warning:
include_once(): Failed opening 'Olo/CartController.php' for inclusion.
bla bla bla (include path) bla bla bla
My directory structure is something like this (thanks tree \F \A and EditPlus++)
+---application
| +---views
| | +---scripts
| | +---layouts
| | | +---default
| | | +---admin
| | +---languages
| | +---helpers
| +---modules
| | +---admin
| | +---mobile
| | +---olo
| | | +---controllers
| | | IndexController.php
| | | MenuController.php
| | | CartController.php
| | | OrderlistController.php
| | | |
| | | +---models
| | | \---views
| | | +---helpers
| | | \---scripts
| | | +---index
| | | +---menu
| | | +---cart
| | | \---orderlist
| | \---olosec
| | +---controllers
| | | IndexController.php
| | | MenuController.php
| | | CartController.php
| | | OrderlistController.php
| | |
| | +---models
| | \---views
| | +---helpers
| | \---scripts
| | +---index
| | +---menu
| | +---cart
| | \---orderlist
| +---models
| +---controllers
| \---configs
+---library
+---public
| +---cli
| \---default
+---tests
\---data
Update
I have used this "nasty" hack which works
require_once( APPLICATION_PATH . '/modules/olo/controllers/CartController.php');
Update # Rakesh
I have this in my bootstrap..
function _initAutoloader() {
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
return $autoloader;
}
In my application.ini
autoloadernamespaces.0 = "Zend"
autoloadernamespaces.1 = "My"
autoloadernamespaces.2 = "Something"
Why not have a custom library folder for common classes
application/
library/ < for common classes
If you are using some classes not only in one controller but at many places in your project this is a good approach.
You just have to add this new application/library/ folder to your include path in your boostrap file.
Another approach is to have an action helper. But as I described the common classes folder should be a good solution. However I found some interesting resources, most of them are about cross module coding but they might help you anyway http://zend-framework-community.634137.n4.nabble.com/Code-re-use-across-modules-td668554.html and How to Use Same Models in Different Modules in Zend Framework?
Let me describe another approach
class BasicController extends Zend_Controller_Action
{
public static $variable = '';
public function init()
{
self::$variable = 'assign value';
}
}
class HomeController extends BasicController
{
public function indexAction()
{
$bioVar = parrent::$variable;
}
}
This is better than simply extending controllers because they represent actions and each action has a corresponding view script. However all your classes should be registered in autoloader.
If you have instantiate the class from Zend Autoloader, the error should go away.
You should have the following code in your bootstrap.php file:
protected function _initAutoloader()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH . '/modules',
));
return $autoloader;
}
In general, the controllers are loaded via Zend_Controller_Dispatcher, you should use Zend_Application_Module_Autoloader to instantiate the class from other controllers.
Related
in Laravel 7 which i installed and i used nWdart module, i didn't have any problem. now after migrating project to Laravel 8 i have some issue which one of them is i get ReflectionException error
when i try to running php artisan route:list i get below error:
1 [internal]:0
Illuminate\Foundation\Console\RouteListCommand::Illuminate\Foundation\Console\{closure}(Object(Illuminate\Routing\Route))
2 C:\xampp\htdocs\v8\vendor\laravel\framework\src\Illuminate\Container\Container.php:809
ReflectionException::
("Class Modules\Media\Http\Controllers\Modules\Media\Http\Controllers\Modules\Media\Http\Controllers\ImagesController does not exist")
php artisan module:list command output:
+-------------+---------+-------+----------------------------------------+
| Name | Status | Order | Path |
+-------------+---------+-------+----------------------------------------+
| Blog | Enabled | | C:\xampp\htdocs\v8\Modules/Blog |
| Media | Enabled | | C:\xampp\htdocs\v8\Modules/Media |
| Profile | Enabled | | C:\xampp\htdocs\v8\Modules/Profile |
| Radio | Enabled | | C:\xampp\htdocs\v8\Modules/Radio |
| Store | Enabled | | C:\xampp\htdocs\v8\Modules/Store |
| Ticket | Enabled | | C:\xampp\htdocs\v8\Modules/Ticket |
| UserMessage | Enabled | | C:\xampp\htdocs\v8\Modules/UserMessage |
+-------------+---------+-------+----------------------------------------+
and my routes:
<?php
use Illuminate\Support\Facades\Route;
use Modules\Media\Http\Controllers\ImagesController;
Route::prefix('panel')->group(function () {
Route::prefix('media')->group(function () {
Route::prefix('mediaResource')->group(function () {
Route::resource('imagesController', ImagesController::class);
...
});
});
});
ImagesController class:
<?php
namespace Modules\Media\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
class ImagesController extends Controller
{
public function index()
{
}
//...
public function destroy($id)
{
}
}
| panel/media/mediaResource/imagesController | imagesController.store |
Modules\Media\Http\Controllers\ImagesController#store | web |
| | GET|HEAD | panel/media/mediaResource/imagesController | imagesController.index |
Modules\Media\Http\Controllers\ImagesController#index | web |
| | GET|HEAD | panel/media/mediaResource/imagesController/create | imagesController.create |
Modules\Media\Http\Controllers\ImagesController#create | web |
| | DELETE | panel/media/mediaResource/imagesController/{imagesController}| imagesController.destroy |
Modules\Media\Http\Controllers\ImagesController#destroy| web |
| | PUT|PATCH | panel/media/mediaResource/imagesController/{imagesController}| imagesController.update |
Modules\Media\Http\Controllers\ImagesController#update | web |
| | GET|HEAD | panel/media/mediaResource/imagesController/{imagesController}| imagesController.show |
Modules\Media\Http\Controllers\ImagesController#show | web |
| | GET|HEAD | panel/media/mediaResource/imagesController/{imagesController}/edit | imagesController.edit
Vehicle.php ( app\Vehicle.php file )
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Vehicles extends Model
{
protected $primaryKey = 'serie';
protected $fillable = ['serie', 'color', 'power', 'capacity', 'speed'];
protected $hidden = ['serie'];
public function maker()
{
return $this->belongsTo('Maker');
}
}
VehicleController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Vehicle;
class VehicleController extends Controller
{
public function index()
{
$vehicles = Vehicle::all();
return response()->json(['data'=> $vehicles], 200);
}
}
Below is my route list
| Domain | Method | URI | Name | Action
| Middleware |
+--------+-----------+-----------------------------------+------------------------+-------------------------------------
-----------------+------------+
| | GET|HEAD | makers | makers.index | App\Http\Controllers\MakerController
#index | web |
| | POST | makers | makers.store | App\Http\Controllers\MakerController
#store | web |
| | PUT|PATCH | makers/{makers} | makers.update | App\Http\Controllers\MakerController
#update | web |
| | DELETE | makers/{makers} | makers.destroy | App\Http\Controllers\MakerController
#destroy | web |
| | GET|HEAD | makers/{makers} | makers.show | App\Http\Controllers\MakerController
#show | web |
| | POST | makers/{makers}/vehicle | makers.vehicle.store | App\Http\Controllers\MakersVehicleCo
ntroller#store | web |
| | GET|HEAD | makers/{makers}/vehicle | makers.vehicle.index | App\Http\Controllers\MakersVehicleCo
ntroller#index | web |
| | PUT|PATCH | makers/{makers}/vehicle/{vehicle} | makers.vehicle.update | App\Http\Controllers\MakersVehicleCo
ntroller#update | web |
| | GET|HEAD | makers/{makers}/vehicle/{vehicle} | makers.vehicle.show | App\Http\Controllers\MakersVehicleCo
ntroller#show | web |
| | DELETE | makers/{makers}/vehicle/{vehicle} | makers.vehicle.destroy | App\Http\Controllers\MakersVehicleCo
ntroller#destroy | web |
| | GET|HEAD | vehicles | vehicles.index | App\Http\Controllers\VehicleControll
er#index | web |
+--------+-----------+-----------------------------------+------------------------+-------------------------------------
when I call to myapp.com/vehicles, it show me 'Class 'App\Vehicle' not found' error. I have also Maker controller and Maker model. I can call myapp.com/makers and it also return properly. Please point me where is my weakness.
You named your class Vehicles not Vehicle. You should name it Vehicle make sure it is Vehicle.php and you will be fine.
The relationship should have the Fully Qualified Class Name in it as well:
public function maker()
{
return $this->belongsTo('App\Maker');
// or
return $this->belongsTo(Maker::class);
// assuming they are in the same namespace
}
I am writing unit tests for a project that use apigility but for some reason the tests classes do not recognize que namespace of the real classes.
here is a test class :
namespace Testzfnewsite\V1\Rest\SendEmail\Entity\DAO;
use PHPUnit_Framework_TestCase;
class GenericDAOTest extends PHPUnit_Framework_TestCase {
public function test_verifica_se_a_classe_existe(){
$classe = class_exists('\\zfnewsite\\V1\\Rest\\SendEmail\\Entity\\DAO\\GenericDAO');
$this->assertTrue($classe);
}
}
In this example, the class_exists function result is always false, I've checked the namespace and the class name and it is rigth, It's seens that this test class dont see the namespace of the real aplication.
This is structure of the zfnewsite module.
_zfnewsite
|
|_config
|
|_src
| |
| |_zfnewsite
| |
| |_V1
| | |
| | |_Rest
| | | |
| | | |_SendEmail
| | | | |
| | | | |_Entity
| | | | | |
| | | | | |_DAO
| | | | | |
| | | | | |_GenericDAO.php
| | | | | |_GenericDAOImpl.php
| | | | |
| | | | |_Service
| | | |
| | | |_Status
| | |
| | |_Rcp
| |
| |_Module.php
|
|_test
| |
| |_zfnewsite
| |
| |_V1
| | |
| | |_Rest
| | | |
| | | |_SendEmail
| | | | |
| | | | |_Entity
| | | | | |
| | | | | |_DAO
| | | | | |
| | | | | |_GenericDAOTest.php
| | | | | |_GenericDAOImplTest.php
| | | | |
| | | | |_Service
| | | |
| | | |_Status
| | |
| | |_Rcp
| |
| |_Bootstrap.php
|
|_Module.php
I need help to figure out what is wrong with this testing enviroment,There is diference in tests for a normal zf2 application and apigility?
This is the code for the class GenericDAO:
namespace zfnewsite\V1\Rest\SendEmail\Entity\DAO;
interface GenericDAO
{
public function save($data);
public function update($id, $data);
public function findOneBy(array $where);
public function findById($id);
public function findAll();
public function delete($id);
}
I solved this adding a bootstrap with configurations for the test enviroment,with the bootstrap file the tests files detected the real namespaces and the tests was sucessfull.
the bootstrap file:
<?php
namespace TestePsAdmin;
use Zend\Mvc;
use Zend\ServiceManager\ServiceManager;
use Zend\Mvc\Service\ServiceManagerConfig;
class bootstrap
{
static $serviceManager;
static function go()
{
// Make everything relative to the root
chdir(dirname(__DIR__));
// Setup autoloading
require_once( __DIR__ . '/../init_autoloader.php' );
// Setup autoloading
include 'vendor/autoload.php';
if (!defined('APPLICATION_PATH')) {
define('APPLICATION_PATH', realpath(__DIR__ . '/../'));
}
// Run application
$appConfig = include APPLICATION_PATH . '/config/application.config.php';
if (file_exists(APPLICATION_PATH . '/config/development.config.php')) {
$appConfig = \Zend\Stdlib\ArrayUtils::merge($appConfig, include APPLICATION_PATH . '/config/development.config.php');
}
\Zend\Mvc\Application::init($appConfig);
$serviceManager = new ServiceManager(new ServiceManagerConfig());
$serviceManager->setService('ApplicationConfig', $appConfig);
$serviceManager->get('ModuleManager')->loadModules();
self::$serviceManager = $serviceManager;
}
static public function getServiceManager()
{
return self::$serviceManager;
}
}
bootstrap::go();
And the init_autoload is required to load Zend application path for the test enviroment:
// Composer autoloading
if (file_exists('vendor/autoload.php')) {
$loader = include 'vendor/autoload.php';
}
if (class_exists('Zend\Loader\AutoloaderFactory')) {
return;
}
$zf2Path = false;
if (is_dir('vendor/ZF2/library')) {
$zf2Path = 'vendor/ZF2/library';
} elseif (getenv('ZF2_PATH')) { // Support for ZF2_PATH environment variable or git submodule
$zf2Path = getenv('ZF2_PATH');
} elseif (get_cfg_var('zf2_path')) { // Support for zf2_path directive value
$zf2Path = get_cfg_var('zf2_path');
}
if ($zf2Path) {
if (isset($loader)) {
$loader->add('Zend', $zf2Path);
$loader->add('ZendXml', $zf2Path);
} else {
include $zf2Path . '/Zend/Loader/AutoloaderFactory.php';
Zend\Loader\AutoloaderFactory::factory(array(
'Zend\Loader\StandardAutoloader' => array(
'autoregister_zf' => true
)
));
}
}
if (!class_exists('Zend\Loader\AutoloaderFactory')) {
throw new RuntimeException('Unable to load ZF2. Run `php composer.phar install` or define a ZF2_PATH environment variable.');
}
with these 2 files just configured the phpunit to load the bootstrap file in the xml test config file:
<phpunit bootstrap="Bootstrap.php"
colors="true">
<php>
<server name='HTTP_HOST' value='psadmin.com' />
<server name="SERVER_NAME" value="localhost"/>
</php>
<testsuites>
<testsuite name="PricingTable Test">
<directory>../module/</directory>
</testsuite>
</testsuites>
</phpunit>
I'm brand new to Laravel 4 and just trying to get started. I can't seem to get the routes and controllers to work nicely together.
I am trying to navigate to:
http://localhost/laravel/public/vehicles
Using the controller VehiclesController.php
<?php
class VehiclesController extends BaseController {
public $restful = true;
public function getIndex() {
return View::make('vehicles.index');
}
}
and the route
Route::controller('/', 'VehiclesController');
I have a view created in views\vehicles\index.php which only contains HTML.
Here is my routes table:
+--------+-------------------------------------------------------+------+----------------------------------+----------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+-------------------------------------------------------+------+----------------------------------+----------------+---------------+
| | GET|HEAD / | | VehiclesController#getIndex | | |
| | GET|HEAD index/{one?}/{two?}/{three?}/{four?}/{five?} | | VehiclesController#getIndex | | |
| | GET|HEAD|POST|PUT|PATCH|DELETE {_missing} | | VehiclesController#missingMethod | | |
+--------+-------------------------------------------------------+------+----------------------------------+----------------+---------------+
I have looked at other posts and still can't quite figure out where I am going wrong. Thanks!
If you want to hit
http://localhost/laravel/public/vehicles
then
Route::controller('/vehicles', 'VehiclesController');
I have the following UML diagram. CurlRequestHandler and KernelRequestHandler are both an implementation of the RequestHandlerInterface. The request handlers are responsible to process a certain Request object, all of them will return the same Response object.
+------------------------+ +-------------------------+
| CurlRequestHandler | | KernelRequestHandler |
|------------------------| |-------------------------|
| | | |
| - handleRequest(Request) | - handleRequest(Request)|
| | | |
| | | |
| | | |
+------------------------+ +-------------------------+
+
| +
| |
| +---------------------------+ |
| | RequestHandlerInterface | | +---------------+
+----> |---------------------------| <-----+ | |
| | | |
| - handleRequest(Request) | | CLIENT |
| | | |
| | +---------------+
| |
| |
+---------------------------+
Now, to determine which handler I need to use, I have the following if statement in my client:
if ($mode == "kernel") {
$handler = new KernelRequestHandler();
} else {
$handler = new CurlRequestHandler();
}
$response = $handler->handleRequest($request);
Now, the problem is, when I need to add a new handler, I need to alter the if statement. I looked into the Chain of Responsibility design pattern and this seems to do a better job at this, but I'm not sure.
Which design pattern would be the best approach for this?
Steffen
What you need is to implement a factory method design pattern to create the handlers.
class HandlerFactory {
public function make($mode) {
switch(strtolower($mode)) {
case 'kernel': return new KernelRequestHandler();
case 'curl': return new CurlRequestHandler();
}
}
}
And, yes, you need to add a case for every new handler you make.
PS: Why you shouldn't call your classes 'handler'
If your $mode equals to the beginning of your RequestHandler class, then you can just append it.
$mode = 'kernel';
$class = ucfirst($mode).'RequestHandler';
$handler = new $class;
Will produce new KernelRequestHandler
class RequestFactory {
public static function getHandler($mode) {
$className = ucfirst($mode).'RequestHandler';
return new $className();
}
}
You can use it like this:
$handler = RequestFactory::getHandler('kernel');
$handler->handleRequest($request);