andrewscofield / parse.com-php-library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

whereInQuery - Willing to pay for a fix

opened this issue · comments

There is an Odesk contract open for anybody willing to give this a go.. should be a quick fix if the library works as expected.
https://www.odesk.com/jobs/PHP-Parse-Queries_~~9e27b82a5a1c762e

What I am trying to do:
I have two Classes (User and Activity). The activity class as two pointers to the User class (toUser and fromUser). My query needs to determine if there is an activity with the field "type" set to a value of "followed" for two email address's which point to the User class. My understanding is the best way to do this is an inner query which I have outlined below, but I'm having issues.

Here is the Error I am getting when I execute my query below.
"Class name must be a string"

Here is my query:

       //Query the specific users
        $usersQuery = new parseQuery('_User');
        $emailArray = array($publisherInfo, $consumerInfo);
        $usersQuery->whereContainedIn('email', $emailArray);

        //Get the activities within the subquery
        $activityQuery = new parseQuery('Activity');
        $activityQuery->where("type", "followed");
        $activityQuery->whereInclude('fromUser');

        $activityQuery->whereInQuery('fromUser', '_User', $usersQuery);
        $result = $activityQuery->find();
    return $result;

Update
I change the lines of the lines above to reflect your recommendations. Independently both of these queries will return results when run as either $usersQuery.find() or $activityQuery.find(). Here is sample output from these independent queries.

Users Result

  (
                    [email] => dougd@mydomain.com
                    [firstName] => Doug
                    [fullName] => Doug D
                    [isConsumer] => 1
                    [lastName] => D
                    [username] => dougd
                    [createdAt] => 2013-11-28T19:34:16.731Z
                    [updatedAt] => 2013-12-02T15:28:13.519Z
                    [objectId] => UoXeoKk4ij
 )

