ZF2 application - Dispatch error event triggered every time - zend-framework

I'am working on a Zend Framework 2 application and have a strange behavior concerning error handling. My code in Module.php:
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_ROUTE, [$this, 'onPreRoute'], 100);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH_ERROR, [$this, 'handleError']);
}
public function onPreRoute(MvcEvent $e)
{
$serviceManager = $e->getTarget()->getServiceManager();
$router = $serviceManager->get('router');
$router->setTranslator($serviceManager->get('translator'));
}
public function handleError(MvcEvent $e)
{
$error = $e->getParam('error');
file_put_contents('error.log', $error . PHP_EOL, FILE_APPEND);
switch($error) {
case 'error-router-no-match':
$router = $e->getRouter();
$url = $router->assemble([], ['name' => 'home']);
header('Location: ' . $url);
exit;
}
}
As you can see I'am translating the routes. This works fine. But on every request the dispatch error event is triggered too. The error.log file will be created every time. But the redirect will be only performed if the route doesn't really exist. I think it depends on the translator or is my code in Module.php not correct?

Resolved!
The reason was that the browser automatically requests /favicon.ico and that was not available :-)

Related

Slim 3 blackholing errors

I have a small slim 3 app, and when I throw an exception slim simply shows the generic error message:
Slim Application Error
A website error has occurred. Sorry for the temporary inconvenience.
In slim 2 you can do something like this to turn on debug mode giving you backtraces etc:
$app->config('debug', true);
In slim 3 there doesn't seem to be one. Additionally, it seems to be overriding my exception and error handlers.
How can I get slim to spit out errors, or at least to call my error handlers (Which pipe the output to kint for debug information)
Looking through the source, it's possible to initialize slim 3 with error display like so:
$app = new \Slim\App(['settings' => ['displayErrorDetails' => true]]);
I'm not sure if it's possible to change this setting after the fact without replacing the errorHandler altogether.
To show full stack trace on default exception handler use what j-v said.
If you want to handle exceptions in Slim yourself then you need to override Slim's default exception handler as it will be used before your "not in Slim" error handler:
$app = new \Slim\App();
$container = $app->getContainer();
$container['errorHandler'] = function(ServerRequestInterface $request, ResponseInterface $response, Exception $exception) {
//Handle exception here
}
Error handling is rather well documented: Official Docs
$app = new \Slim\App();
$c = $app->getContainer();
$c['errorHandler'] = function ($c) {
return function ($request, $response, $exception) use ($c) {
return $c['response']->withStatus(500)
->withHeader('Content-Type', 'text/html')
->write('Something went wrong!');
};
};
Error handling is best solution to this. You can do something like to see Error Trace
$app = new \Slim\App();
$container = $app->getContainer();
$container['phpErrorHandler'] = $container['errorHandler'] = function ($c) {
return function ($request, $response, $exception) use ($c) {
return $c['response']->withStatus(500)
->withHeader('Content-Type', 'text/html')
->write('Something went wrong!<br><br>' .
nl2br($error->getTraceAsString()));
};
};
Make displayErrorDetails->true.
You will find cause of error.
$config = ['settings' => [
'addContentLengthHeader' => true,
'displayErrorDetails' => true
]];
$app = new \Slim\App($config)

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...]

How to detect wrong URL using Joomla! System Plugin?

I have developed a Joomla! system plugin.
I would like to detect wrong URL when that plugin is executed.
For example:
If I enter a URL "http://localhost/wrong-url", I want to catch that error in the system plugin.
How do I know that the system will display the error page (404)?
You can do this using the following technique
Check URL Function
function checkURL($URL){
$ch = curl_init($URL);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpcode != 200) {
return false;
}else{
return true;
}
}
Use Of the CheckURL Function
/*URL May be a Joomla OR Non Joomla Site*/
if(checkURL("http://adidac.github.com/jmm/index.html")){
echo "URL Exist";
}else{
echo "URL NOT Exist";
//JError::raiseWarning(500,$URL. " is not exists");
}
if(checkURL("http://adidac.github.com/jmm/indexsdadssdasaasdaas.html")){
echo "URL Exist";
}else{
echo "URL NOT Exist";
//JError::raiseWarning(500,$URL. " is not exists");
}
NOTE: Check you have PHP curl lib installed
In a system plugin to trap the 404 you would have to add a function from your plugin as a callback to JError error handler array.
I would have a look at the way com_redirect does it, with it's system plugin. e.g.
function __construct(&$subject, $config)
{
parent::__construct($subject, $config);
// Set the error handler for E_ERROR to be the class handleError method.
JError::setErrorHandling(E_ERROR, 'callback', array('plgSystemRedirect', 'handleError'));
}
static function handleError(&$error)
{
// Get the application object.
$app = JFactory::getApplication();
// Make sure we are not in the administrator and it's a 404.
if (!$app->isAdmin() and ($error->getCode() == 404))
{
// Do cool stuff here
}
}
The only problem is JError is depreciated so I'm not sure going forward when this would break e.g. it should be fine in 3.0, 3.1, 3.2 and 3.5 but after that who knows?
I know this is an old question, but I needed a solution today and found this question, so leaving my solution below to help anyone else searching in the future.
In the plugin file:
/**
* The global exception handler registered before the plugin was instantiated
*
* #var callable
* #since 3.6
*/
private static $previousExceptionHandler;
/**
* Constructor.
*
* #param object &$subject The object to observe
* #param array $config An optional associative array of configuration settings.
*
* #since 1.6
*/
public function __construct(&$subject, $config) {
parent::__construct($subject, $config);
// Register the previously defined exception handler so we can forward errors to it
self::$previousExceptionHandler = set_exception_handler(array('PlgSystemVmsreporting', 'handleException'));
}
public static function handleException($exception) {
// Wrap in try/catch to prevent any further exceptions being raised
try {
// Do whatever you need with the error
} catch (Exception $e) {
//Don't make a fuss - fail silently
}
// Proxy to the previous exception handler if available, otherwise use the default Joomla handler
if (self::$previousExceptionHandler) {
call_user_func_array(self::$previousExceptionHandler, array($exception));
} else {
ExceptionHandler::render($exception);
}
}

