I am trying to uploading image to the facebook page using GraphQL API
Bellow is some code I am using
use SammyK\LaravelFacebookSdk\LaravelFacebookSdk as Facebook;
try {
$token = $token ? $token : $this->access_token;
// $fb = app(Facebook::class);
$fb = new Facebook(array( 'appId' => '366774494090568', 'secret' => '9f847b900176325ce45d87dec94e81ea', 'fileUpload' => true));
//$fb->setFileUploadSupport(true);
//$fb->setDefaultAccessToken($token);
return $fb;
} catch (\Exception $e) {
throw $e;
}
$payload = unserialize($scheduledPost->payload);
$images = $payload['images'];
$timezone = $payload['scheduled']['publishTimezone'];
$appUrl = config("app.url");
$mediaIds = [];
$mediaCount = 0;
foreach($images as $image){
$relativePath = $image['relativePath'];
$fullPath = $appUrl."/".$relativePath;
$media = ["url" => $fullPath, "published" => false];
$uploadResponse = $this->uploadMedia($media);
$mediaId = $uploadResponse['id'];
$mediaIds["attached_media[$mediaCount]"] = "{'media_fbid': '$mediaId'}";
$mediaCount++;
}
public function uploadMedia($media)
{
$fb = $this->setAsCurrentUser($this->access_token);
$response = $fb->post("/{$this->original_id}/photos", $media);
return $response->getDecodedBody();
}
When I use setFileUploadSupport(true), there is error that function is not defined
If I use new Facebook with 'fileupload' => 'true' it gives me error like bellow
exception: "Symfony\Component\Debug\Exception\FatalThrowableError"
file: "C:\Users\king\Documents\work\01_Unicilix\API\vendor\sammyk\laravel-facebook-sdk\src\LaravelFacebookSdk\LaravelFacebookSdk.php"
line: 28
message: "Argument 1 passed to SammyK\LaravelFacebookSdk\LaravelFacebookSdk::__construct() must implement interface Illuminate\Contracts\Config\Repository, array given, called in C:\Users\king\Documents\work\01_Unicilix\API\app\Traits\Facebook\FacebookTrait.php on line 22
This code was very correct.
The problem was I can get storage image from url because of the server(ubunt) permmission.
Related
I am consuming a service using CURL. I am able to connect all the functions of the services in the form of a CXF Service List using the following code.
$client = \Config\Services::curlrequest();
$response = $client->request('GET', 'www.soapservice.co.za/service');
var_dump($response->getBody());
Var Dump Returns a string with Available services
The service has 10 functions listed in this manner getDataFunction.
How do I invoke the function? Or how do I get the contents of the body and start using Service functions?
Any help would be appreciated
This is how I resolved my issue using Codeignter 4 and Soap Client.
public function ownersearch()
{
helper(['form']);
$username = "";
$password = "";
$url = 'getProperty?wsdl';
$first_name = $this->request->getVar('first_name');
$second_name = $this->request->getVar('second_name');
$last_name = $this->request->getVar('last_name');
$user_id = $this->request->getVar('user_id');
$session_id = session()->get('user_id');
$client = new \SoapClient($url);
$deedsusagemodel = new UsageLogModel();
$args = [
'idNumber'=> $user_id,
'username'=> $username,
'password' => $password,
'officeCode' => 1
];
$usageData = [
'user_id' => $session_id
];
if($user_id != Null){
$response = $client->getFunctionByIDNumber($args);
$ndata = $response->return;
if($ndata->errorResponse->errorCode == 64)
{
$error = $ndata->errorResponse->errorDescription;
return $this->fail($error);
}
if($ndata->errorResponse->errorCode == 550)
{
$error = $ndata->errorResponse->errorDescription;
return $this->fail($error);
}
else{
$usagemodel->insert($usageData);
return $this->respond($ndata, 200);
}
}
}
I use laravel and I use command laravel to synchronize my database
My command laravel to call api to synchronize like this :
<?php
namespace App\Console\Commands;
...
class MySynchronize extends Command
{
...
public function handle()
{
DB::statement("SET foreign_key_checks=0");
Vendor::truncate();
Location::truncate();
Item::truncate();
DB::statement("SET foreign_key_checks=1");
$requestContent = [
'auth' => ['Administrator', 'www.Secret.com', 'ntlm']
];
//call api vendor
try {
$client = new GuzzleHttpClient();
$apiRequest = $client->request('GET', "http://www.secret.com:1234/ODATA/ODataV4/Company('secret2018')/Vendor", $requestContent);
$jsonResponse = json_decode($apiRequest->getBody(), true);
$data = [];
foreach ($jsonResponse['value'] as $value) {
$created_at = Carbon::now();
$last_modified_at = Carbon::parse($value['Last_Date_Modified']);
$data[] = [
'id' => $value['Code'],
'name' => $value['Name'],
'last_modified_at' => $last_modified_at,
'created_at'=> $created_at,
'updated_at'=> $created_at
];
}
DB::table('vendors')->insert($data);
} catch (RequestException $re) {
// For handling exception.
}
//call api location
try {
$client = new GuzzleHttpClient();
$apiRequest = $client->request('GET', "http://www.secret.com:1234/ODATA/ODataV4/Company('secret2018')/Location", $requestContent);
$jsonResponse = json_decode($apiRequest->getBody(), true);
$data = [];
foreach ($jsonResponse['value'] as $value) {
$created_at = Carbon::now();
$data[] = [
'id' => $value['Code'],
'description' => $value['Name'],
'created_at'=> $created_at,
'updated_at'=> $created_at
];
}
DB::table('locations')->insert($data);
} catch (RequestException $re) {
// For handling exception.
}
//call api item
try {
$client = new GuzzleHttpClient();
$apiRequest = $client->request('GET', "http://www.secret.com:1234/ODATA/ODataV4/Company('secret2018')/Item", $requestContent);
$jsonResponse = json_decode($apiRequest->getBody(), true);
$data = [];
foreach ($jsonResponse['value'] as $value) {
$last_modified_at = Carbon::parse($value['Last_Date_Modified']);
$created_at = Carbon::now();
$data[] = [
'id' => $value['Code'],
'description' => $value['Description'],
'vendor_code' => $value['Vendor_Code']?$value['Vendor_Code']:null,
'last_modified_at' => $last_modified_at,
'created_at'=> $created_at,
'updated_at'=> $created_at
];
}
\DB::table('items')->insert($data);
} catch (RequestException $re) {
// For handling exception.
}
// send output
echo 'synchronize success';
}
}
First I delete all data in the table using truncate. If it is deleted then it will call the api for the insert process to table
My problem is when an error occurs on the api server. For example, server is died or another error. It makes the data in my database empty because I've run truncate
How do I improve the script so that when an error occurs on the api, truncate is not executed?
What is the best way? Do you use try catch in the try catch to handle it?
You should take a look at DB transactions: https://laravel.com/docs/5.7/database#database-transactions
If an exception is thrown within the transaction Closure, the transaction will automatically be rolled back.
So something like that could work:
public function handle()
{
DB::transaction(function () {
// your DB statements
try {
// external API calls
} catch (SomeException $e) {
// If for any reasons you want to catch the exception inside the closure
// (logging maybe?), make sure to rethrow it.
// Otherwise, Laravel won't know it needs to rollback the DB changes
throw $e;
}
});
}
I want to pass pagination parameters through POSTMAN and pass sort,order,limits in my model to get query with paginate.? how can i do this? Currently it return error.
Currently my route :
http://localhost:8000/api/allpost
My PostController function :
public function index(Request $request)
{
try {
$allPost = Post::allUserPost();
if($allPost !="" && count($allPost)>0) {
return [
'status_code' => 200,
'message' => "Post retrieved successfully",
'PostDetails' => $allPost,
];
} else {
return response()->json([
'message' => "Post data not found",
'status_code' => 403,
]);
}
} catch (\Exception $ex) {
return response()->json([
'message' => "Internal server error",
'status_code' => 500,
]);
}
}
And my POST model function :
public static function allUserPost(Request $request){
$sort = $this->parameters->sort();
$order = $this->parameters->order();
$limit = $this->parameters->limit();
$userPost = Post::with(['product','categories','user.userDetails'])->whereStatus("Active")->orderBy($sort, $order)->paginate($limit)->get();
$userPost_array = $userPost->toArray();
foreach ($userPost_array as $key => $value) {
# code...
$attributes_arr = array_column($userPost_array[$key]['categories'], 'attribute_id');
$category_ids = Attribute::whereIn("id",$attributes_arr)->pluck('category_id');
$category_ids = array_unique($category_ids->toArray());
$category_details_with_att = Post::getCategoryWithAttributeData($attributes_arr,$category_ids);
unset($userPost_array[$key]["categories"]);
$userPost_array[$key]["categories"] = $category_details_with_att->toArray();
}
return $userPost_array;
}
Currently it returns error
Type error: Too few arguments to function App\Post::allUserPost(), 0 passed in D:\xampp\htdocs\IDM\app\Api\V1\Controllers\Front\PostController.php on line 30 and exactly 1 expected
So how can i pass parameters in postmen and whats the solution for this error?
First change this line to $allPost = Post::allUserPost();
$allPost = Post::allUserPost($request);
and then change this code
$sort = $this->parameters->sort();
$order = $this->parameters->order();
$limit = $this->parameters->limit();
To
$sort = $request->sort;
$order = $request->order;
$limit = $request->limit;
and then you can pass these paramets in a query string like
http://localhost:8000/api/allpost?sort=somesort&order=asc&limit=10
Also chage this line
$userPost = Post::with(['product','categories','user.userDetails'])->whereStatus("Active")->orderBy($sort, $order)->paginate($limit)->get();
to
$userPost = Post::with(['product','categories','user.userDetails'])->whereStatus("Active")->orderBy($sort, $order)->paginate($limit);
You are missing an argument when calling the allUserPost function inside the try block.
It should be
$allPost = Post::allUserPost($request);
and then you can retrieve the parameters from the $request variable.
Just change this line in your code
$allPost = Post::allUserPost($request);
And then in your function, you have to change your request type. And after that you have to do one more change only use paginate() method not with get() method.
public static function allUserPost(Request $request){
$sort = $request->sort;
$order = $request->order;
$limit = $request->limit;
$userPost = Post::with(['product','categories','user.userDetails'])->whereStatus("Active")->orderBy($sort, $order)->paginate($limit);
$userPost_array = $userPost->toArray();
foreach ($userPost_array as $key => $value) {
$attributes_arr = array_column($userPost_array[$key]['categories'], 'attribute_id');
$category_ids = Attribute::whereIn("id",$attributes_arr)->pluck('category_id');
$category_ids = array_unique($category_ids->toArray());
$category_details_with_att = Post::getCategoryWithAttributeData($attributes_arr,$category_ids);
unset($userPost_array[$key]["categories"]);
$userPost_array[$key]["categories"] = $category_details_with_att->toArray();
}
return $userPost_array;
}
I hope this will help you.
I am hoping someone has some experience with the blueimp fileupload jquery plugin at : https://github.com/blueimp/jQuery-File-Upload
How to add the uploaded file name to database ?
In the options array (look for $this->options = array( )
and insert
'database' => 'database_name',
'host' => 'localhost',
'username' => 'user',
'password' => 'password',
Then after
protected function handle_file_upload($uploaded_file, $name, $size, $type, $error,
$index = null, $content_range = null) {
$file = new stdClass();
$file->name = $this->get_file_name($name, $type, $index, $content_range);
$file->size = $this->fix_integer_overflow(intval($size));
$file->type = $type;</code></pre>
Insert this code
//Start added coded
// prepare the image for insertion
$data = addslashes (file_get_contents($uploaded_file));
// get the image info..
$size = getimagesize($uploaded_file);
$file->upload_to_db = $this->add_img($data, $size, $name);
//end added code
and after the function handle_file_upload insert the following code to actually upload the image to the database.
function query($query) {
$database = $this->options['database'];
$host = $this->options['host'];
$username = $this->options['username'];
$password = $this->options['password'];
$link = mysql_connect($host,$username,$password);
if (!$link) {
die(mysql_error());
}
$db_selected = mysql_select_db($database);
if (!$db_selected) {
die(mysql_error());
}
$result = mysql_query($query);
mysql_close($link);
return $result;
}
function add_img($data,$size,$name)
{
$add_to_db = $this->query("INSERT INTO your_database_name
(image_type ,image, image_size, file_name)
VALUES
('{$size['mime']}', '{$data}', '{$size[3]}', '{$name}')") or die(mysql_error());
return $add_to_db;
}
This will store the actual image in the database if you don't want that change the add_img($data,$size,$name) to add_img($size,$name) and just don't pass the $data variable. The $data variable should be stored as a medium or long blob.
You can also comment out the fileupload to directory stuff so you don't get errors if you don't what the images uploaded to a directory. This is in the protected function handle_file_upload
//comment out file upload stuff since storing in database
/*
if ($this->validate($uploaded_file, $file, $error, $index)) {
$this->handle_form_data($file, $index);
$upload_dir = $this->get_upload_path();
if (!is_dir($upload_dir)) {
mkdir($upload_dir, $this->options['mkdir_mode'], true);
}
$file_path = $this->get_upload_path($file->name);
$append_file = $content_range && is_file($file_path) &&
$file->size > $this->get_file_size($file_path);
if ($uploaded_file && is_uploaded_file($uploaded_file)) {
// multipart/formdata uploads (POST method uploads)
if ($append_file) {
file_put_contents(
$file_path,
fopen($uploaded_file, 'r'),
FILE_APPEND
);
} else {
move_uploaded_file($uploaded_file, $file_path);
}
} else {
// Non-multipart uploads (PUT method support)
file_put_contents(
$file_path,
fopen('php://input', 'r'),
$append_file ? FILE_APPEND : 0
);
}
$file_size = $this->get_file_size($file_path, $append_file);
if ($file_size === $file->size) {
$file->url = $this->get_download_url($file->name);
list($img_width, $img_height) = #getimagesize($file_path);
if (is_int($img_width) &&
preg_match($this->options['inline_file_types'], $file->name)) {
$this->handle_image_file($file_path, $file);
}
} else {
$file->size = $file_size;
if (!$content_range && $this->options['discard_aborted_uploads']) {
unlink($file_path);
$file->error = 'abort';
}
}
$this->set_additional_file_properties($file);
}
*/
I am having a facebook error on stream_publish call. I actually used an extension for Magento for Fconnect. Fconnect & Flogin is working fine. But it is requirement that when user place an order it should be posted on user's wall. For that I have implemented like this
document.observe('click', function(e){
if (e.element().match('a[rel^=facebook-connect]') || e.element().match('button[rel^=facebook-connect]')) {
e.stop();
FB.login(function(response){
if(response.status=='connected') setLocation('http://staging.mystore.com/facebook/customer_account/connect/');
}, {perms:"email,publish_stream"});
}
});
in Facebook Client file generateSignature method is like this
private function _generateSig($params_array)
{
Mage::log($params_array);
$str = '';
ksort($params_array);
foreach ($params_array as $k=>$v) {
$str .= "$k=$v";
}
$str .= $this->_secret;
Mage::log($str);
Mage::log('md5 sigs:: ' . md5($str));
return md5($str);
}
& My code that is calling the API is like this
$message = 'just placed an order on mystore.com';
$attachment = array(
'name' => "mystore",
'href' => 'http://www.mystore.com/',
'description' => 'New order on mystore.com',
'media' => array(array('type' => 'image',
'src' => 'http://www.mystore.com/skin/frontend/default/mystore/images/logo.png',
'href' => 'http://www.mystore.com/')));
$action_links = array( array('text' => 'Buy#mystore', 'href' => 'http://www.mystore.com/'));
$attachment = json_encode($attachment);
$action_links = json_encode($action_links);
try{
// if( $facebook->api_client->stream_publish($message, $attachment, $action_links, null, $target_id))
if($this->_getClient()->call( 'facebook.stream.publish',
array($message, $attachment, $action_links,
$this->_getClient()->users->getLoggedInUser(),
Mage::getSingleton('facebook/config')->getApiKey() )
) )
{
Mage::log( "Added on FB Wall" );
}
} catch(Exception $e)
{
Mage::log( "Exception in wall write" );
Mage::log($e);
}
After logging the Signature I found in log is
api_key=XXXXXXXXmethod=facebook.stream.publishsession_key=2.AQCm5fABfobInAS5.3600.1309352400.1-1000025660978090=just placed an order on mystore.comcall_id=1309345883.3068format=JSONv=1.01={"name":"mystore","href":"http:\/\/www.mystore.com\/","description":"New order on mystore.com","media":[{"type":"image","src":"http:\/\/www.mystore.com\/skin\/frontend\/default\/mystore\/images\/logo.png","href":"http:\/\/www.mystore.com\/"}]}2=[{"text":"Buy#mystore","href":"http:\/\/www.mystore.com\/"}]3=1000025660978094=5070afefb42b162aff748f55ecf44d110d9e2a90117ee1704e2adb41f1d190fa
I have never done any development on Facebook SO I have no Idea what to do? Please help me with solution. & let me know if u guys need any other info to understand this.
Oh yeah One more thing the Client File code that is calling Api (call method) its like this
private function _prepareParams($method, $params)
{
$defaultParams = array(
'api_key' => $this->_apiKey,
'call_id' => microtime(true),
'format' => 'JSON',
'v' => '1.0'
);
if($this->_sessionKey){
$defaultParams['session_key'] = $this->_sessionKey;
}
$params = array_merge($defaultParams, $params);
foreach ($params as $key => &$val) {
if (!is_array($val)) continue;
$val = Zend_Json::encode($val);
}
$params['method'] = $method;
if(isset($params['sig'])) {
unset($params['sig']);
}
$params['sig'] = $this->_generateSig($params);
return $params;
}
public function call($method, $args=array())
{
Mage::log($args);
$params = $this->_prepareParams($method, $args);
$client = self::_getHttpClient()
->setUri(self::FACEBOOK_REST_URI)
->setMethod(Zend_Http_Client::POST)
->resetParameters()
->setParameterPost($params);
try {
$response = $client->request();
} catch(Exception $e) {
throw new Mage_Core_Exception('Service unavaliable');
}
if(!$response->isSuccessful()) {
throw new Mage_Core_Exception('Service unavaliable');
}
$result = Zend_Json::decode($response->getBody());
//json decode returns float on long uid number? is_json check? old php?
if(is_float($result)){
$result = $response->getBody();
}
if(is_array($result) && isset($result['error_code'])) {
throw new Mage_Core_Exception($result['error_msg'], $result['error_code']);
}
return $result;
}
For calling API I used two ways $this->_getClient()->call( 'facebook.stream.publish',
& $this->_getClient()->call( 'stream_publish',
None of them are working
ok GUys I figure out the mistake
look at my code
format=JSONv=1.01={"name":"mystore","href":"http:\/\/www.mystore.com\/","description":"New order on mystore.com","media":[{"type":"image","src":"http:\/\/www.mystore.com\/skin\/frontend\/default\/mystore\/images\/logo.png","href":"http:\/\/www.mystore.com\/"}]}2=[{"text":"Buy#mystore","href":"http:\/\/www.mystore.com\/"}]3=1000025660978094=5070afefb42b162aff748f55ecf44d110d9e2a90117ee1704e2adb41f1d190fa
where u can see format=JSONv=1.01={....}2=[{.....}] the problem was I used numeric arrays for parameters. they should be associated arrays
like message={new order}attachment={....}
Once I fixed the associative array problem my code start working correctly
here is a link that'll give u detail about parameters to pass to stream.publish
http://schoolout.net/en/developers/view/39
Hope this will help somebody else too.