Calling a member function on a non object - php [duplicate] - symfony1

This question already has answers here:
Call to a member function on a non-object [duplicate]
(8 answers)
Closed 10 years ago.
Here is my code of SessionManager.php:
private function generateAuthToken($user)
{
$bits = '';
$fp = #fopen('/dev/urandom', 'rb');
if ($fp !== false) {
$bits .= #fread($fp, 128);
#fclose($fp);
}
return sha1($bits . time() . microtime() . $user->getUsername());
}
I'm getting this error:
Fatal error: Call to a member function getUsername() on a non-object
in
/home/shwetanka/src/Practo/PvrBundle/Manager/SessionManager.php
on line 49
When I'm doing var_dump($user); right before the problem line I'm getting the full user object printed. I'm unable to understand the reason of this error. The function is present in the class User. Even if I try to call any other function of the class even then I get the same error for that function. I'm new to php and having hard time debugging this problem.
Also $user is object of User entity. I'm using symfony2 and this object is returned to me by using this:
$ur = $this->getDoctrine()->getRepository('PractoPvrBundle:User');
$user = $ur->findBy(array('email' => $email));

Sometimes in the implicitly-convert-to-string context, PHP does not do well with method calls... I'm not sure why. Try this:
$username = $user->getUsername();
return sha1($bits . time() . microtime() . $username);
edit:
Also, I suspect that you are actually dealing with an array instead of an object. the line:
$user = $ur->findBy(array('email' => $email));
is probably intended to return many results. Use current() to get the first one:
$user = current($ur->findBy(array('email' => $email)));

