I retrieve data from Zend 2 session container on layout via bootstarp method.
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$sm = $e->getApplication()->getServiceManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$user = $this->getUser($sm);
$viewModel = $e->getApplication()->getMvcEvent()->getViewModel();
$viewModel->user = ($user) ? $user: false;
}
public function getUser($sm)
{
$user= false;
$userTable= $sm->get('User\Model\UserTable');
$userSession = new Container('userSession');
//RETRIEVE USER FROM DB
return $user;
}
Now i'm getting following error sometimes (not always)
Fatal error: Uncaught exception 'Zend\Stdlib\Exception\InvalidArgumentException' with message 'Passed variable is not an array or object, using empty array instead' in /var/www/T2oRecruitment/app/vendor/zendframework/zendframework/library/Zend/Stdlib/ArrayObject.php:184 Stack trace: #0
/var/www/T2oRecruitment/app/vendor/zendframework/zendframework/library/Zend/Stdlib/ArrayObject.php(411): Zend\Stdlib\ArrayObject->exchangeArray(NULL) #1 [internal function]: Zend\Stdlib\ArrayObject->unserialize('a:4:{s:7:"stora...') #2
/var/www/T2oRecruitment/app/vendor/zendframework/zendframework/library/Zend/Session/SessionManager.php(95): session_start() #3
/var/www/T2oRecruitment/app/vendor/zendframework/zendframework/library/Zend/Session/AbstractContainer.php(78): Zend\Session\SessionManager->start() #4
/var/www/T2oRecruitment/app/module/Application/Module.php(22): Zend\Session\AbstractContainer->__construct('userSession') #5
/var/www/T2oRecruitment/app/module/Application/Module.php(43): Application\Module->getUser(Object(Zend\S in /var/www/T2oRecruitment/app/vendor/zendframework/zendframework/library/Zend/Stdlib/ArrayObject.php on line 184
What is the issue ?
Please try with this:
In Module.php file --->
use Zend\Session\Config\SessionConfig, Zend\Session\SessionManager,
Zend\Session\Container, Zend\Mvc\MvcEvent;
// other libraries
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$sm = $e->getApplication()->getServiceManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$config = $sm->get('Config');
$sessionConfig = new SessionConfig();
$sessionConfig->setOptions($config['session']);
$sessionManager = new SessionManager($sessionConfig);
$sessionManager->start();
$user = $this->userSession($sm);
$viewModel = $e->getApplication()->getMvcEvent()->getViewModel();
$viewModel->user = ($user) ? $user: false;
}
In module.config.php file --->
return array(
'session' => array(
'remember_me_seconds' => 2419200,
'use_cookies' => true,
'cookie_httponly' => true
),
);
Hope, this will give some idea to you, for fixing your issue. Thanks :)
There is official bug https://github.com/zendframework/zf2/issues/4821
it's still open, but you can check the progress...
Related
index.php
require "vendor/autoload.php";
require "routes.php";
routes.php
<?php
require "vendor/autoload.php";
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGenerator;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
try {
$form_add_route = new Route(
'/blog/add',
array(
'controller' => '\HAPBlog\Controller\EntityAddController',
'method'=>'load'
)
);
$routes = new RouteCollection();
$routes->add('blog_add', $form_add_route);
// Init RequestContext object
$context = new RequestContext();
$context->fromRequest(Request::createFromGlobals());
$matcher = new UrlMatcher($routes, $context);
$parameters = $matcher->match($context->getPathInfo());
// How to generate a SEO URL
$generator = new UrlGenerator($routes, $context);
$url = $generator->generate('blog_add');
echo $url;
}
catch (Exception $e) {
echo '<pre>';
print_r($e->getMessage());
}
src/Controller/EntityAddController.php
<?php
namespace HAPBlog\Controller;
use Symfony\Component\HttpFoundation\Response;
class EntityAddController {
public function load() {
return new Response('ENTERS');
}
}
I am referring to the tutorial given below:
https://code.tutsplus.com/tutorials/set-up-routing-in-php-applications-using-the-symfony-routing-component--cms-31231
But when I try to access the site http://example.com/routes.php/blog/add
It gives a blank page.
Debugging via PHPStorm shows that it does not enter "EntityAddController" Class
What is incorrect in the above code ?
There is no magic behind this process, once you get the route information, you will have to call the configured controller and send the response content.
Take a complete example here:
// controllers.php
class BlogController
{
public static function add(Request $request)
{
return new Response('Add page!');
}
}
// routes.php
$routes = new RouteCollection();
$routes->add('blog_add', new Route('/blog/add', [
'controller' => 'BlogController::add',
]));
// index.php
$request = Request::createFromGlobals();
$context = new RequestContext();
$context->fromRequest($request);
$matcher = new UrlMatcher($routes, $context);
try {
$attributes = $matcher->match($request->getPathInfo());
$response = $attributes['controller']($request);
} catch (ResourceNotFoundException $exception) {
$response = new Response('Not Found', 404);
} catch (Exception $exception) {
$response = new Response('An error occurred', 500);
}
$response->send();
I am using Module.php onBootstrapfunction to check using authentication. on Postman and with browser everything works fine but when unittesting with zend-test it is not able to access the getHeaders()
MY Module.php
public function onBootstrap(MvcEvent $e)
{
$app = $e->getTarget();
$locator = $app->getServiceManager();
$this->authorize($e);
}
public function authorize($e){
$sm = $e->getApplication()->getServiceManager();
$request = $sm->get('Request');
if($request->getHeaders('auth_token')){
return;
}
$response = $e->getResponse();
$model = new JsonModel(array(
"httpStatus" => 401,
"title" => "Token Not Found",
));
$e->getResponse()->setStatusCode(401);
$model->detail = "Auth Token not provided";
$model->setTerminal(true);
$e->setResult($model);
$e->setViewModel($model);
}
Now i tried to follow this but i couldn't because the code is so difficult to follow.
My test is something like that:
public function testIndexIsAccessibleAction() {
$headers = new \Zend\Http\Headers();
$headers->addHeaders([
"auth_token" => 'token'
]);
$this->getRequest()
->setMethod('GET')
->getHeaders()
->addHeaders($headers);
;
$this->dispatch('/action');
$this->assertResponseStatusCode(200);
}
Now i am checking every request in onBootstrap because nothing is accessible if user is not authentic. How do i do my unit testing correctly. and how should i change it to using Service or Factory?
I try to create a Soap Server in CakePHP 3 but if I want to connent with my client i become error's every time.
I set up the server in a function:
public function view($id) {
$connection = ConnectionManager::get('default');
$user = $connection->execute('SELECT * FROM users WHERE id='.'"'.$id.'"')->fetchAll('assoc');
$obj = new Post;
$this->viewBuilder()->layout = false;
$this->autoRender = false;
ini_set("soap.wsdl_cache_enabled",0); //disable wsdl cache
$server = new SoapServer(null, array(
'uri' => 'http://localhost/test-uri',
'encoding'=>'UTF-8'
)
);
$server->setObject($obj);
$server->handle();
}
in a model I create this function:
namespace App\Model\Entity;
use Cake\ORM\Entity;
use Cake\Utility\Xml;
class Post {
function testfunktion($param){
return $param;
}
}
my client script show this:
$soap = new SoapClient(
null,
array(
"location" => "http://localhost/shop_system/users/view/2",
"uri" => "http://test-uri",
"trace" => 1
)
);
try {
$product = $soap->testfunktion("Michael");
} catch (SoapFault $e) {
echo $e;
print($soap->__getLastResponse());
}
and this is my output:
SoapFault exception: [Client] looks like we got no XML document in C:\xampp\htdocs\shop_system\webroot\client.php:15 Stack trace: #0 C:\xampp\htdocs\shop_system\webroot\client.php(15): SoapClient->__call('testfunktion', Array) #1 C:\xampp\htdocs\shop_system\webroot\client.php(15): SoapClient->testfunktion('Michael') #2 {main}
Notice (8): Undefined index: HTTP_ACCEPT_LANGUAGE [APP/Controller\UsersController.php, line 22]Michael
i dont know what i must do by this error
I want to implement session and cookies in my zend application. Session is working fine within the tabs but when I reopen the browser then sessionId in the cookie changes and my application shows user is not logged in.
Below is the code of Module.php of Application Module.
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$eventManager->attach('dispatch', array($this, 'loadConfiguration' ));
$this->initSession(array(
'remember_me_seconds' => 864000,
'use_cookies' => true,
'cookie_httponly' => true,
'cookie_secure' => false,
));
}
public function initSession($config){
$sessionConfig = new SessionConfig();
$sessionConfig->setOptions($config);
$sessionManager = new SessionManager($sessionConfig);
$sessionManager->start();
Container::setDefaultManager($sessionManager);
}
public function loadConfiguration(MvcEvent $e)
{
$controller = $e->getTarget();
$session = new Container('user_session_data');
if(isset($session->user_id)){
//user is logged in set his data to viewModel
$controller->layout()->user_id = $session->user_id;
$controller->layout()->firstName = $session->firstName;
$controller->layout()->lastName = $session->lastName;
$controller->layout()->profilePicture = $session->profilePicture;
}
}
I access these values in my layout.phtml file. Below is the code to save session data when user is successfully logged in.
$session = new Container('user_session_data');
if($session->user_id){
echo "You are already logged in";
}
// store user details in session
$session->user_id = $responseDataArray['data']['id'];
$session->firstName = $responseDataArray['data']['firstName'];
$session->lastName = $responseDataArray['data']['lastName'];
$session->profilePicture = $responseDataArray['data' ['profilePicture'];
I don't know what I am missing to persist session data.
I am attempting to log a user in programmatically in my functional test on SF 2.7 and FOSUserBundle dev-master. I have already found a good reference to log a user in via SO in this answer - Symfony2 - Tests with FOSUserBundle
The problem is that the second answer, logging the user in programmatically, doesn't work. Here is my code:
<?php
namespace Test\BackEnd\UserBundle\Controller;
use Test\Shared\CoreBundle\Tests\AbstractControllerTest;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Loader;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\ORM\Tools\SchemaTool;
use FA\BackEnd\UserBundle\DataFixtures\ORM\LoadUserData;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\BrowserKit\Cookie;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
class DefaultController extends AbstractControllerTest
{
public function setUp()
{
$this->client = static::createClient();
$container = $this->client->getContainer();
$doctrine = $container->get('doctrine');
$em = $doctrine->getManager();
$schemaTool = new SchemaTool($em);
$metadata = $em->getMetaDataFactory()->getAllMetadata();
// Drop and recreate tables for all entities
$schemaTool->dropSchema($metadata);
$schemaTool->createSchema($metadata);
$loader = new Loader();
$user = new LoadUserData();
$user->setContainer($container);
$loader->addFixture($user);
$purger = new ORMPurger();
$executor = new ORMExecutor($em, $purger);
$executor->execute($loader->getFixtures());
$session = $container->get('session');
$userManager = $container->get('fos_user.user_manager');
$user = $userManager->findUserBy(array('username' => 'test'));
$firewall = 'default';
$token = new UsernamePasswordToken($user, $user->getPassword(), $firewall, $user->getRoles());
self::$kernel->getContainer()->get('security.token_storage')->setToken($token);
$session->set('_security_'.$firewall, serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$this->client->getCookieJar()->set($cookie);
}
public function testProfile()
{
//$this->createAuthorizedClient();
$token = $this->client->getContainer()->get('security.token_storage')->getToken();
$this->client->request('GET', '/profile/');
$this->assertEquals(
200,
$this->client->getResponse()->getStatusCode(),
"/profile isn't accessible"
);
}
}
Whenever I set a break point before the route gets executed, the token is return correctly:
Whenever I get to the function getUser() used by the Controller (http://api.symfony.com/2.7/Symfony/Bundle/FrameworkBundle/Controller/Controller.html#method_getUser) PHPStorm returns an empty token as viewed here:
So I decided to try the following code to log a user in, and it works.
$crawler = $this->client->request('GET', '/login');
$form = $crawler->selectButton('_submit')->form(array(
'_username' => 'test',
'_password' => 'test123',
));
$this->client->submit($form);
$this->client->followRedirect();
Am I not doing something properly whenever I log the user in programmatically? Is the session not being set properly?
Thanks!
Rat
I use this:
protected function createAuthorizedClient()
{
$client = static::createClient();
$container = $client->getContainer();
$session = $container->get('session');
$userManager = $container->get('fos_user.user_manager');
$loginManager = $container->get('fos_user.security.login_manager');
$firewallName = $container->getParameter('fos_user.firewall_name');
$user = $userManager->findUserBy(array('username' => 'USERNAME'));
$loginManager->loginUser($firewallName, $user);
// save the login token into the session and put it in a cookie
$container->get('session')->set('_security_' . $firewallName,
serialize($container->get('security.context')->getToken()));
$container->get('session')->save();
$client->getCookieJar()->set(new Cookie($session->getName(), $session->getId()));
$this->client = $client;
}
and then in your test:
public function testMiInfo()
{
$this->createAuthorizedClient();
//else..
}