Activity Result

  [results] => Array
        (
            [0] => stdClass Object
                (
                    [fromUser] => stdClass Object
                        (
                            [email] => ld@mydomain.com
                            [firstName] => Lisa
                            [fullName] => Lisa D
                            [image] => stdClass Object
                                (
                                    [__type] => File
                                    [name] => 24283a25-574f-4dbb-assb-5444ae1f1642-2013-09-22-231519_image.jpeg
                                    [url] => http://files.parse.com/e/24283a25-574f-4dbb-abeb-2013-09-22-231519_image.jpe
g
                                )

                            [isConsumer] => 
                            [lastName] => D
                            [phone1] => 
                            [thumbnail] => stdClass Object
                                (
                                    [__type] => File
                                    [name] => f94f300a-5293-4a15-8640-3324523454-2013-09-22-231519_image.jpeg
                                    [url] => http://files.parse.com/ecabab4c\0-3b0271d8f084-2013-09-22-231519_image.jpe
g
                                )

                            [username] => ld@mydomain.com
                            [createdAt] => 2013-12-02T01:26:20.486Z
                            [updatedAt] => 2013-12-02T15:24:06.641Z
                            [objectId] => dIrwAyLGuS
                            [__type] => Object
                            [className] => _User
                        )

                    [toUser] => stdClass Object
                        (
                            [__type] => Pointer
                            [className] => _User
                            [objectId] => UoXeoKk4ij
                        )

                    [type] => followed
                    [createdAt] => 2013-12-02T17:06:41.169Z
                    [updatedAt] => 2013-12-02T17:06:48.675Z
                    [objectId] => PxEcqhrLVg
                )

Well firstly you can change this these lines:

From:

$usersQuery = new parseQuery($class = '_User');
$activityQuery = new parseQuery($class = 'Activity');

To:

$usersQuery = new parseQuery('_User');
$activityQuery = new parseQuery('Activity');

_Just to shorten the code._

Do you know where abouts your getting this error from? Is it in the $activityQuery or $usersQuery

Also to help you (and me) you can enable the response and arguments given in the query by uncommenting lines 116-121 in parse.php

Should look like this:

if(!in_array($responseCode,$expectedCode)){
     print_r($response);
     print_r($args);                
}

remember to put back once problem solved

Also you might need to remove the if statement as sometimes the responseCode & expectedCode are true but its not what you want.

So if you could do that and paste me the information outputted by the above line.

Thanks
Eli

My last comment was invalid. Mistake on my side. I have now updated the last couple of lines of my code as follows:

$activityQuery->whereInQuery('fromUser', '_User', $usersQuery);
$result = $activityQuery->find();

I have updated the main ticket to reflect the code.

Here is the debugging information from the parse request:

response code: 400
expected code: Array ( [0] => 200 ) 1
response: {"code":103,"error":"class name must be a string"

Hey is there a reason you are using "_Users" to query a user? Check out this example here:

https://github.com/apotropaic/parse.com-php-library/blob/master/tests/parseUserTest.php#L81

you should be querying like this: $usersQuery = new parseQuery('users');

@apotropaic - I changed it to 'users' as you recommend, but that didn't seem to make any difference. I can't remember why I used '_User', but I will be sure to avoid that in the future. Any idea why the whereInQuery not working ?

Its hard to say without looking at actual data at this point. Anyway you could take a screenshot of your parse data?

Are you still getting 'class name must be a string'?

per the parse docs and error code 103 means this:

Error code indicating a missing or invalid classname. Classnames are case-sensitive. They must start with a letter, and a-zA-Z0-9_ are the only valid characters.

so something somewhere has a funky class name in it

ok.. I’ll grab a screenshot right now.

On Dec 10, 2013, at 2:09 PM, apotropaic notifications@github.com wrote:

Its hard to say without looking at actual data at this point. Anyway you could take a screenshot of your parse data?

Are you still getting 'class name must be a string'?

per the parse docs and error code 103 means this:

Error code indicating a missing or invalid classname. Classnames are case-sensitive. They must start with a letter, and a-zA-Z0-9_ are the only valid characters.

so something somewhere has a funky class name in it


Reply to this email directly or view it on GitHub.

@apotropaic - Here are the screenshots. I had to grey out some of the data. The data highlighted in green shows the relationships..

userclass
activityclass

@apotropaic - See anything unusual ? Is it possible that the classname should be a pointer in this case?

I'm not seeing anything unusual. Can you try to use wherePointer instead of whereInQuery?

https://github.com/apotropaic/parse.com-php-library/blob/master/parseQuery.php#L284

Unfortunately, I can't use wherePointer. Think I will just have to execute separate queries

@apotropaic - I have tried wherePointer now and that isn't working either:

$activityQuery->wherePointer('fromUser', 'Activity', 'zGfeoiDA7o');

Has anybody had either of these two queries working ?

I am having the same problem as well. Please let me know if/when you fix it.

@mdaymond

Does the following return anything?

$activityQuery = new parseQuery('Activity');
$activityQuery->wherePointer('fromUser', '_User', 'zGfeoiDA7o');
$result = $activityQuery->find();
return $result;

If not what kinda error do you get?

@apotropaic @elistone

What I'm trying to do is to find all the activities by passing an array of users. so wherePointer will not work for me.

I want to use something similar to the following

//This will get me all the users that has objectId from the array passed
$usersQuery = new parseQuery('_User');
$objectId_Array = array('6WDTHv03fB','1Q4sBxEekt');
$usersQuery->whereContainedIn('objectId', $objectId_Array);
$activityQuery = new parseQuery('Activity');
$activityQuery->whereInQuery('fromUser', '_User', $usersQuery );
$result = $activityQuery->find();

the error I get
Fatal error: Uncaught ParseLibraryException: [103]: parse.com error: class name must be a string
/parse.php on line 182

Does my code make sense!!

Thanks for your help

@ramezdebbas I'm trying to work it out. I am getting the same error on my system and cannot work out what class "must be a string".

I shall let you know.

@mdaymond @ramezdebbas Think I found the issue, working on a fix now.

@mdaymond @ramezdebbas
Ok I have a possible fix, I am no longer getting any error messages from this so check it out and let me know how it goes.

You need to change the whereInQuery function from:
Found in ParseQuery.php Line 306

    public function whereInQuery($key,$className,$inQuery){
        if(isset($key) && isset($className)){
            $this->_query[$key] = array(
                '$inQuery' => $inQuery,
                'className' => $className
            );
        }   
        else{
            $this->throwError('the $key and $value parameters must be set when setting a "where" query method');        
        }

    }

To:

    public function whereInQuery($key,$className,$inQuery){
        if(isset($key) && isset($className)){
            $inQuery->className = $className;
            $this->_query[$key] = array(
                '$inQuery' => $inQuery
            );
        }   
        else{
            $this->throwError('the $key and $value parameters must be set when setting a "where" query method');        
        }

    }

If it works I shall update my fork.

@elistone , I changed , it actually returned some results , but for some reasons it did not query what I passed to it. It just retuned all the rows in the table activity.

What kind of input the $usersQuery should be

$usersQuery = new parseQuery('_User');
$objectId_Array = array('6WDTHv03fB','1Q4sBxEekt');
$usersQuery->whereContainedIn('objectId', $objectId_Array);
$activityQuery->whereInQuery('fromUser', '_User', $usersQuery );

I'm expecting to get all the activities of those users that i Passed in the userQuery, however it's returning all the rows of all the users.

Thanks again for your help
Cheers,
Ramez

@ramezdebbas, could you try this for me.

change the whereInQuery function to:

    public function whereInQuery($key,$className,$inQuery){
        if(isset($key) && isset($className)){
            if(is_array($inQuery)){
                $inQuery["className"] = $className;
            }elseif(is_object($inQuery)){
                $inQuery->className = $className;
            }
            $this->_query[$key] = array(
                '$inQuery' => $inQuery
            );
        }   
        else{
            $this->throwError('the $key and $value parameters must be set when setting a "where" query method');        
        }

    }

and at the top of parseQuery.php change the private $_query = array(); to public $_query = array();

Lastly change the $activityQuery to:

$activityQuery->whereInQuery('fromUser', 'users', $usersQuery->_query);

Let me know how that goes.

@elistone

No It didn't work as expected
Here is my $usersQuery->_query

{
    "email": {
        "$in": [
            "example1@google.com",
            "example2@google.com",
            "example3@google.com"
        ]
    }
}

When I use the whereInQuery with 'users' not '_User'

I get any empty result

{
    "results": []
}

if I use '_User' instead 'users'
I get all the rows in the table activity

What I really want to do is pretty much like the below code but instead I wanted to check for multiple of them.
I can pretty much do it by a loop for every user and get their activity and merge them together but that is many transactions and I wanted to use the same function such as "whereContainedIn" but for a pointer.

    function getActivityByUser($user){
        $parseQuery = new parseQuery('Activities');
        $parseQuery->wherePointer('fromUser', '_User', $user);
    $return = $parseQuery->find();
    return $return;
    }   

Thanks for your time.

Cheers,
Ramez

Hi @elistone

we figured out the problem, tried it out with curl and it worked. Here is what I found
the parseQuery->_query looks like the following

{
    "User": {
        "$inQuery": {
            "email": {
                "$in": [
                    "example1@gmail.com",
                    "example2@gmail.com",
                    "example3@gmail.com"
                ]
            },
            "className": "_User"
        }
    }
}

and if you compare what I got from the curl input as follows:
there was missing a "where"

    "User": {
        "$inQuery": {
         "where" :{
            "email": {
                "$in": [
                    "example1@gmail.com",
                    "example2@gmail.com",
                    "example3@gmail.com"
                ]
            }},
            "className": "_User"
        }
    }
}

so I changed my command to the following and it worked

$parseQuery->whereInQuery('User', '_User',  array('where' => $users->_query));

Thanks for your help
Ramez

Ah I noticed there was something wrong with the parse call I thought it was the placement of the "className" I can try and look at fixing that later.

On 30 Dec 2013, at 07:07 pm, Rameez notifications@github.com wrote:

Hi @elistone

we figured out the problem, tried it out with curl and it worked. Here is what I found
the parseQuery->_query looks like the following

{
"User": {
"$inQuery": {
"email": {
"$in": [
"example1@gmail.com",
"example2@gmail.com",
"example3@gmail.com"
]
},
"className": "_User"
}
}
}
and if you compare what I got from the curl input as follows:
there was missing a "where"

"User": {
    "$inQuery": {
     "where" :{
        "email": {
            "$in": [
                "example1@gmail.com",
                "example2@gmail.com",
                "example3@gmail.com"
            ]
        }},
        "className": "_User"
    }
}

}
Let me know if you managed to make it work!!

Thanks
Ramez


Reply to this email directly or view it on GitHub.

@elistone
since I need the whereInQuery function too, I just would like to ask when you plan to release a fix for this issue. According to the dates of the latest release and your last comment on this conversation it seems like you haven't done so yet. Do you plan to release it any time soon?

Thanks in advance!

@elistone
Alternatively can you tell which lines/functions exactly have to be changed and how the function call has to look like in order to get it working on our on. Would be very much appreciated! Thanks!