Zend 2 After login how to set user - zend-framework2

I have the following code and which works, but now the next step.
How and where do i have to set a session so the script "sees" that the user is already logged in?
if ($form->isValid()) {
$securePass = $this->getUsersTable()->getUserByUsername( $this->params()->fromPost('username') );
if( $securePass ){
$bcrypt = new Bcrypt();
if ($bcrypt->verify( $this->params()->fromPost('password') , $securePass->password)) {
$sm = $this->getServiceLocator();
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$authAdapter = new AuthAdapter(
$dbAdapter,
'users',
'username',
'password'
);
$authAdapter
->setIdentity($securePass->username)
->setCredential($securePass->password);
$result = $authAdapter->authenticate($authAdapter);
echo $result->getIdentity() . "\n\n";
}
else {
}

The Zend way of doing it is to use Authentication component that handles this for you.
http://framework.zend.com/manual/current/en/modules/zend.authentication.intro.html
This will allow you to check if user is logged in (you will have to setup the authentication adapter first):
use Zend\Authentication\AuthenticationService;
// TODO set-up authentication adapter
$auth = new AuthenticationService()
$identity = $auth->getIdentity();
For accessing post data you should also leverage the framework instead of accessing $_POST directly. In your controller:
$this->params()->fromPost('username');
$this->params()->fromPost('password');
This will guide you through the whole process of adding authentication layer to your app:
https://zf2.readthedocs.org/en/latest/modules/zend.authentication.adapter.dbtable.html

Using the AuthenticationService provided by Zend, setting the user in the PHP session is automatically taken care of.
A good thing to understand the authentication mechanism would be to read, and code along with this introduction to authentication:
http://framework.zend.com/manual/current/en/modules/zend.authentication.intro.html#adapters
In a custom AuthenticationAdapter "setting the user in the session", or identity persistence, would be done by returning \Zend\Authentication\Result with the result of the authentication and the user identity in the authenticate() method.
$user = $this->userService->findByEmail($this->email);
if($user !== false) {
if($this->encryption->verify($this->password, $user->getPassword()) {
return new Result(Result::SUCCESS, $user);
}
return new Result(Result::FAILURE, null);
}
$this->userService being the UserService that leads to the UserMapper
(more about Services: http://framework.zend.com/manual/current/en/in-depth-guide/services-and-servicemanager.html)
$user being the User entity with the encrypted password stored
$this->encryption being your encryption method (Zend\Crypt\Password\Bcrypt for example)
$this->email being the email/username provided by the form
$this->password being the password provided by the form
Result being Zend\Authentication\Result
This is an easy approach. More detailed Result types are:
/**
* General Failure
*/
const FAILURE = 0;
/**
* Failure due to identity not being found.
*/
const FAILURE_IDENTITY_NOT_FOUND = -1;
/**
* Failure due to identity being ambiguous.
*/
const FAILURE_IDENTITY_AMBIGUOUS = -2;
/**
* Failure due to invalid credential being supplied.
*/
const FAILURE_CREDENTIAL_INVALID = -3;
/**
* Failure due to uncategorized reasons.
*/
const FAILURE_UNCATEGORIZED = -4;
/**
* Authentication success.
*/
const SUCCESS = 1;

LoginController.php
if ($form->isValid()) {
$securePass = $this->getUsersTable()->getUserByUsername( $this->params()->fromPost('username') );
if( $securePass ){
$bcrypt = new Bcrypt();
if ($bcrypt->verify( $this->params()->fromPost( 'password' ) , $securePass->password ) ) {
$sm = $this->getServiceLocator();
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$authAdapter = new AuthAdapter(
$dbAdapter,
'users',
'username',
'password'
);
$authAdapter->setIdentity($securePass->username)
->setCredential($securePass->password);
$result = $authAdapter->authenticate($authAdapter);
$sesssionData = $authAdapter->getResultRowObject();
$auth = new AuthenticationService();
$storage = $auth->getStorage();
$storage->write($sesssionData);
return $this->redirect()->toRoute('user_list');
}
}
}
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$app = $e->getParam('application');
$app->getEventManager()->attach('render', array($this, 'setLayoutTitle'));
$eventManager->attach(MvcEvent::EVENT_DISPATCH, array($this, 'checkLogin'));
}
public function checkLogin(MvcEvent $e)
{
$iden = new AuthenticationService();
if( $iden->getIdentity() === NULL ){
$matches = $e->getRouteMatch();
$controller = $matches->getParam('controller');
$getController = explode( '\\', $controller );
if( isset( $getController[2] ) && $getController[2] != 'Login' ){
$controller = $e->getTarget();
return $controller->plugin('redirect')->toRoute('login');
}
}
}

Related

Netsuite OAuth Not Working

I've tried implementing Netsuite's OAuth Example, as illustrated here: https://netsuite.custhelp.com/app/answers/detail/a_id/42165. I've posted it directly below so you don't have to go to the page if you don't want.
Unfortunately, it's not working. I know that I have the correct token and consumer key's and secrets, and the correct account ID. It's giving me a nice error though:
{"error" : {"code" : "INVALID_LOGIN_ATTEMPT", "message" : "Invalid login attempt."}}
I can look in my login audits, and see that it's saying that the signature is invalid. But the code itself looks fine and was provided by Netsuite.
I've also tried some approaches in Node.JS and haven't gotten them working. Any suggestions as to which direction I should go next?
import oauth2 as oauth
import requests
import time
url = "https://rest.netsuite.com/app/site/hosting/restlet.nl?script=992&deploy=1"
token = oauth.Token(key="080eefeb395df81902e18305540a97b5b3524b251772adf769f06e6f0d9dfde5", secret="451f28d17127a3dd427898c6b75546d30b5bd8c8d7e73e23028c497221196ae2")
consumer = oauth.Consumer(key="504ee7703e1871f22180441563ad9f01f3f18d67ecda580b0fae764ed7c4fd38", secret="b36d202caf62f889fbd8c306e633a5a1105c3767ba8fc15f2c8246c5f11e500c")
http_method = "GET"
realm="ACCT123456"
params = {
'oauth_version': "1.0",
'oauth_nonce': oauth.generate_nonce(),
'oauth_timestamp': str(int(time.time())),
'oauth_token': token.key,
'oauth_consumer_key': consumer.key
}
req = oauth.Request(method=http_method, url=url, parameters=params)
signature_method = oauth.SignatureMethod_HMAC_SHA1()
req.sign_request(signature_method, consumer, token)
header = req.to_header(realm)
headery = header['Authorization'].encode('ascii', 'ignore')
headerx = {"Authorization": headery, "Content-Type":"application/json"}
print(headerx)
conn = requests.get("https://rest.netsuite.com/app/site/hosting/restlet.nl?script=992&deploy=1",headers=headerx)
print(conn.text)
I've also implemented a few Node.JS samples (that haven't worked either). Here is one of them (CryptoJS HMAC-SHA1 and HMAC-SHA256 are on top, then the oauth-1.0a library, and then the code provided by Netsuite with a few small changes to make it work (added a hash_function, renamed 'public' to 'key'):
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
var CryptoJS=CryptoJS||function(g,l){var e={},d=e.lib={},m=function(){},k=d.Base={extend:function(a){m.prototype=this;var c=new m;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
p=d.WordArray=k.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=l?c:4*a.length},toString:function(a){return(a||n).stringify(this)},concat:function(a){var c=this.words,q=a.words,f=this.sigBytes;a=a.sigBytes;this.clamp();if(f%4)for(var b=0;b<a;b++)c[f+b>>>2]|=(q[b>>>2]>>>24-8*(b%4)&255)<<24-8*((f+b)%4);else if(65535<q.length)for(b=0;b<a;b+=4)c[f+b>>>2]=q[b>>>2];else c.push.apply(c,q);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
32-8*(c%4);a.length=g.ceil(c/4)},clone:function(){var a=k.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],b=0;b<a;b+=4)c.push(4294967296*g.random()|0);return new p.init(c,a)}}),b=e.enc={},n=b.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],f=0;f<a;f++){var d=c[f>>>2]>>>24-8*(f%4)&255;b.push((d>>>4).toString(16));b.push((d&15).toString(16))}return b.join("")},parse:function(a){for(var c=a.length,b=[],f=0;f<c;f+=2)b[f>>>3]|=parseInt(a.substr(f,
2),16)<<24-4*(f%8);return new p.init(b,c/2)}},j=b.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],f=0;f<a;f++)b.push(String.fromCharCode(c[f>>>2]>>>24-8*(f%4)&255));return b.join("")},parse:function(a){for(var c=a.length,b=[],f=0;f<c;f++)b[f>>>2]|=(a.charCodeAt(f)&255)<<24-8*(f%4);return new p.init(b,c)}},h=b.Utf8={stringify:function(a){try{return decodeURIComponent(escape(j.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return j.parse(unescape(encodeURIComponent(a)))}},
r=d.BufferedBlockAlgorithm=k.extend({reset:function(){this._data=new p.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=h.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,b=c.words,f=c.sigBytes,d=this.blockSize,e=f/(4*d),e=a?g.ceil(e):g.max((e|0)-this._minBufferSize,0);a=e*d;f=g.min(4*a,f);if(a){for(var k=0;k<a;k+=d)this._doProcessBlock(b,k);k=b.splice(0,a);c.sigBytes-=f}return new p.init(k,f)},clone:function(){var a=k.clone.call(this);
a._data=this._data.clone();return a},_minBufferSize:0});d.Hasher=r.extend({cfg:k.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){r.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,d){return(new a.init(d)).finalize(b)}},_createHmacHelper:function(a){return function(b,d){return(new s.HMAC.init(a,
d)).finalize(b)}}});var s=e.algo={};return e}(Math);
(function(){var g=CryptoJS,l=g.lib,e=l.WordArray,d=l.Hasher,m=[],l=g.algo.SHA1=d.extend({_doReset:function(){this._hash=new e.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(d,e){for(var b=this._hash.words,n=b[0],j=b[1],h=b[2],g=b[3],l=b[4],a=0;80>a;a++){if(16>a)m[a]=d[e+a]|0;else{var c=m[a-3]^m[a-8]^m[a-14]^m[a-16];m[a]=c<<1|c>>>31}c=(n<<5|n>>>27)+l+m[a];c=20>a?c+((j&h|~j&g)+1518500249):40>a?c+((j^h^g)+1859775393):60>a?c+((j&h|j&g|h&g)-1894007588):c+((j^h^
g)-899497514);l=g;g=h;h=j<<30|j>>>2;j=n;n=c}b[0]=b[0]+n|0;b[1]=b[1]+j|0;b[2]=b[2]+h|0;b[3]=b[3]+g|0;b[4]=b[4]+l|0},_doFinalize:function(){var d=this._data,e=d.words,b=8*this._nDataBytes,g=8*d.sigBytes;e[g>>>5]|=128<<24-g%32;e[(g+64>>>9<<4)+14]=Math.floor(b/4294967296);e[(g+64>>>9<<4)+15]=b;d.sigBytes=4*e.length;this._process();return this._hash},clone:function(){var e=d.clone.call(this);e._hash=this._hash.clone();return e}});g.SHA1=d._createHelper(l);g.HmacSHA1=d._createHmacHelper(l)})();
(function(){var g=CryptoJS,l=g.enc.Utf8;g.algo.HMAC=g.lib.Base.extend({init:function(e,d){e=this._hasher=new e.init;"string"==typeof d&&(d=l.parse(d));var g=e.blockSize,k=4*g;d.sigBytes>k&&(d=e.finalize(d));d.clamp();for(var p=this._oKey=d.clone(),b=this._iKey=d.clone(),n=p.words,j=b.words,h=0;h<g;h++)n[h]^=1549556828,j[h]^=909522486;p.sigBytes=b.sigBytes=k;this.reset()},reset:function(){var e=this._hasher;e.reset();e.update(this._iKey)},update:function(e){this._hasher.update(e);return this},finalize:function(e){var d=
this._hasher;e=d.finalize(e);d.reset();return d.finalize(this._oKey.clone().concat(e))}})})();
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
var CryptoJS=CryptoJS||function(h,s){var f={},g=f.lib={},q=function(){},m=g.Base={extend:function(a){q.prototype=this;var c=new q;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
r=g.WordArray=m.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=s?c:4*a.length},toString:function(a){return(a||k).stringify(this)},concat:function(a){var c=this.words,d=a.words,b=this.sigBytes;a=a.sigBytes;this.clamp();if(b%4)for(var e=0;e<a;e++)c[b+e>>>2]|=(d[e>>>2]>>>24-8*(e%4)&255)<<24-8*((b+e)%4);else if(65535<d.length)for(e=0;e<a;e+=4)c[b+e>>>2]=d[e>>>2];else c.push.apply(c,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
32-8*(c%4);a.length=h.ceil(c/4)},clone:function(){var a=m.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],d=0;d<a;d+=4)c.push(4294967296*h.random()|0);return new r.init(c,a)}}),l=f.enc={},k=l.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++){var e=c[b>>>2]>>>24-8*(b%4)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b+=2)d[b>>>3]|=parseInt(a.substr(b,
2),16)<<24-4*(b%8);return new r.init(d,c/2)}},n=l.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b<a;b++)d.push(String.fromCharCode(c[b>>>2]>>>24-8*(b%4)&255));return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b<c;b++)d[b>>>2]|=(a.charCodeAt(b)&255)<<24-8*(b%4);return new r.init(d,c)}},j=l.Utf8={stringify:function(a){try{return decodeURIComponent(escape(n.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return n.parse(unescape(encodeURIComponent(a)))}},
u=g.BufferedBlockAlgorithm=m.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=j.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,d=c.words,b=c.sigBytes,e=this.blockSize,f=b/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0);a=f*e;b=h.min(4*a,b);if(a){for(var g=0;g<a;g+=e)this._doProcessBlock(d,g);g=d.splice(0,a);c.sigBytes-=b}return new r.init(g,b)},clone:function(){var a=m.clone.call(this);
a._data=this._data.clone();return a},_minBufferSize:0});g.Hasher=u.extend({cfg:m.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){u.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(c,d){return(new a.init(d)).finalize(c)}},_createHmacHelper:function(a){return function(c,d){return(new t.HMAC.init(a,
d)).finalize(c)}}});var t=f.algo={};return f}(Math);
(function(h){for(var s=CryptoJS,f=s.lib,g=f.WordArray,q=f.Hasher,f=s.algo,m=[],r=[],l=function(a){return 4294967296*(a-(a|0))|0},k=2,n=0;64>n;){var j;a:{j=k;for(var u=h.sqrt(j),t=2;t<=u;t++)if(!(j%t)){j=!1;break a}j=!0}j&&(8>n&&(m[n]=l(h.pow(k,0.5))),r[n]=l(h.pow(k,1/3)),n++);k++}var a=[],f=f.SHA256=q.extend({_doReset:function(){this._hash=new g.init(m.slice(0))},_doProcessBlock:function(c,d){for(var b=this._hash.words,e=b[0],f=b[1],g=b[2],j=b[3],h=b[4],m=b[5],n=b[6],q=b[7],p=0;64>p;p++){if(16>p)a[p]=
c[d+p]|0;else{var k=a[p-15],l=a[p-2];a[p]=((k<<25|k>>>7)^(k<<14|k>>>18)^k>>>3)+a[p-7]+((l<<15|l>>>17)^(l<<13|l>>>19)^l>>>10)+a[p-16]}k=q+((h<<26|h>>>6)^(h<<21|h>>>11)^(h<<7|h>>>25))+(h&m^~h&n)+r[p]+a[p];l=((e<<30|e>>>2)^(e<<19|e>>>13)^(e<<10|e>>>22))+(e&f^e&g^f&g);q=n;n=m;m=h;h=j+k|0;j=g;g=f;f=e;e=k+l|0}b[0]=b[0]+e|0;b[1]=b[1]+f|0;b[2]=b[2]+g|0;b[3]=b[3]+j|0;b[4]=b[4]+h|0;b[5]=b[5]+m|0;b[6]=b[6]+n|0;b[7]=b[7]+q|0},_doFinalize:function(){var a=this._data,d=a.words,b=8*this._nDataBytes,e=8*a.sigBytes;
d[e>>>5]|=128<<24-e%32;d[(e+64>>>9<<4)+14]=h.floor(b/4294967296);d[(e+64>>>9<<4)+15]=b;a.sigBytes=4*d.length;this._process();return this._hash},clone:function(){var a=q.clone.call(this);a._hash=this._hash.clone();return a}});s.SHA256=q._createHelper(f);s.HmacSHA256=q._createHmacHelper(f)})(Math);
(function(){var h=CryptoJS,s=h.enc.Utf8;h.algo.HMAC=h.lib.Base.extend({init:function(f,g){f=this._hasher=new f.init;"string"==typeof g&&(g=s.parse(g));var h=f.blockSize,m=4*h;g.sigBytes>m&&(g=f.finalize(g));g.clamp();for(var r=this._oKey=g.clone(),l=this._iKey=g.clone(),k=r.words,n=l.words,j=0;j<h;j++)k[j]^=1549556828,n[j]^=909522486;r.sigBytes=l.sigBytes=m;this.reset()},reset:function(){var f=this._hasher;f.reset();f.update(this._iKey)},update:function(f){this._hasher.update(f);return this},finalize:function(f){var g=
this._hasher;f=g.finalize(f);g.reset();return g.finalize(this._oKey.clone().concat(f))}})})();
//oauth-1.0a
if (typeof(module) !== 'undefined' && typeof(exports) !== 'undefined') {
module.exports = OAuth;
}
/**
* Constructor
* #param {Object} opts consumer key and secret
*/
function OAuth(opts) {
if(!(this instanceof OAuth)) {
return new OAuth(opts);
}
if(!opts) {
opts = {};
}
if(!opts.consumer) {
throw new Error('consumer option is required');
}
this.consumer = opts.consumer;
this.nonce_length = opts.nonce_length || 32;
this.version = opts.version || '1.0';
this.parameter_seperator = opts.parameter_seperator || ', ';
this.realm = opts.realm;
if(typeof opts.last_ampersand === 'undefined') {
this.last_ampersand = true;
} else {
this.last_ampersand = opts.last_ampersand;
}
// default signature_method is 'PLAINTEXT'
this.signature_method = opts.signature_method || 'PLAINTEXT';
if(this.signature_method == 'PLAINTEXT' && !opts.hash_function) {
opts.hash_function = function(base_string, key) {
return key;
}
}
if(!opts.hash_function) {
throw new Error('hash_function option is required');
}
this.hash_function = opts.hash_function;
this.body_hash_function = opts.body_hash_function || this.hash_function;
}
/**
* OAuth request authorize
* #param {Object} request data
* {
* method,
* url,
* data
* }
* #param {Object} key and secret token
* #return {Object} OAuth Authorized data
*/
OAuth.prototype.authorize = function(request, token) {
var oauth_data = {
oauth_consumer_key: this.consumer.key,
oauth_nonce: this.getNonce(),
oauth_signature_method: this.signature_method,
oauth_timestamp: this.getTimeStamp(),
oauth_version: this.version
};
if(!token) {
token = {};
}
if(token.key !== undefined) {
oauth_data.oauth_token = token.key;
}
if(!request.data) {
request.data = {};
}
if(request.includeBodyHash) {
oauth_data.oauth_body_hash = this.getBodyHash(request, token.secret)
}
oauth_data.oauth_signature = this.getSignature(request, token.secret, oauth_data);
return oauth_data;
};
/**
* Create a OAuth Signature
* #param {Object} request data
* #param {Object} token_secret key and secret token
* #param {Object} oauth_data OAuth data
* #return {String} Signature
*/
OAuth.prototype.getSignature = function(request, token_secret, oauth_data) {
return this.hash_function(this.getBaseString(request, oauth_data), this.getSigningKey(token_secret));
};
/**
* Create a OAuth Body Hash
* #param {Object} request data
*/
OAuth.prototype.getBodyHash = function(request, token_secret) {
var body = typeof request.data === 'string' ? request.data : JSON.stringify(request.data)
if (!this.body_hash_function) {
throw new Error('body_hash_function option is required');
}
return this.body_hash_function(body, this.getSigningKey(token_secret))
};
/**
* Base String = Method + Base Url + ParameterString
* #param {Object} request data
* #param {Object} OAuth data
* #return {String} Base String
*/
OAuth.prototype.getBaseString = function(request, oauth_data) {
return request.method.toUpperCase() + '&' + this.percentEncode(this.getBaseUrl(request.url)) + '&' + this.percentEncode(this.getParameterString(request, oauth_data));
};
/**
* Get data from url
* -> merge with oauth data
* -> percent encode key & value
* -> sort
*
* #param {Object} request data
* #param {Object} OAuth data
* #return {Object} Parameter string data
*/
OAuth.prototype.getParameterString = function(request, oauth_data) {
var base_string_data;
if (oauth_data.oauth_body_hash) {
base_string_data = this.sortObject(this.percentEncodeData(this.mergeObject(oauth_data, this.deParamUrl(request.url))));
} else {
base_string_data = this.sortObject(this.percentEncodeData(this.mergeObject(oauth_data, this.mergeObject(request.data, this.deParamUrl(request.url)))));
}
var data_str = '';
//base_string_data to string
for(var i = 0; i < base_string_data.length; i++) {
var key = base_string_data[i].key;
var value = base_string_data[i].value;
// check if the value is an array
// this means that this key has multiple values
if (value && Array.isArray(value)){
// sort the array first
value.sort();
var valString = "";
// serialize all values for this key: e.g. formkey=formvalue1&formkey=formvalue2
value.forEach((function(item, i){
valString += key + '=' + item;
if (i < value.length){
valString += "&";
}
}).bind(this));
data_str += valString;
} else {
data_str += key + '=' + value + '&';
}
}
//remove the last character
data_str = data_str.substr(0, data_str.length - 1);
return data_str;
};
/**
* Create a Signing Key
* #param {String} token_secret Secret Token
* #return {String} Signing Key
*/
OAuth.prototype.getSigningKey = function(token_secret) {
token_secret = token_secret || '';
if(!this.last_ampersand && !token_secret) {
return this.percentEncode(this.consumer.secret);
}
return this.percentEncode(this.consumer.secret) + '&' + this.percentEncode(token_secret);
};
/**
* Get base url
* #param {String} url
* #return {String}
*/
OAuth.prototype.getBaseUrl = function(url) {
return url.split('?')[0];
};
/**
* Get data from String
* #param {String} string
* #return {Object}
*/
OAuth.prototype.deParam = function(string) {
var arr = string.split('&');
var data = {};
for(var i = 0; i < arr.length; i++) {
var item = arr[i].split('=');
// '' value
item[1] = item[1] || '';
// check if the key already exists
// this can occur if the QS part of the url contains duplicate keys like this: ?formkey=formvalue1&formkey=formvalue2
if (data[item[0]]){
// the key exists already
if (!Array.isArray(data[item[0]])) {
// replace the value with an array containing the already present value
data[item[0]] = [data[item[0]]];
}
// and add the new found value to it
data[item[0]].push(decodeURIComponent(item[1]));
} else {
// it doesn't exist, just put the found value in the data object
data[item[0]] = decodeURIComponent(item[1]);
}
}
return data;
};
/**
* Get data from url
* #param {String} url
* #return {Object}
*/
OAuth.prototype.deParamUrl = function(url) {
var tmp = url.split('?');
if (tmp.length === 1)
return {};
return this.deParam(tmp[1]);
};
/**
* Percent Encode
* #param {String} str
* #return {String} percent encoded string
*/
OAuth.prototype.percentEncode = function(str) {
return encodeURIComponent(str)
.replace(/\!/g, "%21")
.replace(/\*/g, "%2A")
.replace(/\'/g, "%27")
.replace(/\(/g, "%28")
.replace(/\)/g, "%29");
};
/**
* Percent Encode Object
* #param {Object} data
* #return {Object} percent encoded data
*/
OAuth.prototype.percentEncodeData = function(data) {
var result = {};
for(var key in data) {
var value = data[key];
// check if the value is an array
if (value && Array.isArray(value)){
var newValue = [];
// percentEncode every value
value.forEach((function(val){
newValue.push(this.percentEncode(val));
}).bind(this));
value = newValue;
} else {
value = this.percentEncode(value);
}
result[this.percentEncode(key)] = value;
}
return result;
};
/**
* Get OAuth data as Header
* #param {Object} oauth_data
* #return {String} Header data key - value
*/
OAuth.prototype.toHeader = function(oauth_data) {
var sorted = this.sortObject(oauth_data);
var header_value = 'OAuth ';
if (this.realm) {
header_value += 'realm="' + this.realm + '"' + this.parameter_seperator;
}
for(var i = 0; i < sorted.length; i++) {
if (sorted[i].key.indexOf('oauth_') !== 0)
continue;
header_value += this.percentEncode(sorted[i].key) + '="' + this.percentEncode(sorted[i].value) + '"' + this.parameter_seperator;
}
return {
Authorization: header_value.substr(0, header_value.length - this.parameter_seperator.length) //cut the last chars
};
};
/**
* Create a random word characters string with input length
* #return {String} a random word characters string
*/
OAuth.prototype.getNonce = function() {
var word_characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
var result = '';
for(var i = 0; i < this.nonce_length; i++) {
result += word_characters[parseInt(Math.random() * word_characters.length, 10)];
}
return result;
};
/**
* Get Current Unix TimeStamp
* #return {Int} current unix timestamp
*/
OAuth.prototype.getTimeStamp = function() {
return parseInt(new Date().getTime()/1000, 10);
};
////////////////////// HELPER FUNCTIONS //////////////////////
/**
* Merge object
* #param {Object} obj1
* #param {Object} obj2
* #return {Object}
*/
OAuth.prototype.mergeObject = function(obj1, obj2) {
obj1 = obj1 || {};
obj2 = obj2 || {};
var merged_obj = obj1;
for(var key in obj2) {
merged_obj[key] = obj2[key];
}
return merged_obj;
};
/**
* Sort object by key
* #param {Object} data
* #return {Array} sorted array
*/
OAuth.prototype.sortObject = function(data) {
var keys = Object.keys(data);
var result = [];
keys.sort();
for(var i = 0; i < keys.length; i++) {
var key = keys[i];
result.push({
key: key,
value: data[key],
});
}
return result;
};
//NETSUITE'S RESTLET
function callRESTlet(request, response) {
var remoteAccountID = 'ACCOUNT ID HERE';
var restletUrl = 'https://rest.netsuite.com/app/site/hosting/restlet.nl?script=992&deploy=1';
//user token
var token = {
key: 'ACCESS KEY HERE',
secret: 'ACCESS SECRET HERE'
};
//app credentials
var oauth = OAuth({
consumer: {
key: 'INTEGRATION KEY HERE',
secret: 'INTEGRATION SECRET HERE'
},
signature_method: 'HMAC-SHA1',
hash_function: function(base_string, key)
{
return CryptoJS.HmacSHA1(base_string, key).toString(CryptoJS.enc.Base64);
}
});
var request_data = {
url: restletUrl,
method: 'GET',
data: {}
};
var oauth_data = {
oauth_consumer_key: oauth.consumer.key,
oauth_nonce: oauth.getNonce(),
oauth_signature_method: oauth.signature_method,
oauth_timestamp: oauth.getTimeStamp(),
oauth_version: '1.0',
oauth_token: token.key,
realm: remoteAccountID
};
var headerWithRealm = oauth.toHeader(oauth.authorize(request_data, token));
headerWithRealm.Authorization += ',realm="' + remoteAccountID + '"';
var restResponse = nlapiRequestURL(restletUrl, null, headerWithRealm, null, "GET");
var html = 'Calling: ' +
restletUrl +
'<br><br>' +
'Generated OAuth header:<br>' +
headerWithRealm.Authorization +
'<br><br>' +
'Response:<br>' +
restResponse.getBody()
response.write(html);
}
EDIT: Just published an npm module which should make things easier: https://www.npmjs.com/package/nsrestlet
Was able to get some code working after hunting through GitHub Code commits. Still, bknights response is really good.
Here's what I got working.
Assuming you have Node.js and npm installed, run:
npm install request
npm install oauth-1.0a#1.0.1
It's really important that it's version 1.0.1.
Once you have that, this code should work:
/*
================= REQUIRED USER ACCOUNT INFORMATION ==============================================
*/
var accountID = 'PUT ACCOUNT ID HERE';
var token = {
public: 'PUT TOKEN KEY HERE',
secret: 'PUB TOKEN SECRET HERE'
};
var consumer = {
public: 'PUT CONSUMER KEY HERE',
secret: 'PUT CONSUMER SECRET HERE'
};
//use the full restlet URL, not the rest.netsuite.com URL
//for example, https://YOURACCOUNTNUMBER.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=SCRIPTNUMBER&deploy=DEPLOYNUMBER
var restlet_url = 'PUT YOUR RESTLET URL HERE';
/*
=========================================================================================================
*/
//REQUIRED NPM MODULES
const request = require('request');
const OAuth = require('oauth-1.0a'); //version 1.0.1, don't do version 1.1.0
//SET UP THE OAUTH OBJECT
var oauth = OAuth({
consumer: consumer,
signature_method: 'HMAC-SHA256' //you can also use HMAC-SHA1 but HMAC-SHA256 is more secure (supposedly)
});
//SET UP THE REQUEST OBJECT
var request_data = {
url: restlet_url,
method: 'POST',
};
//GET THE AUTHORIZATION AND STICK IT IN THE HEADER, ALONG WITH THE REALM AND CONTENT-TYPE
var authorization = oauth.authorize(request_data, token);
var header = oauth.toHeader(authorization);
header.Authorization += ', realm="' + accountID + '"';
header['content-type'] = 'application/json';
//MAKE THE REQUEST
request({
url: request_data.url,
method: request_data.method,
headers: header,
json: {
message: "test123" //this is your payload
}
}, function(error, response, body) {
if(error)
{
console.log(error);
}
else
{
console.log(body);
}
});
If anybody has any problems with this code, leave a response and I'll do my best to help.
Netsuite's node samples use oauth-1.0a
https://netsuite.custhelp.com/app/answers/detail/a_id/42171
and their sample from https://netsuite.custhelp.com/app/answers/detail/a_id/42172/
is what I've had in production for a couple of years and works well.
var Promise = require('bluebird');
var request = require('request');
var crypto = require('crypto');
var OAuth = require('oauth-1.0a');
var Agent = require('https').Agent;
//var debug = require('debug')('kotn-ns');
function promiseTry(pSrc, maxTries, minDelay, maxDelay, canRetry){ //NS prone to spurious failures due to overloading
return new Promise(function(resolve, reject){
minDelay = minDelay || 0;
var delaySize = maxDelay - minDelay;
var t = function(){ return Math.floor(Math.random()* delaySize)+ minDelay;};
var firstReason = null;
function doRetry(triesLeft){
pSrc().then(function(data){
resolve(data);
}).catch(function(reason){
if(!firstReason) firstReason = reason;
console.error('in retry error with '+reason.toString());
if(triesLeft && canRetry(reason)) setTimeout(function(){ doRetry(triesLeft-1);}, t());
else reject(firstReason);
});
}
doRetry(maxTries -1);
});
}
function hasReason(msg, reasons){
for(var i = 0; i< reasons.length;i++){
if(msg.indexOf(reasons[i]) != -1) return true;
}
return false;
}
var agentPool = {};
function getAgent(accountId, tokenId){
var agentKey = accountId+'::'+ tokenId;
var agent = agentPool[agentKey];
if(!agent){
console.log('new agent for '+agentKey)
agent = new Agent({
keepAlive:false,
maxSockets:5
});
agentPool[agentKey] = agent;
}
return agent;
}
/**
* [RESTHandler description]
* #param {options} options {accountId, consumerKey,consumerSecret,tokenId,tokenSecret}
*/
function RESTHandler(options) {
var config = Object.assign({
maxTries:3,
minRetryDelay: 800,
maxRetryDelay:30000,
canRetry: function(reason){
var reasonText = reason.message || JSON.stringify(reason);
if(hasReason(reasonText, ['ECONNRESET', 'ESOCKETTIMEDOUT','ETIMEDOUT', 'SSS_REQUEST_LIMIT_EXCEEDED'])) {
console.error('retrying because: '+reasonText);
return true;
}
console.error('no retry with: '+reasonText);
return false;
}
}, options);
var oauth = OAuth({
consumer: {
key: config.consumerKey,
secret: config.consumerSecret
},
signature_method: 'HMAC-SHA1',
parameter_seperator: ',',
hash_function: function(base_string, key) {
return crypto.createHmac('sha1', key).update(base_string).digest('base64');
}
});
var token = {
key: config.tokenId,
secret: config.tokenSecret
};
function makeRequest(url, method, payload) {
var requestData = {
url: url,
method: method
};
if(payload){
requestData.body = payload;
}
var headers = oauth.toHeader(oauth.authorize(requestData, token));
headers.Authorization += ',realm="' + config.accountId + '"';
headers.authorization = headers.Authorization;
delete headers.Authorization;
headers['content-type'] = 'application/json';
headers['accept'] = 'application/json';
//console.log(JSON.stringify(headers, null, ' '));
requestData.headers = headers;
Object.assign(requestData, {
pool:getAgent(config.accountId, config.tokenId),
timeout : 30000,
strictSSL : true
});
// requestData.json = true;
// return new Promise(function(resolve){
// resolve({'headers' : 'done'});
// });
var processRequest = function(){
return new Promise(function(resolve, reject) {
request(requestData, function(error, response, body) {
if(error){
console.error('error calling: '+ requestData.url);
console.error(error);
reject((error instanceof Error) ? error : new Error(JSON.stringify(error)));
return;
}
if(!body || !(/"success"/).test(body)) {
console.log(method +' '+ response.statusCode +' '+ url +'\n\t'+body);
reject(new Error(body || 'unexpected error'));
return;
}
try{
resolve(JSON.parse(body));
}catch(e){
console.trace(e);
reject(e);
}
});
});
};
return promiseTry(processRequest, config.maxTries, config.maxRetryDelay, config.minRetryDelay, config.canRetry);
}
return{
get: function(url){
return makeRequest(url, 'GET');
},
put: function(url, data){
return makeRequest(url, 'PUT', data);
},
post: function(url, data){
return makeRequest(url, 'POST', data);
},
destroy : function(){
//nsAgent.destroy();
}
};
}
module.exports = RESTHandler;
More up-to-date as of 2022-12-12
replaced request with its successor needle and removed the now unnecessary bluebird
const needle = require('needle');
const crypto = require('crypto');
const OAuth = require('oauth-1.0a');
const Agent = require('https').Agent;
const debug = require('debug')('kotn-nso');
function promiseTry(pSrc, maxTries, minDelay, maxDelay, canRetry){ //NS prone to spurious failures due to overloading
return new Promise((resolve, reject)=>{
minDelay = minDelay || 0;
const delaySize = maxDelay - minDelay;
const t = function(){ return Math.floor(Math.random()* delaySize)+ minDelay;};
let firstReason = null;
function doRetry(triesLeft){
pSrc().then((data)=>{
resolve(data);
}).catch((reason)=>{
if(!firstReason) firstReason = reason;
console.error('in retry error with '+ triesLeft +' for '+reason.toString());
if(triesLeft && canRetry(reason)){
setTimeout(()=>{ doRetry(triesLeft-1);}, t());
}
else reject(firstReason);
});
}
doRetry(maxTries -1);
});
}
function hasReason(msg, reasons){
for(var i = 0; i< reasons.length;i++){
if(msg.indexOf(reasons[i]) != -1) return true;
}
return false;
}
var agentPool = {};
function getAgent(accountId, maxSockets){
var agentKey = accountId+'::'; // + tokenId;
var agent = agentPool[agentKey];
if(!agent){
console.log('new agent for '+agentKey);
agent = new Agent({
keepAlive:false,
maxSockets:maxSockets || 2 // one in reserve for slow closers
});
agentPool[agentKey] = agent;
}
return agent;
}
/**
* [RESTHandler description]
* #param {options} options {accountId, consumerKey,consumerSecret,tokenId,tokenSecret,maxSockets}
*/
function RESTHandler(options) {
const config = Object.assign({
maxTries:3,
minRetryDelay: 400,
maxRetryDelay:30000,
canRetry: function(reason){
var reasonText = reason.message || JSON.stringify(reason);
if(hasReason(reasonText, ['ECONNRESET', 'ESOCKETTIMEDOUT','ETIMEDOUT', 'SSS_REQUEST_LIMIT_EXCEEDED'])) {
console.error('retrying because: '+reasonText);
return true;
}
console.error('no retry with: '+reasonText);
return false;
}
}, options);
const oauth = OAuth({
consumer: {
key: config.consumerKey,
secret: config.consumerSecret
},
signature_method: 'HMAC-SHA256',
parameter_seperator: ',',
hash_function: function(base_string, key) {
return crypto.createHmac('sha256', key).update(base_string).digest('base64');
}
});
const token = {
key: config.tokenId,
secret: config.tokenSecret
};
function makeRequest(url, method, payload) {
debug(method +' '+ JSON.stringify(url));
var requestData = {
url: url,
method: method
};
if(payload){
requestData.body = payload;
}
var headers = oauth.toHeader(oauth.authorize(requestData, token));
headers.Authorization += ',realm="' + config.accountId + '"';
headers.authorization = headers.Authorization;
delete headers.Authorization;
headers['content-type'] = 'application/json';
headers['accept'] = 'application/json';
//console.log(JSON.stringify(headers, null, ' '));
const options = {
headers:headers,
agent:getAgent(config.accountId, config.maxSockets),
timeout : 30000,
strictSSL : true,
time:false
};
var processRequest = function(){
var headers = null;
return needle(method.toLowerCase(), url, payload, options).then(resp=>{
debug(resp.statusCode +' ' + JSON.stringify(resp.headers, null, ' '));
headers = resp.headers;
if(resp.statusCode != 200 && resp.statusCode != 201){
throw new Error(resp.statusCode +': '+ (resp.body || 'unexpected error'));
}
if(!resp.body) throw new Error('Unexpected Response');
return resp.body;
}).catch(error=>{
if(headers){
debug('Error returned with ' + JSON.stringify(headers));
}
const msg = error instanceof Error ? error.message : JSON.stringify(error);
console.error(method +' error on '+ url + ', '+ msg);
throw (error instanceof Error) ? error : new Error(msg);
});
};
return promiseTry(processRequest, config.maxTries, config.maxRetryDelay, config.minRetryDelay, config.canRetry);
}
return{
get: function(url){
return makeRequest(url, 'GET');
},
put: function(url, data){
return makeRequest(url, 'PUT', data);
},
post: function(url, data){
return makeRequest(url, 'POST', data);
},
destroy : function(){
//nsAgent.destroy();
}
};
}
module.exports = RESTHandler;

Google Oauth2 API - No Refresh Token

I have attempted many solutions provided on Stack Exchange to obtain a refresh token, and they all fail. Below is my whole controller. As you can see, I have included $client->setAccessType('offline') and $client->setApprovalPrompt('force').
In addition, I have ran the revoke token many times, and I have gone into my Google Account here (https://myaccount.google.com/permissions), and removed access. None of these attempts provided me with a refresh token when I made a new authorization.
<?php
/**
* #file
* Contains \Drupal\hello\GAOauthController.
*/
namespace Drupal\ga_reports_per_user\Controller;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Google_Client;
use Google_Service_Analytics;
use Drupal\group\Context\GroupRouteContextTrait;
class GAOauthController extends ControllerBase {
use GroupRouteContextTrait;
public function authorize($group = NULL) {
$client = new Google_Client();
$credentials_file = \Drupal::service('file_system')->realpath("private://") . '/client_credentials.json';
$client->setAuthConfig($credentials_file);
$client->addScope(Google_Service_Analytics::ANALYTICS_READONLY);
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
$protocol = "https";
}
else {
$protocol = "http";
}
$redirect_uri = $protocol . '://' . $_SERVER['HTTP_HOST'] . '/finish_google_oauth';
$client->setState($group);
$client->setRedirectUri($redirect_uri);
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$auth_url = $client->createAuthUrl();
return new TrustedRedirectResponse($auth_url);
}
public function finishOauth() {
if (isset($_GET['code'])) {
$client = new Google_Client();
$credentials_file = \Drupal::service('file_system')->realpath("private://") . '/client_credentials.json';
$client->setAuthConfig($credentials_file);
$client->addScope(Google_Service_Analytics::ANALYTICS_READONLY);
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
$protocol = "https";
}
else {
$protocol = "http";
}
$redirect_uri = $protocol . '://' . $_SERVER['HTTP_HOST'] . '/finish_google_oauth';
$client->setRedirectUri($redirect_uri);
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->authenticate($_GET['code']);
$token = $client->getAccessToken();
$refreshToken = $client->getRefreshToken();
$client->setAccessToken($token);
$group_entity = \Drupal::entityTypeManager()->getStorage('group')->load($_GET['state']);
$group_entity->field_google_oauth_token->value = $token['access_token'];
$group_entity->field_google_oauth_token_type->value = $token['token_type'];
$group_entity->field_google_oauth_token_created->value = $token['created'];
$group_entity->field_google_oauth_token_expire->value = $token['expires_in'];
$save_status = $group_entity->save();
return new RedirectResponse('/group/' . $_GET['state']);
}
}
public function revoke($group = NULL){
$client = new Google_Client();
$group_entity = \Drupal::entityTypeManager()->getStorage('group')->load($group);
$result = $client->revokeToken($group_entity->field_google_oauth_token->value);
$group_entity->field_google_oauth_token->value = '';
$group_entity->field_google_oauth_token_type->value = '';
$group_entity->field_google_oauth_token_created->value = '';
$group_entity->field_google_oauth_token_expire->value = '';
$group_entity->save();
return new RedirectResponse('/group/' . $group);
}
}
If you have already requested an access token for that login / dev. token combo, it won't return it again for you. You'll have to revoke access by going to https://myaccount.google.com/permissions. Find your app, revoke access, and try again.
Source: I had this exact same problem and after nearly pulling my hair out, I figured this out.

