How to get video duration, dimension and size in PHP? - php

I want to know how to get the duration, dimension and size of uploaded video file in PHP. The file can be in any video format.

getID3 supports video formats. See: http://getid3.sourceforge.net/
Edit: So, in code format, that'd be like:
include_once('pathto/getid3.php');
$getID3 = new getID3;
$file = $getID3->analyze($filename);
echo("Duration: ".$file['playtime_string'].
" / Dimensions: ".$file['video']['resolution_x']." wide by ".$file['video']['resolution_y']." tall".
" / Filesize: ".$file['filesize']." bytes<br />");
Note: You must include the getID3 classes before this will work! See the above link.
Edit: If you have the ability to modify the PHP installation on your server, a PHP extension for this purpose is ffmpeg-php. See: http://ffmpeg-php.sourceforge.net/

If you have FFMPEG installed on your server (http://www.mysql-apache-php.com/ffmpeg-install.htm), it is possible to get the attributes of your video using the command "-vstats" and parsing the result with some regex - as shown in the example below. Then, you need the PHP function filesize() to get the size.
$ffmpeg_path = 'ffmpeg'; //or: /usr/bin/ffmpeg , or /usr/local/bin/ffmpeg - depends on your installation (type which ffmpeg into a console to find the install path)
$vid = 'PATH/TO/VIDEO'; //Replace here!
if (file_exists($vid)) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $vid); // check mime type
finfo_close($finfo);
if (preg_match('/video\/*/', $mime_type)) {
$video_attributes = _get_video_attributes($vid, $ffmpeg_path);
print_r('Codec: ' . $video_attributes['codec'] . '<br/>');
print_r('Dimension: ' . $video_attributes['width'] . ' x ' . $video_attributes['height'] . ' <br/>');
print_r('Duration: ' . $video_attributes['hours'] . ':' . $video_attributes['mins'] . ':'
. $video_attributes['secs'] . '.' . $video_attributes['ms'] . '<br/>');
print_r('Size: ' . _human_filesize(filesize($vid)));
} else {
print_r('File is not a video.');
}
} else {
print_r('File does not exist.');
}
function _get_video_attributes($video, $ffmpeg) {
$command = $ffmpeg . ' -i ' . $video . ' -vstats 2>&1';
$output = shell_exec($command);
$regex_sizes = "/Video: ([^,]*), ([^,]*), ([0-9]{1,4})x([0-9]{1,4})/"; // or : $regex_sizes = "/Video: ([^\r\n]*), ([^,]*), ([0-9]{1,4})x([0-9]{1,4})/"; (code from #1owk3y)
if (preg_match($regex_sizes, $output, $regs)) {
$codec = $regs [1] ? $regs [1] : null;
$width = $regs [3] ? $regs [3] : null;
$height = $regs [4] ? $regs [4] : null;
}
$regex_duration = "/Duration: ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}).([0-9]{1,2})/";
if (preg_match($regex_duration, $output, $regs)) {
$hours = $regs [1] ? $regs [1] : null;
$mins = $regs [2] ? $regs [2] : null;
$secs = $regs [3] ? $regs [3] : null;
$ms = $regs [4] ? $regs [4] : null;
}
return array('codec' => $codec,
'width' => $width,
'height' => $height,
'hours' => $hours,
'mins' => $mins,
'secs' => $secs,
'ms' => $ms
);
}
function _human_filesize($bytes, $decimals = 2) {
$sz = 'BKMGTP';
$factor = floor((strlen($bytes) - 1) / 3);
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . #$sz[$factor];
}

If you use Wordpress you can just use the wordpress build in function with the video id provided wp_get_attachment_metadata($videoID):
wp_get_attachment_metadata($videoID);
helped me a lot.
thats why i'm posting it, although its just for wordpress users.

https://github.com/JamesHeinrich/getID3
download getid3 zip and than only getid3 named folder copy paste in project folder and use it as below show...
<?php
require_once('/fire/scripts/lib/getid3/getid3/getid3.php');
$getID3 = new getID3();
$filename="/fire/My Documents/video/ferrari1.mpg";
$fileinfo = $getID3->analyze($filename);
$width=$fileinfo['video']['resolution_x'];
$height=$fileinfo['video']['resolution_y'];
echo $fileinfo['video']['resolution_x']. 'x'. $fileinfo['video']['resolution_y'];
echo '<pre>';print_r($fileinfo);echo '</pre>';
?>

