Facebook Mining
Facebook Mining
Facebook Mining
Sagar Ashraf
Muhammad
Arslan Ijaz
Zeeshan Mushtaq
1
Dedication
We dedicate our dissertation work to our family and friends, our strong pillars. A special feeling
of gratitude to our loving parents whose words of encouragement and push for tenacity ring in
our ears. We also want to dedicate this Dissertation to Mr. Muhammad Salman Chaudary who
has supported us throughout the process. We will always appreciate all they have done,
especially for helping, advising and improving our skills in the new fields which were unknown
to us.
2
Declaration
This project is submitted to the Forman Christian College (A Chartered University) in partial
fulfillment of the requirements for the degree of Bachelor of Science, Majoring in Computer
Science, Software Engineering and Information technology. The project is equivalent to 28
weeks of full time studies or 6 credit hours.
Contact Information:
Sagar Ashraf
Bahar Colony #2 Durrani Street #4 House #4, Kot Lakhpat,
Lahore.
sagarashraf93@gmail.com
Zeeshan Mushtaq
House No 87 Waheed Brothers Colony 18 KM Ferozepur Road
Lahore. tranceaddict921@gmail.com
University Advisor/Supervisor:
4
Abstract
Data mining is one of the power technology that has emerged and it facilitates the users both
individuals and organizations to dig and find data from a collection or large cluster of data. It can
be used to find pattern from large group of data. For e.g. an organization can find out customer
behavior from the data collected.
Facebook is a massive social networking site turned towards fast communication. More than 2.2
billion active users publish over 510,000 comments, 293,000 statuses and 136,000 photos every
“single minute”. Facebook’s speed and ease of publication have made it an important
communication medium for people from all walk of life. Facebook is playing and important role
in all the events taking place around the world. Facebook is a great source for getting the data.
.
It is a PHP based application that will analyze a Facebook profile and would draw some useful
insights about the user’s overall personality in the form of a graph by analyzing all of it’s
previous 500 posts. More over this application will also tell based on the user’s posts that which
political party the user is supporting in the coming elections. This application will also mine
user’s recent 50 photos and describe the most liked photo of them all and it will also describe
your most favorite place based on the data this application receives. Our application would be
calling Graph API which is the Facebook’s own application programming interface to fetch the
data the application requires. The posts will be analyzed by the analyzer made in python IDE.
5
Table of Contents
1.0. Introduction........................................................................................................................................7
2.0. Literature Review................................................................................................................................8
3.0. System Architecture And Design.........................................................................................................9
4.0. Context Diagram...............................................................................................................................10
5.0. DFD Level 0........................................................................................................................................11
6.0. Use Case Model.................................................................................................................................12
7.0. ERD Diagram.....................................................................................................................................13
8.0. Implementation.................................................................................................................................14
8.1. Platform and Tools........................................................................................................................14
8.2. Xampp Server................................................................................................................................14
8.3. Python IDLE...................................................................................................................................14
8.4. Graph API......................................................................................................................................15
8.5. Visual Studio Code..............................................................................................................................16
8.6. HTML..................................................................................................................................................16
8.7. PHP.....................................................................................................................................................16
8.8. Facebook SDK Code:...........................................................................................................................17
8.9. Facebook Code For Graph API.......................................................................................................85
8.10. Facebook Code For Fetching Data and Storing it in the Database.............................................91
8.11. Personality Analyzer In Python................................................................................................108
8.12. Python code for Political Views...............................................................................................111
9.0. Methodology........................................................................................................................................114
10.0. Testing And Validation.......................................................................................................................115
10.1. Login Through Facebook................................................................................................................116
10.2. Main Homepage.............................................................................................................................118
10.3. Facebook Login Page......................................................................................................................118
10.4. Confirmation Page..........................................................................................................................119
10.5. Main Results Page (Facebook Photo Likes)....................................................................................120
10.6. Main Results Page (Personality Analysis).......................................................................................121
10.7. Main Results Page (Political Views)................................................................................................121
10.8. Main Results Page (Recent Video)..................................................................................................122
10.9. Main Results Page (Recently Liked Pages)......................................................................................122
11.0. User manual for Application..............................................................................................................123
6
12.0. Conclusion And Recommendation.....................................................................................................124
13.0. References..........................................................................................................................................125
14.0. Information Sheet..............................................................................................................................126
7
1.0. Introduction
This application of Facebook Data Mining is a PHP based application that will analyze a
Facebook user profile for posts, photos, videos, liked pages, friends and tagged places and draw
some useful insights from them. Our application would mine Facebook posts and send it to
analyzer (made using python) which will analyze all the data and draws a personality graph as in
how many positive posts are there and how many are the negative ones. Furthermore, it will also
tell that which political party the user support based on the positive posts made by that user
regarding the political party. If the user has not made any post regarding any politics than the
graph would return neutral but it would still be able to draw the overall personality graph.
Our application would also mine photos and tagged places and do some analysis on it. Our
application will return the most liked picture of the user along with the number of likes plus also
return the most tagged place of the user. Recently posted video and liked pages would also be
displayed. Graph API is the backbone of this application as it is used to mine all the Facebook
data. Facebook does not allow any other application programming interface to gather data. So
8
2.0. Literature Review
The current phase on the internet is witnessing a tremendous growth of social networks
and huge amount of new data are being created every second. With the advent of social
networks, it has become possible to disseminate this information at a very fast rate.
Millions of new user posts everyday are posted on social networking sites like Facebook,
Twitter, Instagram and many others. Among these social networking sites, Facebook is
the only a fantastic real-time social networking tool which can act as a great source of
rich information for data mining.
Data mining is the process of sorting through large data sets to identify patterns and
establish relationships to solve problems through data analysis. Data mining tools allow
enterprises to predict future trends.I n data mining, association rules are created by
analyzing data for frequent if/then patterns, then using the support and confidence criteria
to locate the most important relationships within the data. Support is how frequently the
items appear in the database, while confidence is the number of times if/then statements
are accurate.
Other data mining parameters include Sequence or Path
Analysis, Classification, Clustering and Forecasting. Sequence or Path Analysis
parameters look for patterns where one event leads to another later event. A Sequence is
an ordered list of sets of items, and it is a common type of data structure found in many
databases. A Classification parameter looks for new patterns, and might result in a
change in the way the data is organized. Classification algorithms predict variables based
on other factors within the database.
As the social media is gaining immense power with the passage of time due to its
popularity among all the age groups now, this is a need of an hour for the whole world to
take the social media seriously for the betterment and the evolution of the organizations
and businesses.
We have selected the incremental model for the development of Facebook data
mining application. We have selected this model because the app we were building have
different modules. We have developed them incrementally and then integrated them
9
altogether. We have design the model, implemented and tested incrementally (a little
more is added each time) until the product is finished. It involves both development
and maintenance. The product is satisfying all the
requirements stated
in SRS.
3.1System Architecture
10
4.0. Context Diagram
11
5.0. DFD Level 0
12
6.0. Use Case Model
13
7.0. ERD Diagram
14
8.0. Implementation
15
IDLE is intended to be a simple IDE and suitable for beginners, especially in
an educational environment. To that end, it is cross-platform, and avoids feature
clutter.
16
token). The app can then use the new User token to make Graph API requests, but
can only access that specific User's photos, videos, and email address.
The APIs provide functionality like analytics, machine learning as a service (the
Prediction API) or access to user data (when permission to read the data is given).
8.6. HTML
Hypertext Markup Language (HTML) is the standard markup language for
creating web pages and web applications.
8.7. PHP
PHP has been used to store user data and execute analyzer residing on our Xampp
local server. PHP is a server-side scripting language designed primarily for web
development but also used as a general-purpose programming language.
PHP code may be embedded into HTML or HTML5 markup, or it can be
used in combination with various web template systems, web content
management systems and web frameworks.
17
8.8. Facebook SDK Code:
Following is the Facebook SDK code that was used to call Facebook Graph API
using PHP.
/**
* Register the autoloader for the Facebook SDK classes.
*
* Based off the official PSR-4 autoloader example found here:
* https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-
examples.md
*
* @param string $class The fully-qualified class name.
*
* @return void
*/
spl_autoload_register(function ($class) {
// project-specific namespace prefix
$prefix = 'Facebook\\';
18
$customBaseDir = FACEBOOK_SDK_V4_SRC_DIR;
} elseif (defined('FACEBOOK_SDK_SRC_DIR')) {
$customBaseDir = FACEBOOK_SDK_SRC_DIR;
}
// base directory for the namespace prefix
$baseDir = $customBaseDir ?: __DIR__ . '/';
// replace the namespace prefix with the base directory, replace namespace
// separators with directory separators in the relative class name, append
// with .php
$file = rtrim($baseDir, '/') . '/' . str_replace('\\', '/', $relativeClass) . '.php';
namespace Facebook;
use Facebook\Authentication\AccessToken;
use Facebook\Authentication\OAuth2Client;
19
use Facebook\FileUpload\FacebookFile;
use Facebook\FileUpload\FacebookResumableUploader;
use Facebook\FileUpload\FacebookTransferChunk;
use Facebook\FileUpload\FacebookVideo;
use Facebook\GraphNodes\GraphEdge;
use Facebook\Url\UrlDetectionInterface;
use Facebook\Url\FacebookUrlDetectionHandler;
use Facebook\PseudoRandomString\PseudoRandomStringGeneratorFactory;
use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface;
use Facebook\HttpClients\HttpClientsFactory;
use Facebook\PersistentData\PersistentDataFactory;
use Facebook\PersistentData\PersistentDataInterface;
use Facebook\Helpers\FacebookCanvasHelper;
use Facebook\Helpers\FacebookJavaScriptHelper;
use Facebook\Helpers\FacebookPageTabHelper;
use Facebook\Helpers\FacebookRedirectLoginHelper;
use Facebook\Exceptions\FacebookSDKException;
/**
* Class Facebook
*
* @package Facebook
*/
class Facebook
{
/**
* @const string Version number of the Facebook PHP SDK.
*/
const VERSION = '5.6.1';
/**
* @const string Default Graph API version for requests.
20
*/
const DEFAULT_GRAPH_VERSION = 'v2.10';
/**
* @const string The name of the environment variable that contains the app ID.
*/
const APP_ID_ENV_NAME = 'FACEBOOK_APP_ID';
/**
* @const string The name of the environment variable that contains the app
secret.
*/
const APP_SECRET_ENV_NAME = 'FACEBOOK_APP_SECRET';
/**
* @var FacebookApp The FacebookApp entity.
*/
protected $app;
/**
* @var FacebookClient The Facebook client service.
*/
protected $client;
/**
* @var OAuth2Client The OAuth 2.0 client service.
*/
protected $oAuth2Client;
/**
* @var UrlDetectionInterface|null The URL detection handler.
*/
21
protected $urlDetectionHandler;
/**
* @var PseudoRandomStringGeneratorInterface|null The cryptographically
secure pseudo-random string generator.
*/
protected $pseudoRandomStringGenerator;
/**
* @var AccessToken|null The default access token to use with requests.
*/
protected $defaultAccessToken;
/**
* @var string|null The default Graph version we want to use.
*/
protected $defaultGraphVersion;
/**
* @var PersistentDataInterface|null The persistent data handler.
*/
protected $persistentDataHandler;
/**
* @var FacebookResponse|FacebookBatchResponse|null Stores the last request
made to Graph.
*/
protected $lastResponse;
/**
* Instantiates a new Facebook super-class object.
*
22
* @param array $config
*
* @throws FacebookSDKException
*/
public function __construct(array $config = [])
{
$config = array_merge([
'app_id' => getenv(static::APP_ID_ENV_NAME),
'app_secret' => getenv(static::APP_SECRET_ENV_NAME),
'default_graph_version' => static::DEFAULT_GRAPH_VERSION,
'enable_beta_mode' => false,
'http_client_handler' => null,
'persistent_data_handler' => null,
'pseudo_random_string_generator' => null,
'url_detection_handler' => null,
], $config);
if (!$config['app_id']) {
throw new FacebookSDKException('Required "app_id" key not supplied in
config and could not find fallback environment variable "' .
static::APP_ID_ENV_NAME . '"');
}
if (!$config['app_secret']) {
throw new FacebookSDKException('Required "app_secret" key not
supplied in config and could not find fallback environment variable "' .
static::APP_SECRET_ENV_NAME . '"');
}
if (isset($config['default_access_token'])) {
$this->setDefaultAccessToken($config['default_access_token']);
}
/**
* Returns the FacebookApp entity.
*
* @return FacebookApp
*/
public function getApp()
{
return $this->app;
}
/**
24
* Returns the FacebookClient service.
*
* @return FacebookClient
*/
public function getClient()
{
return $this->client;
}
/**
* Returns the OAuth 2.0 client service.
*
* @return OAuth2Client
*/
public function getOAuth2Client()
{
if (!$this->oAuth2Client instanceof OAuth2Client) {
$app = $this->getApp();
$client = $this->getClient();
$this->oAuth2Client = new OAuth2Client($app, $client, $this-
>defaultGraphVersion);
}
return $this->oAuth2Client;
}
/**
* Returns the last response returned from Graph.
*
* @return FacebookResponse|FacebookBatchResponse|null
*/
public function getLastResponse()
25
{
return $this->lastResponse;
}
/**
* Returns the URL detection handler.
*
* @return UrlDetectionInterface
*/
public function getUrlDetectionHandler()
{
return $this->urlDetectionHandler;
}
/**
* Changes the URL detection handler.
*
* @param UrlDetectionInterface $urlDetectionHandler
*/
private function setUrlDetectionHandler(UrlDetectionInterface
$urlDetectionHandler)
{
$this->urlDetectionHandler = $urlDetectionHandler;
}
/**
* Returns the default AccessToken entity.
*
* @return AccessToken|null
*/
public function getDefaultAccessToken()
{
26
return $this->defaultAccessToken;
}
/**
* Sets the default access token to use with requests.
*
* @param AccessToken|string $accessToken The access token to save.
*
* @throws \InvalidArgumentException
*/
public function setDefaultAccessToken($accessToken)
{
if (is_string($accessToken)) {
$this->defaultAccessToken = new AccessToken($accessToken);
return;
}
return;
}
/**
* Returns the default Graph version.
*
* @return string
27
*/
public function getDefaultGraphVersion()
{
return $this->defaultGraphVersion;
}
/**
* Returns the redirect login helper.
*
* @return FacebookRedirectLoginHelper
*/
public function getRedirectLoginHelper()
{
return new FacebookRedirectLoginHelper(
$this->getOAuth2Client(),
$this->persistentDataHandler,
$this->urlDetectionHandler,
$this->pseudoRandomStringGenerator
);
}
/**
* Returns the JavaScript helper.
*
* @return FacebookJavaScriptHelper
*/
public function getJavaScriptHelper()
{
return new FacebookJavaScriptHelper($this->app, $this->client, $this-
>defaultGraphVersion);
}
28
/**
* Returns the canvas helper.
*
* @return FacebookCanvasHelper
*/
public function getCanvasHelper()
{
return new FacebookCanvasHelper($this->app, $this->client, $this-
>defaultGraphVersion);
}
/**
* Returns the page tab helper.
*
* @return FacebookPageTabHelper
*/
public function getPageTabHelper()
{
return new FacebookPageTabHelper($this->app, $this->client, $this-
>defaultGraphVersion);
}
/**
* Sends a GET request to Graph and returns the result.
*
* @param string $endpoint
* @param AccessToken|string|null $accessToken
* @param string|null $eTag
* @param string|null $graphVersion
*
* @return FacebookResponse
*
29
* @throws FacebookSDKException
*/
public function get($endpoint, $accessToken = null, $eTag = null,
$graphVersion = null)
{
return $this->sendRequest(
'GET',
$endpoint,
$params = [],
$accessToken,
$eTag,
$graphVersion
);
}
/**
* Sends a POST request to Graph and returns the result.
*
* @param string $endpoint
* @param array $params
* @param AccessToken|string|null $accessToken
* @param string|null $eTag
* @param string|null $graphVersion
*
* @return FacebookResponse
*
* @throws FacebookSDKException
*/
public function post($endpoint, array $params = [], $accessToken = null, $eTag
= null, $graphVersion = null)
{
return $this->sendRequest(
30
'POST',
$endpoint,
$params,
$accessToken,
$eTag,
$graphVersion
);
}
/**
* Sends a DELETE request to Graph and returns the result.
*
* @param string $endpoint
* @param array $params
* @param AccessToken|string|null $accessToken
* @param string|null $eTag
* @param string|null $graphVersion
*
* @return FacebookResponse
*
* @throws FacebookSDKException
*/
public function delete($endpoint, array $params = [], $accessToken = null,
$eTag = null, $graphVersion = null)
{
return $this->sendRequest(
'DELETE',
$endpoint,
$params,
$accessToken,
$eTag,
$graphVersion
31
);
}
/**
* Sends a request to Graph for the next page of results.
*
* @param GraphEdge $graphEdge The GraphEdge to paginate over.
*
* @return GraphEdge|null
*
* @throws FacebookSDKException
*/
public function next(GraphEdge $graphEdge)
{
return $this->getPaginationResults($graphEdge, 'next');
}
/**
* Sends a request to Graph for the previous page of results.
*
* @param GraphEdge $graphEdge The GraphEdge to paginate over.
*
* @return GraphEdge|null
*
* @throws FacebookSDKException
*/
public function previous(GraphEdge $graphEdge)
{
return $this->getPaginationResults($graphEdge, 'previous');
}
/**
32
* Sends a request to Graph for the next page of results.
*
* @param GraphEdge $graphEdge The GraphEdge to paginate over.
* @param string $direction The direction of the pagination: next|previous.
*
* @return GraphEdge|null
*
* @throws FacebookSDKException
*/
public function getPaginationResults(GraphEdge $graphEdge, $direction)
{
$paginationRequest = $graphEdge->getPaginationRequest($direction);
if (!$paginationRequest) {
return null;
}
$this->lastResponse = $this->client->sendRequest($paginationRequest);
/**
* Sends a request to Graph and returns the result.
*
* @param string $method
* @param string $endpoint
* @param array $params
* @param AccessToken|string|null $accessToken
33
* @param string|null $eTag
* @param string|null $graphVersion
*
* @return FacebookResponse
*
* @throws FacebookSDKException
*/
public function sendRequest($method, $endpoint, array $params = [],
$accessToken = null, $eTag = null, $graphVersion = null)
{
$accessToken = $accessToken ?: $this->defaultAccessToken;
$graphVersion = $graphVersion ?: $this->defaultGraphVersion;
$request = $this->request($method, $endpoint, $params, $accessToken,
$eTag, $graphVersion);
/**
* Sends a batched request to Graph and returns the result.
*
* @param array $requests
* @param AccessToken|string|null $accessToken
* @param string|null $graphVersion
*
* @return FacebookBatchResponse
*
* @throws FacebookSDKException
*/
public function sendBatchRequest(array $requests, $accessToken = null,
$graphVersion = null)
{
34
$accessToken = $accessToken ?: $this->defaultAccessToken;
$graphVersion = $graphVersion ?: $this->defaultGraphVersion;
$batchRequest = new FacebookBatchRequest(
$this->app,
$requests,
$accessToken,
$graphVersion
);
/**
* Instantiates an empty FacebookBatchRequest entity.
*
* @param AccessToken|string|null $accessToken The top-level access token.
Requests with no access token
* will fallback to this.
* @param string|null $graphVersion The Graph API version to use.
* @return FacebookBatchRequest
*/
public function newBatchRequest($accessToken = null, $graphVersion = null)
{
$accessToken = $accessToken ?: $this->defaultAccessToken;
$graphVersion = $graphVersion ?: $this->defaultGraphVersion;
/**
* Instantiates a new FacebookRequest entity.
*
* @param string $method
* @param string $endpoint
* @param array $params
* @param AccessToken|string|null $accessToken
* @param string|null $eTag
* @param string|null $graphVersion
*
* @return FacebookRequest
*
* @throws FacebookSDKException
*/
public function request($method, $endpoint, array $params = [], $accessToken =
null, $eTag = null, $graphVersion = null)
{
$accessToken = $accessToken ?: $this->defaultAccessToken;
$graphVersion = $graphVersion ?: $this->defaultGraphVersion;
/**
* Factory to create FacebookFile's.
*
* @param string $pathToFile
*
* @return FacebookFile
*
* @throws FacebookSDKException
*/
public function fileToUpload($pathToFile)
{
return new FacebookFile($pathToFile);
}
/**
* Factory to create FacebookVideo's.
*
* @param string $pathToFile
*
* @return FacebookVideo
*
* @throws FacebookSDKException
*/
public function videoToUpload($pathToFile)
{
return new FacebookVideo($pathToFile);
}
/**
* Upload a video in chunks.
37
*
* @param int $target The id of the target node before the /videos edge.
* @param string $pathToFile The full path to the file.
* @param array $metadata The metadata associated with the video file.
* @param string|null $accessToken The access token.
* @param int $maxTransferTries The max times to retry a failed upload chunk.
* @param string|null $graphVersion The Graph API version to use.
*
* @return array
*
* @throws FacebookSDKException
*/
public function uploadVideo($target, $pathToFile, $metadata = [], $accessToken
= null, $maxTransferTries = 5, $graphVersion = null)
{
$accessToken = $accessToken ?: $this->defaultAccessToken;
$graphVersion = $graphVersion ?: $this->defaultGraphVersion;
do {
$chunk = $this->maxTriesTransfer($uploader, $endpoint, $chunk,
$maxTransferTries);
} while (!$chunk->isLastChunk());
return [
'video_id' => $chunk->getVideoId(),
38
'success' => $uploader->finish($endpoint, $chunk->getUploadSessionId(),
$metadata),
];
}
/**
* Attempts to upload a chunk of a file in $retryCountdown tries.
*
* @param FacebookResumableUploader $uploader
* @param string $endpoint
* @param FacebookTransferChunk $chunk
* @param int $retryCountdown
*
* @return FacebookTransferChunk
*
* @throws FacebookSDKException
*/
private function maxTriesTransfer(FacebookResumableUploader $uploader,
$endpoint, FacebookTransferChunk $chunk, $retryCountdown)
{
$newChunk = $uploader->transfer($endpoint, $chunk, $retryCountdown < 1);
$retryCountdown--;
// If transfer() returned the same chunk entity, the transfer failed but is
resumable.
return $this->maxTriesTransfer($uploader, $endpoint, $chunk,
$retryCountdown);
39
}
}
namespace Facebook;
use ArrayIterator;
use IteratorAggregate;
use ArrayAccess;
use Facebook\Authentication\AccessToken;
use Facebook\Exceptions\FacebookSDKException;
/**
* Class BatchRequest
*
* @package Facebook
*/
class FacebookBatchRequest extends FacebookRequest implements
IteratorAggregate, ArrayAccess
{
/**
* @var array An array of FacebookRequest entities to send.
*/
protected $requests;
/**
* @var array An array of files to upload.
*/
protected $attachedFiles;
/**
* Creates a new Request entity.
*
* @param FacebookApp|null $app
40
* @param array $requests
* @param AccessToken|string|null $accessToken
* @param string|null $graphVersion
*/
public function __construct(FacebookApp $app = null, array $requests = [],
$accessToken = null, $graphVersion = null)
{
parent::__construct($app, $accessToken, 'POST', '', [], null, $graphVersion);
$this->add($requests);
}
/**
* Adds a new request to the array.
*
* @param FacebookRequest|array $request
* @param string|null|array $options Array of batch request options e.g.
'name', 'omit_response_on_success'.
* If a string is given, it is the value of the 'name' option.
*
* @return FacebookBatchRequest
*
* @throws \InvalidArgumentException
*/
public function add($request, $options = null)
{
if (is_array($request)) {
foreach ($request as $key => $req) {
$this->add($req, $key);
}
return $this;
41
}
$this->addFallbackDefaults($request);
// File uploads
$attachedFiles = $this->extractFileAttachments($request);
unset($options['name']);
$requestToAdd = [
'name' => $name,
'request' => $request,
'options' => $options,
'attached_files' => $attachedFiles,
];
$this->requests[] = $requestToAdd;
return $this;
42
}
/**
* Ensures that the FacebookApp and access token fall back when missing.
*
* @param FacebookRequest $request
*
* @throws FacebookSDKException
*/
public function addFallbackDefaults(FacebookRequest $request)
{
if (!$request->getApp()) {
$app = $this->getApp();
if (!$app) {
throw new FacebookSDKException('Missing FacebookApp on
FacebookRequest and no fallback detected on FacebookBatchRequest.');
}
$request->setApp($app);
}
if (!$request->getAccessToken()) {
$accessToken = $this->getAccessToken();
if (!$accessToken) {
throw new FacebookSDKException('Missing access token on
FacebookRequest and no fallback detected on FacebookBatchRequest.');
}
$request->setAccessToken($accessToken);
}
}
/**
* Extracts the files from a request.
43
*
* @param FacebookRequest $request
*
* @return string|null
*
* @throws FacebookSDKException
*/
public function extractFileAttachments(FacebookRequest $request)
{
if (!$request->containsFileUploads()) {
return null;
}
$files = $request->getFiles();
$fileNames = [];
foreach ($files as $file) {
$fileName = uniqid();
$this->addFile($fileName, $file);
$fileNames[] = $fileName;
}
$request->resetFiles();
/**
* Return the FacebookRequest entities.
*
* @return array
*/
44
public function getRequests()
{
return $this->requests;
}
/**
* Prepares the requests to be sent as a batch request.
*/
public function prepareRequestsForBatch()
{
$this->validateBatchRequestCount();
$params = [
'batch' => $this->convertRequestsToJson(),
'include_headers' => true,
];
$this->setParams($params);
}
/**
* Converts the requests into a JSON(P) string.
*
* @return string
*/
public function convertRequestsToJson()
{
$requests = [];
foreach ($this->requests as $request) {
$options = [];
$options += $request['options'];
$requests[] = $this->requestEntityToBatchArray($request['request'],
$options, $request['attached_files']);
}
return json_encode($requests);
}
/**
* Validate the request count before sending them as a batch.
*
* @throws FacebookSDKException
*/
public function validateBatchRequestCount()
{
$batchCount = count($this->requests);
if ($batchCount === 0) {
throw new FacebookSDKException('There are no batch requests to send.');
} elseif ($batchCount > 50) {
// Per: https://developers.facebook.com/docs/graph-api/making-multiple-
requests#limits
throw new FacebookSDKException('You cannot send more than 50 batch
requests at a time.');
}
}
/**
* Converts a Request entity into an array that is batch-friendly.
*
46
* @param FacebookRequest $request The request entity to convert.
* @param string|null|array $options Array of batch request options e.g.
'name', 'omit_response_on_success'.
* If a string is given, it is the value of the 'name' option.
* @param string|null $attachedFiles Names of files associated with the
request.
*
* @return array
*/
public function requestEntityToBatchArray(FacebookRequest $request, $options
= null, $attachedFiles = null)
{
$compiledHeaders = [];
$headers = $request->getHeaders();
foreach ($headers as $name => $value) {
$compiledHeaders[] = $name . ': ' . $value;
}
$batch = [
'headers' => $compiledHeaders,
'method' => $request->getMethod(),
'relative_url' => $request->getUrl(),
];
// Since file uploads are moved to the root request of a batch request,
47
// the child requests will always be URL-encoded.
$body = $request->getUrlEncodedBody()->getBody();
if ($body) {
$batch['body'] = $body;
}
$batch += $options;
return $batch;
}
/**
* Get an iterator for the items.
*
* @return ArrayIterator
*/
public function getIterator()
{
return new ArrayIterator($this->requests);
}
/**
* @inheritdoc
*/
public function offsetSet($offset, $value)
{
$this->add($value, $offset);
}
48
/**
* @inheritdoc
*/
public function offsetExists($offset)
{
return isset($this->requests[$offset]);
}
/**
* @inheritdoc
*/
public function offsetUnset($offset)
{
unset($this->requests[$offset]);
}
/**
* @inheritdoc
*/
public function offsetGet($offset)
{
return isset($this->requests[$offset]) ? $this->requests[$offset] : null;
}
}
49
namespace Facebook;
use Facebook\Authentication\AccessToken;
use Facebook\Url\FacebookUrlManipulator;
use Facebook\FileUpload\FacebookFile;
use Facebook\FileUpload\FacebookVideo;
use Facebook\Http\RequestBodyMultipart;
use Facebook\Http\RequestBodyUrlEncoded;
use Facebook\Exceptions\FacebookSDKException;
/**
* Class Request
* @package Facebook
*/
class FacebookRequest
/**
*/
protected $app;
/**
*/
protected $accessToken;
50
/**
*/
protected $method;
/**
*/
protected $endpoint;
/**
*/
/**
*/
/**
*/
51
/**
*/
protected $eTag;
/**
*/
protected $graphVersion;
/**
*/
$this->setApp($app);
$this->setAccessToken($accessToken);
52
$this->setMethod($method);
$this->setEndpoint($endpoint);
$this->setParams($params);
$this->setETag($eTag);
/**
* @param AccessToken|string|null
* @return FacebookRequest
*/
$this->accessToken = $accessToken;
$this->accessToken = $accessToken->getValue();
return $this;
/**
* Sets the access token with one harvested from a URL or POST params.
53
*
* @return FacebookRequest
* @throws FacebookSDKException
*/
$existingAccessToken = $this->getAccessToken();
if (!$existingAccessToken) {
$this->setAccessToken($accessToken);
return $this;
/**
* @return string|null
*/
return $this->accessToken;
/**
* @return AccessToken|null
*/
/**
*/
$this->app = $app;
/**
* @return FacebookApp
*/
return $this->app;
/**
* @return string|null
*/
if (!$accessTokenEntity = $this->getAccessTokenEntity()) {
return null;
return $accessTokenEntity->getAppSecretProof($this->app->getSecret());
/**
* @throws FacebookSDKException
56
*/
$accessToken = $this->getAccessToken();
if (!$accessToken) {
/**
* @param string
*/
$this->method = strtoupper($method);
/**
* @return string
*/
{
57
return $this->method;
/**
* @throws FacebookSDKException
*/
if (!$this->method) {
/**
* @param string
* @return FacebookRequest
*
58
* @throws FacebookSDKException
*/
// Harvest the access token from the endpoint to keep things in sync
$params = FacebookUrlManipulator::getParamsAsArray($endpoint);
if (isset($params['access_token'])) {
$this->setAccessTokenFromParams($params['access_token']);
// Clean the token & app secret proof from the endpoint.
$this->endpoint = FacebookUrlManipulator::removeParamsFromUrl($endpoint,
$filterParams);
return $this;
/**
* @return string
*/
59
return $this->endpoint;
/**
* @return array
*/
$headers = static::getDefaultHeaders();
if ($this->eTag) {
$headers['If-None-Match'] = $this->eTag;
/**
*/
{
60
$this->headers = array_merge($this->headers, $headers);
/**
*/
$this->eTag = $eTag;
/**
* @return FacebookRequest
* @throws FacebookSDKException
*/
if (isset($params['access_token'])) {
$this->setAccessTokenFromParams($params['access_token']);
61
}
unset($params['access_token'], $params['appsecret_proof']);
//$params = $this->sanitizeAuthenticationParams($params);
$params = $this->sanitizeFileParams($params);
$this->dangerouslySetParams($params);
return $this;
/**
* Set the params for this request without filtering them first.
* @return FacebookRequest
*/
return $this;
}
62
/**
* Iterate over the params and pull out the file uploads.
* @return array
*/
$this->addFile($key, $value);
unset($params[$key]);
return $params;
/**
*/
63
public function addFile($key, FacebookFile $file)
$this->files[$key] = $file;
/**
*/
$this->files = [];
/**
* @return array
*/
return $this->files;
/**
*
64
* @return boolean
*/
return !empty($this->files);
/**
* @return boolean
*/
return true;
return false;
/**
*
65
* @return RequestBodyMultipart
*/
$params = $this->getPostParams();
/**
* @return RequestBodyUrlEncoded
*/
$params = $this->getPostParams();
/**
* @return array
*/
66
public function getParams()
$params = $this->params;
$accessToken = $this->getAccessToken();
if ($accessToken) {
$params['access_token'] = $accessToken;
$params['appsecret_proof'] = $this->getAppSecretProof();
return $params;
/**
* @return array
*/
return $this->getParams();
return [];
}
67
/**
* @return string
*/
return $this->graphVersion;
/**
* @return string
*/
$this->validateMethod();
$graphVersion = FacebookUrlManipulator::forceSlashPrefix($this->graphVersion);
$endpoint = FacebookUrlManipulator::forceSlashPrefix($this->getEndpoint());
return $url;
/**
* @return array
*/
return [
];
namespace Facebook;
use Facebook\GraphNodes\GraphNodeFactory;
use Facebook\Exceptions\FacebookResponseException;
use Facebook\Exceptions\FacebookSDKException;
/**
* Class FacebookResponse
*
* @package Facebook
69
*/
class FacebookResponse
{
/**
* @var int The HTTP status code response from Graph.
*/
protected $httpStatusCode;
/**
* @var array The headers returned from Graph.
*/
protected $headers;
/**
* @var string The raw body of the response from Graph.
*/
protected $body;
/**
* @var array The decoded body of the Graph response.
*/
protected $decodedBody = [];
/**
* @var FacebookRequest The original request that returned this response.
*/
protected $request;
/**
* @var FacebookSDKException The exception thrown by this request.
*/
protected $thrownException;
/**
* Creates a new Response entity.
*
* @param FacebookRequest $request
* @param string|null $body
* @param int|null $httpStatusCode
* @param array|null $headers
*/
public function __construct(FacebookRequest $request, $body = null, $httpStatusCode = null,
array $headers = [])
{
$this->request = $request;
$this->body = $body;
$this->httpStatusCode = $httpStatusCode;
$this->headers = $headers;
70
$this->decodeBody();
}
/**
* Return the original request that returned this response.
*
* @return FacebookRequest
*/
public function getRequest()
{
return $this->request;
}
/**
* Return the FacebookApp entity used for this response.
*
* @return FacebookApp
*/
public function getApp()
{
return $this->request->getApp();
}
/**
* Return the access token that was used for this response.
*
* @return string|null
*/
public function getAccessToken()
{
return $this->request->getAccessToken();
}
/**
* Return the HTTP status code for this response.
*
* @return int
*/
public function getHttpStatusCode()
{
return $this->httpStatusCode;
}
/**
* Return the HTTP headers for this response.
*
* @return array
71
*/
public function getHeaders()
{
return $this->headers;
}
/**
* Return the raw body response.
*
* @return string
*/
public function getBody()
{
return $this->body;
}
/**
* Return the decoded body response.
*
* @return array
*/
public function getDecodedBody()
{
return $this->decodedBody;
}
/**
* Get the app secret proof that was used for this response.
*
* @return string|null
*/
public function getAppSecretProof()
{
return $this->request->getAppSecretProof();
}
/**
* Get the ETag associated with the response.
*
* @return string|null
*/
public function getETag()
{
return isset($this->headers['ETag']) ? $this->headers['ETag'] : null;
}
/**
* Get the version of Graph that returned this response.
72
*
* @return string|null
*/
public function getGraphVersion()
{
return isset($this->headers['Facebook-API-Version']) ? $this->headers['Facebook-API-
Version'] : null;
}
/**
* Returns true if Graph returned an error message.
*
* @return boolean
*/
public function isError()
{
return isset($this->decodedBody['error']);
}
/**
* Throws the exception.
*
* @throws FacebookSDKException
*/
public function throwException()
{
throw $this->thrownException;
}
/**
* Instantiates an exception to be thrown later.
*/
public function makeException()
{
$this->thrownException = FacebookResponseException::create($this);
}
/**
* Returns the exception that was thrown for this request.
*
* @return FacebookResponseException|null
*/
public function getThrownException()
{
return $this->thrownException;
}
/**
73
* Convert the raw response into an array if possible.
*
* Graph will return 2 types of responses:
* - JSON(P)
* Most responses from Graph are JSON(P)
* - application/x-www-form-urlencoded key/value pairs
* Happens on the `/oauth/access_token` endpoint when exchanging
* a short-lived access token for a long-lived access token
* - And sometimes nothing :/ but that'd be a bug.
*/
public function decodeBody()
{
$this->decodedBody = json_decode($this->body, true);
if (!is_array($this->decodedBody)) {
$this->decodedBody = [];
}
if ($this->isError()) {
$this->makeException();
}
}
/**
* Instantiate a new GraphObject from response.
*
* @param string|null $subclassName The GraphNode subclass to cast to.
*
* @return \Facebook\GraphNodes\GraphObject
*
* @throws FacebookSDKException
*
* @deprecated 5.0.0 getGraphObject() has been renamed to getGraphNode()
* @todo v6: Remove this method
*/
public function getGraphObject($subclassName = null)
74
{
return $this->getGraphNode($subclassName);
}
/**
* Instantiate a new GraphNode from response.
*
* @param string|null $subclassName The GraphNode subclass to cast to.
*
* @return \Facebook\GraphNodes\GraphNode
*
* @throws FacebookSDKException
*/
public function getGraphNode($subclassName = null)
{
$factory = new GraphNodeFactory($this);
return $factory->makeGraphNode($subclassName);
}
/**
* Convenience method for creating a GraphAlbum collection.
*
* @return \Facebook\GraphNodes\GraphAlbum
*
* @throws FacebookSDKException
*/
public function getGraphAlbum()
{
$factory = new GraphNodeFactory($this);
return $factory->makeGraphAlbum();
}
/**
* Convenience method for creating a GraphPage collection.
*
* @return \Facebook\GraphNodes\GraphPage
*
* @throws FacebookSDKException
*/
public function getGraphPage()
{
$factory = new GraphNodeFactory($this);
return $factory->makeGraphPage();
}
75
/**
* Convenience method for creating a GraphSessionInfo collection.
*
* @return \Facebook\GraphNodes\GraphSessionInfo
*
* @throws FacebookSDKException
*/
public function getGraphSessionInfo()
{
$factory = new GraphNodeFactory($this);
return $factory->makeGraphSessionInfo();
}
/**
* Convenience method for creating a GraphUser collection.
*
* @return \Facebook\GraphNodes\GraphUser
*
* @throws FacebookSDKException
*/
public function getGraphUser()
{
$factory = new GraphNodeFactory($this);
return $factory->makeGraphUser();
}
/**
* Convenience method for creating a GraphEvent collection.
*
* @return \Facebook\GraphNodes\GraphEvent
*
* @throws FacebookSDKException
*/
public function getGraphEvent()
{
$factory = new GraphNodeFactory($this);
return $factory->makeGraphEvent();
}
/**
* Convenience method for creating a GraphGroup collection.
*
* @return \Facebook\GraphNodes\GraphGroup
*
* @throws FacebookSDKException
76
*/
public function getGraphGroup()
{
$factory = new GraphNodeFactory($this);
return $factory->makeGraphGroup();
}
/**
* Instantiate a new GraphList from response.
*
* @param string|null $subclassName The GraphNode subclass to cast list items to.
* @param boolean $auto_prefix Toggle to auto-prefix the subclass name.
*
* @return \Facebook\GraphNodes\GraphList
*
* @throws FacebookSDKException
*
* @deprecated 5.0.0 getGraphList() has been renamed to getGraphEdge()
* @todo v6: Remove this method
*/
public function getGraphList($subclassName = null, $auto_prefix = true)
{
return $this->getGraphEdge($subclassName, $auto_prefix);
}
/**
* Instantiate a new GraphEdge from response.
*
* @param string|null $subclassName The GraphNode subclass to cast list items to.
* @param boolean $auto_prefix Toggle to auto-prefix the subclass name.
*
* @return \Facebook\GraphNodes\GraphEdge
*
* @throws FacebookSDKException
*/
public function getGraphEdge($subclassName = null, $auto_prefix = true)
{
$factory = new GraphNodeFactory($this);
namespace Facebook;
use Facebook\Exceptions\FacebookSDKException;
77
/**
* Class SignedRequest
*
* @package Facebook
*/
class SignedRequest
{
/**
* @var FacebookApp The FacebookApp entity.
*/
protected $app;
/**
* @var string The raw encrypted signed request.
*/
protected $rawSignedRequest;
/**
* @var array The payload from the decrypted signed request.
*/
protected $payload;
/**
* Instantiate a new SignedRequest entity.
*
* @param FacebookApp $facebookApp The FacebookApp entity.
* @param string|null $rawSignedRequest The raw signed request.
*/
public function __construct(FacebookApp $facebookApp, $rawSignedRequest = null)
{
$this->app = $facebookApp;
if (!$rawSignedRequest) {
return;
}
$this->rawSignedRequest = $rawSignedRequest;
$this->parse();
}
/**
* Returns the raw signed request data.
*
* @return string|null
*/
public function getRawSignedRequest()
{
return $this->rawSignedRequest;
}
/**
* Returns the parsed signed request data.
*
* @return array|null
*/
public function getPayload()
{
return $this->payload;
}
/**
* Returns a property from the signed request data if available.
*
* @param string $key
* @param mixed|null $default
78
*
* @return mixed|null
*/
public function get($key, $default = null)
{
if (isset($this->payload[$key])) {
return $this->payload[$key];
}
return $default;
}
/**
* Returns user_id from signed request data if available.
*
* @return string|null
*/
public function getUserId()
{
return $this->get('user_id');
}
/**
* Checks for OAuth data in the payload.
*
* @return boolean
*/
public function hasOAuthData()
{
return $this->get('oauth_token') || $this->get('code');
}
/**
* Creates a signed request from an array of data.
*
* @param array $payload
*
* @return string
*/
public function make(array $payload)
{
$payload['algorithm'] = isset($payload['algorithm']) ? $payload['algorithm'] : 'HMAC-
SHA256';
$payload['issued_at'] = isset($payload['issued_at']) ? $payload['issued_at'] : time();
$encodedPayload = $this->base64UrlEncode(json_encode($payload));
$hashedSig = $this->hashSignature($encodedPayload);
$encodedSig = $this->base64UrlEncode($hashedSig);
return $encodedSig . '.' . $encodedPayload;
}
/**
* Validates and decodes a signed request and saves
* the payload to an array.
*/
protected function parse()
{
list($encodedSig, $encodedPayload) = $this->split();
// Signature validation
$sig = $this->decodeSignature($encodedSig);
$hashedSig = $this->hashSignature($encodedPayload);
$this->validateSignature($hashedSig, $sig);
$this->payload = $this->decodePayload($encodedPayload);
79
// Payload validation
$this->validateAlgorithm();
}
/**
* Splits a raw signed request into signature and payload.
*
* @return array
*
* @throws FacebookSDKException
*/
protected function split()
{
if (strpos($this->rawSignedRequest, '.') === false) {
throw new FacebookSDKException('Malformed signed request.', 606);
}
return explode('.', $this->rawSignedRequest, 2);
}
/**
* Decodes the raw signature from a signed request.
*
* @param string $encodedSig
*
* @return string
*
* @throws FacebookSDKException
*/
protected function decodeSignature($encodedSig)
{
$sig = $this->base64UrlDecode($encodedSig);
if (!$sig) {
throw new FacebookSDKException('Signed request has malformed encoded signature
data.', 607);
}
return $sig;
}
/**
* Decodes the raw payload from a signed request.
*
* @param string $encodedPayload
*
* @return array
*
* @throws FacebookSDKException
*/
protected function decodePayload($encodedPayload)
{
$payload = $this->base64UrlDecode($encodedPayload);
if ($payload) {
$payload = json_decode($payload, true);
}
if (!is_array($payload)) {
throw new FacebookSDKException('Signed request has malformed encoded payload data.',
607);
}
return $payload;
}
80
/**
* Validates the algorithm used in a signed request.
*
* @throws FacebookSDKException
*/
protected function validateAlgorithm()
{
if ($this->get('algorithm') !== 'HMAC-SHA256') {
throw new FacebookSDKException('Signed request is using the wrong algorithm.', 605);
}
}
/**
* Hashes the signature used in a signed request.
*
* @param string $encodedData
*
* @return string
*
* @throws FacebookSDKException
*/
protected function hashSignature($encodedData)
{
$hashedSig = hash_hmac(
'sha256',
$encodedData,
$this->app->getSecret(),
$raw_output = true
);
if (!$hashedSig) {
throw new FacebookSDKException('Unable to hash signature from encoded payload data.',
602);
}
return $hashedSig;
}
/**
* Validates the signature used in a signed request.
*
* @param string $hashedSig
* @param string $sig
*
* @throws FacebookSDKException
*/
protected function validateSignature($hashedSig, $sig)
{
if (\hash_equals($hashedSig, $sig)) {
return;
}
throw new FacebookSDKException('Signed request has an invalid signature.', 602);
}
/**
* Base64 decoding which replaces characters:
* + instead of -
* / instead of _
*
* @link http://en.wikipedia.org/wiki/Base64#URL_applications
*
* @param string $input base64 url encoded input
*
* @return string decoded string
81
*/
public function base64UrlDecode($input)
{
$urlDecodedBase64 = strtr($input, '-_', '+/');
$this->validateBase64($urlDecodedBase64);
return base64_decode($urlDecodedBase64);
}
/**
* Base64 encoding which replaces characters:
* + instead of -
* / instead of _
*
* @link http://en.wikipedia.org/wiki/Base64#URL_applications
*
* @param string $input string to encode
*
* @return string base64 url encoded input
*/
public function base64UrlEncode($input)
{
return strtr(base64_encode($input), '+/', '-_');
}
/**
* Validates a base64 string.
*
* @param string $input base64 value to validate
*
* @throws FacebookSDKException
*/
protected function validateBase64($input)
{
if (!preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $input)) {
throw new FacebookSDKException('Signed request contains malformed base64 encoding.',
608);
}
}
}
namespace Facebook\Http;
/**
* Class GraphRawResponse
*
* @package Facebook
*/
class GraphRawResponse
{
/**
* @var array The response headers in the form of an associative array.
*/
protected $headers;
/**
* @var string The raw response body.
*/
protected $body;
/**
* @var int The HTTP status response code.
*/
protected $httpResponseCode;
82
/**
* Creates a new GraphRawResponse entity.
*
* @param string|array $headers The headers as a raw string or array.
* @param string $body The raw response body.
* @param int $httpStatusCode The HTTP response code (if sending headers as parsed
array).
*/
public function __construct($headers, $body, $httpStatusCode = null)
{
if (is_numeric($httpStatusCode)) {
$this->httpResponseCode = (int)$httpStatusCode;
}
if (is_array($headers)) {
$this->headers = $headers;
} else {
$this->setHeadersFromString($headers);
}
$this->body = $body;
}
/**
* Return the response headers.
*
* @return array
*/
public function getHeaders()
{
return $this->headers;
}
/**
* Return the body of the response.
*
* @return string
*/
public function getBody()
{
return $this->body;
}
/**
* Return the HTTP response code.
*
* @return int
*/
public function getHttpResponseCode()
{
return $this->httpResponseCode;
}
/**
* Sets the HTTP response code from a raw header.
*
* @param string $rawResponseHeader
*/
public function setHttpResponseCodeFromHeader($rawResponseHeader)
{
preg_match('|HTTP/\d\.\d\s+(\d+)\s+.*|', $rawResponseHeader, $match);
$this->httpResponseCode = (int)$match[1];
}
/**
* Parse the raw headers and set as an array.
83
*
* @param string $rawHeaders The raw headers from the response.
*/
protected function setHeadersFromString($rawHeaders)
{
// Normalize line breaks
$rawHeaders = str_replace("\r\n", "\n", $rawHeaders);
// There will be multiple headers if a 301 was followed
// or a proxy was followed, etc
$headerCollection = explode("\n\n", trim($rawHeaders));
// We just want the last response (at the end)
$rawHeader = array_pop($headerCollection);
$headerComponents = explode("\n", $rawHeader);
foreach ($headerComponents as $line) {
if (strpos($line, ': ') === false) {
$this->setHttpResponseCodeFromHeader($line);
} else {
list($key, $value) = explode(': ', $line, 2);
$this->headers[$key] = $value;
}
}
}
}
namespace Facebook\Http;
use Facebook\FileUpload\FacebookFile;
/**
* Class RequestBodyMultipartt
*
* Some things copied from Guzzle
*
* @package Facebook
*
* @see https://github.com/guzzle/guzzle/blob/master/src/Post/MultipartBody.php
*/
class RequestBodyMultipart implements RequestBodyInterface
{
/**
* @var string The boundary.
*/
private $boundary;
/**
* @var array The parameters to send with this request.
*/
private $params;
/**
* @var array The files to send with this request.
*/
private $files = [];
/**
* @param array $params The parameters to send with this request.
* @param array $files The files to send with this request.
* @param string $boundary Provide a specific boundary.
*/
public function __construct(array $params = [], array $files = [], $boundary = null)
{
$this->params = $params;
$this->files = $files;
84
$this->boundary = $boundary ?: uniqid();
}
/**
* @inheritdoc
*/
public function getBody()
{
$body = '';
// Compile normal params
$params = $this->getNestedParams($this->params);
foreach ($params as $k => $v) {
$body .= $this->getParamString($k, $v);
}
// Compile files
foreach ($this->files as $k => $v) {
$body .= $this->getFileString($k, $v);
}
// Peace out
$body .= "--{$this->boundary}--\r\n";
return $body;
}
/**
* Get the boundary
*
* @return string
*/
public function getBoundary()
{
return $this->boundary;
}
/**
* Get the string needed to transfer a file.
*
* @param string $name
* @param FacebookFile $file
*
* @return string
*/
private function getFileString($name, FacebookFile $file)
{
return sprintf(
"--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"%s\r\n\r\n%s\r\n",
$this->boundary,
$name,
$file->getFileName(),
$this->getFileHeaders($file),
$file->getContents()
);
}
/**
* Get the string needed to transfer a POST field.
*
* @param string $name
* @param string $value
*
* @return string
*/
private function getParamString($name, $value)
85
{
return sprintf(
"--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n",
$this->boundary,
$name,
$value
);
}
/**
* Returns the params as an array of nested params.
*
* @param array $params
*
* @return array
*/
private function getNestedParams(array $params)
{
$query = http_build_query($params, null, '&');
$params = explode('&', $query);
$result = [];
foreach ($params as $param) {
list($key, $value) = explode('=', $param, 2);
$result[urldecode($key)] = urldecode($value);
}
return $result;
}
/**
* Get the headers needed before transferring the content of a POST file.
*
* @param FacebookFile $file
*
* @return string
*/
protected function getFileHeaders(FacebookFile $file)
{
return "\r\nContent-Type: {$file->getMimetype()}";
}
}
89
/**
* Whether the access token is still valid or not.
*
* @return boolean|null
*/
public function getIsValid()
{
return $this->getField('is_valid');
}
/**
* DateTime when this access token was issued.
*
* Note that the issued_at field is not returned
* for short-lived access tokens.
*
* @see https://developers.facebook.com/docs/facebook-login/access-tokens#debug
*
* @return \DateTime|null
*/
public function getIssuedAt()
{
return $this->getField('issued_at');
}
/**
* General metadata associated with the access token.
* Can contain data like 'sso', 'auth_type', 'auth_nonce'.
*
* @return array|null
*/
public function getMetadata()
{
return $this->getField('metadata');
}
/**
* The 'sso' child property from the 'metadata' parent property.
*
* @return string|null
*/
public function getSso()
{
return $this->getMetadataProperty('sso');
}
/**
* The 'auth_type' child property from the 'metadata' parent property.
*
* @return string|null
*/
public function getAuthType()
{
return $this->getMetadataProperty('auth_type');
}
/**
* The 'auth_nonce' child property from the 'metadata' parent property.
*
* @return string|null
*/
public function getAuthNonce()
{
return $this->getMetadataProperty('auth_nonce');
}
90
/**
* For impersonated access tokens, the ID of
* the page this token contains.
*
* @return string|null
*/
public function getProfileId()
{
return $this->getField('profile_id');
}
/**
* List of permissions that the user has granted for
* the app in this access token.
*
* @return array
*/
public function getScopes()
{
return $this->getField('scopes');
}
/**
* The ID of the user this access token is for.
*
* @return string|null
*/
public function getUserId()
{
return $this->getField('user_id');
}
/**
* Ensures the app ID from the access token
* metadata is what we expect.
*
* @param string $appId
*
* @throws FacebookSDKException
*/
public function validateAppId($appId)
{
if ($this->getAppId() !== $appId) {
throw new FacebookSDKException('Access token metadata contains unexpected app ID.',
401);
}
}
/**
* Ensures the user ID from the access token
* metadata is what we expect.
*
* @param string $userId
*
* @throws FacebookSDKException
*/
public function validateUserId($userId)
{
if ($this->getUserId() !== $userId) {
throw new FacebookSDKException('Access token metadata contains unexpected user ID.',
401);
}
}
/**
* Ensures the access token has not expired yet.
91
*
* @throws FacebookSDKException
*/
public function validateExpiration()
{
if (!$this->getExpiresAt() instanceof \DateTime) {
return;
}
if ($this->getExpiresAt()->getTimestamp() < time()) {
throw new FacebookSDKException('Inspection of access token metadata shows that the
access token has expired.', 401);
}
}
/**
* Converts a unix timestamp into a DateTime entity.
*
* @param int $timestamp
*
* @return \DateTime
*/
private function convertTimestampToDateTime($timestamp)
{
$dt = new \DateTime();
$dt->setTimestamp($timestamp);
return $dt;
}
/**
* Casts the unix timestamps as DateTime entities.
*/
private function castTimestampsToDateTime()
{
foreach (static::$dateProperties as $key) {
if (isset($this->metadata[$key]) && $this->metadata[$key] !== 0) {
$this->metadata[$key] = $this->convertTimestampToDateTime($this->metadata[$key]);
}
}
}
}
92
The following code fetches the data from Facebook profile and stores it in the database.
<?php
session_start();
error_reporting(E_ERROR);
set_time_limit(0);
$db = new mysqli('localhost','root','','fbminingfinal');
$sql = "SELECT Name, Comments, likes, links FROM photos order by likes desc limit 1";
$result = $db->query($sql);
if (!$result) {
echo "Error: ".$sql."<br>".$db->error;
}
else{
while($row = mysqli_fetch_array($result)){
$slide1= $row['links'];
$name= $row['Name'];
$likes1= $row['likes'];
$com1= $row['Comments'];
}
}
$sql = "SELECT Name, Comments, likes, links FROM photos order by likes asc limit 2";
$result1 = $db->query($sql);
if (!$result1) {
echo "Error: ".$sql."<br>".$db->error;
}
else{
$storeArray1 = Array();
$storeArray2 = Array();
while($row = mysqli_fetch_array($result1)){
$storeArray1[] = $row['links'];
$storeArray2[] = $row['Comments'];
$name1= $row['Name'];
$likes3= $row['likes'];
}
$slide3= $storeArray1[1];
$com3= $storeArray2[1];
}
$sql = "SELECT Name, Comments, likes, links FROM photos order by likes asc limit 3";
$result1 = $db->query($sql);
if (!$result1) {
echo "Error: ".$sql."<br>".$db->error;
}
else{
$storeArray1 = Array();
while($row = mysqli_fetch_array($result1)){
$storeArray1[] = $row['links'];
$name1= $row['Name'];
$likes4= $row['likes'];
}
$slide4= $storeArray1[2];
}
$sql = "SELECT Name, Comments, likes, links FROM photos order by likes desc limit 2";
$result4 = $db->query($sql);
if (!$result4) {
echo "Error: ".$sql."<br>".$db->error;
}
else{
$storeArray4 = Array();
93
while($row = mysqli_fetch_array($result4)){
$storeArray4[] = $row['links'];
$name1= $row['Name'];
$likes2= $row['likes'];
}
$slide2= $storeArray4[1];
}
$sql = "SELECT Name, likes, links FROM photos order by likes desc limit 8";
$result2 = $db->query($sql);
$storeArray = Array();
while ($row = mysqli_fetch_array($result2)) {
$storeArray[] = $row['links'];
}
$b1= $storeArray[0];
$b2= $storeArray[1];
$b3= $storeArray[2];
$b4= $storeArray[3];
$b5= $storeArray[4];
$b6= $storeArray[5];
$b7= $storeArray[6];
$b8= $storeArray[7];
$sql = "SELECT page FROM pages limit 6";
$result2 = $db->query($sql);
$storeArrayp = Array();
while ($row = mysqli_fetch_array($result2)) {
$storeArrayp[] = $row['page'];
}
$p1= $storeArrayp[0];
$p2= $storeArrayp[1];
$p3= $storeArrayp[2];
$p4= $storeArrayp[3];
$p5= $storeArrayp[4];
$p6= $storeArrayp[5];
$sql = "SELECT video FROM vidandfri";
$video = $db->query($sql);
$storeArrayv = Array();
while ($row = mysqli_fetch_array($video)) {
$storeArrayv[] = $row['video'];
}
$v1= $storeArrayv[0];
//echo $v1;
$sql = "SELECT friends FROM vidandfri";
$friend = $db->query($sql);
$storeArrayf = Array();
while ($row = mysqli_fetch_array($friend)) {
$storeArrayf[] = $row['friends'];
}
$fr= $storeArrayf[0];
//echo $fr;
$intfriend= (int)$fr;
//echo $intfriend;
if ( $intfriend< "200") {
$w1="not dependent people means self-sufficient";
$w2="concentrate with everything they’ve got";
$w3=" you don’t need much to feel happy and content";
$w4="identify changes in the environment very quickly";
$w5= "you believe knowledge is power.";
$w6="you are trustworthy";
$w7="you tend to be driven and discipline";
$w8="you tend to process greater volumes of information in any given situation";
} else {
$w1="Numerous, broad interests";
$w2="Likes to communicate by talking";
94
$w3="Enjoys being at the center of attention";
$w4="Tends to act first before thinking";
$w5= "Looks to others and outside sources for ideas and inspiration";
$w6="Enjoys group work";
$w7="Feels isolated by too much time spent alone";
$w8="Likes to talk about thoughts and feelings";
}
//echo $intro;
$sql = "SELECT Party FROM party";
$party = $db->query($sql);
$storeArrayp = Array();
while ($row = mysqli_fetch_array($party)) {
$storeArrayp[] = $row['Party'];
}
$party= $storeArrayp[0];
//echo $storeArrayp[0];
$p1= (string)$party;
$lenp1=trim($p1);
switch ($lenp1) {
case "Neutral":
$neutral="From The Analysis of your Posts,
it Might be Possible to Say that you have Neutral Opinion towards Politics";
$view = "NEU.jpg";
break;
case "PMLN":
$neutral="From The Analysis of your Posts, it Might be Possible to
Say that you Support PLMN and Would Likely to Vote for them in Coming Elections";
$view = "PMLN.jpg";
break;
case "PTI":
$neutral="From The Analysis of your Posts, it Might be Possible to
Say that you Support PTI and Would Likely to Vote for them in Coming Elections";
$view = "PTI.jpg";
break;
default:
$neutral="From The Analysis of your Posts,
it Might be Possible to Say that you have neutral opion towards politics";
$view = "pol.png";
}
$sql = "SELECT place FROM places GROUP BY place ORDER BY COUNT(*) desc limit 1";
$result = $db->query($sql);
if (!$result) {
echo "Error: ".$sql."<br>".$db->error;
}
else{
while($row = mysqli_fetch_array($result)){
$place= $row['place'];
//echo $place;
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Uniquebiz is a responsive creative business template">
<meta name="keywords" content="onepage, portfolio, corporate, business, parallax, creative,
agency">
<meta name="author" content="trendytheme.net">
95
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-
awesome/4.7.0/css/font-awesome.min.css">
<style>
*{
box-sizing: border-box;
}
/* Create two equal columns that floats next to each other */
.column {
float: left;
width: 50%;
padding: 10px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* Style the buttons */
.btn {
border: none;
outline: none;
padding: 12px 16px;
background-color: #f1f1f1;
cursor: pointer;
}
.btn:hover {
background-color: #ddd;
}
.btn.active {
background-color: #666;
color: white;
}
</style>
<style>
body {margin:0;height:2000px;}
.icon-bar {
position: fixed;
top: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
.icon-bar a {
display: block;
text-align: center;
padding: 16px;
transition: all 0.3s ease;
color: white;
font-size: 20px;
}
.icon-bar a:hover {
background-color: #000;
}
.facebook {
background: #3B5998;
color: white;
}
96
.twitter {
background: #55ACEE;
color: white;
}
.google {
background: #dd4b39;
color: white;
}
.linkedin {
background: #007bb5;
color: white;
}
.youtube {
background: #bb0000;
color: white;
}
.content {
margin-left: 75px;
font-size: 30px;
}
</style>
<style>
#snackbar {
visibility: hidden;
min-width: 250px;
margin-left: -125px;
background-color: #333;
color: #fff;
text-align: center;
border-radius: 2px;
padding: 16px;
position: fixed;
z-index: 1;
left: 50%;
bottom: 30px;
font-size: 17px;
}
#snackbar.show {
visibility: visible;
-webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
animation: fadein 0.5s, fadeout 0.5s 2.5s;
}
@-webkit-keyframes fadein {
from {bottom: 0; opacity: 0;}
to {bottom: 30px; opacity: 1;}
}
@keyframes fadein {
from {bottom: 0; opacity: 0;}
to {bottom: 30px; opacity: 1;}
}
@-webkit-keyframes fadeout {
from {bottom: 30px; opacity: 1;}
to {bottom: 0; opacity: 0;}
}
@keyframes fadeout {
from {bottom: 30px; opacity: 1;}
97
to {bottom: 0; opacity: 0;}
}
</style>
<title>Final year project</title>
<!-- favicon -->
<link rel="shortcut icon" href="assets/images/ico/favicon.png">
<!-- apple-touch-icon -->
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/images/ico/apple-
touch-icon-144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="assets/images/ico/apple-
touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="assets/images/ico/apple-
touch-icon-72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="assets/images/ico/apple-touch-icon-57-
precomposed.png">
<link href='https://fonts.googleapis.com/css?
family=Roboto:400,300,300italic,400italic,500,700' rel='stylesheet' type='text/css'>
<!-- Animate CSS -->
<link href="assets/css/animate.css" rel="stylesheet">
<!-- jvectormap CSS -->
<link href="assets/css/jquery-jvectormap.css" rel="stylesheet">
<!-- FontAwesome CSS -->
<link href="assets/fonts/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<!-- magnific-popup -->
<link href="assets/magnific-popup/magnific-popup.css" rel="stylesheet">
<!-- owl.carousel -->
<link href="assets/owl.carousel/assets/owl.carousel.css" rel="stylesheet">
<link href="assets/owl.carousel/assets/owl.theme.default.min.css" rel="stylesheet">
<!-- Bootstrap -->
<link href="assets/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<!-- Style CSS -->
<link href="style.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body id="page-top" data-spy="scroll" data-target=".navbar" style="background-color:
#fccc63;">
<style style="text/css">
div.slide-left {
width:100%;
overflow:hidden;
}
div.slide-left h3 {
animation: slide-left 10s;
}
@keyframes slide-left {
from {
margin-left: 100%;
width: 300%;
}
to {
margin-left: 0%;
width: 100%;
}
}
98
</style>
<div class="icon-bar">
<a href="https://www.facebook.com" class="facebook"><i class="fa fa-facebook"></i></a>
<a href="https://www.twitter.com" class="twitter"><i class="fa fa-twitter"></i></a>
<a href="https://www.google.com" class="google"><i class="fa fa-google"></i></a>
<a href="https://www.linkdin.com" class="linkedin"><i class="fa fa-linkedin"></i></a>
<a href="https://www.youtube.com" class="youtube"><i class="fa fa-youtube"></i></a>
</div>
99
<h2 class="animated fadeInDown animation-delay-4 crousel-subtitle">likes <?php
echo $likes1 ?> </h2>
The following code is written in python and is called by our web application to analyze the
personality of the user according to its posts
109
from nltk.tokenize import word_tokenize, sent_tokenize
import nltk
import json
import sys
import io
import codecs
import re
import scipy as sp
import numpy as np
import pandas as pd
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
train1 = [('', 'PTI'),
('', 'PTI'),
('', 'PMLN'),
('', 'PTI'),
('', 'PMLN'),
('','PMLN'),
('', 'PTI'),
('', 'PMLN'),
('', 'PMLN'),
('', 'PTI')]
test1 = [('The beer was good.', 'pos'),
('I do not enjoy my job', 'neg'),
("I ain't feeling dandy today.", 'neg'),
("I feel amazing!", 'pos'),
('Gary is a friend of mine.', 'pos'),
("I can't believe I'm doing t", 'neg') ]
train = [('I love this sandwich.', 'pos'),
('This is an amazing place!', 'pos'),
('I feel very good about these beers.', 'pos'),
('This is my best work.', 'pos'),
("What an awesome view", 'pos'),
('I do not like this restaurant', 'neg'),
('I am tired of this stuff.', 'neg'),
("I can't deal with this", 'neg'),
('He is my sworn enemy!', 'neg'),
('My boss is horrible', 'neg')]
test = [('The beer was good', 'pos'),
('I do not enjoy my job', 'neg'),
("I ain't feeling dandy today", 'neg'),
("I feel amazing!", 'pos'),
('Gary is a friend of mine', 'pos'),
("I can't believe I'm doing this", 'neg') ]
111
8.12. Python code for Political Views
Following code was written in python and It takes the user’s posts and analyze it according to the
training data we provided to check that which political party the user supports.
from nltk.tokenize import word_tokenize, sent_tokenize
import nltk
import json
import sys
import io
import codecs
import re
import scipy as sp
import numpy as np
import pandas as pd
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
train = [('Imran Khan possesses all the great qualities of great leader', 'PTI'),
('whoever loves his country would definitely support Imran Khan and PTI', 'PTI'),
('I love pti', 'PTI'),
('I like pti government in kpk ', 'PTI'),
('vote for PTI', 'PTI'),
('Imran khan is a good,Honest and brave leader', 'PTI'),
('no threat greater than the militant Islamic State group that Muslim-majority countries could
jointly fight','Neu'),
('this country cannot afford to get embroiled in conflict in the Middle East', 'Neu'),
('Pakistan values its relations with all countries and the Pakistani national interest requires it to stay
neutral in the current crisis','Neu'),
('Pakistan really wants to play a leading role in the Muslim world, then it should aim to assert its
military hegemony ','Neu'),
('Nawaz shareef great leader', 'PMLN'),
('NAWAZ SHARIF ZINDABAD', 'PMLN'),
('I love you nawaz sharif i Love u pmln','PMLN'),
('President PMLN Shehbaz Sharif addressed charged crowds at multiple locations', 'PMLN'),
('Vote for PMLN', 'PMLN')
]
test = [('Imran Khan possesses all the great qualities of great leader', 'PTI'),
('whoever loves his country would definitely support Imran Khan and PTI', 'PTI'),
('I love pti', 'PTI'),
('I like pti government in kpk ', 'PTI'),
('vote for PTI', 'PTI'),
('no threat greater than the militant Islamic State group that Muslim-majority countries could
jointly fight','Neu'),
('this country cannot afford to get embroiled in conflict in the Middle East', 'Neutral'),
('Pakistan values its relations with all countries and the Pakistani national interest requires it to stay
neutral in the current crisis','Neu'),
('Pakistan really wants to play a leading role in the Muslim world, then it should aim to assert its
military hegemony ','Neu'),
('Imran khan is a good,Honest and brave leader', 'PTI'),
('Nawaz shareef great leader', 'PMLN'),
('NAWAZ SHARIF ZINDABAD', 'PMLN'),
('I love you nawaz sharif i Love u pmln','PMLN'),
('President PMLN Shehbaz Sharif addressed charged crowds at multiple locations', 'PMLN'),
('Vote for PMLN', 'PMLN')]
PMLN = ['Nawaz shareef great leader',
'NAWAZ SHARIF ZINDABAD',
'I love you nawaz sharif i Love u pmln',
112
'President PMLN Shehbaz Sharif addressed charged crowds at multiple locations',
'Vote for PMLN','Empire ki ungli','ro imran ro','Vote ko izzat do' ]
PTI =['#ImranKhan',
'Imran Khan', 'PTI',
' pti','gonawazgo','PTIMinarePakistanJalsa','Dam Mast Qalandar Mast Mast', 'Empire ki ungli
uth gai',
'Empire ki ungli uth gae','Do nahi ek pakistan','2 nhi aik Pakistan!']
#vectorizer = CountVectorizer(analyzer = "word", \
# tokenizer = None, \
# preprocessor = None, \
# stop_words = None, \
# max_features = 5000)
#train_data_features = vectorizer.fit_transform(X_train)
#train_data_features = train_data_features.toarray()
array = []
#print(len(text_tok))
#test_sentence = ""
for test_sentence in range(0,len(text_tok)):
w = word_tokenize(text_tok[test_sentence].lower())
#test_sentence = test_sentence + 1
test_sent_features = {word.lower(): (word in word_tokenize(text_tok[test_sentence].lower()))
for word in all_words}
p = classifier.classify(test_sent_features)
#print(test_sent_features)
array.append(str(p))
#print(w)
#print(array)
a = text_tok
for i in PMLN:
b = word_tokenize(i.lower())
for j in PTI:
c = word_tokenize(i.lower())
lst = []
113
def check(array1,array2, array3):
for i in array1:
for j in array2:
if i==j:
lst.append('PMLN')
for k in array3:
if i==k:
lst.append('PTI')
for l in lst:
add = 0
add1 = 0
if l == 'PMLN':
add = add + 1
elif l == 'PTI':
add1 = add1 + 1
if(add<10 or add1<10):
print('Neutral')
elif(add>=10):
print('PMLN')
elif(add1>=10):
print('PTI')
#print('PMLN:'+ str(add) + '& PTI:' + str(add1))
check(a,b,c)
"""def politicalViews(lis):
count =0
count1 = 0
count2 = 0
for i in array:
if (i == 'PMLN'):
count = count + 1
elif(i=='PTI'):
count1 = count1 + 1
elif(i=='Neu'):
count2 = count2 + 1
#%matplotlib inline
#plt.style.use('ggplot')
a = round((count/len(array))*100)
b = round((count1/len(array))*100)
c = round((count2/len(array))*100)
x = ['PMLN','PTI','Neutral']
per = [a,b,c]
x_pos = [i for i, _ in enumerate(x)]
plt.bar(x_pos, per, color=['green', 'red','blue'])
#plt.bar(x_pos, per1, color='red')
plt.xlabel("Political Parties")
plt.ylabel("Attraction Percentage")
plt.title("Overall Political Attraction ")
#plt.text(x_pos, .25, str(123), color='blue', fontweight='bold')
plt.xticks(x_pos, x)
plt.savefig('Polfig')
plt.show()
#fig.savefig('test.png')
#return('Neg:'+ str((count1/len(array))*100)+'%' + '\n Pos:'+ str((count/len(array))*100)+'%')
print(politicalViews(array)) """
f.close()
114
9.0. Methodology
We have applied incremental model which is a method of software development for building,
designing and testing of the software under development and in it we done work in chunks.
Every subsequent chunk adds on some new functionality to the previously build software.
We have developed our whole system in several chunks including data retrieving using Graph
API, storing data in the database and coding the analyzer and then integrate all these chunks to
make a full fledge working software.
Firstly, we would design our home page using PHP and write all the get methods of the Graph
API. After getting data from the Graph API, we would create a database using php myadmin and
store all the information on there for the analysis. All of the data we retrieve from Graph API
would be stored in database except for the posts. We would create a file in the local drive
containing all of the user posts which would be analyzed by our analyzer.
Analyzer is the most imperative and important part of this project. By analyzing user posts, we
extracted out the information about the user’s personality and political views. We have written
our analyzer in python with third party libraries such as Natural Language Tool Kit (NLTK),
Scipy, Pandas, Numpy and Matlibplot.
We used NLTK tool as it helps in tokenize the raw data into words and sentences. It also helps in
preprocessing of data like cleaning and using stopwords. We used Pandas and Numpy for the
vectorization of data and we used Matlibplot to draw the personality Graph.
115
10.0. Testing And Validation
Login Through
Facebook
Step# Step Detail Expected Result Actual result Pass/ fail/ not
executed/
Suspended
1 Go to the User is As expected Pass
homepage and redirected to
click on login Facbook login
2 Enter username Username and As expected Pass
and password password entered
116
10.1. Login Through Facebook
117
Test case ID: FM_02
Test case Description: Triggering Analyzer and Displaying Results
Created by: Sagar Ashraf & Muhammad Arslan Ijaz & Zeeshan
Mushtaq
Reviewed by: Sagar Ashraf & Muhammad Arslan Ijaz & Zeeshan
Mushtaq
Test Design Date: 23/4/2018
Test Executed by: Sagar Ashraf & Muhammad Arslan Ijaz & Zeeshan Mushtaq
Test Execution Date: 24/4/2018
Pre-Conditions: Active internet connect and clicked on login button
Test Case Status (Pass/Fail/Not Executed): Pass
Test Data: N/A
Post Conditions: Analyzer is triggered, the users posts have been analyzed and displayed on a
new webpage along with the other results.
Posts Analyzer
Step# Step Detail Expected Result Actual result Pass/ fail/ not
executed/
Suspended
1 User clicks Application As expected Pass
login button triggers graph
api.
2 After logging Analyzer is As expected Pass
in through triggered and
Facebook user the application
clicks get starts retrieving
results button values from
database.
118
10.2. Main Homepage
119
10.4. Confirmation Page
120
10.5. Main Results Page (Facebook Photo Likes)
121
10.6. Main Results Page (Personality Analysis)
122
10.8. Main Results Page (Recent Video)
123
124
11.0. User manual for Application
This web application helps user to understand his/herself better.
Below are some guidelines for the users in order to use our application smoothly and
effortlessly.
When the user clicks on the login button, the application redirects user to the Facebook
login so that the user can login with their Facebook account and can give access to our
application.
After that the user will be redirected to our application with its facebook username and
picture displayed confirming the successful login.
After that the user will click the get results button which would redirect the user to a new
page containing all the analyzed results.
Since, Graph API uses more time to fetch all the data from Facebook so it is
recommended that you must use a high speed internet or stop all the other applications
that are using the internet as it will slow down the process.
User must have a working computer and Internet.
User must have a Facebook account already created and should’ve made at least 500
photos for the analyzer to properly analyze the posts. The more the user posts, the better.
User should’ve uploaded at least 50 photos in their Facebook account for it work
properly and clearly demonstrate the most liked picture.
User must have removed all privacy of their account because even though you’ve given
access token to the graph API, but Graph API itself cannot bypass certain restrictions
that you have applied on your data that is on Facebook.
125
12.0. Conclusion And Recommendation
After six months of implementation we have come to conclude that this application
work perfectly fine for the users who have access of internet. This application doesn’t work if
the internet connection has been lost. This application works perfectly for analyzing the large
set of data to get the result of any field of interest. This application gathers the data from
Facebook with the help of Graph API and then the analyzer analyses the data. This application
would be very useful for the users who want to know more about themselves and how much
they are inclined towards politics. This application is entertaining and informative at the same
time and it will help you explore more about yourself.
126
13.0. References
https://www.quora.com/Whats-the-best-way-to-mine-data-from-a-Facebook-fan-page
https://packetstormsecurity.com/files/129918/Facebook-Data-Mining-Utility.html
https://towardsdatascience.com/how-to-use-facebook-graph-api-and-extract-data-using-python-
1839e19d6999
https://developers.facebook.com/docs/reference/php/
http://text-processing.com/demo/sentiment/
https://www.kaggle.com/ngyptr/python-nltk-sentiment-analysis
https://pythonspot.com/python-sentiment-analysis/
https://programminghistorian.org/lessons/sentiment-analysis
127
128
14.0. Information Sheet
Roll No Name Email Address (FC College) Frequently Checked Email Personal Cell
Address Phone
Number
18-10615 Sagar 18- sagarashraf93@gmail.com 0304-
Ashraf 10615@formanite.fccollege.ed 4862262
u.pk
18-10756 Muham 18- 0347-
mad 10756@formanite.fccollege.ed Arslanijaz1911@gmail.com 4425121
Arslan u.pk
Ijaz
18-10638 Zeeshan 18- 0337-
Mushtaq 10638@formanite.fccollege.ed Tranceaddict921@gmail.com 4826228
u.pk
129
130