Youtube SDK - How to get Analytics Reporting access and data dumps in PHP?

I wish to download all data from each of my channel's analytics reports minute by minute but I am getting a 403 error. What sort of permissions do I need? How do I get access to the Analytics Reporting API? It says that the API is not available for me.
Additionally will the server 2 server auth work for getting data on a regular bases (at least 10 times a day)?
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
/*
* This OAuth 2.0 access scope allows for read access to the YouTube Analytics monetary reports for
* authenticated user's account. Any request that retrieves earnings or ad performance metrics must
* use this scope.
*/
$client->setScopes(array('https://www.googleapis.com/auth/youtube.readonly', 'https://www.googleapis.com/auth/yt-analytics.readonly'));
$redirect = filter_var('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],
FILTER_SANITIZE_URL);
$redirect = str_replace('.php', '', $redirect);
$client->setRedirectUri($redirect);
if (isset($_GET['code'])) {
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
die('The session state did not match.');
}
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
header('Location: ' . $redirect);
}
try {
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()) {
$youtube = new Google_Service_YouTube($client);
//die("<pre>" . var_export($youtube->channels->listChannels('id', array('forUsername' => 'kingbach')),1));
$analytics = new Google_Service_YouTubeAnalytics($client);
$id = 'channel==<CHANNEL_ID>';
$start_date = '2016-09-17';
$end_date = '2016-09-24';
$optparams = array(
'onBehalfOfContentOwner' => '<USERNAME>'
);
$metrics = array(
'views',
'estimatedMinutesWatched',
'averageViewDuration',
'comments',
//'favoritesAdded',
//'favoritesRemoved',
'likes',
'dislikes',
'shares',
'subscribersGained',
'subscribersLost'
);
$api_response = $metrics;
foreach ($metrics as $metric) {
$api = $analytics->reports->query($id, $start_date, $end_date, $metric, $optparams);
if (isset($api['rows'])) {
$api_response[$metric] = $api['rows'][0][0];
}
}
} else {
// If the user hasn't authorized the app, initiate the OAuth flow
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
$authUrl = $client->createAuthUrl();
$htmlBody = <<<END
<h3>Authorization Required</h3>
<p>You need to authorize access before proceeding.<p>
END;
}
} catch (\Exception $e) {
die("<pre>" . $e->getMessage() . "</pre>");
}
You need to enable the API in the Cloud Platform Console. See https://support.google.com/cloud/answer/6158841?hl=en for details