Related

Check for Valid/Active URLs before download - Laravel 7

I'm trying to check download images and store locally in my assets folder.
Before start downloading, I want to check and make sure the link is still live.
I only want to start my download if the link is live 200 Ok.
Try #1
public function handle()
{
$skills = Skill::all();
if($skills != null){
foreach($skills as $i=>$skill){
if (strpos($skill->img_path, 'http') !== false) {
if(!isset($exception)) {
//update the path in DB
$image_path = '/assets/fe/img/skill/';
$img_name = $skill->name.'.png';
$path = public_path() . $image_path . $img_name;
$uploadSuccess = file_put_contents($path, file_get_contents($skill->img_path));
// dd($uploadSuccess);
if($uploadSuccess) {
$skill->img_path = $image_path . $img_name;
}
}
}
$skill->save();
}
}
}
I seems to get so many issues
One of them is
curl: (6) Could not resolve host: thumbsplus.tutsplus.com
Another one is
file_get_contents(https://assets-cdn.github.com/images/modules/logos_page/Octocat.png): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
What is the cleaner way ? Please suggest, I will try now.
Try #2
public function handle()
{
$skills = Skill::all();
if($skills != null){
foreach($skills as $i=>$skill){
if (strpos($skill->img_path, 'http') !== false) {
$file_headers = #get_headers($skill->img_path);
if(!$file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found') {
$exists = false;
}
else {
$exists = true;
if(!isset($exception)) {
//update the path in DB
$image_path = '/assets/fe/img/skill/';
$img_name = $skill->name.'.png';
$path = public_path() . $image_path . $img_name;
$uploadSuccess = file_put_contents($path, file_get_contents($skill->img_path));
// dd($uploadSuccess);
if($uploadSuccess) {
$skill->img_path = $image_path . $img_name;
}
}
}
}
$skill->save();
}
}
}
Try #3
public function handle()
{
$skills = Skill::all();
$failCount = 0;
$successCount = 0;
$failList = [];
if($skills != null){
foreach($skills as $i=>$skill){
if (strpos($skill->img_path, 'http') !== false) {
$file_headers = #get_headers($skill->img_path);
if(!$file_headers || strpos($file_headers[0], '404') !== false) {
$exists = false;
$failCount++;
array_push($failList,$skill->name);
// break;
}
else {
$exists = true;
$successCount++;
//DEBUG
// dd($file_headers[0]);
if(strpos($file_headers[0], '200')) {
//update the path in DB
$image_path = '/assets/fe/img/skill/';
$img_name = $skill->name.'.png';
$path = public_path() . $image_path . $img_name;
$uploadSuccess = file_put_contents($path, file_get_contents($skill->img_path));
// dd($uploadSuccess);
if($uploadSuccess) {
$skill->img_path = $image_path . $img_name;
}
}
}
}
$skill->save();
echo ".";
}
}
echo "\r\n";
$this->info('=========================');
$this->info('Success :'. $successCount);
$this->info('=========================');
$this->info('Fail :'. $failCount);
$this->info('List :'. print_r($failList));
$this->info('=========================');
}
seems to work
but it hang, sometimes more than 1 minute, at a certain dot
⚡️ php artisan skillIcons:download
..............................................................................................................................
=========================
Success :12
=========================
Fail :7
Array
(
[0] => GitHub
[1] => Geolocation API
[2] => Xcode
[3] => Protractor
[4] => Sketch
[5] => Amazon ECR
[6] => WinSCP
)
List :1
=========================
All images seems to be downloaded successfully
⚡️ ls public/assets/fe/img/skill/
AWS Console.png Digital Ocean.png Javascript.png PayPal.png Terminal.png
AWS.png Disqus.png Jest.png Photoshop.png TextMate.png
Alimofire.png Divvy.png Jira.png Pod.png TextWrangler.png
Amazon ECS.png Docker.png Kamar.png PostgreSQL.png Transmit.png
Amazon RDS.png Duet.png LESS.png PyCharm.png Twitter.png
Angular.png EC2.png Laravel Elixir.png Python.png Ubuntu.png
AngularJS.png Evernote .png Laravel.png QuickBooks.png VMWare Fusion .png
Apache.png Express.png Linode.png React Native.png VS Code.png
Atom.png Facebook.png Mac OS X.png Realm.png Vagrant.png
Bash.png Final Cut.png Markdown.png Redis.png Virtual Machine.png
BitBucket.png FusionCharts.png MobaXTerm.png RequireJS.png Virtualbox.png
Bower.png GitLab.png Mocha.png S3.png Webpack.png
CKEditor.png Go Daddy.png MySQL.png SAML 2.0.png Windows.png
CSS.png Google Chart.png NPM.png Salesforce.png Wireshark.png
Camtasia.png Google Map.png Navicat Premium.png Sass.png Word.png
Cent OS.png Google Translation.png Nginx.png Secure Shell.png Yarn.png
Chai.png Gulp.png Node.png Selenium.png iMovie.png
Chat.io.png HTML.png Noteability.png Shopify.png iOS.png
Coda.png Heroku.png OAuth 2.0.png SinonJS.png jQuery.png
CodeBox.png Illustrator.png Open Stack.png Siteground.png
Composer .png Instagram.png OpenID Connect.png Sublime Text.png
Confluence .png J Player.png PHP.png Swagger.png
3 seconds
How do I decrease the wait time to only 3 seconds ?
You have to handle error in some way.
You can try
try {
...
} catch () {
...
}
But I prefer doing things this way
public function handle()
{
Skill::get()->map(function($skill){
if(strpos($skill->img_path, 'http')) return;
$img = $this->getImageFromUrl($skill->img_path)
if(!$img == null) return;
$image_path = '/assets/fe/img/skill/';
$img_name = $skill->name.'.png';
$path = public_path() . $image_path . $img_name;
$fp = fopen($path,'x');
fwrite($fp, $img);
fclose($fp);
if($uploadSuccess) {
$skill->img_path = $image_path . $img_name;
$skill->save();
}
});
}
public function getImageFromUrl($url){
$ch = curl_init ($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); // The number of seconds to wait while trying to connect. Use 0 to wait indefinitely.
curl_setopt($ch, CURLOPT_TIMEOUT, 2); // The maximum number of seconds to allow cURL functions to execute
$img = curl_exec($ch);
$err = curl_error($ch);
if($err) {
echo $err;
return null;
}
curl_close($ch);
return $img;
}
I refactored some code and if you prefer this keep it if not get only logic and do it as you prefer
Hope this helps
You may use active_url validation rule to check if the given URL is alive. According to the docs:
The field under validation must have a valid A or AAAA record according to the dns_get_record PHP function. The hostname of the provided URL is extracted using the parse_url PHP function before being passed to dns_get_record.
if (validator([$skill->img_path], ['active_url'])->fails()) {
// URL is not valid/active
}
else {
// URL is valid/active
}

Microsoft Graph API file upload using PHP SDK for large file still fails

I am currently using microsoft-php-sdk and it has been pretty good. I have managed to upload small files from the server to OneDrive. But when I tried to upload a 38MB Powerpoint file it was failing. The Microsoft Graph API documentation suggests creating an upload session. I thought it would just be as easy as just updating the URI from /content to /createUploadSession but it was still failing.
$response = $graph->createRequest('POST', '/me/drive/root/children/'.basename($path).'/createUploadSession')
->setReturnType(Model\DriveItem::class)
->upload($path);
My code looks something like this. I have difficulty figuring out the PHP SDK documentation and there was no example for upload session. Has anyone used the PHP SDK for this scenario before?
i used the similar approach with https://github.com/microsoftgraph/msgraph-sdk-php/wiki and laravel framework. here is the code that worked for me finally.
public function test()
{
//initialization
$viewData = $this->loadViewData();
// Get the access token from the cache
$tokenCache = new TokenCache();
$accessToken = $tokenCache->getAccessToken();
// Create a Graph client
$graph = new Graph();
$graph->setAccessToken($accessToken);
//upload larger files
// 1. create upload session
$fileLocation = 'S:\ebooks\myLargeEbook.pdf';
$file = \File::get($fileLocation);
$reqBody=array(
"#microsoft.graph.conflictBehavior"=> "rename | fail | replace",
"description"=> "description",
"fileSystemInfo"=> ["#odata.type"=> "microsoft.graph.fileSystemInfo"] ,
"name"=> "ebook.pdf",
);
$uploadsession=$graph->createRequest("POST", "/drive/root:/test/ebook.pdf:/createUploadSession")
->attachBody($reqBody)
->setReturnType(Model\UploadSession::class)
->execute();
//2. upload bytes
$fragSize =320 * 1024;// 1024 * 1024 * 4;
$fileLocation = 'S:\ebooks\myLargeEbook.pdf';
// check if exists file if not make one
if (\File::exists($fileLocation)) {
$graph_url = $uploadsession->getUploadUrl();
$fileSize = filesize($fileLocation);
$numFragments = ceil($fileSize / $fragSize);
$bytesRemaining = $fileSize;
$i = 0;
while ($i < $numFragments) {
$chunkSize = $numBytes = $fragSize;
$start = $i * $fragSize;
$end = $i * $fragSize + $chunkSize - 1;
$offset = $i * $fragSize;
if ($bytesRemaining < $chunkSize) {
$chunkSize = $numBytes = $bytesRemaining;
$end = $fileSize - 1;
}
if ($stream = fopen($fileLocation, 'r')) {
// get contents using offset
$data = stream_get_contents($stream, $chunkSize, $offset);
fclose($stream);
}
$content_range = "bytes " . $start . "-" . $end . "/" . $fileSize;
$headers = array(
"Content-Length"=> $numBytes,
"Content-Range"=> $content_range
);
$uploadByte = $graph->createRequest("PUT", $graph_url)
->addHeaders($headers)
->attachBody($data)
->setReturnType(Model\UploadSession::class)
->setTimeout("1000")
->execute();
$bytesRemaining = $bytesRemaining - $chunkSize;
$i++;
}
}
dd($uploadByte);
}
}
I have developed a similar library for oneDrive based on microsoft graph rest api. This problem is also solved here : tarask/oneDrive
look at the documentation in the Upload large files section
I'm not familiar with PHP, but I am familiar with the upload API. Hopefully this will help.
The /content endpoint you were using before allows you to write binary contents to a file directly and returns a DriveItem as your code expects. The /createUploadSession method works differently. The Graph documentation for resumable upload details this, but I'll summarize here.
Instead of sending the binary contents in the CreateUploadSession request, you either send an empty body or you send a JSON payload with metadata like the filename or conflict-resolution behavior.
The response from CreateUploadSession is an UploadSession object, not a DriveItem. The object has an uploadUrl property that you use to send the binary data.
Upload your binary data over multiple requests using the HTTP Content-Range header to indicate which byte range you're uploading.
Once the server receives the last bytes of the file, the upload automatically finishes.
While this overview illustrates the basics, there are some more concepts you should code around. For example, if one of your byte ranges fails to upload, you need to ask the server which byte ranges it already has and where to resume. That and other things are detailed in the docs. https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/driveitem_createuploadsession
<?php
require __DIR__.'/path/to/vendor/autoload.php';
use Microsoft\Graph\Graph;
use Microsoft\Graph\Model;
$graph = new Graph();
$graph->setAccessToken('YOUR_TOKEN_HERE');
/** #var Model\UploadSession $uploadSession */
$uploadSession = $graph->createRequest("POST", "/me/drive/items/root:/doc-test2.docx:/createUploadSession")
->addHeaders(["Content-Type" => "application/json"])
->attachBody([
"item" => [
"#microsoft.graph.conflictBehavior" => "rename",
"description" => 'File description here'
]
])
->setReturnType(Model\UploadSession::class)
->execute();
$file = __DIR__.'/path/to/large-file.avi';
$handle = fopen($file, 'r');
$fileSize = fileSize($file);
$fileNbByte = $fileSize - 1;
$chunkSize = 1024*1024*4;
$fgetsLength = $chunkSize + 1;
$start = 0;
while (!feof($handle)) {
$bytes = fread($handle, $fgetsLength);
$end = $chunkSize + $start;
if ($end > $fileNbByte) {
$end = $fileNbByte;
}
/* or use stream
$stream = \GuzzleHttp\Psr7\stream_for($bytes);
*/
$res = $graph->createRequest("PUT", $uploadSession->getUploadUrl())
->addHeaders([
'Content-Length' => ($end - 1) - $start,
'Content-Range' => "bytes " . $start . "-" . $end . "/" . $fileSize
])
->setReturnType(Model\UploadSession::class)
->attachBody($bytes)
->execute();
$start = $end + 1;
}
It's work for Me !

