Forwarding a request with custom routes in zend framework - zend-framework

I am working with custom routes in zend framework. I had managed my custom routes successfully
but I had a problem i.e. I want to forward a request according some predefined condition after routing but I am unable to forward my. I did not get any error.
Following is the code of routing configuration file -
;--- routing for multiple requests
routes.resource.route = "resource/:moduleName/:fileType/"
routes.resource.defaults.controller = resources
routes.resource.defaults.module = 'default'
routes.resource.defaults.action = 'index'
;--- routing for singles file
routes.resourceCSS.type = "Zend_Controller_Router_Route_Regex"
routes.resourceCSS.route = "resource/(\w+)/([a-zA-z0-9]+\.([a-zA-z0-9]+))"
routes.resourceCSS.defaults.module = 'default'
routes.resourceCSS.defaults.controller = "resources"
routes.resourceCSS.defaults.action = checkfiletype
routes.resourceCSS.map.moduleName = 1
routes.resourceCSS.map.fileName = 2
routes.resourceCSS.map.fileType = 3
controller name is resources
Follwoing is code of controller : -
class ResourcesController extends Zend_Controller_Action
{
public function checkfiletypeAction()
{
var_dump($this->_getAllParams());
$moduleName = $this->getRequest()->getParam('moduleName');
$fileName = $this->getRequest()->getParam('fileName');
$fileType = strtolower($this->getRequest()->getParam('fileType'));
switch($fileType)
{
case 'css' :
echo $fileType ;
$this->_forward('css') ;
break ;
case 'js' :
$this->_forward('js') ;
break ;
default :
break;
}
die();
}
public function cssAction()
{
var_dump($this->_getAllParams());
die();
}
public function jsAction()
{
var_dump($this->_getAllParams());
die();
}
}
Please help me.

You are passing in numbers as your filetype, and checking for words:
;ini file
routes.resourceCSS.map.fileType = 3
//controller
case 'css' :
Change the case to match the number:
//controller
case '3' :

Related

Slim 4 get all routes into a controller without $app

I need to get all registed routes to work with into a controller.
In slim 3 it was possible to get the router with
$router = $container->get('router');
$routes = $router->getRoutes();
With $app it is easy $routes = $app->getRouteCollector()->getRoutes();
Any ideas?
If you use PHP-DI you could add a container definition and inject the object via constructor injection.
Example:
<?php
// config/container.php
use Slim\App;
use Slim\Factory\AppFactory;
use Slim\Interfaces\RouteCollectorInterface;
// ...
return [
App::class => function (ContainerInterface $container) {
AppFactory::setContainer($container);
return AppFactory::create();
},
RouteCollectorInterface::class => function (ContainerInterface $container) {
return $container->get(App::class)->getRouteCollector();
},
// ...
];
The action class:
<?php
namespace App\Action\Home;
use Psr\Http\Message\ResponseInterface;
use Slim\Http\Response;
use Slim\Http\ServerRequest;
use Slim\Interfaces\RouteCollectorInterface;
final class HomeAction
{
/**
* #var RouteCollectorInterface
*/
private $routeCollector;
public function __construct(RouteCollectorInterface $routeCollector)
{
$this->routeCollector = $routeCollector;
}
public function __invoke(ServerRequest $request, Response $response): ResponseInterface
{
$routes = $this->routeCollector->getRoutes();
// ...
}
}
This will display basic information about all routes in your app in SlimPHP 4:
$app->get('/tests/get-routes/', function ($request, $response, $args) use ($app) {
$routes = $app->getRouteCollector()->getRoutes();
foreach ($routes as $route) {
echo $route->getIdentifier() . " → ";
echo ($route->getName() ?? "(unnamed)") . " → ";
echo $route->getPattern();
echo "<br><br>";
}
return $response;
});
From there, one can use something like this to get the URL for a given route:
$routeParser = \Slim\Routing\RouteContext::fromRequest($request)->getRouteParser();
$path = $routeParser->urlFor($nameofroute, $data, $queryParams);
With the following caveats:
this will only work for named routes;
this will only work if the required route parameters are provided -- and there's no method to check whether a route takes mandatory or optional route parameters.
there's no method to get the URL for an unnamed route.

How do I parse a Typoscript file?

