i have written following code to learn how fql multiquery works:
include_once "fbmain.php";
try{
$your_id=xxxxxxxx;
$fql= '{
"friends":"SELECT uid2 FROM friend WHERE uid1='.$your_uid.',"
"friendinfo":"SELECT * FROM standard_user_info WHERE uid IN (SELECT uid2
FROM #friends)"
}';
$res = $facebook->api_client->fql_multiquery($fql);
}
catch(Exception $o){
d($o); // d() is function to print
}
but the output shows error
Call to a member function fql_multiquery() on a non-object on line 9
i have also tried other queries instead of these two , but the problem remains same. i am using php sdk 3.0.
help pls.
I do not use Multi Query, since fql has moved to the graph api. Instead i use batch request.
Here is a sample of a request of /feed, the comments of the 1st 10 results and fql multi of the permalink from the 1st 10 posts. I am sure this is a bit over kill for what you need but is the best example i have for mixing graph and fql and using name feature, which seems is what you need to carry friends.
https://developers.facebook.com/docs/reference/api/batch/
<?php
if($type=="home"){
$relURL = '/'.$pageid.'/'.$type.'?'.$access_token.'%26limit='.$limit.'%26return_ssl_resources=1%26fields=id,from,name,message,likes,comments,link,picture,caption,story,source,created_time,type,actions,application,object_id,description%26since='.$since.'%26until='.$until.'%26offset='.$offset.'';
}else{
$relURL = '/'.$pageid.'/'.$type.'?'.$app_access_token.'%26limit='.$limit.'%26return_ssl_resources=1%26fields=id,from,name,message,likes,comments,link,picture,caption,story,source,created_time,type,actions,application,object_id,description%26since='.$since.'%26until='.$until.'%26offset='.$offset.'';
}
$queryProfile = array(
array('method' => 'GET', 'relative_url' => '/'.$pageid.'?fields=id,name,link,picture%26'.$app_access_token.''),
array('method' => 'GET', 'relative_url' => ''.$relURL.'', 'name' => 'comments', 'omit_response_on_success' => false),
array('method' => 'GET', 'relative_url' => '/{result=comments:$.data.0.id}/comments?fields=id,from,message,created_time%26limit=3%26offset=0'),
array('method' => 'GET', 'relative_url' => '/{result=comments:$.data.1.id}/comments?fields=id,from,message,created_time%26limit=3%26offset=0'),
array('method' => 'GET', 'relative_url' => '/{result=comments:$.data.2.id}/comments?fields=id,from,message,created_time%26limit=3%26offset=0'),
array('method' => 'GET', 'relative_url' => '/{result=comments:$.data.3.id}/comments?fields=id,from,message,created_time%26limit=3%26offset=0'),
array('method' => 'GET', 'relative_url' => '/{result=comments:$.data.4.id}/comments?fields=id,from,message,created_time%26limit=3%26offset=0'),
array('method' => 'GET', 'relative_url' => '/{result=comments:$.data.5.id}/comments?fields=id,from,message,created_time%26limit=3%26offset=0'),
array('method' => 'GET', 'relative_url' => '/{result=comments:$.data.6.id}/comments?fields=id,from,message,created_time%26limit=3%26offset=0'),
array('method' => 'GET', 'relative_url' => '/{result=comments:$.data.7.id}/comments?fields=id,from,message,created_time%26limit=3%26offset=0'),
array('method' => 'GET', 'relative_url' => '/{result=comments:$.data.8.id}/comments?fields=id,from,message,created_time%26limit=3%26offset=0'),
array('method' => 'GET', 'relative_url' => '/{result=comments:$.data.9.id}/comments?fields=id,from,message,created_time%26limit=3%26offset=0'),
array('method' => 'GET', 'relative_url' => '/fql?q=SELECT+permalink+FROM+stream+WHERE+source_id=\''.$pageid.'\'+AND+post_id=\'{result=comments:$.data.0.id}\''),
array('method' => 'GET', 'relative_url' => '/fql?q=SELECT+permalink+FROM+stream+WHERE+source_id=\''.$pageid.'\'+AND+post_id=\'{result=comments:$.data.1.id}\''),
array('method' => 'GET', 'relative_url' => '/fql?q=SELECT+permalink+FROM+stream+WHERE+source_id=\''.$pageid.'\'+AND+post_id=\'{result=comments:$.data.2.id}\''),
array('method' => 'GET', 'relative_url' => '/fql?q=SELECT+permalink+FROM+stream+WHERE+source_id=\''.$pageid.'\'+AND+post_id=\'{result=comments:$.data.3.id}\''),
array('method' => 'GET', 'relative_url' => '/fql?q=SELECT+permalink+FROM+stream+WHERE+source_id=\''.$pageid.'\'+AND+post_id=\'{result=comments:$.data.4.id}\''),
array('method' => 'GET', 'relative_url' => '/fql?q=SELECT+permalink+FROM+stream+WHERE+source_id=\''.$pageid.'\'+AND+post_id=\'{result=comments:$.data.5.id}\''),
array('method' => 'GET', 'relative_url' => '/fql?q=SELECT+permalink+FROM+stream+WHERE+source_id=\''.$pageid.'\'+AND+post_id=\'{result=comments:$.data.6.id}\''),
array('method' => 'GET', 'relative_url' => '/fql?q=SELECT+permalink+FROM+stream+WHERE+source_id=\''.$pageid.'\'+AND+post_id=\'{result=comments:$.data.7.id}\''),
//array('method' => 'GET', 'relative_url' => '/'.$pageInfo[id].'/photos?fields=id,name%26limit=9')
);
$batchResponse = $facebook->api('?batch='.json_encode($queryProfile), 'POST');
$pageInfo = json_decode($batchResponse[0]['body'], true);
$pageType = $pageInfo[type];
$pageLink = $pageInfo[link];
$thispageid = $pageInfo[id];
$MEcomments = json_decode($batchResponse[1]['body'], true);
?>
Looks rather a problem with the instantiation of
$facebook->api_client
Worth to note also that in [standard_user_info] the column [uid] is of type string so you would probably also need to add quotes.
https://developers.facebook.com/docs/reference/fql/standard_user_info/
According to FB docs, FQL multiquery should be faster than subsequent batch calls.
https://developers.facebook.com/docs/reference/fql/
Related
I am struggling with regex routing....
The following urls should be valid:
/shop/api/list
/shop/api/cart
/shop/api/login
/shop/api/details/0123456789
And the details url, the last one, is not really cooperating with the following route:
'child_routes' => array(
'angularlist' => array(
'type' => 'Regex',
'options' => array(
'regex' => '/api/(?<page>login|cart|list|details(?<id>\/[0-9]+))',
'spec' => '/api/%page%[/:%id%]',
'defaults' => array(
'__NAMESPACE__' => 'Shop\Controller',
'controller' => 'Api',
//'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => 'list',
// 'param' => '[0-9]',
),
/* todo ipv elke child toe te voegen 'route' => '/api/[:action]', 'constraints' => array(
'action' => 'list|details|login|dashboard'
)*/
),
),
)
Instead of struggling with less-readable & dirty regex hacks, you can easily implement a Segment route stack like below:
'shop' => array(
'type' => 'Segment',
'options' => array(
'route' => '/shop/api',
'defaults' => array(
'__NAMESPACE__' => 'Shop\Controller',
'controller' => 'Api',
'action' => 'index'
),
),
'may_terminate' => true,
'child_routes' => array(
'angularlist' => array(
'type' => 'Segment',
'options' => array(
'route' => '/:action[/:id]', // id is optional
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'action' => 'index',
),
),
),
)
Based on this stackoverflow question 15077075 i have accomplished that my application has a regex based route so i can pass this to my view and edit action.
app/123 - app controller view action (get by article id)
app/name-of-article - app controller view action (get by article name)
app/123/edit - app controller edit action (article id)
app/name-of-article/edit - app controller edit action (article name)
app/search/{search-string} - app controler search action (currently only accepts a searchstring without spaces and special characters)
This i have accomplished with the code below and is similar to the code in the link above:
'app' => array(
'type' => 'literal',
'options' => array(
'route' => '/app',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'index',
),
),
'may_terminate' => true,
),
'view' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'view',
),
'spec' => '/app/%view%',
),
'priority' => -1000,
),
'edit' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)/(?<edit>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'edit',
),
'spec' => '/app/%view%/%edit%',
),
'priority' => -1000,
),
I have twoone issue
the first is that the url viewhelper doesn't recognize my routes
$controller = app
$action = recent
$this->url( $controller, array( 'action' => $action ) )
it just prints /app instead of /app/recent,
The same occurs when $action = 'search' or $action = 'new' it only prints /app
the second is that the search is recognized to its controller action only it fails when i put spaces or special characters in it
when i try to add \s in the constraints of the searchkey ( '[\sa-zA-Z0-9_-]+' ) it routes to the edit function
the route of search looks like this
Edited the route to this and it worked
'search' => array(
'type' => 'literal',
'options' => array(
'route' => '/app/search',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'search',
),
),
'may_terminate' => true,
'child_routes' => array(
'search' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:searchkey]',
'constraints' => array(
'searchkey' => '[a-zA-Z0-9_\+-]+'
),
'defaults' => array(
'action' => 'search'
),
),
),
),
),
i hope it's clear what i want if any code snippits are needed please ask
Sorted it out!
If one needs to get routes in his application this way you can use the code below
/App App/Index
/App/name-of-article App/View
/App/123 App/View
/App/name-of-article/edit App/Edit
/App/123/edit App/Edit
/App/recent App/Recent
/App/search App/Search
/App/new App/New
In my module.config.php i changed the route to:
'app' => array(
'type' => 'segment',
'options' => array(
'route' => '/app[/:action]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'index',
),
),
'may_terminate' => true,
),
'search' => array(
'type' => 'literal',
'options' => array(
'route' => '/app/search',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'search',
),
),
'priority' => 1,
'may_terminate' => true,
'child_routes' => array(
'search' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:searchkey]',
'constraints' => array(
'searchkey' => '[\sa-zA-Z0-9_\+-]+'
),
'defaults' => array(
'action' => 'search'
),
),
'priority' => 2,
'may_terminate' => true,
),
),
),
'new' => array(
'type' => 'literal',
'options' => array(
'route' => '/app/new',
'defaults' => array(
'controller' => 'App',
'action' => 'recent',
),
),
'priority' => 2,
),
'view' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'view',
),
'spec' => '/app/%view%',
),
),
'edit' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)/(?<edit>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'edit',
),
'spec' => '/app/%view%/%edit%',
),
),
If you need other routes you can just add a new literal route below te app route, make sure you don't forget to set the priority
I use CakePHP 2.4.6.
In routes.php, I put
Router::mapResources('themes');
Then, I can access 'localhost/themes/211' which display screen generated by the action "view" of the controller "themes" just as I expect.
BUt in a view file, I use
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' => 'view',
$theme['Theme']['id']));
?>
Then this generate '/themes/view/211' in html, where I expected '/themes/211'.
Does $this->Html->url() generate RESTful URL?
If not, How can Cake view file generate RESTful URL in other way?
Do I do any mistake?
Thanks in advance.
leave the action blank
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' => '',
$theme['Theme']['id']));
?>
Or,
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' =>$theme['Theme']['id']
));
?>
If you want this to happen, go to your \app\Config\routes.php and add Router::connect('/themes', array('controller' => 'themes', 'action' => 'view'));
You don't have to change
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' => 'view',
$theme['Theme']['id']));
?>
You probably have some more Restfull api calls to define, so maybe something more generic:
Router::connect('/api/:controller', array('api' => true, 'action' => 'index', "[method]" => "GET"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
Router::connect('/api/:controller', array('api' => true, 'action' => 'add', "[method]" => "POST"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
Router::connect('/api/:controller/:id', array('api' => true, 'action' => 'view', "[method]" => "GET"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
Router::connect('/api/:controller/:id', array('api' => true, 'action' => 'edit', "[method]" => "POST"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
These route calls like "api/Themes/123" to the action index in the Themes controller, however, if you try and do a POST request it will route to the add action.
I have this contact form which also relates to a few other tables with a HABTM relationship. They are displayed in the form either as a list or as checkboxes. What I want is to be able to search through them while still in the form to select those that are applicable to the contact I am adding with the form. I'm not sure how to do this- was thinking maybe Javascript?
An example of what I am talking about is like Facebook when you're searching through your friends list.
Below are the HABTM relationships for the Contact Model:
public $hasAndBelongsToMany = array(
'Company' => array(
'className' => 'Company',
'joinTable' => 'companies_contacts',
'foreignKey' => 'contact_id',
'associationForeignKey' => 'company_id',
'unique' => 'keepExisting',
'dependent' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
),
'Event' => array(
'className' => 'Event',
'joinTable' => 'contacts_events',
'foreignKey' => 'contact_id',
'associationForeignKey' => 'event_id',
'unique' => 'keepExisting',
'dependent' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
),
'Screenoccupation' => array(
'className' => 'Screenoccupation',
'joinTable' => 'contacts_screenoccupations',
'foreignKey' => 'contact_id',
'associationForeignKey' => 'screenoccupation_id',
'unique' => 'keepExisting',
'dependent' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
),
'Tapearchive' => array(
'className' => 'Tapearchive',
'joinTable' => 'contacts_tapearchives',
'foreignKey' => 'contact_id',
'associationForeignKey' => 'tapearchive_id',
'unique' => 'keepExisting',
'dependent' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
),
'Relation' => array(
'className' => 'Contact',
'joinTable' => 'contacts_contacts',
'foreignKey' => 'contact_id',
'associationForeignKey' => 'related_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
Not sure what other codes I need to show you guys, so please do let me know what codes are needed and I will add them to this question.
Thanks!
You could use a jquery plugin to do the job for you.
It seems that this one corresponds to your criteria. Chosen is nice too.
Anyway, do a google search to see all the jquery plugin available, and see if one fits your need.
I want to build a FB app which posts messages to the walls of those registered for the app.
There are two setups:
One message to many people (1-many, could occur few times a day)
Many user-specific massages (1-1, but many of them, could occur few times a day for each user)
All in all; one user could get a few different updates on his wall per day, but it could affect many users (that's pretty much the whole point of my idea)
Into what extend is Facebook going to allow me to do this, and won't think I'll be spamming.
PS:
I've come along this post, which seems to have remained unsolved...:
Post on Multiple Friend's Wall
And this post, which doesn't make it clear for me whether my idea is something I should start or not ;)
Graph API post to wall limitation
You can use Facebook batch API to do what you intent.
You can get more information on Facebook batch request at: http://25labs.com/tutorial-post-to-multiple-facebook-wall-or-timeline-in-one-go-using-graph-api-batch-request/
$batchPost[] = array(
'method' => 'POST',
'relative_url' => "/{ID1}/feed?access_token={ACCESS_TOKEN_FOR_ID1}",
'body' => http_build_query($body) );
$batchPost[] = array(
'method' => 'POST',
'relative_url' => "/{ID2}/feed?access_token={ACCESS_TOKEN_FOR_ID2}",
'body' => http_build_query($body) );
$batchPost[] = array(
'method' => 'POST',
'relative_url' => "/{ID3}/feed?access_token={ACCESS_TOKEN_FOR_ID3}",
'body' => http_build_query($body) );
$multiPostResponse = $facebook->api('?batch='.urlencode(json_encode($batchPost)), 'POST');
I developed an app in my website http://www.cefozyt.com which can post links, message etc. to multiple facebook users wall & groups. I used :-
if($user){
// Proceed knowing you have a logged in user who has a valid session.
//========= Batch requests over the Facebook Graph API using the PHP-SDK ========
// Save your method calls into an array
$queries = array(
array('method' => 'GET', 'relative_url' => '/'.$user),
array('method' => 'GET', 'relative_url' => '/'.$user.'/friends'),
array('method' => 'GET', 'relative_url' => '/'.$user.'/groups'),
array('method' => 'GET', 'relative_url' => '/'.$user.'/likes'),
);
// POST your queries to the batch endpoint on the graph.
try{
$batchResponse = $facebook->api('?batch='.json_encode($queries), 'POST');
}catch(Exception $o){
error_log($o);
}
//Return values are indexed in order of the original array, content is in ['body'] as a JSON
//string. Decode for use as a PHP array.
$user_info = json_decode($batchResponse[0]['body'], TRUE);
$friends_list = json_decode($batchResponse[1]['body'], TRUE);
$groups = json_decode($batchResponse[2]['body'], TRUE);
$pages = json_decode($batchResponse[3]['body'], TRUE);
//========= Batch requests over the Facebook Graph API using the PHP-SDK ends =====
if(isset($_POST['submit_x'])){
if($_POST['message'] || $_POST['link'] || $_POST['picture']) {
$body = array(
'message' => $_POST['message'],
'link' => $_POST['link'],
'picture' => $_POST['picture'],
'name' => $_POST['name'],
'caption' => $_POST['caption'],
'description' => $_POST['description'],
);
$batchPost=array();
$i=1;
$flag=1;
foreach($_POST as $key => $value) {
if(strpos($key,"id_") === 0) {
$batchPost[] = array('method' => 'POST', 'relative_url' => "/$value/feed", 'body' => http_build_query($body));
if($i++ == 50) {
try{
$multiPostResponse = $facebook->api('?batch='.urlencode(json_encode($batchPost)), 'POST');
}catch(FacebookApiException $e){
error_log($e);
echo("Batch Post Failed");
}
$flag=0;
unset($batchPost);
$i=1;
}
}
}
if(isset($batchPost) && count($batchPost) > 0 ) {
try{
$multiPostResponse = $facebook->api('?batch='.urlencode(json_encode($batchPost)), 'POST');
}catch(FacebookApiException $e){
error_log($e);
echo("Batch Post Failed");
}
$flag=0;
}
}
else {
$flag=2;
}
}
}
?>