ErrorException in PlaceController.php line 101: Trying to get property of non-object - Laravel 5.1*

I am trying to create a page where an user can put some data and save or post it. But when I try to visit my place adding url I get an error "ErrorException in PlaceController.php line 101: Trying to get property of non-object"
My Route:
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
Route::get('/','FrontView#index');
Route::get('/placesbydiv','FrontView#placesByDiv');
Route::get('/placesbydist','FrontView#placesByDist');
Route::get('/blog',['as' => 'blog', 'uses' => 'PostController#blog']);
//authentication
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
// check for logged in user
Route::group(['middleware' => ['auth']], function()
{
// show new post form
Route::get('new-post','PostController#create');
// save new post
Route::post('new-post','PostController#store');
// edit post form
Route::get('edit/{slug}','PostController#edit');
// update post
Route::post('update','PostController#update');
// delete post
Route::get('delete/{id}','PostController#destroy');
// display user's all posts
Route::get('my-all-posts','UserController#user_posts_all');
// display user's drafts
Route::get('my-drafts','UserController#user_posts_draft');
// add comment
Route::post('comment/add','CommentController#store');
// delete comment
Route::post('comment/delete/{id}','CommentController#distroy');
});
//users profile
Route::get('user/{id}','UserController#profile')->where('id', '[0-9]+');
// display list of posts
Route::get('user/{id}/posts','UserController#user_posts')->where('id', '[0-9]+');
// display list of posts by category
Route::get('category/{id}/posts','UserController#category_posts')->where('id', '[0-9]+');
// display single post
Route::get('/{slug}',['as' => 'post', 'uses' => 'PostController#show'])->where('slug', '[A-Za-z0-9-_]+');
//Places
Route::get('/place',['as' => 'place', 'uses' => 'PlaceController#place']);
// check for logged in user
Route::group(['middleware' => ['auth']], function()
{
// show new post form
Route::get('new-place','PlaceController#create');
// save new post
Route::post('new-place','PlaceController#store');
// edit post form
Route::get('edit/{slug}','PlaceController#edit');
// update post
Route::post('update','PlaceController#update');
// delete post
Route::get('delete/{id}','PlaceController#destroy');
// display user's all posts
Route::get('my-all-places','UserController#user_places_all');
// display user's drafts
Route::get('my-places-drafts','UserController#user_places_draft');
// add comment
//Route::post('comment/add','CommentController#store');
// delete comment
//Route::post('comment/delete/{id}','CommentController#distroy');
});
//users profile
//Route::get('user/{id}','UserController#profile')->where('id', '[0-9]+');
// display list of posts
Route::get('user/{id}/places','UserController#user_places')->where('id', '[0-9]+');
// display single post
Route::get('/{slug}',['as' => 'place', 'uses' => 'PlaceController#show'])->where('slug', '[A-Za-z0-9-_]+');
My Place controller:
<?php
namespace App\Http\Controllers;
use App\Places;
use App\User;
use App\Div;
use Redirect;
use App\Http\Controllers\Controller;
use App\Http\Requests\PlaceFormRequest;
use Illuminate\Http\Request;
class PlaceController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return view('home', array('page' => 'home'));
}
public function place(Request $request){
//fetch 5 posts from database which are active and latest
$places = Places::where('active',1)->orderBy('created_at','desc');
//page heading
$title = 'দর্শনীয় স্থান';
$search_key = $request->input('body');
if(!empty('$search_key')){
$places->where('body','LIKE','%'.$search_key.'%');
}
$places = $places->paginate(5);
//return home.blade.php template from resources/views folder
return view('place')->withPlaces($places)->withTitle($title);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create(Request $request)
{
// if user can post i.e. user is admin or author
if($request->user()->can_post())
{
$divs = \DB::table('divs')->lists('div', 'id');
return view('places.create')->with('divs', $divs);
}
else
{
return redirect('/')->withErrors('You have not sufficient permissions for writing post');
}
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(PlaceFormRequest $request)
{
$place = new Places();
$place->title = $request->get('title');
$place->url = $request->get('url');
$place->location = $request->get('location');
$place->gmap_location = $request->get('gmap_location');
$place->slug = $place->url;
$place->body = $request->get('body');
//$post->slug = str_slug($post->title);
// $place->author_id = $request->user()->id;
$place->div_id = $request->get('div');
$place->source_url = $request->get('source_url');
if($request->has('save'))
{
$place->active = 0;
$message = 'Place saved successfully';
}
else
{
$place->active = 1;
$message = 'Place added successfully';
}
$place->save();
return redirect('edit/'.$place->slug)->withMessage($message);
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($slug)
{
$place = Places::where('slug',$slug)->first();
$div = \DB::table('divs')->where('id',$place->div_id)->first(); **//THIS IS THE ERROR LINE**
if(!$place)
{
return redirect('/')->withErrors('requested page not found');
}
// $comments = $post->comments;
return view('places.show')->withPlace($place)->withDiv($div);
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit(Request $request,$slug)
{
$place = Places::where('slug',$slug)->first();
if($place && ($request->user()->can_post() || $request->user()->is_admin()))
return view('places.edit')->with('place',$place);
return redirect('/')->withErrors('you have not sufficient permissions');
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request)
{
$place_id = $request->input('place_id');
$place = Places::find($place_id);
if($place && ($request->user()->can_post() || $request->user()->is_admin()))
{
$title = $request->input('title');
$slug = str_slug($title);
$duplicate = Places::where('slug',$slug)->first();
if($duplicate)
{
if($duplicate->id != $place_id)
{
return redirect('edit/'.$place->slug)->withErrors('Title already exists.')->withInput();
}
else
{
$place->slug = $slug;
}
}
$place->title = $title;
$place->location = $request->get('location');
$place->gmap_location = $request->get('gmap_location');
$place->body = $request->input('body');
$place->source_url = $request->get('source_url');
if($request->has('save'))
{
$place->active = 0;
$message = 'Place saved successfully';
$landing = 'edit/'.$place->slug;
}
else {
$place->active = 1;
$message = 'Place updated successfully';
$landing = $place->slug;
}
$place->save();
return redirect($landing)->withMessage($message);
}
else
{
return redirect('/')->withErrors('you have not sufficient permissions');
}
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy(Request $request, $id)
{
$place = Places::find($id);
if($place && ($request->user()->is_admin()))
{
$place->delete();
$data['message'] = 'Place deleted Successfully';
}
else
{
$data['errors'] = 'Invalid Operation. You have not sufficient permissions';
}
return redirect('/')->with($data);
}
}
Your check for if(!$place) belongs before you use $place->div_id.
It's possible that $place = Places::where('slug',$slug)->first(); is not returning a model.

Symfony task on the hosting

I have task:
<?php
require_once(dirname(__FILE__).'/../../config/ProjectConfiguration.class.php');
class GroupCheckTask extends sfBaseTask
{
protected function configure()
{
// // add your own arguments here
// $this->addArguments(array(
// new sfCommandArgument('my_arg', sfCommandArgument::REQUIRED, 'My argument'),
// ));
$this->addOptions(array(
new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name'),
new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'dev'),
new sfCommandOption('connection', null, sfCommandOption::PARAMETER_REQUIRED, 'The connection name', 'doctrine'),
// add your own options here
));
$this->namespace = '';
$this->name = 'GroupCheck';
$this->briefDescription = '';
$this->detailedDescription = <<<EOF
The [GroupCheck|INFO] task does things.
Call it with:
[php symfony GroupCheck|INFO]
EOF;
}
protected function execute($arguments = array(), $options = array())
{
$databaseManager = new sfDatabaseManager($this->configuration);
$connection = $databaseManager->getDatabase($options['connection'])->getConnection();
// add your code here
$users= Doctrine::getTable('sfGuardUserProfile')->getUserDelay() ;
foreach($users as $sfGuardUserProfile)
{
$users_id =$sfGuardUserProfile-> getUserId();
$userForChange = Doctrine::getTable('sfGuardUserGroup')->getUserForChange($users_id) ;
foreach($userForChange as $sfGuardUserGroup)
{
$sfGuardUserGroup->setSfGuardGroup(Doctrine::getTable('sfGuardGroup')- >findOneByName('basic'))->save();
}
}
}
}
And in my localhost all works fine, but it is not work in hosting. What is the correct way to run task on hosting from cron tab?
first, you dont need put the line require_once(dirname(__FILE__).'/../../config/ProjectConfiguration.class.php');
second, write a namespace for your task is a good practice
third, you need the the a php file like:
<?php
/* /path/to/file.php */
chdir("/the/path/in/your/host/to/symfony/project");
exec("symfony your_namespace:GroupCheck");
?>
last, you can put this file in your crontab
00 59 23 * * php /path/to/file.php

Resources