Take the user out of the return like:
$username = $user->getUsername();
return sha1($bits . time() . microtime() . $username);
If this doesn't fix it, for debugging purpose you can try:
$username = 'N/A';
if(is_object($user) && method_exists($user, 'getUsername'))
{
$username = $user->getUsername();
}
Also you can cast your parameter $user like:
private function generateAuthToken(User $user) {...
This will throw an error if you get different class instance or non object

$ur = $this->getDoctrine()->getRepository('PractoPvrBundle:User');
$user = $ur->findBy(array('email' => $email));
-> findBy returns array of objects, use -> findOneBy

Related

Using the mock returned by another mock in phpspec

I'm new at phpspec (coming from phpunit) and I have problems setting the behavior of a mock returned by another mock.
I'm creating a wrapper class around the Guzzle client and I want to check the output of the response.
Here's the spec:
function it_gets_response_status_code(Client $client, Url $url, Response $response)
{
$this->beConstructedWith($client);
$url->__toString()->willReturn('http://example.com');
$data = ['foo' => 'bar'];
$response->getStatusCode()->willReturn(200);
$client->request('POST', $url, ['form_params' => $data])->willReturn($response);
$this->post($url, $data);
assert($this->getResponseStatusCode() === 200); // Failing! :(
}
and the corresponding functions in my class:
public function post(Url $url, array $data)
{
$this->response = $this->client->request('POST', (string) $url, ['form_params' => $data]);
}
public function getResponseStatusCode()
{
return $this->response->getStatusCode();
}
The assertion is failing and when I check what is this status code, I see that instead of the integer 200, it's an instance of PhpSpec\Wrapper\Subject. What am I missing here?
I've searched and googled but cannot find resources about using the mock returned by another mock in phpspec. I'm wondering if the reason for this is that it's a code smell? If so I'd be glad to see how I could do this differently (currently I cannot see how I could keep the code simple and doing differently).
try:
assert($this->getResponseStatusCode()->getWrappedObject() === 200);
this:
$response->getStatusCode()->willReturn(200)
returns a '200' string wrapped in an Subject object, on which you can then make mock/stub calls if needed. To get the real value of the subject you need to call getWrappedObject

IronResponse calls an JsObjectImpl object, but I cant find class docs on it

I was trying to parse the return of an IronAjax success handler and set the response to an instance of Map. It seems to not like that.
My HTML Markup is:
<iron-ajax id="myAjaxId" auto
url="http://localhost:12345/test_server/v1/daily"
handle-as="json"
on-response="handleResponse" on-error="handleError"></iron-ajax>
My Dart Code is:
void handleResponse(CustomEventWrapper cew, IronRequest ir){
print("inside handleResponse");
var data = ir.response; // <-- is type JsObjectImpl
print("data");
print(data);
if (data == null) return;
print ("About to set rows");
List<Map> rows = data.containsKey("data") ? data["data"] : [];
print("Variables are Set locally");
$['myDatagrid'].render();
}
#reflectable
String camelToFormal (String input){
String out;
RegExp regex = new RegExp("([A-Z])");
out = input[0].toUpperCase() + input.substring(1).replaceAllMapped(regex, (Match m) => " ${m[1]}");
return out;
}
#reflectable
void handleError(CustomEventWrapper cew, IronRequest ir){
print("____Error:____");
print(ir.response);
}
The Error I get is:
type 'JsObjectImpl' is not a subtype of type 'Map' of 'other'.
I wasnt sure if I need to run convert over it, even though the return type set by IronAjax was json
So, since ir.response will either be set or null, i check if it is null first. the var data line in responseHandler currently sets is, but i have also attempted to do something like: Map data = new Map.from(ir.response); which fails as well.
Even though this is said to be handled as JSON, and is returning a jslint confirmed objected, it seems to have issues to convert it to a proper map instance.
According to Polymer IronRequest at: https://elements.polymer-project.org/elements/iron-ajax?active=iron-request
it says that responseis *, the parsed response body. Am I mistaken as to how this is properly set up, or am I missing something?
You could try Object instead of map on the property and then use convertToDart. Not sure this results in a Map but worth a try I guess. See also Polymer 1.0 - iron-list - selection

laravel 5.1 trouble with queueing email sending

i'm trying to queue an email sending invoice emails in laravel 5.1, i pass in a variable called invoice, when i dd($invoice->dateString()) in the Job class it's return the correct value but when i pass it in to the view the $invoice variable return empty array (so i get an error about trying to get property from non-object...).
the second problem i have is when i try to add attachment to the job it returns an error : "Serialization of closure failed: Serialization of 'SplFileInfo' is not allowed".
the job class looks like that:
namespace LM2\Jobs;
use Guzzle\Service\Client;
use LM2\Jobs\Job;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
use LM2\Models\User as User;
use LM2\Models\Client as LMClient;
class SendInvoiceEmail extends Job implements SelfHandling, ShouldQueue
{
protected $user;
protected $invoice;
protected $attachment;
protected $update;
public function __construct(User $user, LMClient $client, $invoice,$update)
{
$this->user = $user;
$this->client = $client;
$this->invoice = $invoice;
$this->update = $update;
}
public function handle()
{
$attachment = $this->client->invoiceFile($this->invoice->id,['vendor' => 'Test','product' => 'Your Product']);
$invoice = $this->invoice;
$data = [
'invoice' => $this->invoice,
'update'=> $this->update,
];
$user = $this->user;
\Mail::queue('emails.invoices', $data , function($m) use ($user,$invoice,$attachment){
$m->to($user->email)->subject('New payment received')->attach($attachment);
});
}
}
and my controller function looks like that:
public function sendEmailInvoice($update = false){
$client = \Auth::client();
$user = \Auth::user();
$invoices = $client->invoices();
$this->dispatch(new SendInvoiceEmail($user,$client,$invoices[0],$update));
$activity = $data['update'] ? 'updated': 'added';
return ['success', $activity];
}
can someone please tell me what am i doing wrong?
thanks a lot you all :)
Just a guess... but when using Mail::queue() the $data get's converted/cast to an array/you lose your objects inside of the view - hence why you're receiving errors when trying to call methods(), because they don't exist.
Rather than passing invoice + update objects, get what you need from them in the handle method and construct the $data array.
$data = [
'invoice_foo' => $invoice->getFoo(),
'invoice_bar' => $invoice->getBar(),
];
*** Apologies if this doesn't help at all!
so i found the answer thanks to #Michael, i have changed my handle so it's look like this now:
public function handle(Mailer $mailer)
{
$client = $this->client;
$invoice = $this->invoice;
$data = [
'date' => $invoice->dateString(),
'amount' => $invoice->dollars(),
'update'=> $this->update,
];
$user = $this->user;
return $mailer->queue('emails.invoices', $data , function($m) use ($user,$client,$invoice){
$attachment = $client->invoiceFile($invoice->id,['vendor' => 'Infogamy','product' => 'Your Product']);
$m->to($user->email)->subject('New payment received')->attach($attachment);
});
}
The attachment should be processed inside the mailer callback function, and the function called from the $invoice variable (object) should be called inside the handle function and not in the blade view template.

Smarty Fetch is not loading anything into my variable