open_basedir restriction in effect. File() is not within the allowed path(s) and Uncaught CurlException: 3: No URL set! thrown in base_facebook.php

protected function makeRequest($url, $params, $ch=null) {
if (!$ch) {
$ch = curl_init();
}
$opts = self::$CURL_OPTS;
if ($this->useFileUploadSupport()) {
$opts[CURLOPT_POSTFIELDS] = $params;
} else {
$opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&');
}
$opts[CURLOPT_URL] = $url;
// disable the 'Expect: 100-continue' behaviour. This causes CURL to wait
// for 2 seconds if the server does not support this header.
if (isset($opts[CURLOPT_HTTPHEADER])) {
$existing_headers = $opts[CURLOPT_HTTPHEADER];
$existing_headers[] = 'Expect:';
$opts[CURLOPT_HTTPHEADER] = $existing_headers;
} else {
$opts[CURLOPT_HTTPHEADER] = array('Expect:');
}
curl_setopt_array($ch, $opts);
$result = curl_exec($ch);
if (curl_errno($ch) == 60) { // CURLE_SSL_CACERT
self::errorLog('Invalid or no certificate authority found, '.
'using bundled information');
curl_setopt($ch, CURLOPT_CAINFO,
dirname(__FILE__) . '/fb_ca_chain_bundle.crt');
$result = curl_exec($ch);
}
if ($result === false) {
$e = new FacebookApiException(array(
'error_code' => curl_errno($ch),
'error' => array(
'message' => curl_error($ch),
'type' => 'CurlException',
),
));
curl_close($ch);
throw $e;
}
curl_close($ch);
return $result;
}
I have built a facebook app, but something went wrong in this piece of code of base_facebook.php.
Whole code is here. All i get everytime are this 2 errors -
1.Warning: curl_setopt_array() [function.curl-setopt-array]: open_basedir restriction in effect. File() is not within the allowed path(s): (/home/:/usr/lib/php:/tmp) in /home/a2424901/public_html/base_facebook.php on line 802
2.Uncaught CurlException: 3: No URL set! thrown in /home/a2424901/public_html/base_facebook.php on line 814
Here is the code of my facebook app i.e.(index.php)
Yeap, non-obvious error message.
But it means, that realpath() returns empty value:
File() is not within the allowed path(s)...
Make sure, that the file passed to realpath() function really exists in the specified path.
Other exceptions in your example were caused by this problem.
By the way, it's good practice to wrap all weak spots (in your example - Facebook API calls) in try-catch blocks.

Sending a SOAP message with PHP

what I'm trying to do is send a load of values captured from a form to a CRM system with SOAP and PHP. I've been reading up on SOAP for a while and I don't understand how to go about doing so, does anybody else know?
In order to do this it might be easiest to download a simple soap toolkit like 'NuSOAP' from sourceforge.
And then you would code something like the following (example submission of ISBN number):
<?php
// include the SOAP classes
require_once('nusoap.php');
// define parameter array (ISBN number)
$param = array('isbn'=>'0385503954');
// define path to server application
$serverpath ='http://services.xmethods.net:80/soap/servlet/rpcrouter';
//define method namespace
$namespace="urn:xmethods-BNPriceCheck";
// create client object
$client = new soapclient($serverpath);
// make the call
$price = $client->call('getPrice',$param,$namespace);
// if a fault occurred, output error info
if (isset($fault)) {
print "Error: ". $fault;
}
else if ($price == -1) {
print "The book is not in the database.";
} else {
// otherwise output the result
print "The price of book number ". $param[isbn] ." is $". $price;
}
// kill object
unset($client);
?>
This code snippet was taken directly from, which is also a good resource to view
http://developer.apple.com/internet/webservices/soapphp.html
Hope this helps.
You probably found a solution since then - but maybe the following helps someone else browsing for this:
soap-server.php:
<?php
class MySoapServer {
public function getMessage ()
{
return "Hello world!";
}
public function add ($n1,$n2)
{
return $n1+n2;
}
}
$option = array ('uri' => 'http://example.org/stacky/soap-server');
$server = new SoapServer(null,$option);
$server->setClass('MySoapServer');
$server->handle();
?>
and soap-client.php
<?php
$options = array ('uri' => 'http://example.org/stacky/soap-server',
'location' => 'http://localhost/soap-server.php');
$client = new SoapClient(null,$options);
echo $client ->getMessage();
echo "<br>";
echo $client ->add(41,1);
?>