How to retrieve all comments of the Fan Page - facebook

I need to get all comments of the Fan Page. Not only from the wall, but from the albums, photos, notes, etc.
I solved this problem in such a way. First I get all objects (albums, notes, etc.) of the Fan Page. Second I get commets to each object, using FQL multi query.
// Import comment list
$facebook = \Yii::app()->facebook->setUserAccessToken();
$commentsColumns = array(
'xid', 'object_id', 'post_id', 'fromid', 'time', 'text', 'username',
'reply_xid', 'post_fbid', 'app_id', 'likes', 'comments', 'user_likes',
'is_private', 'id',
);
$offset = 0;
$limit = 30;
while (($offset <= count($objectIdList)) && ($offset <= count($postIdList))) {
$currentObjectIdList = array_slice($objectIdList, $offset, $limit);
$currentPostIdList = array_slice($postIdList, $offset, $limit);
$multiQuery = array(
'comments' =>
' SELECT '.implode(', ', $commentsColumns).' '.
' FROM comment '.
' WHERE ((object_id IN ('.implode(',', $currentObjectIdList).')) '.
' OR (post_id IN ('.implode(',', $currentPostIdList).'))) '.
' AND (time >= ' . $lastCommentTime . ') ' .
' ORDER BY time DESC '.
' LIMIT 1000 ',
'users' =>
' SELECT uid, name ' .
' FROM user ' .
' WHERE uid IN (SELECT fromid FROM #comments) ',
'pages' =>
' SELECT page_id, name ' .
' FROM page ' .
' WHERE page_id IN (SELECT fromid FROM #comments) '
);
$multiQueryResult = $facebook->api(array(
'method' => 'fql.multiquery',
'queries' => $multiQuery
));
// Parse multi query results
$from = array();
foreach ($multiQueryResult as $result) {
switch ($result['name']) {
case 'comments':
$commentList = $result['fql_result_set'];
break;
case 'users':
case 'pages':
foreach ($result['fql_result_set'] as $set) {
switch ($result['name']) {
case 'users':
$from[$set['uid']] = $set['name'];
break;
case 'pages':
$from[$set['page_id']] = $set['name'];
break;
}
}
break;
}
}
// Save comments to local DB
foreach ($commentList as $commentData) {
$comment = new Comment();
$comment->fbId = $commentData['id'];
$comment->fbPageId = $this->fbId;
$comment->from = array(
'id' => $commentData['fromid'],
'name' => isset($from[$commentData['fromid']]) ? $from[$commentData['fromid']] : null,
);
$comment->message = $commentData['text'];
$comment->created_time = $commentData['time'];
$comment->likes = $commentData['likes'];
$comment->save();
}
// Next step
$offset = $offset + $limit;
}
This solution works, but is not pretty fast. Has anyone know better solution?

I think you can use the graph API method given below,
https://graph.facebook.com/userid/feed to get all the feeds of the user .It will return an json array,from there you can collect the comments,statuses etc etc

Related

Paragraph breaks missing from shortcode output

I created a shortcode in Wordpress to perform a query and display the content, but the content line breaks are being removed.
add_shortcode( 'resource' , 'Resource' );
function Resource($atts) {
$atts = shortcode_atts( array(
'category' => ''
), $atts );
$categories = explode(',' , $atts['category']);
$args = array(
'post_type' => 'resource',
'post_status' => 'publish',
'orderby' => 'title',
'order' => 'ASC',
'posts_per_page'=> -1,
'tax_query' => array( array(
'taxonomy' => 'category',
'field' => 'term_id',
'operator' => 'AND',
'terms' => $categories
) )
);
$string = '';
$query = new WP_Query( $args );
if( ! $query->have_posts() ) {
$string .= '<p>no listings at this time...</p>';
}
while( $query->have_posts() ){
$query->the_post();
$string .= '<div id="links"><div id="linksImage">' . get_the_post_thumbnail() . '</div>
<div id="linksDetails"><h1>'. get_the_title() .'</h1><p>' . get_the_content() . '</p>
<p>for more information CLICK HERE</div></div>';
}
wp_reset_postdata();
$output = '<div id="linksWrapper">' . $string . '</div>';
return $output;
}
Any suggestion on why this is happening and what to do to fix it. This is only happening on the shortcode output. On regular pages - the content displays correctly.
found a solution through more searches:
function get_the_content_with_formatting ($more_link_text = '(more...)', $stripteaser = 0, $more_file = '') {
$content = get_the_content($more_link_text, $stripteaser, $more_file);
$content = apply_filters('the_content', $content);
$content = str_replace(']]>', ']]>', $content);
return $content;
}
works perfect, so I thought I would share..

TYPO3: Generate in realURL multiple URLs with the same postVarSets in different levels

