How can I use my session database with Zend's Session Manager? - php

When the Zend Session Manager from the tutorial starts a session, it generates a session key and posts a whole lot of data into the session. But I have a session system already set up with my own session keys and a different set of session data. How can I change the Zend configuration to use mine instead?
For reference, here is the Zend Session:
array (size=2)
'__ZF' =>
array (size=2)
'_REQUEST_ACCESS_TIME' => float 1468447555.1396
'_VALID' =>
array (size=3)
'Zend\Session\Validator\Id' => string 'xxxxxxxxxxxxxxxxxxxxxxxxxx' (length=26)
'Zend\Session\Validator\RemoteAddr' => string '--ip addr--' (length=13)
'Zend\Session\Validator\HttpUserAgent' => string '--user agent info--' (length=114)
'initialized' =>
object(Zend\Stdlib\ArrayObject)[371]
protected 'storage' =>
array (size=3)
'init' => int 1
'remoteAddr' => string '--ip addr--' (length=13)
'httpUserAgent' => string '--user agent info--' (length=114)
protected 'flag' => int 2
protected 'iteratorClass' => string 'ArrayIterator' (length=13)
protected 'protectedProperties' =>
array (size=4)
0 => string 'storage' (length=7)
1 => string 'flag' (length=4)
2 => string 'iteratorClass' (length=13)
3 => string 'protectedProperties' (length=19)
And here's what the session information I'm currently storing looks like (it's in a database, so I currently reference it with a Doctrine Entity):
object(MyModule\Entity\MySession)[550]
protected 'sessionid' => string 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' (length=40)
protected 'data1' => string 'xxxxx' (length=5)
protected 'data2' => string 'xxxxxxxxxxxx' (length=12)
protected 'datatime' =>
object(DateTime)[547]
public 'date' => string '2016-07-13 17:05:52.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'xxxxxxxxxxxxxxx' (length=15)
protected 'data3' => boolean false
protected 'data4' => string '' (length=0)
protected 'data5' => int 9
protected 'data6' => int 17765
protected 'data7' => boolean false
My code for the session manager comes from this SO answer, so I'm providing a link rather than repasting it and cluttering up this question.
The reason I want to use Zend Session Manager rather than simply referencing my stored session information with Doctrine is so that I have a layer between the my program and the stored session information - so then I can change the way I access the session information without having to change my entire program.

I ended up solving this on my own by extending the SessionManager, SessionStorage, and SessionSaveHandler classes and rewriting some of the functionality. I also changed the Module.php and module.config.php files. This is what the changes look like:
module.config.php
<?php
/* ...required use statements... */
return array(
'session' => array(
'config' => array(
'class' => 'Zend\Session\Config\SessionConfig',
'options' => array(
'name' => [my session name],
),
),
'storage' => 'MySession\Model\MySessionStorage',
'save_handler' => 'MySession\Model\MySessionSaveHandler'
),
'service_manager' => array(
'factories' => array(
'session_service' => function($serviceManager) {
$entityManager = $serviceManager->get('Doctrine\ORM\EntityManager');
return new SessionService($entityManager, 'MySession');
},
'MySession\Model\MySessionSaveHandler' => function($serviceManager) {
$sess = $serviceManager->get('onmysession_service');
/* #var $adapter \Zend\Db\Adapter\Adapter */
$adapter = $sm->get('Zend\Db\Adapter\Adapter');
$tableGateway = new TableGateway('mytablename', $adapter);
return new MySessionSaveHandler($tableGateway, new DbTableGatewayOptions(), $sess);
},
'MySessionManager' => function ($sm) {
$config = $sm->get('config');
if (isset($config['session'])) {
$session = $config['session'];
$sessionConfig = null;
if (isset($session['config'])) {
$class = isset($session['config']['class']) ? $session['config']['class'] : 'Zend\Session\Config\SessionConfig';
$options = isset($session['config']['options']) ? $session['config']['options'] : array();
$sessionConfig = new $class();
$sessionConfig->setOptions($options);
}
$sessionStorage = null;
if (isset($session['storage'])) {
$class = $session['storage'];
$sessionStorage = new $class();
}
$sessionSaveHandler = null;
if (isset($session['save_handler'])) {
// class should be fetched from service manager since it will require constructor arguments
$sessionSaveHandler = $sm->get($session['save_handler']);
}
$sessionManager = new MySessionManager($sessionConfig, $sessionStorage, $sessionSaveHandler);
} else {
$sessionManager = new MySessionManager();
}
MySession::setDefaultManager($sessionManager);
return $sessionManager;
},
),
),
'db' => array(
[db info here]
),
/***************************************************************************************************************
* Below is the doctrine configuration which holds information about the entities in this module and some
* other doctrine stuff like orm drivers etc.
***************************************************************************************************************/
'doctrine' => array(
'driver' => array(
'session_entities' => array(
'class' =>'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(__DIR__ . '/../src/MySession/Entity')
),
'orm_default' => array(
'drivers' => array(
'MySession\Entity' => 'session_entities'
),
),
),
),
);
Module.php
<?php
namespace MySession;
/* ...required use statements... */
/***************************************************************************************************
* This class holds a few utility functions related to loading the module and accessing config
* files for the module etc. These functions are primarily used by Zend under the hood.
***************************************************************************************************/
class Module implements AutoloaderProviderInterface, ConfigProviderInterface
{
public function onBootstrap(MvcEvent $e) {
$eventManager = $e->getApplication()->getEventManager();
// create the session manager
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$sessionManager = $e->getApplication()
->getServiceManager()
->get('MySessionManager');
$sessionManager ->start();
// attach dispatch listener to validate user session
$eventManager->attach(MvcEvent::EVENT_DISPATCH, array($sessionManager, 'handleSessionValidation')); // TODO: we already handleSessionValidation on bootstrap, find out if it's necessary to do it on dispatch as well
}
/***************************************************************************************************
* Returns the location of the module.config.php file. This function is used by the Zend Framework
* underneath the hood.
***************************************************************************************************/
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
/***************************************************************************************************
* Returns the Zend StandardAutoLoader which contains the directory structure of the module source
* folder.
***************************************************************************************************/
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
}
MySessionManager
<?php
namespace MySession\Model;
/* ...required use statements... */
class MySessionManager extends SessionManager
{
/**
* Is this session valid?
*
* A simple validation: checks if a row for the session name exists in the database
*
* #return bool
*/
public function isValid()
{
$id = $_COOKIE[SessionVariableNames::$SESSION_NAME];
return !is_null($this->getSaveHandler()->readMetadata($id));
}
/**
* checks if the session is valid and dies if not.
*/
public function handleSessionValidation() {
if(stristr($_SERVER["SCRIPT_NAME"],"login.php"))
{
// we don't need to check the session at the login page
return;
}
if (!$this->isValid()) {
die("Not logged in.")
}
}
/**
* Start session
*
* If no session currently exists, attempt to start it. Calls
* {#link isValid()} once session_start() is called, and raises an
* exception if validation fails.
*
* #param bool $preserveStorage If set to true, current session storage will not be overwritten by the
* contents of $_SESSION.
* #return void
* #throws RuntimeException
*/
public function start($preserveStorage = false)
{
if ($this->sessionExists()) {
return;
}
$saveHandler = $this->getSaveHandler();
if ($saveHandler instanceof SaveHandlerInterface) {
// register the session handler with ext/session
$this->registerSaveHandler($saveHandler);
}
// check if old session data exists and merge it with new data if so
$oldSessionData = [];
if (isset($_SESSION)) {
$oldSessionData = $_SESSION;
}
session_start();
if ($oldSessionData instanceof \Traversable
|| (! empty($oldSessionData) && is_array($oldSessionData))
) {
$_SESSION = ArrayUtils::merge($oldSessionData, $_SESSION, true); // this may not act like you'd expect, because the sessions are stored in ArrayObjects, so the second will always overwrite the first
}
$storage = $this->getStorage();
// Since session is starting, we need to potentially repopulate our
// session storage
if ($storage instanceof SessionStorage && $_SESSION !== $storage) {
if (!$preserveStorage) {
$storage->fromArray($_SESSION);
}
$_SESSION = $storage;
} elseif ($storage instanceof StorageInitializationInterface) {
$storage->init($_SESSION);
}
$this->handleSessionValidation();
}
/**
* Write session to save handler and close
*
* Once done, the Storage object will be marked as isImmutable.
*
* #return void
*/
public function writeClose()
{
// The assumption is that we're using PHP's ext/session.
// session_write_close() will actually overwrite $_SESSION with an
// empty array on completion -- which leads to a mismatch between what
// is in the storage object and $_SESSION. To get around this, we
// temporarily reset $_SESSION to an array, and then re-link it to
// the storage object.
//
// Additionally, while you _can_ write to $_SESSION following a
// session_write_close() operation, no changes made to it will be
// flushed to the session handler. As such, we now mark the storage
// object isImmutable.
$storage = $this->getStorage();
if (!$storage->isImmutable()) {
$_SESSION = $storage->toArray(true);
$this->saveHandler->writeMetadata(null, '_metadata');
$this->saveHandler->writeData($_SESSION['_data']);
session_write_close();
$storage->fromArray($_SESSION);
$storage->markImmutable();
}
}
}
MySessionStorage
<?php
namespace MySession\Model;
/* ...required use statements... */
class MySessionStorage extends SessionArrayStorage
{
/**
* Set storage metadata
*
* Metadata is used to store information about the data being stored in the
* object. Some example use cases include:
* - Setting expiry data
* - Maintaining access counts
* - localizing session storage
* - etc.
*
* #param string $key
* #param mixed $value
* #param bool $overwriteArray Whether to overwrite or merge array values; by default, merges
* #return ArrayStorage
* #throws Exception\RuntimeException
*/
public function setMetadata($key, $value, $overwriteArray = false)
{
if ($this->isImmutable()) {
throw new Exception\RuntimeException(
sprintf('Cannot set key "%s" as storage is marked isImmutable', $key)
);
}
// set the value
$sessVar = $_SESSION['_metadata'];
if (isset($sessVar[$key]) && is_array($value)) {
// data is array, check if we're replacing the whole array or modify/add to it
if ($overwriteArray) {
$sessVar[$key] = $value;
} else {
$sessVar[$key] = array_replace_recursive($sessVar[$key], $value);
}
} else {
// data is not an array, set or remove it in the session
if ((null === $value) && isset($sessVar[$key])) {
// remove data
$array = $sessVar;
unset($array[$key]);
$_SESSION[SessionVariableNames::$SESSION_METADATA] = $array; // we can't use $sessVar here because it's only a copy of $_SESSION
unset($array);
} elseif (null !== $value) {
// add data
$sessVar[$key] = $value;
}
}
return $this;
}
/**
* Retrieve metadata for the storage object or a specific metadata key
*
* Looks at session db for the metadata
*
* Returns false if no metadata stored, or no metadata exists for the given
* key.
*
* #param null|int|string $key
* #return mixed
*/
public function getMetadata($key = null)
{
if (!isset($_SESSION)) {
return false;
}
if (null === $key) {
return $_SESSION;
}
if (!array_key_exists($key, $_SESSION)) {
return false;
}
return $_SESSION[$key];
}
/**
* Set the request access time
*
* #param float $time
* #return ArrayStorage
*/
protected function setRequestAccessTime($time)
{
// make a metadata write call, since that sets a timestamp
$this->setMetadata('datatime', new DateTime("now"));
return $this;
}
}
MySessionSaveHandler
<?php
namespace MySession\Model;
/* ...required use statements... */
/**
* This class is the back end of the $_SESSION variable, when used together with a SessionStorage and SessionManager in a ZF module
*/
class MySessionSaveHandler implements SaveHandlerInterface
{
protected $sessionService;
private $tableGateway;
private $options;
private $sessionName;
private $sessionSavePath;
private $lifetime;
public function __construct(
TableGateway $tableGateway,
DbTableGatewayOptions $options,
ISessionService $sessionService)
{
$this->tableGateway = $tableGateway;
$this->options = $options;
$this->sessionService = $sessionService;
}
protected function getSessionService()
{
return $this->sessionService;
}
/**
* Read session data
*
* #param string $id
* #return string
*/
public function read($id)
{
// Get data from database
$metadata = $this->readMetadata($id);
// Put data in PHP-session-serialized form
$data = "_metadata|".serialize($metadata);
return $data;
}
/**
* Read session metadata
*
* #param string $id
* #return mixed
*/
public function readMetadata($id = null)
{
if (is_null($id))
{
if (!array_key_exists('sessionid', $_COOKIE))
{
// can't get id from cookie
return null;
}
$id = $_COOKIE['sessionid'];
}
if ($data = $this->getSessionService()->findById($id))
{
return $data->getArrayCopy();
}
return null;
}
/** deprecated, use writeMetadata instead
* Write session data
*
* #param string $id
* #param string $data
* #return bool
* Note sessions use an alternative serialization method.
*/
public function write($id, $data)
{
// don't use this because $data is serialized strangely and can't be automatically inserted into my table
}
/**
* Write session metadata
*
* #param string $id
* #param array $data an associative array matching a row in the table
* #return mixed
*/
public function writeMetadata($id = null, $data = null)
{
if (is_null($id))
{
if (!array_key_exists('sessionid', $_COOKIE))
{
// can't get id from cookie
return null;
}
$id = $_COOKIE['sessionid'];
}
// get the session info from the database so we can modify it
$sessionService = $this->getSessionService();
$session = $sessionService->findByID($id);
if (is_null($session)) {
$session = new \MyModule\Entity\MySession();
}
if (!is_null($data))
{
// overwrite the stored data
$session->setDataFromArray($data);
}
return $sessionService->save($session);
}
/**
* Destroy session - deletes data from session table
*
* #param string $id The session ID being destroyed.
* #return bool
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
*/
public function destroy($id)
{
$this->getSessionService()->delete($id);
return true;
}
/**
* Garbage Collection - cleanup old sessions
*
* #param int $maxlifetime
* Sessions that have not updated for
* the last maxlifetime seconds will be removed.
* #return bool
* The return value (usually TRUE on success, FALSE on failure).
* Note this value is returned internally to PHP for processing.
*/
public function gc($maxlifetime)
{
$metadata = $this->readMetadata(); // gets session id from cookie, then gets session from that
if (!is_null($metadata))
{
$datatime = $metadata['datatime'];
$previousTime = (new DateTime($datatime))->getTimestamp();
// if (current time - datatime) > maxlifetime, destroy the session
$val = time() - $previousTime;
if ($val > $maxlifetime) {
$this->destroy($metadata['sessionid']);
}
}
}
}
The end result of all this is that you can access information stored in the database simply by accessing the $_SESSION variable, because the data gets loaded from the database into the $_SESSION variable on bootstrap, and the $_SESSION variable is written back into the database when the session is closed (which as I understand it, happens when the page is sent to the client).

Related

What are the best practices when redirecting users after OAuth 2.0 token renew?

I have implemented an Mautic API in a website. I use OAuth 2.0 to authenticate the communications between the two. The problem that I have is that I must renew the token from time to time, and in order to do that I have to provide a callback URL, I figured that I just have to use http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI] as my callback URL, that way, when the authentication or renew is done the user would be redirected to the last called URL. The problem is that sometimes the user is being redirected to the login page of the API to authorize the integration. That, to the best of my knowledge, should be done by me, only once.
In short, how can I avoid my users being shown the API authentication screen?
I haven't finished the integration yet; I still must work on some security issues.
The class responsible for doing that is right below:
<?php
use Mautic\Auth\ApiAuth;
use Mautic\MauticApi;
class Mautic
{
private static $instance;
private $publicKey;
private $secretKey;
private $callback;
private $baseURL;
private $Api;
private $ApiURL;
private $auth;
private $token;
private $companyName;
public function __construct()
{
$config = $this->getConfig();
$this->publicKey = $config['publicKey'];
$this->secretKey = $config['secretKey'];
$this->baseURL = $config['baseURL'];
$this->companyName = $config['companyName'];
$this->Api = new MauticApi();
$this->ApiURL = $this->baseURL . '/api/';
if (!$this->isTokenValid()) {
$this->getToken();
}
}
/**
* Read the config file "mautic.json" located in the root directory and returns an array with config values
*
* #return array
*/
private function getConfig(): array
{
return $this->getJSON('mautic.json');
}
/**
* Instantiates a new API class
*
* #param string $apiName
* #return object
*/
private function setApi(string $apiName): object
{
if(!$this->auth){
$this->getToken();
}
return $this->Api->newApi($apiName, $this->auth, $this->ApiURL);
}
/**
* Retorna la instancia de la clase actual
*
* #return object
*/
public static function getInstance(): object
{
if (!self::$instance)
self::$instance = new self();
return self::$instance;
}
public function isTokenValid(): bool
{
$oldTokenExpiration = $this->checkForToken()['expires'];
if (time() >= $oldTokenExpiration) {
return false;
}
return true;
}
private function getToken($accessToken = null, $tokenExpiration = null, $refreshToken = null)
{
if ($previousToken = $this->checkForToken()) {
$settings['accessToken'] = $previousToken['access_token'];
$settings['accessTokenExpires'] = $previousToken['expires'];
$settings['refreshToken'] = $previousToken['refresh_token'];
}
$settings = [
'baseUrl' => $this->baseURL, // Base URL of the Mautic instance
'version' => 'OAuth2', // Version of the OAuth
'clientKey' => $this->publicKey, // Client/Consumer key from Mautic
'clientSecret' => $this->secretKey, // Client/Consumer secret key from Mautic
'callback' => "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"
];
if (isset($accessToken) && isset($tokenExpiration) && isset($refreshToken)) {
}
$initAuth = new ApiAuth();
$auth = $initAuth->newAuth($settings);
// Initiate process for obtaining an access token; this will redirect the user to the authorize endpoint and/or set the tokens when the user is redirected back after granting authorization
if ($auth->validateAccessToken()) {
if ($auth->accessTokenUpdated()) {
$accessTokenData = $auth->getAccessTokenData();
$this->storeToken($accessTokenData);
$this->auth = $auth;
$this->token = $accessTokenData['access_token'];
return $this->auth;
}
}
}
private function storeToken($accessTokenData)
{
$tokenInfo = json_encode($accessTokenData);
file_put_contents("token.json", $tokenInfo);
}
/**
* Read the file "token.json" located in the root directory and returns an array with any passed token values
*
* #return array
*/
private function checkForToken(): array
{
return $this->getJSON('token.json');
}
/**
* Reads a JSON file and returns its key and values as an array
*
* #param string $filePath
* #return array
*/
private function getJSON($filePath): array
{
if (!file_exists($filePath)) {
return false;
}
$oldToken = file_get_contents($filePath);
$oldToken = json_decode($oldToken);
return (array) $oldToken;
}
/**
* Creates a new contact
*
* #param string $name
* #param string $phone
* #param string $email
* #param string $companyName
* #return array
*/
public function createContact(string $name, string $phone, string $email, int $companyName = null): array
{
if ($companyName == null) {
$companyName = $this->getConfig()['companyName'];
}
$data = array(
'firstname' => $name,
'phone' => $phone,
'email' => $email,
'company' => $companyName,
'ipAddress' => $_SERVER['REMOTE_ADDR'],
'overwriteWithBlank' => true,
);
$contactApi = $this->setApi('contacts');
$newContact = $contactApi->create($data);
return $newContact;
}
/**
* Retorna los datos de un contacto
*
* #param int $contactId
* #return object
*/
public function getContact(int $contactId): object
{
return json_decode($this->curlGET("contacts", array($contactId)));
}
/**
* Ejecuta una requisición GET al servidor de la API
*
* #param string $APIMethod
* #param array $dataToSend
* #return string
*/
private function curlGET(string $APIMethod, array $dataToSend = array()): string
{
$dataToSend["access_token"] = $this->token;
$baseURL = $this->ApiURL . $APIMethod;
$curl = curl_init();
$curlOptions = array(
CURLOPT_URL => $baseURL . '?' . http_build_query($dataToSend),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false
);
curl_setopt_array($curl, $curlOptions);
$returnedData = curl_exec($curl);
if (!$returnedData) {
return curl_error($curl);
} else {
curl_close($curl);
return $returnedData;
}
}
}
The problem seems to be re-authentication. Once you authenticate successfully you should not need to do that again and again.
You get Token, Token Expires and Refresh Token when the process is complete. Here's complete example(https://tutorialsjoint.com/mautic-rest-api/).
Once you have the token and you are checking if token is expired, you should use refresh token to obtain fresh access token. For some reason if your refresh token becomes invalid then only you need to re-authenticate, that usually happens when you change the client credentials.
In your code I see you are doing authentication But can't see refresh token call, that should be your issue here.

