How to upload presentation file into Google Slides using PHP? - api

How can I upload presentation file (ppt, pptx, pdf) to Google Slides service using PHP.
I didn't find an example in these links:
https://developers.google.com/slides/quickstart/php
https://developers.google.com/api-client-library/php/support
My code:
$service = new Google_Service_Drive($client);
$fileMetadata = new Google_Service_Drive_DriveFile([
'name' => 'My Presentation',
'mimeType' => 'application/vnd.google-apps.presentation',
// 'mimeType' => 'application/vnd.google-apps.document',
]);
$file = $service->files->create($fileMetadata, [
'data' => file_get_contents(realpath(dirname(__FILE__)) . '/Modelo_Slide_Padrao.pptx'),
// 'mimeType' => 'application/vnd.ms-powerpoint', // 'application/pdf',
'uploadType' => 'multipart',
'fields' => 'id',
]);
printf("File ID: %s\n", $file->id);
Somebody help me?
Thank you.

You cannot upload a presentation file to Google Slides. What you are required to do is to import the file to Google Drive using a Google Doc Type. Take a look at the reference documentation which has an example of how to achieve this. Here are the examples of how to achieve what you need.
PPT to Google Slides Presentation:
$service = new Google_Service_Drive($client);
// Create a new file
$file = new Google_Service_Drive_DriveFile(array(
'name' => 'PPT Test Presentation',
'mimeType' => 'application/vnd.google-apps.presentation'
));
// Read power point ppt file
$ppt = file_get_contents("SamplePPT.ppt");
// Declare optional parameters
$optParams = array(
'uploadType' => 'multipart',
'data' => $ppt,
'mimeType' => 'application/vnd.ms-powerpoint'
);
// Import pptx file as a Google Slide presentation
$createdFile = $service->files->create($file, $optParams);
// Print google slides id
print "File id: " . $createdFile->id;
PPTX to Google Slides Presentation:
$service = new Google_Service_Drive($client);
// Create a new file
$file = new Google_Service_Drive_DriveFile(array(
'name' => 'PPTX Test Presentation',
'mimeType' => 'application/vnd.google-apps.presentation'
));
// Read Powerpoint pptx file
$pptx = file_get_contents("SamplePPTX.pptx");
// Declare opts params
$optParams = array(
'uploadType' => 'multipart',
'data' => $pptx,
'mimeType' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
);
// Import pptx file as a Google Slide presentation
$createdFile = $service->files->create($file, $optParams);
// Print google slides id
print "File id: " . $createdFile->id;
PDF to Google Document Doc: (is not possible to Google Slide Presentation)
$service = new Google_Service_Drive($client);
// Create a new file
$file = new Google_Service_Drive_DriveFile(array(
'name' => 'PDF Test Document',
'mimeType' => 'application/vnd.google-apps.document'
));
// Read pdf file
$pdf = file_get_contents("SamplePDF.pdf");
// Declare opts params
$optParams = array(
'uploadType' => 'multipart',
'data' => $pdf,
'mimeType' => 'application/pdf'
);
// Import pdf file as a Google Document File
$createdFile = $service->files->create($file, $optParams);
// Print google document id
print "File id: " . $createdFile->id;
The only thing that changes in each code snippet is the mimeType. For a reference of Mime Types you can visit here and for a reference of Google Mime Types you can visit here.

Related

Yii2 - Generate Pdf on the fly and attach to email

This is how I can generate pdf page
public function actionPdf(){
Yii::$app->response->format = 'pdf';
$this->layout = '//print';
return $this->render('myview', []);
}
And this is how I send emails
$send = Yii::$app->mailer->compose('mytemplate',[])
->setFrom(Yii::$app->params['adminEmail'])
->setTo($email)
->setSubject($subject)
->send();
How I can generate pdf as a file and attach it to my emails on the fly?
Mailer have method called attachContent(), where you can put pdf file.
PDF should be rendered with output destination set as string, and then pass it as param to attachContent().
Sample:
Yii::$app->mail->compose()
->attachContent($pathToPdfFile, [
'fileName' => 'Name of your pdf',
'contentType' => 'application/pdf'
])
// to & subject & content of message
->send();
This is how I did it
In my controller:
$mpdf=new mPDF();
$mpdf->WriteHTML($this->renderPartial('pdf',['model' => $model])); //pdf is a name of view file responsible for this pdf document
$path = $mpdf->Output('', 'S');
Yii::$app->mail->compose()
->attachContent($path, ['fileName' => 'Invoice #'.$model->number.'.pdf', 'contentType' => 'application/pdf'])
This is how I sent mails in Yii2
private function sendPdfAsEmail($mpdf)
{
$mpdf->Output('filename.pdf', 'F');
$send = Yii::$app->mailer->compose()
->setFrom('admin#test.com')
->setTo('to#gmail.com')
->setSubject('Test Message')
->setTextBody('Plain text content. YII2 Application')
->setHtmlBody('<b>HTML content.</b>')
->attach(Yii::getAlias('#webroot').'/filename.pdf')
->send();
if($send) {
echo "Send";
}
}
Pass the mpdf instance to our custom function.
Use the F option in mpdf to save the output as a file.
use the attach option in Yii mailer and set the path of the saved file.