Sending image using sockets with base 64 format by JSON

I'm trying to send an image taken from the camera and converted to base 64 format to be converted into a JSON format. Everything is working fine except when I use the function of json.dump in python it adds \n to the image_64 base format, where in the server, it can't decode the picture properly- It's giving a blank image .
Python code to send the image :
import socket
import datetime
import json
import base64 , urllib
from cam import *
Signal = "200"
Date = datetime.datetime.now()
captureImage()
del(camera)
facechop('test_image.png')
image ='test_image.png'
image_64 = base64.encodestring(open(image,"rb").read())
print "----------------------------------------------"
try:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('X.X.X.X', 20001))
code = json.dumps({"number": Signal, "date" : "{:%m/%d/%Y}".format(Date), "image" : image_64}).encode('utf8')
client_socket.sendall(code)
receive = client_socket.recv(5012)
print receive
except Exception as e:
print("ERROR: "+str(e))
& the server code is :
function checkMessageRecieved(){
foreach ($this->changed as $key => $socket) {
$buffer = null;
while(socket_recv($socket, $buffer, 10240000, 0) >= 1) {
$n = trim($buffer);
$decodeJSON = json_decode($n, true);
$number = $decodeJSON['number'];
$date = $decodeJSON['date'];
$image = $decodeJSON['image'];
echo $number;
echo $date;
echo $image;
$image=str_replace("\n", "" , $image);
$img = str_replace('data:image/png;base64,', '', $image);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = __DIR__ . "/../photos/public/" . uniqid() . '.png';
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
$this->sendMessage(trim("Successfully done...") . PHP_EOL);
unset($this->changed[$key]);
break;
}
}
}