ZF2 Cookies for affiliates

I am attempting to write a cookie class to store referral information and need a bit of guidance.
The documentation on this seems a little sparse.
As with any affiliate programme, the idea is to grab information from a link: http://example.com/referrer_id=123 and to store this on the users computer for later use.
So this is what I have thus far:
Controller:
$cookieObject = new CookieService();
$cookieObject->setCookie(
[
'value' => [
'name' => 'test',
'referring_site'=>'test site'
]
]
);
die(var_dump($cookieObject->getCookie()));
CookieService class:
<?php
namespace Application\Library\Session;
use Zend\Http\Header\SetCookie;
use Zend\Http\Cookies;
class CookieService extends SetCookie
{
public function __construct() {
$this->cookie = new SetCookie();
$this->header = new Cookies();
}
/**
* Create a new cookie
* #param $params
*/
public function setCookie($params)
{
$key = (isset($params['key'])) ? $params['key'] : 'referrer';
$value = (isset($params['value'])) ? $params['value'] : [];
$expires = (isset($params['time'])) ? time() + $params['time'] : time() + 365 * 60 * 60 * 24;
/**
* Test whether the cookie exists before updating
*/
if (!$this->exists($key))
{
$this->cookie->setName($key);
$this->cookie->setValue($value);
$this->cookie->setExpires($expires);
$this->header->addCookie($this->cookie);
}
}
/**
* Get a cookie based on a given key
* #param string $key
* #return null
*/
public function getCookie($key = 'referrer')
{
$cookieArray = $this->header->getAllCookies();
foreach ($cookieArray AS $cookie)
{
if ($cookie->name === $key)
{
return $cookie;
}
}
return null;
}
/**
* Returns whether a cookie exists or not
* #param $key
* #return bool
*/
public function exists($key)
{
return ( $this->getCookie($key) ) ? true : false;
}
}
I am struggling with the following:
If I save a cookie then close the browser, the cookie is deleted. I can't seem to find any documentation that clearly covers this use.
Any advice, greatly appreciated.
ND: The dump of the cookie object:
object(Zend\Http\Header\SetCookie)[1085]
protected 'name' => string 'referrer' (length=8)
protected 'value' =>
array (size=2)
'name' => string 'test' (length=4)
'referring_site' => string 'test site' (length=9)
protected 'version' => null
protected 'maxAge' => null
protected 'expires' => int 1475931242
protected 'domain' => null
protected 'path' => null
protected 'secure' => boolean false
protected 'quoteFieldValue' => boolean false
protected 'httponly' => boolean false
public 'type' => string 'Cookie' (length=6)
Ok - so I have written my own class to deal with this. It is pretty simple:
<?php
namespace Application\Library\Session;
/**
* Use this service to set persistent cookies on a users machine
* Class CookieService
* #package Application\Library\Session
*/
class CookieService
{
/**
* Create a new cookie
* #param $params
*/
public function setCookie($params)
{
$name = (isset($params['name'])) ? $params['name'] : 'referrer';
$value = (isset($params['value'])) ? $params['value'] : '';
$expire = (isset($params['expire'])) ? time() + $params['expire'] : time() + 365 * 60 * 60 * 24;
$path = (isset($params['path'])) ? $params['path'] : '';
$domain = (isset($params['domain'])) ? $params['domain'] : '';
$secure = (isset($params['secure'])) ? $params['secure'] : 0;
$httponly = (isset($params['httponly'])) ? $params['httponly'] : 1;
/**
* Test whether the cookie exists before updating
*/
if (!$this->exists($name))
{
setcookie(
$name,
$value,
$expire ,
$path ,
$domain ,
$secure ,
$httponly
);
}
}
/**
* Get a cookie based on a given key
* #param string $name
* #return null
*/
public function getCookie($name = 'referrer')
{
return (isset($_COOKIE[$name])) ? $_COOKIE[$name] : null;
}
/**
* Returns whether a cookie exists or not
* #param $name
* #return bool
*/
public function exists($name)
{
return ( $this->getCookie($name) ) ? true : false;
}
/**
* Remove a cookie
* #param $name
*/
function deleteCookie($name)
{
if ($this->exists($name))
{
setcookie($name, "", time()-(60*60*24) );
}
}
}