In my TYPO3 there are multiple storages with different sport activities.
The one belongs to place A, the other to place B with different content.
Now I would like to generate the followingURLs.
The first one is for general, the other one are specific.
/sport/golf
/place-a/sport/golf
/place-b/sport/golf
sport is decoded to /sport-detail/controller/action/sport/
I used the default lookUpTable, but the URLs cant be resolved.
'lookUpTable' => array(
'table' => 'tx_myext_domain_model_sport',
'id_field' => 'uid',
'alias_field' => "url",
'addWhereClause' => ' AND deleted = 0 AND hidden = 0',
'useUniqueCache' => 1,
'languageGetVar' => 'L',
'languageField' => 'sys_language_uid',
'transOrigPointerField' => 'l10n_parent',
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-',
),
)
What is needed to create valid URLs, without golf-1 etc.. for all levels?
I'm not exactly sure what you want to do. Are "place-a" and "place-b" separate pages or are these additional parameters for your ext?Also, could you provide the full RealURL config?
Depending on the targeted performance you could also just avoid using the UniqueCache...
Finally I wrote a UserFunction that fulfills my needs. In this function I extend the given lookuptable function from realURL and fetch me the values yourself.
The model has been renamed in the meantime to activity.
I do now save the detail pid for the show action and the storage pid in the sport model so I can search the whole URL path to find place name and lookup the storage pid. With the storage pid of the place I can find the right activity. And with a correct lookup in the database I can return a valid ID.
For SEO reasons I added a new field URL to the model that contains the string in the URL path. In the id2alias method I return the url value of the activity with the given ID.
I noticed one behavior that realURL doesn't find the correct entry in the caching table once all the parameters are hashed, so I had to exclude the activity GETvar from cHash generation.
$GLOBALS['TYPO3_CONF_VARS']['FE']['cHashExcludedParameters'] = tx_myext_activity[activity]
After all this is my working setup :-)
RealURL config:
'GETvar' => 'tx_myext_activity[activity]',
'type' => 'user',
'languageGetVar' => 'L',
'languageField' => 'sys_language_uid',
'useUniqueCache' => 0,
'userFunc' => 'EXT:MyUserFunc.php:&MyUserFunc->main'
The UserFunction handles now the URL generation.
<?php
class MyUserFunc
{
protected $sys_language_uid;
protected $params;
protected $localizedStrings;
public function main($params, $ref)
{
if ($params) {
$this->params = $params;
$dirParts = $this->params['pObj']->dirParts;
//language
$this->sys_language_uid = 0;
//is realUrl in encode or decode
if ($this->params['decodeAlias']) {
return $this->alias2id($this->params['value']);
} else {
return $this->id2alias($this->params['value']);
}
}
}
/*
* Generate URL param
*/
protected function id2alias($value)
{
$sysLanguageToBuild = $this->params['pathParts'][0];
//if not default, use l10n_parent with sysuid
if ($sysLanguageToBuild > 0) {
$additionalWhere = ' AND l10n_parent = ' . (int)$value;
$additionalWhere .= ' AND sys_language_uid = ' . (int)$sysLanguageToBuild;
} else {
$additionalWhere = ' AND uid = ' . (int)$value;
}
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'url',
'tx_myext_domain_model_activity',
'deleted = 0 AND hidden = 0' . $additionalWhere
);
$activityRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
if (is_array($activityRow)) {
return $activityRow['url'];
}
return 'undefined';
}
/**
* Decode string to uid
* respect activities with different pid
*
* #param $value
* #return int
*/
protected function alias2id($value)
{
$dirParts = $this->params['pObj']->dirParts; //get array of complete path
$place = htmlspecialchars($this->params['pObj']->dirParts[2]); //get place
//transform place string
$place = strtolower($place);
$place = preg_replace("/[^A-Za-z0-9\s-._\/]/", "", $place);
$place = trim(preg_replace("/[\s-]+/", " ", $place));
//Query Place
$placeRes = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'uid, activity_storage_page',
'tx_myext_domain_model_place',
'deleted = 0 AND hidden = 0 AND sys_language_uid = '. $this->sys_language_uid .
' AND LOWER(name) = "' . $place . '"'
);
$placeRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($placeRes);
//Query Activity
if (is_array($placeRow)) {
$additionalWhere .= " AND tx_myext_domain_model_activity.pid = '" . (int)$placeRow['activity_storage_page'] . "'";
}
$additionalWhere = " AND tx_myext_domain_model_activity.sys_language_uid = " . $this->sys_language_uid;
$additionalWhere .= " AND tx_myext_domain_model_activity.url = '" . $value . "'";
$additionalWhere .= " AND tx_myext_domain_model_activity.pid = '" . $pid . "'";
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'tx_myext_domain_model_activity.uid',
'tx_myext_domain_model_activity',
'deleted = 0 AND hidden = 0' . $additionalWhere
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
return (int)$row['uid'];
}
//catch old URLs and return uid
$additionalWhere = " AND tx_myext_domain_model_activity.sys_language_uid = " . $this->sys_language_uid;
$additionalWhere .= " AND tx_myext_domain_model_activity.name = '" . $value . "'";
$resElse = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'tx_myext_domain_model_activity.uid',
'tx_myext_domain_model_activity',
'deleted = 0 AND hidden = 0' . $additionalWhere
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($resElse)) {
return (int)$row['uid'];
}
return false;
}
}

