I am creating a simple dropbox app where after authenticating the user, the app is supposed to prompt for some information, read the content of a txt file. Use ajax for everything after authentication.
so far I have managed to authenticate but when I send the info to the server using ajax I am failing to open the file.
I have the following server side script:
<?php
require_once "../app/start.php";
require_once __DIR__.'/../app/config.php';
$regex = $_POST['regex'];
(...)
$accessToken = $_SESSION['accessToken'] ;
$client = new Dropbox\Client($accessToken, $GLOBALS['app_name'], 'UTF-8');
var_dump($client);
// Read File todo.txt
$filename = __DIR__.'/todo/todo.txt';
$f = fopen($filename, "w+b") or die("Unable to open file!");
$fileMetadata = $client->getFile('/todo/todo.txt', $f);
var_dump($fileMetadata);
and when I execute it the output is the following:
object(Dropbox\Client)#8 (6) {
["accessToken":"Dropbox\Client":private]=>
string(64) "xxxxxxxxxxxxxxxxxxxxxxxxx"
["clientIdentifier":"Dropbox\Client":private]=>
string(13) "oauth-php/1.0"
["userLocale":"Dropbox\Client":private]=>
string(5) "UTF-8"
["apiHost":"Dropbox\Client":private]=>
string(15) "api.dropbox.com"
["contentHost":"Dropbox\Client":private]=>
string(23) "api-content.dropbox.com"
["host"]=>
object(Dropbox\Host)#5 (3) {
["api":"Dropbox\Host":private]=>
string(15) "api.dropbox.com"
["content":"Dropbox\Host":private]=>
string(23) "api-content.dropbox.com"
["web":"Dropbox\Host":private]=>
string(15) "www.dropbox.com"
}
}
NULL
Where the last NULL refers to the content of $fileMetadata. Why is it empty?
the contnet of start.php are the dropbox objects.
<?php
session_start();
require_once __DIR__.'/../vendor/autoload.php';
$key = "XCV...";
$secret = "DFG...";
$GLOBALS['app_name'] = "oauth-php/1.0";
$GLOBALS['redirectURI'] = "https://oauth.dev/dropbox_finish.php";
$GLOBALS['HomeURI'] = "https://oauth.dev";
$appInfo = new Dropbox\AppInfo($key, $secret);
$csrfTokenStore = new Dropbox\ArrayEntryStore($_SESSION, 'dropbox-auth-csrf-token');
$webAuth = new Dropbox\WebAuth($appInfo, $GLOBALS['app_name'], $GLOBALS['redirectURI'], $csrfTokenStore);
Edit: in the local files I have a directory called web, where the files executed are. the there is as well a folder (inside web) called todo and the file todo.txt it is inside. __DIR__ refers to inside the web directory that i have mentioned.
In Dropbox i have a direcotry called todo with todo.txt inside.
Edit2: adding the rest of the code.
index.php contains:
<?php
include_once __DIR__.'/../app/start.php';
include_once __DIR__.'/../app/dropbox_auth.php';
Then dropbox_auth.php has the following code:
$authURL = $webAuth->start();
header("Location: $authURL");
and finally dropbox_finish.php
<?php
//session_start();
require_once "../app/start.php";
try {
list($accessToken, $userId, $urlState) = $webAuth->finish($_GET);
assert($urlState === null); // Since we didn't pass anything in start()
}
catch (Dropbox\WebAuthException_BadRequest $ex) {
error_log("/dropbox-auth-finish: bad request: " . $ex->getMessage());
// Respond with an HTTP 400 and display error page...
}
//review
catch (Dropbox\WebAuthException_BadState $ex) {
// Auth session expired. Restart the auth process.
header('Location: '.$GLOBALS['HomeURI']);
}
catch (Dropbox\WebAuthException_Csrf $ex) {
error_log("/dropbox-auth-finish: CSRF mismatch: " . $ex->getMessage());
// Respond with HTTP 403 and display error page...
}
catch (Dropbox\WebAuthException_NotApproved $ex) {
error_log("/dropbox-auth-finish: not approved: " . $ex->getMessage());
}
catch (Dropbox\WebAuthException_Provider $ex) {
error_log("/dropbox-auth-finish: error redirect from Dropbox: " . $ex->getMessage());
}
catch (Dropbox\Exception $ex) {
error_log("/dropbox-auth-finish: error communicating with Dropbox API: " . $ex->getMessage());
}
$client = new Dropbox\Client($accessToken, $GLOBALS['app_name'], 'UTF-8');
$_SESSION['accessToken'] = $accessToken;
$_SESSION['client_object'] = $client;
{... here I load an HTML form that uses AJAX send to `insert.php`}
Sorry I cant write a comment right now.
Try to get the folder/file list by calling $client->getMetadataWithChildren('/todo/') and check if $f is a valid FilePointerRessource :)
Related
I am trying to retrieve a new access token with my refresh token. Before I run a script to retrieve a new access token I want to check if my access token is still valid.
I am trying to do this with exceptions:
try
{
// Connect
$session = new SoapClient("../webservices/session.asmx?wsdl", array('trace' => 1));
$result = $session->AccessTokenLogon($accessTokenparams);
}
catch (SoapFault $e)
{
// Check if AcccessToken returns TokenInvalid
if ($result->AccessTokenLogonResult == "TokenInvalid")
{
// AccessToken is not valid anymore
// ..
// Run script to get new access token
// ..
// $_SESSION["access_token"] = $access_token;
}
else
{
// AccessToken is valid
echo "AccessToken is valid";
}
}
finally
{
// Run script with valid AccessToken
global $result, $session;
$cluster = $result->cluster;
$qq = new domDocument();
$qq->loadXML($session->__getLastResponse());
$newurl = $cluster . '/webservices/processxml.asmx?wsdl';
try
{
$client = new SoapClient($newurl);
$header = new SoapHeader('http://www.website.com/', 'Header', array('AccessToken' =>$_SESSION["access_token"]));
}
catch (SoapFault $e)
{
echo $e->getMessage();
}
try
{
echo '<br /><br />XML Result:<br /><br />';
$xml = ""; // XML request
$result = $client->__soapCall('ProcessXmlString', array(array('xmlRequest'=>$xml)), null, $header);
}
catch (SoapFault $e)
{
echo $e->getMessage();
}
}
With a valid access token the script is working. The XML request is posted to the webservice.
The script is not working when the accesstoken is not valid anymore. The script stores the new accesstoken in the session: $_SESSION["access_token"] = $access_token; but is not running the 'finally' part after retrieving a new accesstoken.
Does someone know how I can fix this and run the 'finally' after retrieving a new accesstoken?
I have created following code. I have to download files from my Google Drive folder. The folder is shared. After downloading, I have to delete those files from the Google Drive.
I tried -
$file = $service->parents->delete($file_id,$folder_id); - It doesn't do anything, nor does it give any error.
$file = $service->files->trash($file_id); - It gives Error calling DELETE - (403) Insufficient permissions for this file" Error.
My code :
<?php
require_once "google/google-api-php-client/src/Google_Client.php";
require_once "google/google-api-php-client/src/contrib/Google_DriveService.php";
require_once "google/google-api-php-client/src/contrib/Google_Oauth2Service.php";
require_once "google/vendor/autoload.php";
$file_id = '1bJm_cqIRVh5RaVrqVXGRL0CSYwTBlZur';
$folder_id='1gEllj4B9TCnLPe_dnl1ujX4u8smLL-Ky';
$DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive';
$SERVICE_ACCOUNT_EMAIL = 'service_account_email#domain.com';
$SERVICE_ACCOUNT_PKCS12_FILE_PATH = 'GoogleDriveApi-7cd8056e9eae.p12';
function buildService() {//function for first build up service
global $DRIVE_SCOPE, $SERVICE_ACCOUNT_EMAIL, $SERVICE_ACCOUNT_PKCS12_FILE_PATH;
$key = file_get_contents($SERVICE_ACCOUNT_PKCS12_FILE_PATH);
$auth = new Google_AssertionCredentials(
$SERVICE_ACCOUNT_EMAIL, array($DRIVE_SCOPE), $key);
$client = new Google_Client();
$client->setUseObjects(true);
$client->setAssertionCredentials($auth);
return new Google_DriveService($client);
}
function printFilesInFolder($service, $folderId) {
$pageToken = NULL;
$arrayFile=array();
do {
try {
$parameters = array();
if ($pageToken) {
$parameters['pageToken'] = $pageToken;
}
$children = $service->children->listChildren($folderId, $parameters);
$arrayFile=$children;
$pageToken = $children->getNextPageToken();
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
$pageToken = NULL;
}
} while ($pageToken);
return $arrayFile;
}
try {
$service = buildService();
$children=printFilesInFolder($service,$folder_id);
$myfile = fopen("D:/list.txt", "wb") or die("Unable to open file!");
foreach ($children->getItems() as $child) {
print "\r\nFile Id: " . $child->getId();
fwrite($myfile, $child->getId());
fwrite($myfile, "\r\n");
}
$file = $service->parents->delete($file_id,$folder_id);
$file = $service->files->trash($file_id);
fclose($myfile);
} catch (Exception $e) {
print "An error occurred1: " . $e->getMessage();
}
?>
Your error indicates that the user doesn't have a write access to the file, and an app is attempting to modify the particular file.
Suggested action: Report to the user that there is a need to ask for
those permissions in order to update the file. You may also want to
check user access levels in the metadata retrieved by
files.get and use that to change your UI to a read only UI.
i am using the below code to connect to salesforce using php
require_once ('SforcePartnerClient.php');
require_once ('SforceHeaderOptions.php');
require_once ('SforceMetadataClient.php');
$mySforceConnection = new SforcePartnerClient();
$mySforceConnection->createConnection("cniRegistration.wsdl");
$loginResult = $mySforceConnection->login("username", "password.token");
$queryOptions = new QueryOptions(200);
try {
$sObject = new stdclass();
$sObject->Name = 'Smith';
$sObject->Phone = '510-555-5555';
$sObject->fieldsToNull = NULL;
echo "**** Creating the following:\r\n";
$createResponse = $mySforceConnection->create($sObject, 'Account');
$ids = array();
foreach ($createResponse as $createResult) {
print_r($createResult);
array_push($ids, $createResult->id);
}
} catch (Exception $e) {
echo $e->faultstring;
}
But the above code is connect to salesforce database.
But is not executing the create commands. it's giving me the below error message
Creating the following: Element {}item invalid at this location
can any one suggest me to overcome the above problem
MAK, in your sample code SessionHeader and Endpoint setup calls are missing
$mySforceConnection->setEndpoint($location);
$mySforceConnection->setSessionHeader($sessionId);
after setting up those, if you still see an issue, check the namespace urn
$mySforceConnection->getNamespace
It should match targetNamespace value in your wsdl
the value of $mySforceConnection should point to the xml file of the partner.wsdl.xml.
E.g $SoapClient = $sfdc->createConnection("soapclient/partner.wsdl.xml");
Try adding the snippet code below to reference the WSDL.
$sfdc = new SforcePartnerClient();
// create a connection using the partner wsdl
$SoapClient = $sfdc->createConnection("soapclient/partner.wsdl.xml");
$loginResult = false;
try {
// log in with username, password and security token if required
$loginResult = $sfdc->login($sfdcUsername, $sfdcPassword.$sfdcToken);
}
catch (Exception $e) {
global $errors;
$errors = $e->faultstring;
echo "Fatal Login Error <b>" . $errors . "</b>";
die;
}
// setup the SOAP client modify the headers
$parsedURL = parse_url($sfdc->getLocation());
define ("_SFDC_SERVER_", substr($parsedURL['host'],0,strpos($parsedURL['host'], '.')));
define ("_SALESFORCE_URL_", "https://test.salesforce.com");
define ("_WS_NAME_", "WebService_WDSL_Name_Here");
define ("_WS_WSDL_", "soapclient/" . _WS_NAME_ . ".wsdl");
define ("_WS_ENDPOINT_", 'https://' . _SFDC_SERVER_ . '.salesforce.com/services/wsdl/class/' . _WS_NAME_);
define ("_WS_NAMESPACE_", 'http://soap.sforce.com/schemas/class/' . _WS_NAME_);
$urlLink = '';
try {
$client = new SoapClient(_WS_WSDL_);
$sforce_header = new SoapHeader(_WS_NAMESPACE_, "SessionHeader", array("sessionId" => $sfdc->getSessionId()));
$client->__setSoapHeaders(array($sforce_header));
} catch ( Exception $e ) {
die( 'Error<br/>' . $e->__toString() );
}
Please check the link on Tech Thought for more details on the error.
I have been trying to get the google api php client to work on app engine. After reading the app.yaml configuration resources provided by the documentation, I have still not been able to get this to work. My app.yaml has the google-api-php-client as it follows:
- url: /google-api-php-client/(.*?)/(.*?)/(.*)
script: google-api-php-client/\3/\2/\1.php
And, the structure of the folder is:
google-api-php-client->(some_folders)->(some_folders+files)->(some_files)
| level1 | | level2 | | level3 | | level4 |
I would like to have the configuration set so that I would be able to access the files in level 3 and level 4 and be able to do require_once calls just like these:
require_once ('/google-api-php-client/src/Google_Client.php');
require_once ('/google-api-php-client/src/contrib/Google_DriveService.php');
I am able to do these require_once calls on localhost but not when I deploy the files to app engine. The logs on app engine dashboard show this:
PHP Fatal error: require_once(): Failed opening required '/google-api-php-client/src/Google_Client.php' (include_path='.;/base/data/home/apps/s~...
I would appreciate any and all input.
Thanks!
EDIT: I am adding the code where I'm using require_once
require_once ('google-api-php-client/src/Google_Client.php');
require_once ('google-api-php-client/src/contrib/Google_DriveService.php');
session_start();
$client = new Google_Client();
$client->setApplicationName("Drive Demo");
$client->setClientId('****');
$client->setClientSecret('****');
$client->setRedirectUri('http://localhost:8080');
$client->setDeveloperKey('****');
$client->setScopes(array(
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile'));
$client->setAccessType('offline');
$service = new Google_DriveService($client);
$fileId = '****';
function printFile($service, $fileId) {
try {
$file = $service->files->get($fileId);
print_r($file);
print "Title: " . $file->getTitle();
print "Description: " . $file->getDescription();
print "MIME type: " . $file->getMimeType();
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
function retrieveAllFiles($service) {
$result = array();
$pageToken = NULL;
do {
try {
$parameters = array('q'=>'', 'maxResults'=> '25', 'fields'=>'items(title,description,mimeType)');
if ($pageToken) {
$parameters['pageToken'] = $pageToken;
}
$files = $service->files->listFiles($parameters);
$result = array_merge($result, $files->getItems());
$pageToken = $files->getNextPageToken();
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
$pageToken = NULL;
}
} while ($pageToken);
return $result;
}
if (!isset($_REQUEST['code']) && !isset($_SESSION['access_token'])) {
$authUrl = $client->createAuthUrl();
print("<a href='".$authUrl."'>Authorize me</a>");
}else {
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
}
if (isset($_SESSION['access_token'])) {
$client->setAccessToken($_SESSION['access_token']);
}
if ($client->getAccessToken()) {
$_SESSION['access_token'] = $client->getAccessToken();
}
$files = retrieveAllFiles($service);
foreach($files as $file){
//print_r($file);
print "Title: " . $file->getTitle().'<br/>';
print "Description: " . $file->getDescription().'<br/>';
print "MIME type: " . $file->getMimeType().'<br/>';
}
}
Update: Removed the '/' as per #Stuart's comment, which solved the issue.
You don't need to configure app.yaml in this case - as you don't want to route any requests directly to these scripts.
Just put the source code for google-api-php-client in the same directory as your app and deploy it using appcfg.py.
Check my article on configuring the client here.
I am trying to upload a video to youtube, using the direct upload method as explained here, at documentation.
I have included my developer key correctly, and am getting the session token too without any problem. The problem appears when it directs me to the upload page with the token. Instead of uploading and returning with the video id, it shows me a single line,
Premature end of file.
I am new to zend as well as using youtube api's for the first time, I managed to work out authentication and few errors, that were shown but I have no idea, why or where is this problem.
Here is my php file,
<?php
session_start();
require_once 'Zend/Loader.php'; // the Zend dir must be in your include_path
Zend_Loader::loadClass('Zend_Gdata_YouTube');
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Uri_Http');
function getAuthSubRequestUrl()
{
$next = 'http://localhost/trial/trial.php';
$scope = 'http://gdata.youtube.com';
$secure = false;
$session = true;
return Zend_Gdata_AuthSub::getAuthSubTokenUri($next, $scope, $secure, $session);
}
//generate link if no session or token has been requested
if (!isset($_SESSION['sessionToken']) && !isset($_GET['token'])){
echo 'Login to YouTube API!';
//if token has been requested but not saved to a session then save the new token to a session
} else if (!isset($_SESSION['sessionToken']) && isset($_GET['token'])) {
$_SESSION['sessionToken'] = Zend_Gdata_AuthSub::getAuthSubSessionToken($_GET['token']);
}
if(isset($_SESSION['sessionToken'])) {
$clientLibraryPath = '/library';
$oldPath = set_include_path(get_include_path() . PATH_SEPARATOR . $clientLibraryPath);
$sessionToken = $_SESSION['sessionToken'];
$developerKey = 'my-key-here'; //I have inserted the key correctly.
$httpClient = new Zend_Gdata_HttpClient();
$httpClient->setAuthSubToken($sessionToken);
$yt = new Zend_Gdata_YouTube($httpClient, '23', '234', $developerKey);
$myVideoEntry = new Zend_Gdata_YouTube_VideoEntry();
$file= '../path_to_file/filename.mp4';
$file = realpath($file);
$filesource = $yt->newMediaFileSource($file);
// create a new Zend_Gdata_App_MediaFileSource object
$filesource = $yt->newMediaFileSource('file.mov');
$filesource->setContentType('video/quicktime');
// set slug header
$filesource->setSlug('file.mov');
$myVideoEntry->setVideoTitle('My Test Movie');
$myVideoEntry->setVideoDescription('My Test Movie');
$myVideoEntry->setVideoCategory('Entertainment');
$myVideoEntry->SetVideoTags('testme');
$myVideoEntry->setVideoDeveloperTags(array('tester', 'test'));
$uploadUrl = 'http://uploads.gdata.youtube.com/feeds/api/users/default/uploads';
try {
$newEntry = $yt->insertEntry($myVideoEntry, $uploadUrl, 'Zend_Gdata_YouTube_VideoEntry');
} catch (Zend_Gdata_App_HttpException $httpException) {
echo $httpException->getRawResponseBody();
} catch (Zend_Gdata_App_Exception $e) {
echo $e->getMessage();
}
}
?>
Thanks. Please ask for further explanations or information regarding the problem or code if required.
I suggest to use the Data API instead and utilize the resumable upload. Here's a PHP upload example.