Phalcon ORM doesn't work

I am learning phalcon. I have some problems with models.
Function FindFirst returns nothing, also it doesn't show any errors or exceptions. Here is my code:
public function indexAction()
{
$user = Users::findFirst(1);
var_dump($user);
}
And all what I get - is empty page.
Here is my Users Model:
<?php
namespace Models\User;
use Phalcon\Mvc\Model\Validator\Email as Email;
class Users extends \Phalcon\Mvc\Model
{
/**
*
* #var integer
*/
public $id;
/**
*
* #var string
*/
public $login;
/**
*
* #var string
*/
public $email;
public function initialize()
{
$this->setSource("users");
}
/**
* Validations and business logic
*/
public function validation()
{
$this->validate(
new Email(
array(
'field' => 'email',
'required' => true,
)
)
);
if ($this->validationHasFailed() == true) {
return false;
}
}
/**
* Independent Column Mapping.
* Keys are the real names in the table and the values their names in the application
*
* #return array
*/
public function columnMap()
{
return array(
'id' => 'id',
'login' => 'login',
'email' => 'email'
);
}
}
Some additional information:
I have edited config files.
Phalcon version is 2.0
First you should ensure that the User model you are trying to load is in the right namespace, what means in your case you should use:
$user = \Models\User\Users::findFirst(1);
And to retrieve an output (depending on your index.php but probably this way) you should return "something", otherwise the buffer will be empty and nothing will be displayed.