I have a class that sets up my smarty instances:
class View {
protected $templateEngine;
protected $templateExtension = '.tpl';
public function __construct(){
global $ABS_PUBLIC_PATH;
global $ABS_PUBLIC_URL;
$this->templateEngine = new Smarty();
$this->templateEngine->error_reporting = E_ALL & ~E_NOTICE;
$this->templateEngine->setTemplateDir($ABS_PUBLIC_PATH . '/templates/');
$this->templateEngine->setCompileDir($ABS_PUBLIC_PATH . '/templates_c/');
$this->templateEngine->assign('ABS_PUBLIC_URL', $ABS_PUBLIC_URL);
if(isset($_SESSION['loggedIn'])){
$this->assign('session', $_SESSION);
}
}
public function assign($key, $value){
$this->templateEngine->assign($key, $value);
}
public function display($templateName){
$this->templateEngine->display($templateName . $this->templateExtension);
}
public function fetch($templateName){
$this->templateEngine->fetch($templateName . $this->templateExtension);
}
}
Then in my functions, I use the class like this:
public function showMeSomething()
{
$view = new View();
$view->assign('session', $_SESSION);
$view->display('header');
$view->display('index');
$view->display('footer');
}
Now, I'm trying to fetch some data into a variable, in order to send emails from my template files as well. Unfortunately, this var_dumps below (both of them) output NULL - even though the template file referenced has a lot of HTML in it. Furthermore, changing the word fetch to display below will correctly display the template file. So, the problem certainly lies within the fetch command. I'm not sure what to do to continue debugging.
function emailPrep($data,){
$mailView = new View();
$emailHTML = $mailView->fetch('myEmail');
var_dump($mailView->fetch("myEmail"));
var_dump($emailHTML);
}
Your code must be
public function fetch($templateName){
return $this->templateEngine->fetch($templateName . $this->templateExtension);
}

symfony - returning JSON from a peer method call in an action

I have some code that checks a parameter and the calls a peer method to get me items from the DB.
What I need to get is these items in JSON.
My peer method is like:
public static function searchFromRequest($word)
{
$c = new Criteria();
$c->addJoin(self::ARTICLE_ID, ArticlePeer::ID);
$c->add(self::TITLE, '%'.$word.'%', Criteria::LIKE);
$c->addAnd(self::ARTICLE_ID, null, Criteria::ISNOTNULL);
$c->addAscendingOrderByColumn(self::TITLE);
return self::doSelect($c);
}
and my action is:
public function executeSearch()
{
$this->word = $this->getRequestParameter('word');
$this->content_type = $this->getRequestParameter('content_type');
if($this->content_type == 'article')
{
$words = ItemPeer::searchFromRequest($this->word);
}
else
{
echo "Nothing here";
}
I can var_dump($words) and I get an array (collection) of items. The problem is, how do I return all of the items in JSON?
I've tried using:
$this->getResponse()->setHttpHeader('Content-type', 'application/json');
$words = ItemPeer::searchFromArticleRequest($this->word);
return $this->renderText(json_encode($words));
But this just returns loads of empty JSON brackets: [{},{},{},{},{},{},{},{},{},{},{},{},{},{}]
Thanks
It seems that json_encode() doesn't like the way Propel Objects are built.
Another solution could be forcing Propel to returnin basic associative objects, using XXXPeer::doSelectStmt()
public static function searchFromRequest($word, $returnPropelObjects = true)
{
$c = new Criteria();
$c->addJoin(self::ARTICLE_ID, ArticlePeer::ID);
$c->add(self::TITLE, '%'.$word.'%', Criteria::LIKE);
$c->addAnd(self::ARTICLE_ID, null, Criteria::ISNOTNULL);
$c->addAscendingOrderByColumn(self::TITLE);
if ($returnPropelObjects)
return self::doSelect($c);
$stmt = self::doSelectStmt($c);
$results = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$results[] = $row;
}
return $results;
}
Propel 1.6:
object->toJSON();
collection->exportTo('JSON');
The json_encode/json_decode can only encode/decode PHP arrays not objects. The variable
$words
will be an array of Item objects, that's why the output you wrote.
There are basically two solutions. You write your own json encoder that works for objects, like the first comment here:
http://php.net/manual/en/function.json-encode.php
or you write a function that converts your Item objects into PHP arrays like here:
http://www.phpro.org/examples/Convert-Object-To-Array-With-PHP.html
You could also call toArray() on your objects.
$words = ItemPeer::searchFromArticleRequest($this->word);
$wordsArray = array();
foreach ($words as $word)
{
$wordsArray[] = $word->toArray();
}
return $this->renderText(json_encode($wordsArray));
Propel 1.6 will have a toJSON() method for the individual objects or for a whole collection of objects.

Resources