how to integrate multimodelform with echmultiselect yii?

I am running into a little snag with combining extensions "EchMultiSelect" and "MultiModelForm" of YII framework.
What I'm trying to do is copy a set of form elements one of which elements is an EchMultiSelect widget.
According to tutorial on the jqRelCopy page, I would need to pass a copy of the element (datePicker in their example) to the 'jsAfterNewId' option:
'jsAfterNewId' => JQRelcopy::afterNewIdDatePicker($datePickerConfig),
So, I tried to modify that to:
'jsAfterNewId' => MultiModelForm::afterNewIdMultiSelect($memberFormConfig['elements']),
Where I also added the following to MultiModelForm.php:
public static function afterNewIdMultiSelect($element)
{
$options = isset($element['options']) ? $element['options'] : array();
$jsOptions = CJavaScript::encode($options);
return "if(this.attr('multiple')=='multiple'){this.multiselect(jQuery.extend({$jsOptions}));};";
}
its copied and working properly when i am using Add Person link but what happens if i am adding/cloning three items for example and when i change the third item multiselct option then its reflecting to the first multiselect dropdown only this is same for other as well also when i am adding new items by clicking on the Add Person link then its cloning the same element to the new row item
here is the code for the form configuration variables and multimodel widget call.
//$userList=array of the userIds from users table
$memberFormConfig = array(
'elements'=>array(
'userId'=>array(
'type'=>'ext.EchMultiSelect.EchMultiSelect',
'model' => $User,
'dropDownAttribute' => 'userId',
'data' => $userList,
'dropDownHtmlOptions'=> array(
'style'=>'width:500px;',
),
),
...
...
));
calling the MultiModelForm widget from the same view file
$this->widget('ext.multimodelform.MultiModelForm',array(
'id' => 'id_member', //the unique widget id
'formConfig' => $memberFormConfig, //the form configuration array
'model' => $model, //instance of the form model
'tableView' => true,
'validatedItems' => $validatedMembers,
'data' => Person::model()->findAll('userId=:userId', array(':userId'=>$model->id)),
'addItemText' => 'Add Person',
'showAddItemOnError' => false, //not allow add items when in validation error mode (default = true)
'fieldsetWrapper' => array('tag' => 'div',
'htmlOptions' => array('class' => 'view','style'=>'position:relative;background:#EFEFEF;')
),
'removeLinkWrapper' => array('tag' => 'div',
'htmlOptions' => array('style'=>'position:absolute; top:1em; right:1em;')
),
'jsAfterNewId' => MultiModelForm::afterNewIdMultiSelect($memberFormConfig['elements']),
));
Can someone help me with this please?
Thanks in advance!
After a long searching and googleing i found the solution for this, just replace the function in your MultiModelForm.php:
public static function afterNewIdMultiSelect($element)
{
$options = isset($element['options']) ? $element['options'] : array();
$jsOptions = CJavaScript::encode($options);
return "if ( this.hasClass('test123456') )
{
var mmfComboBoxParent = this.parent();
// cloning autocomplete and select elements (without data and events)
var mmfComboBoxClone = this.clone();
var mmfComboSelectClone = this.prev().clone();
// removing old combobox
mmfComboBoxParent.empty();
// addind new cloden elements ()
mmfComboBoxParent.append(mmfComboSelectClone);
mmfComboBoxParent.append(mmfComboBoxClone);
// re-init autocomplete with default options
mmfComboBoxClone.multiselect(jQuery.extend({$jsOptions}));
}";
}
Thats It....!!
Thanks...!!!

yii2 response formatter not being called