how to create session in php with mongodb

in node.js i will create mongodb session like this.
app.configure(function()
{
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({
secret: 'MY SECRET',
store: new MongoStore({
db: 'MY SESSION DB',
host: 'localhost',
port:88888
})
}));
app.use(everyauth.middleware());
app.use(express.methodOverride());
app.use(app.router);
});
how to create session with mongodb in php.i am new one for php..i want to create session with mongodb in php(webserver: apache),so let me know how to create
You must use a session handler to accomplish this. Normally we don't answer these sort of questions which lack research of any kind but, this one time, here is a small, extremely simple, self contained edition I have:
class Session{
public $db;
/**
* This decides the lifetime (in seconds) of the session
*
* #access private
* #var int
*/
public $life_time='+2 weeks';
/**
* This stores the found session collection so that we don't
* waste resources by constantly going back for it
*
* #access private
* #var sessions
*/
private $_session = array();
/**
* Constructor
*/
function open() {
// Ensure index on Session ID
$this->db->sessions->ensureIndex(array('session_id' => 1), array("unique" => true));
// Register this object as the session handler
session_set_save_handler(
array( $this, "openSession" ),
array( $this, "closeSession" ),
array( $this, "readSession" ),
array( $this, "writeSession"),
array( $this, "destroySession"),
array( $this, "gcSession" )
);
session_start(); // Start the damn session
}
/**
* Open session
*
* This function opens a session from a save path.
* The save path can be changed the method of opening also can
* but we do not change that we just do the basics and return
*
* #param string $save_path
* #param string $session_name
*/
function openSession( $save_path, $session_name ) {
global $sess_save_path;
$sess_save_path = $save_path;
// Don't need to do anything. Just return TRUE.
return true;
}
/**
* This function closes the session (end of session)
*/
function closeSession() {
// Return true to indicate session closed
return true;
}
/**
* This is the read function that is called when we open a session.
* This function attempts to find a session from the Db. If it cannot then
* the session class variable will remain null.
*
* #param string $id
*/
function readSession( $id ) {
// Set empty result
$data = '';
// Fetch session data from the selected database
$time = time();
$this->_sessions = $this->db->sessions->findOne(array("session_id"=>$id));
if (!empty($this->_sessions)) {
$data = $this->_sessions['session_data'];
}
return $data;
}
/**
* This is the write function. It is called when the session closes and
* writes all new data to the Db. It will do two actions depending on whether or not
* a session already exists. If the session does exist it will just update the session
* otherwise it will insert a new session.
*
* #param string $id
* #param mixed $data
*
* #todo Need to make this function aware of other users since php sessions are not always unique maybe delete all old sessions.
*/
function writeSession( $id, $data ) {
//Write details to session table
$time = strtotime('+2 weeks');
// If the user is logged in record their uid
$uid = $_SESSION['logged'] ? $_SESSION['uid'] : 0;
$fields = array(
"session_id"=>$id,
"user_id"=>$uid,
"session_data"=>$data,
"expires"=>$time,
"active"=>1
);
$fg = $this->db->sessions->update(array("session_id"=>$id), array('$set'=>$fields), array("upsert"=>true));
// DONE
return true;
}
/**
* This function is called when a user calls session_destroy(). It
* kills the session and removes it.
*
* #param string $id
*/
function destroySession( $id ) {
// Remove from Db
$this->db->sessions->remove(array("session_id" => $id), true);
return true;
}
/**
* This function GCs (Garbage Collection) all old and out of date sessions
* which still exist in the Db. It will remove by comparing the current to the time of
* expiring on the session record.
*
* #todo Make a cronjob to delete all sessions after about a day old and are still inactive
*/
function gcSession() {
$this->db->sessions->remove(array('expires' => array('$lt' => strtotime($this->life_time))));
return true;
}
}
Which can be called like so:
$session = new Session;
$session->db=$mongo->my_db;
$session->open();
It is a very basic example of how to do this.
Afterwards you can just use it like a normal session like so:
$_SESSION['user_id'] = $id;