I am writing a unit test and want to check if the data in a certain typoscript file satisfies my requirements. How do I convert the text file to an array? The Typo3-Framework is available.
My google research points to using the class \TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser but I don't find usage examples ...
(Using Typo3 7.6)
This is working (but possibly there are nicer ways to do this):
<?php
use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
class TyposcriptTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
public function setUp() {
parent::setUp();
$this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
}
protected function loadTSFile($filename) {
$content = file_get_contents($filename);
$parser = $this->objectManager->get(TypoScriptParser::class);
$parser->parse($content);
return $parser->setup;
}
public function testTS() {
$array = $this->loadTSFile('...');
$this->assertTrue(isset($array['tx_extension.']['flexForm.']['andsoon.']]), 'Assertion failed. TS content: ' . var_export($array, true));
}
}
Here is the working example for TYPO3 v - 10.4.x
$tsString = 'colors {
backgroundColor = red
fontColor = blue
}
[ip("123.45.*")]
headerImage = fileadmin/img1.jpg
[ELSE]
headerImage = fileadmin/img2.jpg
[GLOBAL]
// Wonder if this works... :-)
wakeMeUp = 7:00';
$TSparserObject = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
\TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser::class
);
$TSparserObject->parse($tsString);
echo '<pre>';
print_r($TSparserObject->setup);
echo '</pre>';

How to get typoscript setup in a scheduler/cron script?

I need to get the extension typoscript setup in schedular script.
I am using typo3 v 4.5.
My schedular script looks like this.
class tx_myext_scheduler extends tx_scheduler_Task {
public function execute() {
//here i need to get typoscript setup
}
}
and my extension setup looks like this.
plugin.tx_myext_pi1{
listView{
file.height = 216c
}
}
In schedualr script I need to get the file.height value.
How to do that ?
Currently i tried this without success
$pObj = $GLOBALS['TSFE'];
$conf = $pObj->tmpl->setup['plugin.']['tx_myext_pi1.'];
Thank you.
The TSFE is only available in the frontend, so have to initialize it yourself (that consumes some resources!). You can create it like that in scheduler: (source)
$GLOBALS['TT'] = new t3lib_timeTrackNull;
$GLOBALS['TSFE'] = t3lib_div::makeInstance('tslib_fe', $GLOBALS['TYPO3_CONF_VARS'], 2, 0);
$GLOBALS['TSFE']->sys_page = t3lib_div::makeInstance('t3lib_pageSelect');
$GLOBALS['TSFE']->sys_page->init(TRUE);
$GLOBALS['TSFE']->initTemplate();
$GLOBALS['TSFE']->rootLine = '';
$GLOBALS['TSFE']->sys_page->getRootLine(1, '');
$GLOBALS['TSFE']->getConfigArray();
or in an eID script: (source)
require_once(PATH_tslib.'class.tslib_fe.php');
require_once(PATH_t3lib.'class.t3lib_page.php');
$temp_TSFEclassName = t3lib_div::makeInstanceClassName('tslib_fe');
$GLOBALS['TSFE'] = new $temp_TSFEclassName($TYPO3_CONF_VARS, $pid, 0, true);
$GLOBALS['TSFE']->connectToDB();
$GLOBALS['TSFE']->initFEuser();
$GLOBALS['TSFE']->determineId();
$GLOBALS['TSFE']->getCompressedTCarray();
$GLOBALS['TSFE']->initTemplate();
$GLOBALS['TSFE']->getConfigArray();
or in a backend module: (source)
function loadTypoScriptForBEModule($extKey) {
require_once(PATH_t3lib . 'class.t3lib_page.php');
require_once(PATH_t3lib . 'class.t3lib_tstemplate.php');
require_once(PATH_t3lib . 'class.t3lib_tsparser_ext.php');
list($page) = t3lib_BEfunc::getRecordsByField('pages', 'pid', 0);
$pageUid = intval($page['uid']);
$sysPageObj = t3lib_div::makeInstance('t3lib_pageSelect');
$rootLine = $sysPageObj->getRootLine($pageUid);
$TSObj = t3lib_div::makeInstance('t3lib_tsparser_ext');
$TSObj->tt_track = 0;
$TSObj->init();
$TSObj->runThroughTemplates($rootLine);
$TSObj->generateConfig();
return $TSObj->setup['plugin.'][$extKey . '.'];
}
If you have missing class errors somewhere, maybe you have to add some requires.
This solution is perfect if the page is in standard mode, but doesn't work if the page is a Draft:
function loadTypoScriptForBEModule($extKey) {
require_once(PATH_t3lib . 'class.t3lib_page.php');
require_once(PATH_t3lib . 'class.t3lib_tstemplate.php');
require_once(PATH_t3lib . 'class.t3lib_tsparser_ext.php');
list($page) = t3lib_BEfunc::getRecordsByField('pages', 'pid', 0);
$pageUid = intval($page['uid']);
$sysPageObj = t3lib_div::makeInstance('t3lib_pageSelect');
$rootLine = $sysPageObj->getRootLine($pageUid);
$TSObj = t3lib_div::makeInstance('t3lib_tsparser_ext');
$TSObj->tt_track = 0;
$TSObj->init();
$TSObj->runThroughTemplates($rootLine);
$TSObj->generateConfig();
return $TSObj->setup['plugin.'][$extKey . '.'];
}