create separate pdf files in yii

I am trying to create 2 separate pdf files with different content. I have the following code which creates the 2 files.
$invoice = Invoices::model()->findByPk($_GET['id']);
$invoicedetail = InvoicesDetail::model()->findAll(array("condition"=>"invoiceno=".$invoice->INVOICENO . " && biditems_id is null"));
$client = $invoice->pROJ->oRDERNO->addressesinvoices;
$invoices = Invoices::model()->findAll(array("condition"=>"PROJID=".$invoice->PROJID . " && INVOICENO != ".$invoice->INVOICENO));
/*$this->renderPartial("partialInvoice",
array(
"invoice"=>$invoice,
"client"=>$client,
//"lookupprocesstotalArr"=>$lookupprocesstotalArr,
"adjustments"=>$invoices,
"invoicedetail"=>$invoicedetail[0]
),true);
*/
$html = $this->renderPartial("partialInvoice",
array(
"invoice"=>$invoice,
"client"=>$client,
//"lookupprocesstotalArr"=>$lookupprocesstotalArr,
"adjustments"=>$invoices,
"invoicedetail"=>$invoicedetail[0]),true);
$filename_invoice = 'invoice_'.$invoice->INVOICENO.'.pdf';
Yii::import('application.extensions.pdfable.WkHtmlToPdf');
$pdf = new WkHtmlToPdf(array(
'no-outline', // Make Chrome not complain
'margin-top' => 10,
'margin-right' => 10,
'margin-bottom' => 10,
'margin-left' => 10,
));
$pdf->setOptions(array(
'orientation' => 'portrait'
));
// Add a HTML file, a HTML string or a page from a URL
$pdf->addPage($html);
// Save the PDF
$pdf->saveAs("/tmp/$filename_invoice");
// ... or send to client as file download
/*if(!$pdf->send($filename)){
throw new Exception('Could not create PDF: '.$pdf->getError());
}*/
$globalController = new GlobalController;
//$project = Projects::model()->findAll(array("condition"=>"PROJID=".$_GET['PROJID']));
//$projid = $_GET['PROJID'];
$pdfDetail = new WkHtmlToPdf();
$orientation = "Landscape";
$pdfDetail->setOptions(array('orientation'=>$orientation,
'no-outline', // Make Chrome not complain
'margin-right' => 10,
'margin-bottom' => 5,
'margin-left' => 10,
));
//$this->layout = 'pdf';
//get list of process stages for this project
$lastrun = $globalController->lastRun($invoice->PROJID);
$processstages = ExtHtml::listData($lastrun, 'ID',array('cumulative','ITEM'));
$lookupprocesstotalArr = $globalController->lookupprocesstotal($invoice->PROJID,$processstages);
// get all lines
$connection = Yii::app()->db;
$sql = "SELECT jobs.JOBNO, jobs.NAME, FSP, LSP, SHOTS, KM
FROM hdb.jobs
join detailsseismic on jobs.JOBNO = detailsseismic.JOBNO
where jobs.PROJID = :pid";
$command=$connection->createCommand($sql);
$command->bindValue(":pid",$invoice->PROJID,PDO::PARAM_INT);
$command->execute();
$lines = $command->queryAll();
$dates = array();
foreach ($lines as $arr) {
$sql = "SELECT jobsprocesscomplete.datedone, ITEM_fk
FROM hdb.jobsprocesscomplete
left join lookupprocess on jobsprocesscomplete.lookupprocess_id = lookupprocess.ID
left join biditems on lookupprocess.biditems_id = biditems.ITEMID
where jobno = :jobno";
$command=$connection->createCommand($sql);
$command->bindValue(":jobno",$arr['JOBNO'],PDO::PARAM_INT);
$command->execute();
$dates[$arr['JOBNO']] = $command->queryAll();
}
/*echo $this->renderPartial('pdf_'.$_GET['type'],array(
'lookupprocesstotalArr'=>$lookupprocesstotalArr,
"currency"=>$project[0]->currency0->currency,
"projectpercent"=>$project[0]->PERCENT,
"name"=>$project[0]->PROJECT . " - " . $project[0]->oRDERNO->cONTACTsugar->first_name . " " . $project[0]->oRDERNO->cONTACTsugar->last_name,
"lines"=>$lines,
"dates"=>$dates,
"project"=>$project[0]));
*/
$detail = $this->renderPartial('/lookupprocess/pdf_detail',array(
'lookupprocesstotalArr'=>$lookupprocesstotalArr,
"currency"=>$invoice->pROJ->currency0->currency,
"projectpercent"=>$invoice->pROJ->PERCENT,
"name"=>$invoice->pROJ->PROJECT . " - " . $invoice->pROJ->oRDERNO->cONTACTsugar->first_name . " " . $invoice->pROJ->oRDERNO->cONTACTsugar->last_name,
"lines"=>$lines,
"dates"=>$dates,
"project"=>$invoice->pROJ
),true);
$filename_detail = $invoice->PROJID . "_" . date("ymd-his") . ".pdf";
// Add a HTML file, a HTML string or a page from a URL
$pdfDetail->addPage($detail);
// Save the PDF
$pdfDetail->saveAs("/tmp/$filename_detail");
shell_exec("gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=/tmp/$filename_invoice /tmp/$filename_invoice /tmp/$filename_detail");
echo "gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=/tmp/$filename_invoice /tmp/$filename_invoice /tmp/$filename_detail";
exit();
/*
// ... or send to client as file download
if(!$pdf->send($filename_invoice)){
throw new Exception('Could not create PDF: '.$pdf->getError());
}
The problem i have is the 1st pdf that gets created is overwritten by the content of the 2nd pdf which makes no sense.
I do not know the class you are using but this code seems suspicios:
-sOutputFile=/tmp/$filename_invoice /tmp/$filename_invoice /tmp/$filename_detail
For me it seems that you convert 2 files into 1 output files, so logically you overwrite it!?

oop concept implementation

I have this class content in which i am using s3 and sdb class how can i improve this class structure for using advanced oop concepts.
<?php
Class content{
function getcontent(){
if(!$_GET){
echo "{'success':false, 'error':'No query parameters submitted'}";
return;
}
// create connection
$sdb = new SimpleDB(awsAccessKey, awsSecretKey);
$condition = "";
$status = "";
//$params = json_decode(stripslashes($_POST['hash']));
$params = $_GET;
unset($params['command']);
foreach($params as $key => $value){
$condition .= " " . $key . " = '" . $value . "' and" ;
}
$condition = preg_replace('/and$/', "", $condition);
if($condition!='')
$condition=" and ".$condition;
$query = "select * from ".domain;
if($condition!= " _empty_ = '' "){
$query .= " where time_stamp is not null $condition order by time_stamp asc";
}
//~ echo $query;
$fileHash = '{';
if($files = $sdb->select($domain, $query)){
$status = 'true';
}else{
$status = 'false';
$files= array();
$message = "No records retrieved from SimpleDB ".json_encode($sdb->ErrorCode);
}
$array=array(
'files'=>$files,
'success'=>$status,
'message'=>$message
);
echo (json_encode($array));
}
function getthumb(){
$_url = $_REQUEST['url'];
$url='';
if ( $_url != "" ) {
echo $url = file_get_contents("$_url");
}
return $url;
}
function upload(){
//instantiate the S3 class
$s3 = new S3(awsAccessKey, awsSecretKey);
//instantiate the SimpleDB class
$sdb = new SimpleDB(awsAccessKey, awsSecretKey);
// Set temp directory where files will be written temporarily
$uploaddir = 'uploads/';
// Max file size 100 MB
$maxFileSize = 100 * 1024 * 1024;
$thumb = '';
$status = '';
$imgWidth = '';
$imgHeight = '';
// Get file size from Apache headers
$fileSize = getSize();
// Get MIME type from Apache headers
$fileType = getFileType();
if ($fileSize == 0){
return array(success=>false, error=>"File is empty.");
}
if ($fileSize > $maxFileSize){
return array(success=>false, error=>"File is too large.");
}
// Put data of pathinfo() array into $pathinfo
$pathinfo = pathinfo(getName());
// Get file name - eg: myphoto
$filename = $pathinfo['filename'];
// Get extension - eg: .jpg
$ext = $pathinfo['extension'];
$originalName = $filename.'.'.$ext;
// Generate unique id for the current object
$randName = uniqid();
// Unique file name with extension
$fileTempName = $randName . '.' . $ext;
// Complete temp file name and path
$fullTempName = $uploaddir . $fileTempName;
// Upload the file to temp directory on .net server
save($fullTempName);
// If images, call the function imgThumbs() to generate thumbnails
if(preg_match("/^image/", $fileType)){
$tbnail = $_GET['thumb_size'];
$thumb = imgThumbs($tbnail, $fullTempName, $fileType, bucket, cloudfront);
if($_REQUEST['profile_pic']=='y'){
$crop_url=$thumb;
}
list($imgWidth, $imgHeight) = getimagesize($fullTempName);
}
// If videos, call convertVideo() and return path of converted video. Then call vidThumbs() to generate thumbnails
if(preg_match("/^video/", $fileType)){
$fullTempName = convertVideo($fullTempName, $fileType); // Capture filename with complete path and flv extension
$fileTempName = preg_replace('/^uploads\//', '', $fullTempName);// Remove directory to get only the filename of flv
$fileType = "video/x-flv"; // Assign $fileType
$randName = substr($fileTempName, 0, 13); // Parse and assign the unique id to $randName
$imgWidth = 120; // Hardcoding width of video thumbnail
$imgHeight = 90; // Hardcoding height of video thumbnail
$thumb = vidThumbs($fullTempName, bucket, cloudfront); // Call the video thumbnail func
}
// If audio, call convertAudio() and return path of converted audio.
if(preg_match("/^audio/", $fileType)){
$fullTempName = convertAudio($fullTempName, $fileType); // Capture filename with complete path and mp3 extension
$fileTempName = preg_replace('/^uploads\//', '', $fullTempName);// Remove directory to get only the filename of mp3
$fileType = "audio/mpeg"; // Assign $fileType
$randName = substr($fileTempName, 0, 13); // Parse and assign the unique id to $randName
$imgWidth = $imgHeight = 100; // Hardcoding for positioning the thumbnail for audio
$thumb = 'http://dtzhqpwfdzscm.cloudfront.net/4c7247570bd4b.jpg'; // Hardcoding this url for audio thumbs
}
// Metadata for SimpleDB
$contentObjectType = "upload";
$timeStamp = time();
$url = cloudfront.$fileTempName;
$on_floor = "true";
/*
* An array of (name => (value [, replace])),
* where replace is a boolean of whether to replace the item.
* replace is optional, and defaults to false.
* If value is an array, multiple values are put.
*/
$putAttributesRequest = array(
"contentid" => array("value" => "$randName"), // unique id for EVERY object and link
"content_obj_type" => array("value" => "$contentObjectType"), // whether link or file upload
"file_name" => array("value" => "$fileTempName"), // unique generated filename
"url" => array("value" => "$url"), //file's CDN url
"original_name" => array("value" => "$originalName"), //original name of the file
"file_size" => array("value" => "$fileSize"), //size of file uploaded
"time_stamp" => array("value" => "$timeStamp"), //time
"file_type" => array("value" => "$fileType"), //mime type of uploaded file
"thumb" => array("value" => "$thumb"), //thumbnail link
"width" => array("value" => "$imgWidth"), //width of uploaded image
"height" => array("value" => "$imgHeight"), //height of uploaded image
"on_floor" => array("value" => "$on_floor") //by default all cObj on floor
);
// Get ALL the parameter hash passed
$contentObjHash = getParam();
foreach($contentObjHash as $key => $value){
$putAttributesRequest["$key"] = array("value" => "$value");
}
//check whether a form was submitted
if(isset($fileTempName)){
// Begin object hash here
$objHash = '{';
/* Move the file to S3
*
* #param mixed $fileTempName Location of temp file
* #param string bucket Bucket
* #param string $newFileName Unique generated file name
* #param constant ACL
* #param array() Dont worry about this
* #param string $fileType MIME type of file
* #return boolean
*/
if($_REQUEST['profile_pic']!='y' && !$s3->putObjectFile($fullTempName, bucket, $fileTempName, S3::ACL_PUBLIC_READ, array(), $fileType) ) {
$status = 'false';
$objHash .= "success : ".json_encode($status)."}"; // End object hash here id S3 error
echo $objHash;
return;
}
/**
* Create or update attributes
*
* #param string $domain Domain
* #param string $randName Unique generated file name
* #param array $putAttributesRequest See up for more info
* #return boolean
*/
if($sdb->putAttributes(domain, $randName, $putAttributesRequest)){
$status = 'true';
unlink($fullTempName);
}else{
$status = 'false';
$objHash .= "'SimpleDB_error' : ".json_encode($sdb->ErrorCode).",";
}
foreach($putAttributesRequest as $key => $value){
$objHash .= json_encode($key). " : " . json_encode($value["value"]) .", ";
}
$objHash .= "'success' : ".$status."}"; // End object hash after SimpleDB transaction
echo $objHash;
}
}
}
?>
Using the class by this code :
$content=new content();
switch($command){
case 'getcontent':
$content->getcontent();
break;
case 'thumb':
$content->getthumb();
break;
case 'upload':
$content->upload();
break;
case 'update':
$content->update();
break;
default:
break;
}
-- comment
your class seems to be more like a "service" class (you don't have any property). Then you need just one instance of the class : implement the singleton pattern. If the instance is used quite often or once created, you call almost all methods : create a DB attribute to avoid multiple connections (actually you could do that with a singleton on the application scope). All of that depends on your way of use the class.
-- /comment
for the singleton pattern, read this.
About the DB attribute, it will allow you to connect just once for each instance of the Content Class instead of several local variables in methods.
It could be useful in case of multiple calls of methods that need DB which is not your case for the moment.
Here is an example :
Class content{
private $db=null; // db
public function __construct(){ // CONSTRUCTOR : called with the new operator
// create connection (created once for the instance)
$this->db = new SimpleDB(awsAccessKey, awsSecretKey);
// you can pass the connection strings as parameter
}
public function getcontent(){
// You should not use directly GET here : pass it as parameter
// as the origin of the data may change some day
// in this method, it doesn't where the data come from
// -> encapsulation : the code keeps consistent when environment changes
if(!$_GET){
echo "{'success':false, 'error':'No query parameters submitted'}";
return;
}
...
// query something using the local attribute
if($files = $this->db->select($domain, $query)){

Categories