PHP PDO custom class returning an object and not what it should

So I made a database class to handle all of my database requests. Everything goes through the constructor and it should return values.
The class is so
<?php
class Database {
/**
* This array holds all of the configuration settings for the database
* #var array
*/
private $config = array(
'username' => '',
'password' => '',
'host' => '',
'database' => ''
);
/**
* Holds the parameters passed to the class
* #var mixed
*/
private $parameters;
/**
* Database Handler
* #var [type]
*/
private $DBH;
/**
* Class constructor
* #param [type] $action [description]
* #param [type] $parameters [description]
*/
public function __construct($action, $parameters){
$this->parameters = $parameters;
$this->DBH = new PDO("mysql:host=".$this->config['host'].";dbname=".$this->config['database'], $this->config['username'], $this->config['password']);
return $this->$action();
}
private function query(){
$STH = $this->DBH->prepare($this->parameters);
$STH->execute();
$result = $STH->fetchColumn();
echo "<br><br>RESULT:".$result."<br><br><br>";
echo "<br><br>RESULT:".empty($result)."<br><br><br>";
return (empty($result)) ? FALSE : TRUE;
}
}
I removed everything bar the function giving issues. It is meant to return true or false. Instead the return value when I call $result = new Database('query', $query); is an object with a ton of data
Any idea what I have done wrong?
PHP ignores what you return in __construct. If you create a new object with new then the new object is returned and not what the return in __construct says.
To achieve what you want you have to create a new function which executes the action for you outside of the constructor - like that:
class Database {
// your code...
public function __construct($parameters) {
$this->parameters = $parameters;
$this->DBH = new PDO("mysql:host=".$this->config['host'].
";dbname=".$this->config['database'],
$this->config['username'],
$this->config['password']);
}
public function perform($action) {
return $this->$action();
}
// rest of your code...
}
// usage:
$db = new Database($query);
$result = $db->perform('query'); // result should be a boolean.
__construct is suposed to return the newly created object. This behaviour cannot be overriden. See usage.
Btw, this is the behaviour for most OOP languages when the new operator is involved.

Categories