FacebookPostImporterBundle

UNIX name Owner Status
FacebookPostImporterBundle 7x stable
Version Compatible with
N/A N/A
eZ Platform and eZ Publish bundle for importing Facebook posts from a page to eZ content, using a given mapping of post edges to callables.

Facebook Post Importer Bundle

This is an eZ Publish Symfony bundle to make it easy to import posts from a Facebook page. You simply have to describe how to map the Facebook posts to the eZ content class.

Installation

Add this repo to your composer.json file configuration:

{
"require": {
"contextualcode/facebook-post-importer-bundle": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "[email protected]:contextualcode/FacebookPostImporterBundle.git"
}
]
}

and run composer update contextualcode/facebook-post-importer-bundle.

Enable the bundle in app/AppKernel.php (ezpublish/EzPublishKernel.php) by adding this line in the registerBundles method:

public function registerBundles()
{
$bundles = array(
...
new ContextualCode\FacebookPostImporterBundle\ContextualCodeFacebookPostImporterBundle()
);

Setup (tokens, config)

You'll have to have these before using the bundle.

  1. page_id: The ID of your Facebook page.
  2. app_id: The ID of your Facebook app.
  3. app_secret: The secret for your Facebook app.
  4. access_token: A page access token. You can generate a token that never expires by following the instructions from this StackOverflow answer.

And set these as parameters in a yml file like:

cc_facebook_post_importer:
access_token: ...
app_id: ...
app_secret: ...
page_id: ...
facebook_version: ...

The facebook_version is optional. You can see the current version here here, which is "v2.12" as of January 30th, 2018.

These are are optional in the yml config, so you are able to set them dynamically:

// make a new service instance
$fbImporter = new FacebookPostImporterService();
// or, from inside a Controller or ContainerAwareCommand, use the existing one
// $fbImporter = $this->getContainer()->get( "contextualcode.facebookpostimporter.importer" );
$fbImporter->setFBParam("app_id", $appID);
$fbImporter->setFBParam("facebook_version", $facebookVersion);
...

But they must all be set before running the actual import.

You can set the language to import to by calling setLanguage:

$fbImporter->setLanguage('eng-GB');

The default is 'eng-US'.

Usage

Attribute mapping

The main part of using the FacebookPostImporter service is the function setCallableForEdge. This is the how the attribute mapping from a FB post to an eZ class is done.

The two parameters to setCallableForEdge are 1) a PHP callable (callback) that will do the mapping from Facebook data to eZ attributes, and 2) an optional parameter that chooses which data from Facebook to give to the first parameter.

More specifically, the second parameter (which is optional) to setCallableForEdge is the FB post edge name. It determines what data from the post is sent in the first parameter. If "none" (or left out), the first parameter will be the post itself (/post). Otherwise, you can specify any of the /post edges (https://developers.facebook.com/docs/graph-api/reference/v2.11/post#edges). For example, you can pass "/attachments" (or "attachments") as this parameter, and then the first parameter will be the data from /{$POST_ID}/attachments, so you could access any image attachment URLs (see example below in Usage).

The parameters that will be passed to the callable (callback) function you provide as the first parameter to setCallableForEdge are 1) data from the Facebook post and 2) a reference to an eZ\Publish\API\Repository\Values\Content\ContentCreateStruct. The callable should set the ContentCreateStruct fields as necessary, presumably using the Facebook data.

Important: Every one of your callables should return true if the eZ object should be published. If one callable returns false, the object won't be published. You can use this to control whether or not the importer publishes an object for posts that meet certain criteria (has image, long enough message, before or after a certain date, etc.).

Importing

After setting up the service and setting all of the callables, you can run import() to do the actual import. Import takes three optional parameters:
1) since, which should be a Unix timestamp. It will get added as a query param to all of the FB API calls, to limit the posts grabbed to only posts 'since' a certain datetime.
2) until, which should be a Unix timestamp that behaves just like since, but 'until' a certain datetime.
3) verbose, which should be a boolean that controls whether or not to output progress messages when importing.

Simple example

Assuming you have an eZ class with identifier fb_post with attributes fb_post_id (text line), name (text line), and message (text block), the basic flow of using the FacebookPostImporter service will look like:

use ContextualCode\FacebookPostImporterBundle\Services\FacebookPostImporterService;

// make a new service instance
$fbImporter = new FacebookPostImporterService();
// or, from inside a Controller or ContainerAwareCommand, use the existing one
// $fbImporter = $this->getContainer()->get('contextualcode.facebookpostimporter.importer');

// set our container node ID
$fbImporter->setContainerNodeID(123);

// set our eZ class identifier
$fbImporter->setImportClass('fb_post');

// set the field to check before double-importing any post
$fbImporter->setPostIDAttribute('fb_post_id');

// set the mappings
// this will be run for each post's data
$fbImporter->setCallableForEdge('fbImporterPostEdgeMapper');

// run the import
$fbImporter->import();

// if you wanted to only grab the posts since yesterday
// $yesterdayTimestamp = time() - (24 * 60 * 60);
// $fbImporter->import($yesterdayTimestamp);

// this function will receive FB post data
// and a eZ\Publish\API\Repository\Values\Content\ContentCreateStruct by reference
function fbImporterPostEdgeMapper($data, &$contentCreateStruct)
{
// set the necessary fields with the FB data
// (you'll want to do more error checking than this)
$contentCreateStruct->setField('name', substr($data['message'], 0, 20));
$contentCreateStruct->setField('fb_post_id', $data['id']);
$contentCreateStruct->setField('message', $data['message']);

// give the green light to eventually publish this object
return true;
}

Note that we called $fbImporter->setPostIDAttribute('fb_post_id'); and stored the FB post id into the eZ object's fb_post_id field. These two things means that the next time we run this import, we won't import posts from Facebook that have an ID that is already in any eZ fb_post object (in our container node)'s fb_post_id attribute. So this import will be safe to run on a cronojob to import only the new posts. You should also take advantage of the since parameter when calling import().

Using data from a different edge

What if you wanted to upload an image attachment from the Facebook post into an ezbinaryfile attribute called image, for example? That data is not available in the default /post edge. It's in the /{$POST_ID}/attachments edge. So, call setCallableForEdge like this (before you run import()):

$fbImporter->setCallableForEdge('fbImporterAttachmentsEdgeMapper', '/attachments');

function fbImporterAttachmentEdgeMapper($data, &$contentCreateStruct)
{
if (count($data) == 0) {
return true;
}
if (!isset($data[0]['media']['image']['src'])) {
return true;
}

$imgSrc = $data[0]['media']['image']['src'];

// download the image to disk however you want
// $filePath = downloadImage($imgSrc);

$contentCreateStruct->setField('image', $filePath);

return true;
}

There's a full example of downloading an image in /examples/ImportFBPostsCommand.php.

Note that you can set as many setCallableForEdges as there are post edges, but only the last one set for each edge will run.

Command example

There's an example Symfony command located at /examples/ImportFBPostsCommand.php. This shows how to use a Symfony command (that can be run as a cronjob) to import all Facebook posts as an eZ class named fb_post, in a certain container node.

License

http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2

No news yet.

This project has no reviews yet. Be the first one to review it!

No forum messages yet.