I'm trying to use robregonm pdfresponseFormatter to create a PDF, problem is, the pdf class is never called as the format reponse type.
'response' => [
'formatters' => [
'html' => [
'class' => 'yii\web\HtmlResponseFormatter',
],
'pdf' => [
'class' => 'robregonm\pdf\PdfResponseFormatter',
'mode' => '',
'format' => 'A4',
'defaultFontSize' => 0,
'defaultFont' => '',
'marginLeft' => 15,
'marginRight' => 15,
'marginTop' => 16,
'marginBottom' => 16,
'marginHeader' => 9,
'marginFooter' => 9,
]
]
],
....
$file = $this->getPdf($report);
....
private function getPdf($report){
Yii::$app->response->format = 'pdf';
Yii::$container->set(Yii::$app->response->formatters['pdf']['class']);
$this->layout = '//attachment';
return $this->render('pdf/actionplan', ['model' => $report]);
}
the $file variable has the HTML text in it from the view
You are asking the wrong question. Of course $file has HTML in it, you are returning HTML from your view.
Yii::$app->response->format = 'pdf';
works when the controller returns a response to the browser.
What you want to ask is why the controller function (I hope this is in a controller) does not return a PDF created from the HTML.
If you just want to save a PDF look how I handle this: https://github.com/Mihai-P/yii2-core/blob/master/components/Controller.php in the actionPdf function. That function returns a file that you can save on the server if you want.
Unfortunately I've not been able to get this extension to work. I did get kartik pdf to work great
I recommend using the kartik extension instead.

BOX-API upload file form

i'm trying to upload a file in BOX_API with php and Zend framework. But i'm missing somethin. It's the first time that i use an interface like this o i've read the manual. But it is confusig for me. My question are two:
-First, why do you have to pass to the post call only the name of the file and not the whole file with the right header for file upload? File upload in a form is not like passing the name of the file through a post call;
-secondly and consequently, do i have to make a form for file upload or simply a textarea where to write the name of the file to be passed to the BOX-API?
UPDATE:
This is the code of my upload form:
$form = new Zend_Form;
$form->setAction('/imball-reagens/public/upload')
->setMethod('post');
$file = new Zend_Form_Element_File('file');
$file->setLabel('Choose a file to upload:');
$file->addValidator('alnum');
$file->setRequired(true);
$form->addElement($file);
$access_token = new Zend_Form_Element_Hidden(array('name' => 'access_token', 'value' => $result->access_token));
$form->addElement($access_token);
$refresh_token = new Zend_Form_Element_Hidden(array('name' => 'refresh_token', 'value' => $result->refresh_token));
$form->addElement($refresh_token);
$form->addElement('submit', 'upload', array('label' => 'Upload File'));
echo $form;
And this s the POST cal to the box API which comes after the form:
$access_token= $this->getRequest()->getParam('access_token');
$client = new Zend_Http_Client('https://upload.box.com/api/2.0/files/content');
$client->setMethod(Zend_Http_Client::POST);
$client->setHeaders('Authorization: Bearer '.$access_token);
$data = $_FILES["file"]["name"];
$client->setParameterPost(array(
'filename' => '#'.$data,
'parent_id' => '0'
));
$response = $client->request()->getBody();
$this->view->response= $response;
$result = json_decode($response);
The error it throws is below:
{"type":"error","status":400,"code":"invalid_request_parameters","help_url":"http:\/\/developers.box.com\/docs\/#errors","message":"Invalid input parameters in request","request_id":"172518183652dcf2a16af73"}
Tricky to debug without seeing all of the code, but in the bit you pasted it looks like you are passing $_FILES["file"]["name"] to the API - this only contains the original name of the file which was uploaded by the user - you need to pass the location to the file on the server which is sending the data to the Box API client so that it can grab it and send it to the Box server - this should be stored in $_FILES["file"]["tmp_name"].
I would recommend changing the code to this and trying again:
$access_token= $this->getRequest()->getParam('access_token');
$client = new Zend_Http_Client('https://upload.box.com/api/2.0/files/content');
$client->setMethod(Zend_Http_Client::POST);
$client->setHeaders('Authorization: Bearer '.$access_token);
$data = $_FILES["file"]["tmp_name"];
$client->setParameterPost(array(
'parent_id' => '0'
));
$client->setFileUpload($data, 'filename');
$response = $client->request()->getBody();
$this->view->response= $response;
$result = json_decode($response);

Rendering links in tweet when using Get Statuses API 1.1