Zend redirector not working properly

I have just uploaded my app into a shared hosting environment and it does not seem to be working properly.
I have 2 plugins registered. One checks for session timeout and the other check for session is created after logged in.
the pproblem is that after the second plugin(security.php) kicks in it suppose to redirect the user to the login screen because session has not been created yet. Upon redirection the page displays :The page isn't redirecting properly.
I am not sure what is happenning since everything works fine locally.Below are my two files i mentioned here.
Security.php(here you can see that i have tried couple options, but nothing worked).
class Plugins_security extends Zend_Controller_Plugin_Abstract
{
public function preDispatch (Zend_Controller_Request_Abstract $request)
{
$auth = Zend_Auth::getInstance();
$moduleName = $request->getModuleName();
//$vc = new Zend_Application_Resource_View();
if ($request->getModuleName() != "auth")
{
$auth = Zend_Auth::getInstance();
if (! $auth->hasIdentity())
{
//$redirector = Zend_Controller_Action_HelperBroker::getStaticHelper(
//'redirector');
$flashMessenger = Zend_Controller_Action_HelperBroker::getStaticHelper('FlashMessenger');
$flashMessenger->addMessage(array('message' => 'Sua sessão expirou. Favor logar novamente', 'status' => 'info'));
//$this->_redirect('/auth/login/',array(‘code’ => 301));
$r = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
$r->gotoSimple("index", "login", "auth");
//header('Location: /auth/login/');
//return;
}
}
}
}
timeout.php
class Plugins_timeout extends Zend_Controller_Plugin_Abstract
{
protected $_auth = null;
protected $_acl = null;
protected $_flashMessenger = null;
protected static $_ZEND_SESSION_NAMESPACE_EXPIRATION_SECONDS= 900;
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
Zend_Session::start();
$moduleName = parent::getRequest()->getModuleName();
if($moduleName !='auth'){
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > self::$_ZEND_SESSION_NAMESPACE_EXPIRATION_SECONDS)) {
// last request was more than 30 minates ago
session_destroy(); // destroy session data in storage
session_unset(); // unset $_SESSION variable for the runtime
$front = Zend_Controller_Front::getInstance();
$_baseUrl=$front->getBaseUrl();
Zend_Debug::dump(time() - $_SESSION['LAST_ACTIVITY']);
header("Location:$_baseUrl/auth/login/index/timeout/1" );
}else{
$_SESSION['LAST_ACTIVITY']= time();
}
}
}
}
Any help is appreciated. I need to deploy this app ASAP.
thank you.
I think you want:
$r = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
$r->gotoSimpleAndExit("index", "login", "auth"); // Note the 'AndExit' suffix.
$r->gotoXXX() just sets the correct header and codes in the $response object, but allows the rest of the dispatch to continue. In contrast, the AndExit part immediately sends the response to the client and exits.
[Not clear why AndExit would not be required in your local environment, though...]

Module based application.ini in Zend Framework

I want to have module based application.ini in my application.
Is it possible?
Basic requirement arises because I am having multiple databases depending on modules.
Please guide.
You can use multiple Db in application.ini:
resources.db.master.adapter = "PDO_MYSQL"
resources.db.master.default = false
resources.db.master.params.dbname = "db1"
resources.db.master.params.host = "127.0.0.1"
resources.db.master.params.username = "root"
resources.db.master.params.password = ""
resources.db.slave.adapter = "PDO_MYSQL"
resources.db.slave.default = true
resources.db.slave.params.dbname = "db2"
resources.db.slave.params.host = "127.0.0.1"
resources.db.slave.params.username = "root"
resources.db.slave.params.password = ""
And initialize in your bootstrap:
public function _initDatabase() {
$config = $this->getApplication()->getOption('resources');
$dbArrays = array();
foreach($config['db'] as $name => $dbConf){
// Set up database
$db = Zend_Db::factory($dbConf['adapter'], $dbConf['params']);
$db->query("SET NAMES 'utf8'");
$dbArrays[$name] = $db;
if((boolean)$dbConf['default']){
Zend_Db_Table::setDefaultAdapter($db);
}
unset($db);
}
Zend_Registry::set("db", $dbArrays);
}
In my case I always save each adapter in the registry so I can use them separately later.
I also made a new class which extend Zend_Db_table where I have My own getAdapter($name) like so:
public function getAdapter($name = null){
if($name !== null){
$dbAdapters = Zend_Registry::get('db');
return $dbAdapters[$name];
}
return parent::getAdapter();
}
With that in each model I can do:
$this->getAdapter('slave')->fecthAll($sql);
$this->getAdapter('master')->fecthAll($sql);
The application.ini is read long before the module is determined. I'd suggest you forget about application.ini and instead try and write a controller plugin that will load in some additional configuration depending on which module was selected.