Filter users by fullname in configureDatagridFilters

I'm trying to filter the user list with de getFullname() method, with no result.
$filterMapper
->add('fullname', null, array('label' => 'Full name'))
FileTypeGuesser don't find the property 'fullname'.
its resolves using callback
->add('NombreCompleto', 'doctrine_orm_callback', array(
'callback' => function($queryBuilder, $alias, $field, $value) {
if (!$value || $value['value'] == '') {
return;
}
$queryBuilder->andWhere('CONCAT(' . $alias . '.firstname, CONCAT(\' \', ' . $alias . '.lastname)) LIKE :term')->setParameter(':term', '%' . $value['value'] . '%');
return true;
},
'field_type' => 'text'
))

I've user_birthday, but FQL returns NULL in birthday result

This is my Facebook UID: 1053557928. If I run this FQL in the explorer, I get results I expect. To be more precise, I get exactly the "birthday" field. I have the correct permission "user_birthday".
SELECT uid, birthday, name
FROM user
WHERE uid IN (
SELECT uid2
FROM friend
WHERE uid1='1053557928'
) limit 3
If I run same query from a Symfony2 command console, I get the results, but no the field birthday. I am sure to have permissions.
array(3) {
[0] =>
array(3) {
'uid' =>
string(9) "0987654321234567890"
'birthday' =>
NULL
'name' =>
string(12) "Middle John"
}
[1] =>
array(3) {
'uid' =>
string(9) "0987654321234567890"
'birthday' =>
NULL
'name' =>
string(15) "Short John"
}
[2] =>
array(3) {
'uid' =>
string(9) "0987654321234567890"
'birthday' =>
NULL
'name' =>
string(12) "Long John"
}
}
Also, if I try to execute:
$accessToken = $this->container->getParameter('facebook_app_token');
$uid1 = '1053557928';
$wishInterval = new WishDates();
$startSearchDate = clone $wishInterval->getDateFrom();
$fqlDates = "";
for ($i = 0; $i <= 6; $i++) {
$month = $startSearchDate->format("F");
$day = (int)$startSearchDate->format("d");
if ($fqlDates != "") {
$fqlDates .= " OR ";
}
$fqlDates .= " strpos(birthday, \"{$month} {$day},\")>=0";
$startSearchDate->modify("+1 days");
}
$fql = "SELECT uid, birthday, name " .
" FROM user " .
" WHERE uid IN (SELECT uid2 FROM friend WHERE uid1='$uid1') limit 3";
// Interrogo Facebook
$config = array(
'appId' => $this->container->getParameter('facebook_app_id'),
'secret' => $this->container->getParameter('facebook_client_secret'),
'allowSignedRequest' => true
);
$facebook = new Facebook($config);
$query = array(
'method' => 'fql.query',
'query' => $fql,
'access_token' => $accessToken
);
$return = $facebook->api($query);
I get "Requires user session". But I am logged in with Facebook. The query generated ($fql) still works fine in facebook explorer API. But this code returns array birthday. What happen?

FQL: Order photos by likes

Is there anyway to retrieve photos ordered by the number of likes in FQL?
PLEASE NOTE: I have never played with FQL before, but I need this exact solution yesterday, so I gave it a go!
Try adding references to "like_info" in the first line in the previous answer (maybe like_info is new since you asked this?):
$fql = "SELECT like_info, object_id,src_small,link FROM photo WHERE aid = '2389563453799923709' ORDER BY like_info created DESC";
$param = array(
'method' => 'fql.query',
'query' => $fql,
'callback' => ''
);
$photos = $facebook->api($param);
This may well give you answers returned in order from most to least liked. At least, it worked for me! :)
Please note: This solution is no longer require as like_info has been added to photo
So, I'm guessing this is impossible to do nicely? Here's the ugly solution:
$fql = "SELECT object_id,src_small,link FROM photo WHERE aid = '2389563453799923709' ORDER BY created DESC";
$param = array(
'method' => 'fql.query',
'query' => $fql,
'callback' => ''
);
$photos = $facebook->api($param);
if (count($photos) > 0) {
for ($i = 0; $i < count($photos); $i++) {
$objectId = $photos[$i]['object_id'];
$like_count = $facebook->api('/'.$objectId.'/likes');
$photos[$i]['likes'] = count($like_count['data']);
}
}
function cmp($a, $b) {
if ($a['likes'] == $b['likes'])
return 0;
return $a['likes'] > $b['likes'] ? -1 : 1;
}
usort($photos, 'cmp');