I'm using the Twitter API 1.1 Get statuses method to return the latest tweet from an account on the client's website. This is working fine but I can't find any clear documentation on how to render any links that may be included (Both included usernames and included links) as clickable links?
I can see in the JSON response that any included links are in the XML but it's not clear to me how to go about adding clickable links into the rendered output. The documentation around the new API seems to be lacking practical examples.
Can anyone advise?
The code I'm using the pull out the latest tweet is as follows:
$token = 'TOKEN HERE';
$token_secret = 'TOKEN SECRET HERE';
$consumer_key = 'CONSUMER KEY HERE';
$consumer_secret = 'CONSUMER SECRET HERE';
$host = 'api.twitter.com';
$method = 'GET';
$path = '/1.1/statuses/user_timeline.json'; // api call path
$query = array( // query parameters
'screen_name' => 'SCREEN NAME HERE',
'count' => '1'
);
$oauth = array(
'oauth_consumer_key' => $consumer_key,
'oauth_token' => $token,
'oauth_nonce' => (string)mt_rand(), // a stronger nonce is recommended
'oauth_timestamp' => time(),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_version' => '1.0'
);
$oauth = array_map("rawurlencode", $oauth); // must be encoded before sorting
$query = array_map("rawurlencode", $query);
$arr = array_merge($oauth, $query); // combine the values THEN sort
asort($arr); // secondary sort (value)
ksort($arr); // primary sort (key)
// http_build_query automatically encodes, but our parameters
// are already encoded, and must be by this point, so we undo
// the encoding step
$querystring = urldecode(http_build_query($arr, '', '&'));
$url = "https://$host$path";
// mash everything together for the text to hash
$base_string = $method."&".rawurlencode($url)."&".rawurlencode($querystring);
// same with the key
$key = rawurlencode($consumer_secret)."&".rawurlencode($token_secret);
// generate the hash
$signature = rawurlencode(base64_encode(hash_hmac('sha1', $base_string, $key, true)));
// this time we're using a normal GET query, and we're only encoding the query params
// (without the oauth params)
$url .= "?".http_build_query($query);
$oauth['oauth_signature'] = $signature; // don't want to abandon all that work!
ksort($oauth); // probably not necessary, but twitter's demo does it
// also not necessary, but twitter's demo does this too
function add_quotes($str) { return '"'.$str.'"'; }
$oauth = array_map("add_quotes", $oauth);
// this is the full value of the Authorization line
$auth = "OAuth " . urldecode(http_build_query($oauth, '', ', '));
// if you're doing post, you need to skip the GET building above
// and instead supply query parameters to CURLOPT_POSTFIELDS
$options = array( CURLOPT_HTTPHEADER => array("Authorization: $auth"),
//CURLOPT_POSTFIELDS => $postfields,
CURLOPT_HEADER => false,
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false);
// do our business
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);
$twitter_data = json_decode($json);
Thanks a lot for your response. I actually found a solution thanks to this blog post from the guys at Asheville - http://www.appliedtns.com/blog/tag/twitter/
It works fine for me.
// Parse any links found in our tweet
$formatted_text = preg_replace('/(\b(www\.|http\:\/\/)\S+\b)/', "<a target='_blank' href='$1'>$1</a>", $post->text);
$formatted_text = preg_replace('/\#(\w+)/', "<a target='_blank' href='http://search.twitter.com/search?q=$1'>#$1</a>", $formatted_text);
$formatted_text = preg_replace('/\#(\w+)/', "<a target='_blank' href='http://twitter.com/$1'>#$1</a>", $formatted_text);
Not sure if this exactly what you need but I am using the tmhOAuth library for my application, see https://github.com/themattharris/tmhOAuth-examples. Using code from Matt Harris' examples I loop through the response and build the output as in the code below. The links in the tweets are created by the library function entify_with_options($tweet).
// Decode response
$timeline = json_decode($this->tmhOAuth->response['response'], true);
if(!$timeline){
throw new Exception('Error: No response was found.');
}
else{
// Start building the output
foreach ($timeline as $tweet) :
... start of response processing
// Format and set tweet text
$tw_entified_tweet = tmhUtilities::entify_with_options($tweet);
// Format and set creation date for permalink
$tw_created_at_formatted = is_twitterlist_format_date($tweet['created_at']);
// Format and set permalink
$tw_permalink = str_replace(
array(
'%screen_name%',
'%id%',
'%created_at%'
),
array(
$tweet['user']['screen_name'],
$tweet['id_str'],
$tw_created_at_formatted,
),
'%created_at%'
);
... end response processing
endforeach;
}
The date format function is:
function is_twitterlist_format_date($created_date)
{
if ( is_null($created_date)) {
return '';
}
else{
// Format: March 4th, 9:19 am
return date('F jS, g:i a', strtotime($created_date));
}
}
Hope this is useful.