Related
I am creating a zip folder in which I need to attach to an email. Attaching the zip folder is not working.
I included three files below that work together:
The SEND file is where the ajax sends the files to. Then there is a fileUpload.php file that uploads single files and generates the $filename variable array for all the files uploaded. This is where the zip folder gets created and where I attempt to attach it with $message.
The COMMUNICATION CLASS is used to send emails. Originally, the zip folder was created/attached here. For some reason, I can't figure out how to get the two files to work together, outside of what it already does.
The TEMPLATE file is where email html and css are contained. Also are the {variables}. This is where the filename and message variables are. Though, filename should be all that is required.
The zip folder is being created. It is just not attaching.
Does anyone see why when the zip is created that it isn't attaching to the email? Specifically, this part of the code is where I am trying to do it:
$message["attachment[0]"] = curl_file_create($target_dir . $filename[0] . ".zip",
pathinfo("uploads/{$filename[0]}.zip", PATHINFO_EXTENSION),
$filename[0] . ".zip");
SEND FILE
ini_set('display_errors', 1);
error_reporting(E_ALL);
require 'classes/Communication.php';
require 'fileUpload.php';
$first_name = trim(htmlspecialchars($_POST['first_name'], ENT_QUOTES));
$last_name = trim(htmlspecialchars($_POST['last_name'], ENT_QUOTES));
$email = trim(htmlspecialchars($_POST['email']));
$phone = trim(htmlspecialchars($_POST['phone']));
$zip = trim(htmlspecialchars($_POST['zip']));
$company = trim(htmlspecialchars($_POST['company'], ENT_QUOTES));
$details = trim(htmlspecialchars($_POST['description'], ENT_QUOTES));
$file = null;
require_once '../config.php';
/************************ Start to Company ******************************/
$placeholders = ['{first_name}',
'{last_name}',
'{phone}',
'{zip}',
'{company}',
'{description}',
'{interest}',
'{email}',
'{lead_owner}',
'{lead_assign}'
];
$values = [
htmlentities($_POST['first_name']),
htmlentities($_POST['last_name']),
htmlentities($_POST['phone']),
htmlentities($_POST['zip']),
htmlentities($_POST['company']),
nl2br(htmlentities($_POST['description'])),
htmlentities($_POST['interest']),
htmlentities($_POST['email']),
$lead_owner = htmlentities($_POST['leadOwner']),
$lead_assign = htmlentities($_POST['leadAssign']),
];
$template = str_replace($placeholders, $values, file_get_contents("templates/quote_to_domain.html"));
$files = null;
if (!empty($_FILES["uploadedFile"]["name"])) {
if ($_FILES['uploadedFile']['error'] == 1) {
$error = "The file {$_POST['first_name']} attempted to upload is too large. Contact them for an alternate way to send this file.";
$template = str_replace("{filename}", "$error", $template);
}
$date = new DateTime();
$fu = new fileUpload();
$filename = $fu->upload();
$uploadedFileTypes = $fu->getImageFileTypes();
$extensions = ['pdf','jpg', 'jpeg', 'png', 'gif'];
//file_put_contents('file_type_log', "\n[{$date->format('Y-m-d H:i:s')}]" . print_r($uploadedFileTypes, true), FILE_APPEND);
$target_dir = "uploads/";
$differentExtensions = array_diff($uploadedFileTypes, $extensions);
if (count($differentExtensions) > 0) {
//file_put_contents('file_norm_log', "\n[{$date->format('Y-m-d H:i:s')}]" . print_r('There were other types of files uploaded', true), FILE_APPEND);
$f = new ZipArchive();
$zip = $f->open($target_dir . $filename[0] . ".zip", ZipArchive::CREATE | ZipArchive::OVERWRITE);
if ($zip) {
for ($index = 0; $index < count($filename); $index++) {
$f->addFile($target_dir . basename($_FILES["uploadedFile"]["name"][$index]), basename($_FILES["uploadedFile"]["name"][$index]));
}
$f->close();
$message["attachment[0]"] = curl_file_create($target_dir . $filename[0] . ".zip",
pathinfo("uploads/{$filename[0]}.zip", PATHINFO_EXTENSION),
$filename[0] . ".zip");
//$template = str_replace("{filename}", $message, $template);
} else {
throw new Exception("Could not zip the files.");
$msg = "Could not zip the files.";
echo json_encode(['status_code' => 500,
'message' => $msg]);
}
} else {
$out = (count($filename) > 1 ? 'Multiple files were' : 'A file was'). ' uploaded. You can download ' . (count($filename) > 1 ? 'them' : 'the file'). ' from:</ul>';
foreach ($filename as $indFile) {
//print_r($template);
$out .= "<li><a href='/php/uploads/{$indFile}'>{$indFile}</a></li>";
}
$out .= '</ul>';
$template = str_replace("{filename}", $out, $template);
}
foreach ($_FILES as $file) {
foreach($file['name'] as $key => $value) {
if (empty($value)) {
//echo "name is empty!";
$template = str_replace("{filename}", '', $template);
}
if ($file['error'][$key] != 4) {
//echo "error code is 4";
}
}
}
clearstatcache();
}
$to_company = Communication::mail_api($_POST, $filename, $template, 0);
Then here is the communication class. Originally, the zip code was in here (and still is). I can't figure out how to get the two files to work together as they should have.
COMMUNICATION CLASS
class Communication
{
public static function mail_api(Array $msg, Array $filename = null, $template = null, $recipient = false, $attachment = null)
{
$date = new DateTime();
$config = array();
$message = array();
$message['to'] = !$recipient ? $email_to_send_to : $msg['email'];
$message['h:Reply-To'] = !$recipient ? $msg['email'] : '';
$message['subject'] = isset($msg['subject']) ? $msg['subject'] : '';
if ($attachment) {
try {
if (!file_exists($attachment)) {
throw new Exception("File $attachment not found!");
}
$parts = explode('/', $attachment);
$filenames = end($parts);
$message['attachment[0]'] = curl_file_create($attachment,
pathinfo($attachment, PATHINFO_EXTENSION),
$filenames);
file_put_contents('log', "\n[{$date->format('Y-m-d H:i:s')}]" . "Attachment added: \n", FILE_APPEND); //here
} catch (Exception $e) {
file_put_contents('error_log', "\n[{$date->format('Y-m-d H:i:s')}]" . "Error adding attachment: \n" . print_r($e, 1), FILE_APPEND);
}
}
$message['html'] = $template;
try {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $config['api_url']);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'o:tracking-clicks: false'
));
curl_setopt($ch, CURLOPT_USERPWD, "api:{$config['api_key']}");
$self = new Communication();
if (!empty($file) && !$recipient && count($filename) > 1) {
$f = new ZipArchive();
$zip = $f->open('uploads/' . $filename[0] . ".zip", ZipArchive::CREATE | ZipArchive::OVERWRITE);
if ($zip) {
for ($index = 0; $index < count($_FILES['uploadedFile']['name']); $index++) {
// echo $file['uploadedFile']['name'][$index] . "\n";
//$f->addFile($_FILES['uploadedFile']['tmp_name'][$index], $file['uploadedFile']['name'][$index]);
$f->addFile($target_dir . basename($_FILES["uploadedFile"]["name"][$index]), basename($_FILES["uploadedFile"]["name"][$index]));
}
$f->close();
$message["attachment[0]"] = curl_file_create("uploads/{$filename[0]}.zip",
pathinfo("uploads/{$filename[0]}.zip", PATHINFO_EXTENSION),
$filename[0] . ".zip");
} else {
throw new Exception("Could not zip the files.");
}
// $message['html'] = str_replace("{filename}", "A file was uploaded. You can download the file from: <a href='/php/uploads/{$file['uploadedFile']['name']}.zip'>{$file['uploadedFile']['name']}</a>", $message['html']);
} elseif (count($filename) == 1) {
$message["attachment[0]"] = curl_file_create("uploads/{$filename}",
pathinfo("uploads/{$filename}", PATHINFO_EXTENSION),
$filename);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $message);
$result = curl_exec($ch);
curl_close($ch);
$resp = json_decode($result);
file_put_contents('communication_log', "\n[{$date->format('Y-m-d H:i:s')}] " . "Log for {$message['to']}: \n" . print_r(json_encode($resp) . "\n\n" . print_r($message,1), 1), FILE_APPEND);
// print_r($resp);
if (isset($resp->id))
return true;
return false;
} catch (Exception $e) {
file_put_contents('error_log', "\n[{$date->format('Y-m-d H:i:s')}]" . "Error for {$message['to']}: \n" . print_r($e, 1), FILE_APPEND);
}
}
Then the template, which is an email that sends the file link or attachment (though attachment not sending):
TEMPLATE
<tr>
<td> {filename} </td>
</tr>
<tr>
<td><i>{message}</i></td>
</tr>
I have a bunch of PDFs that were downloaded using a scraper. This scraper didn't check to see if the file was a JPG or a PDF so by default all of them were downloaded and saved with the '.pdf' extension. So, just to clarify all the files in the batch are .pdf. However, if I try to open them(The files that are not PDF but rather JPGs) via a server or locally I'm hit with an error.
My question. Is there a way with PHP to check and see if this file is a valid PDF? I would like to run all the URLs through a loop to check these files. There are hundreds of them and it would take hours upon hours to check.
Thanks
For local files (PHP 5.3+):
$finfo = finfo_open(FILEINFO_MIME_TYPE);
foreach (glob("path/to/files") as $filename) {
if(finfo_file($finfo, $filename) === 'application/pdf') {
echo "'{$filename}' is a PDF" . PHP_EOL;
} else {
echo "'{$filename}' is not a PDF" . PHP_EOL;
}
}
finfo_close($finfo);
For remote files:
$ch = curl_init();
$url = 'http://path.to/your.pdf';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$results = split("\n", trim(curl_exec($ch)));
foreach($results as $line) {
if (strtok($line, ':') == 'Content-Type') {
$parts = explode(":", $line);
echo trim($parts[1]); // output: application/pdf
}
}
Get MIME type of the file using function: finfo_file()
if (function_exists('finfo_open')) {
$finfo = finfo_open(FILEINFO_MIME);
$mimetype = finfo_file($finfo, "PATH-TO-YOUR-FILE");
finfo_close($finfo);
echo $mimetype;
}
echo "<pre>";
print_r($mimetype);
echo "</pre>";
Use finfo_file() function
<?php
if (function_exists('finfo_open')) {
$mime = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($mime, "FILE-PATH");
if($mime_type == "application/pdf")
echo "file is pdf";
else
echo "file is not pdf";
finfo_close($mime);
}
Sometimes you gotta check a mime signature of a file and sometimes of a variable. These are how you do both checkings:
$filename = '/path/to/my/file.pdf';
$content = file_get_contents($filename);
$file_is_pdf = function(string $filename) : bool {
return mime_content_type($filename) === 'application/pdf';
};
$var_is_pdf = function(string $content) : bool {
$mime_type_found = (new \finfo(FILEINFO_MIME))->buffer($content);
return $mime_type_found === 'application/pdf; charset=binary';
};
// Checks if a file contains a pdf signature.
var_dump($file_is_pdf($filename));
// Checks if a variable contains a pdf signature.
var_dump($var_is_pdf($content));
i have this upload form and i want to resize image when uploaded
its upload form from url i did it from file upload but cant for url upload
can anyone help me?
<?php
if($_POST["sub"]){
$url = trim($_POST["url"]);
if($url){
$file = fopen($url,"rb");
if($file){
$directory = "../images/news/";
$valid_exts = array("jpg","jpeg","gif","png");
$ext = substr(basename($url), strrpos(basename($url), '.'));
$ext = str_replace('.','',$ext);
if(in_array($ext,$valid_exts)){
$rand = rand(0,9999999999);
$filename = $rand.'.'.$ext;
$newfile = fopen($directory . $filename, "wb");
if($newfile){
while(!feof($file)){
fwrite($newfile,fread($file,1024 * 8),1024 * 8);
}
echo ''."";
echo ''.$filename.'';
} else { echo 'Could not establish new file ('.$directory.$filename.') on local server. Be sure to CHMOD your directory to 777.'; }
} else { echo 'Invalid file type. Please try another file.'; }
} else { echo 'Could not locate the file: '.$url.''; }
} else { echo 'Invalid URL entered. Please try again.'; }
}
?>
Use GD or Image Magic library to resize image:
http://php.net/manual/en/imagick.resizeimage.php
http://php.net/manual/en/function.imagecopyresized.php
For saving the file from URL:
If you have allow_url_fopen set to true:
$url = 'http://example.com/image.php';
$img = '/my/folder/flower.gif';
file_put_contents($img, file_get_contents($url));
Else use cURL:
$ch = curl_init('http://example.com/image.php');
$fp = fopen('/my/folder/flower.gif', 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
This is the same as the answer in this post...
I have 2 functions: one that uses chunked uploading and the other that uploads the entire file
public function chunkedUpload($file, $filename = false, $path = '', $overwrite = true)
{
if (file_exists($file)) {
if ($handle = #fopen($file, 'r')) {
// Set initial upload ID and offset
$uploadID = null;
$offset = 0;
// Read from the file handle until End OF File, uploading each chunk
while ($data = fread($handle, $this->chunkSize)) {
$chunkHandle = fopen('php://temp', 'rw');
fwrite($chunkHandle, $data);
$this->OAuth->setInFile($chunkHandle);
// On subsequent chunks, use the upload ID returned by the previous request
if (isset($response['body']->upload_id)) {
$uploadID = $response['body']->upload_id;
}
$params = array('upload_id' => $uploadID, 'offset' => $offset);
$response = $this->fetch('PUT', self::CONTENT_URL, 'chunked_upload', $params);
$offset += mb_strlen($data, '8bit');
fclose($chunkHandle);
}
// Complete the chunked upload
$filename = (is_string($filename)) ? $filename : basename($file);
$call = 'commit_chunked_upload/' . $this->root . '/' . $this->encodePath($path . $filename);
$params = array('overwrite' => (int) $overwrite, 'upload_id' => $uploadID);
$response = $this->fetch('POST', self::CONTENT_URL, $call, $params);
return $response;
} else {
throw new Exception('Could not open ' . $file . ' for reading');
}
}
// Throw an Exception if the file does not exist
throw new Exception('Local file ' . $file . ' does not exist');
}
public function putFile($file, $filename = false, $path = '', $overwrite = true)
{
if (file_exists($file)) {
if (filesize($file) <= 157286400) {
$filename = (is_string($filename)) ? $filename : basename($file);
$call = 'files/' . $this->root . '/' . $this->encodePath($path . $filename);
// If no filename is provided we'll use the original filename
$params = array(
'filename' => $filename,
'file' => '#' . str_replace('\\', '\\', $file) . ';filename=' . $filename,
'overwrite' => (int) $overwrite,
);
$response = $this->fetch('POST', self::CONTENT_URL, $call, $params);
return $response;
}
throw new Exception('File exceeds 150MB upload limit');
}
// Throw an Exception if the file does not exist
throw new Exception('Local file ' . $file . ' does not exist');
}
I have tested these functions from the same server directory and they both work fine; however, chunkedUpload is able to upload from remote http:// and ftp:// urls but putFile is not able to. Why does this happen? Is there a problem within these two functions that might cause this?
this is because file_exists does not work on remote servers
file_exists() in PHP 5 does not accept URLs only local path names
use curl to send a head request instead
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'your url');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
var_dump($size);
How do I go about deleting instructions.pdf from a temp directory?
My web script creates temporary folders with a unique id and requests some files from another server. One such file is "instructions.pdf". I want to delete this file before the temporary folder gets packaged into a zip file.
I think the easiest way would be to overwrite these files using some PHP code AFTER the package is downloaded from the API but before the package is zipped up for the user. Understanding the steps in the process may make this easier to conceptualize.
a) User click "package source code"
b) Self hosted panel contacts API
c) API returns a project package (containing the instructions.pdf) this is a zip archive
d) Self hosted panel unzips the archive for processing
e) Self hosted panel adds plugins and other assets and makes some adjustments to the package
f) Self hosted panel creates a zip archive in the /files/temp folder for the user to download.
This means that I would add an additional step before f). "Delete the instructions.pdf from the package and replace with "this file on my server" before creating the zip archive."
I want to add new logic approximately where it reads "process plugins". I need to do this in two places (same logic but a bit different for each platform) once for iOS and once for Android. Same file handles both packages.
I have tried unlink but it's not deleting anything. Here is the code I am using without success:
// delete pdf...
if($fh = fopen($rootFolder . "instructions.pdf", 'w')){
fclose($fh);
unlink('instructions.pdf');
}
the full php code is :
<?php require_once("../../config.php");
require_once("../../includes/zip.php");
//who's logged in
$guid = "";
if(isset($_SESSION[APP_LOGGEDIN_COOKIE_NAME])) $guid = fnFormInput($_SESSION[APP_LOGGEDIN_COOKIE_NAME]);
//init user object
$thisUser = new User($guid);
$thisUser -> fnLoggedInReq($guid);
$thisUser -> fnUpdateLastRequest($guid, "1");
//try to increase max execution time..This is only necessary on painfully slow servers!
if(!ini_get('safe_mode')){
#set_time_limit(120);
}
//project vars posted in AJAX request...
$appGuid = fnGetReqVal("appGuid", "", $myRequestVars);
$whatPlatform = fnGetReqVal("whatPlatform", "", $myRequestVars);
$saveToPath = "";
$packageURL = "";
//init some variables for the json result...
$bolPassed = true;
$strMessage = "";
//must have an app id...
if(strlen($appGuid) < 5 || strlen($guid) < 5){
$bolPassed = false;
$strMessage .= "<br>No app id found";
}
//must have a platoform selected...
if(strlen($whatPlatform) < 1){
$bolPassed = false;
$strMessage .= "<br>There was a problem figuring out what platform to package the project for?";
}
//create an app object so we can get the project name...
if($bolPassed){
//ceate an app object...
$objApp = new App($appGuid);
//make sure user can manage this app...
$objApp->fnCanManageApp($thisUser->infoArray["guid"], $thisUser->infoArray["userType"], $appGuid, $objApp->infoArray["ownerGuid"]);
//appAPIKey and project name comes from objApp
$appAPIKey = $objApp->infoArray["apiKey"];
$appAPISecret = $objApp->infoArray["appSecret"];
$appName = $objApp->infoArray["name"];
$projectName = $objApp->infoArray["projectName"];
$projectName = fnCleanProjectName($projectName);
$projectName = strtolower($projectName);
$appIconURL = $objApp->infoArray["iconUrl"];
$appVersion = $objApp->infoArray["version"];
}//bolPassed
/////////////////////////////////////////////////
//start functions
//replace in text file function
function fnReplaceText($filePath, $replaceWhat, $replaceWith){
if(is_file($filePath)){
if(is_readable($filePath)){
$str = file_get_contents($filePath);
if(strlen($str) > 0){
//echo "<br> Replacing text in: " . $filePath;
$fp = fopen($filePath,"w");
$str = str_replace($replaceWhat,$replaceWith,$str);
if(fwrite($fp, $str, strlen($str))){
//echo " ~ SUCCESS";
}else{
//echo " ~ ERROR!";
}
}else{
//echo "<br>This file is empty: " . $filePath;
}
}else{
//echo "<br>File not readable: " . $filePath;
}
}else{
//echo "<br>Not a file: " . $filePath;
}
}
//delete a directory and all of it's contents..
function delete_directory($dirname) {
if (is_dir($dirname))
$dir_handle = opendir($dirname);
if (!$dir_handle)
return false;
while($file = readdir($dir_handle)) {
if ($file != "." && $file != "..") {
if (!is_dir($dirname."/".$file))
unlink($dirname."/".$file);
else
delete_directory($dirname.'/'.$file);
}
}
closedir($dir_handle);
rmdir($dirname);
return true;
}
//copies directory and all it's sub-directories
function copy_directory($source, $destination){
if(is_dir($source)){
#mkdir($destination);
chmod($destination, 0755);
$directory = dir($source);
chmod($directory, 0755);
while(FALSE !== ($readdirectory = $directory->read())){
if($readdirectory == '.' || $readdirectory == '..'){
continue;
}
$PathDir = $source . '/' . $readdirectory;
if(is_dir($PathDir)){
copy_directory($PathDir, $destination . '/' . $readdirectory );
chmod($destination . '/' . $readdirectory, 0755);
continue;
}
copy($PathDir, $destination . '/' . $readdirectory);
chmod($destination . '/' . $readdirectory, 0755);
}
$directory->close();
}else {
copy($source, $destination);
chmod($destination, 0755);
}
}
//calls buzztouch.com's API to build project. Returns a download URL for the .zipped up package
function fnGetBuzztouchPackageUsingAPI($appGuid, $projectName, $appName, $iconURL, $platform, $version){
//we'll be returning a download URL or an errors[] array...
$errors = array();
$packageURL = "";
//key/value pairs to send in the request...
$postVars = "";
$fields = array(
//needed by the buzztouch.com api to validate this request
"apiKey" => urlencode(APP_BT_SERVER_API_KEY),
"apiSecret" => urlencode(APP_BT_SERVER_API_KEY_SECRET),
"command" => urlencode("packageProject"),
//required by "packageProject" command...
"appGuid" => urlencode($appGuid),
"projectName" => urlencode($projectName),
"appName" => urlencode($appName),
"iconURL" => urlencode($iconURL),
"platform" => urlencode($platform),
"version" => urlencode($version)
);
//prepare the data for the POST
foreach($fields as $key => $value){
$postVars .= $key . "=" . $value . "&";
}
//setup api url
$apiURL = rtrim(APP_BT_SERVER_API_URL, "/");
//init a cURL object, set number of POST vars and the POST data
$ch = curl_init($apiURL . "/app/");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $postVars);
//get JSON result from buzztouch API
$jsonResult = curl_exec($ch);
//close connection
curl_close($ch);
//decode json vars
if($jsonResult != ""){
$json = new Json;
$decoded = $json->unserialize($jsonResult);
if(is_object($decoded)){
//init status and pacakgeURL
$status = "";
$packageURL = "";
//must have a result...
if(array_key_exists("result", $decoded)){
$results = $decoded -> result;
//must have a status...
if(array_key_exists("status", $results)){
$status = $results -> status;
}else{
$errors[] = "API result does not contain a required field: status missing.";
}
}else{
$errors[] = "API result does not contain a required field: result missing.";
}//key exists..
//still no errors?
if(count($errors) < 1){
//success means we'll get a package URL from the API...
if(strtoupper($status) == "SUCCESS"){
if(array_key_exists("packageURL", $results)){
$packageURL = $results -> packageURL;
}
}else{
//show the errors...
if(array_key_exists("errors", $results)){
$errorList = $results -> errors;
for($e = 0; $e < count($errorList); $e++){
$errors[] = $errorList[$e] -> message;
}
}else{
$errors[] = "buzztouch API returned an error but no details were provided";
}
}//success
}//errors...
}else{
$errors[] = "buzztouch API return invalid JSON";
}
}else{
$errors[] = "buzztouch API return invalid JSON";
}
//did we have errors?
if(strlen($packageURL) > 0){
return $packageURL;
}else{
return $errors;
}
}//fnPackageUsingAPI
//downloads and saves a .zip from buzztouch.com so it can be processed locally.
function fnDownloadAndSaveZip($packageURL, $saveAsLocalFileName){
//create a file pointer for cURL to save to...
$fp = fopen($saveAsLocalFileName, 'w');
//init a cURL session to download the zip
$ch = curl_init($packageURL);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FILE, $fp);
$zipData = curl_exec($ch);
//close cURL and file pointer...
curl_close($ch);
fclose($fp);
//make sure .zip project was downloaded and saved!
if(is_file($saveAsLocalFileName)){
return true;
}else{
return false;
}
}
//gets config data from this server's API
function fnGetConfigData($appGuid, $appAPIKey, $appAPISecret){
//post vars to using CURL to make an API call to the same box.
$postVars = "";
$fields = array(
"apiKey" => urlencode($appAPIKey),
"apiSecret" => urlencode($appAPISecret),
"command" => urlencode("getAppData"),
"appGuid" => urlencode($appGuid)
);
//prepare the data for the POST
foreach($fields as $key => $value){
$postVars .= $key . "=" . $value . "&";
}
//init a cURL object to this UR
$ch = curl_init(rtrim(APP_URL, "/") . "/api/app/");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $postVars);
//get JSON result from buzztouch API
$configDataString = curl_exec($ch);
//close connection
curl_close($ch);
return $configDataString;
}
//end functions
/////////////////////////////////////////////////
//validate...
if($bolPassed){
if(strlen($appAPIKey) < 1){
$bolPassed = false;
$strMessage .= "<br>No API key found for this project?";
}
if(strlen($appAPISecret) < 1){
$bolPassed = false;
$strMessage .= "<br>No App Secret found for this project?";
}
if(strlen($appName) < 1){
$bolPassed = false;
$strMessage .= "<br>No application name found for this project?";
}
if(strlen($projectName) < 1){
$bolPassed = false;
$strMessage .= "<br>No project name found for this project?";
}
if(strlen($appIconURL) < 1){
$bolPassed = false;
$strMessage .= "<br>No Icon URL found for this project?";
}
if(strlen($appVersion) < 1){
$bolPassed = false;
$strMessage .= "<br>No version found for this project?";
}
}//bolPassed
//if we have an API key then fetch project from buzztouch.com's API
if($bolPassed){
//temp directory path...
$temp_directory = APP_PHYSICAL_PATH . APP_DATA_DIRECTORY . "/temp";
//remove previous .folders if they are still hanging around from last attempt...
fnRemoveDirectory(APP_PHYSICAL_PATH . APP_DATA_DIRECTORY . "/temp/" . $projectName . "-iOS-BTv2.0-" . $appGuid);
fnRemoveDirectory(APP_PHYSICAL_PATH . APP_DATA_DIRECTORY . "/temp/" . $projectName . "-Android-BTv2.0-" . $appGuid);
//remove previous zip's if they are still hanging around from last attempt...
if(is_file(APP_PHYSICAL_PATH . APP_DATA_DIRECTORY . "/temp/" . $projectName . "-iOS-BTv2.0-" . $appGuid . ".zip")){
#unlink(APP_PHYSICAL_PATH . APP_DATA_DIRECTORY . "/temp/" . $projectName . "-iOS-BTv2.0-" . $appGuid . ".zip");
}
if(is_file(APP_PHYSICAL_PATH . APP_DATA_DIRECTORY . "/temp/" . $projectName . "-Android-BTv2.0-" . $appGuid . ".zip")){
#unlink(APP_PHYSICAL_PATH . APP_DATA_DIRECTORY . "/temp/" . $projectName . "-Android-BTv2.0-" . $appGuid . ".zip");
}
//file names for the .zip we will be preparing...
if(strtoupper($whatPlatform) == "IOS"){
$saveToFolderName = $projectName . "-iOS-BTv2.0-" . $appGuid . ".zip";
}
if(strtoupper($whatPlatform) == "ANDROID"){
$saveToFolderName = $projectName . "-Android-BTv2.0-" . $appGuid . ".zip";
}
//save the folder in the /files/temp directory
$saveToPath = "../../" . ltrim(APP_DATA_DIRECTORY, "/") . "/temp/" . $saveToFolderName;
//root folder is where we are saving the all the unzipped files to...
$rootFolder = str_replace(".zip", "", $saveToPath);
//make sure we have a writable temp directory...
if(is_dir("../../" . ltrim(APP_DATA_DIRECTORY, "/") . "/temp")){
if(!is_writable("../../" . ltrim(APP_DATA_DIRECTORY, "/") . "/temp")){
$bolPassed = false;
$strMessage .= "The ../../" . ltrim(APP_DATA_DIRECTORY, "/") . "/temp directory is not writable by PHP. This folder needs write access.";
}
}else{
$bolPassed = false;
$strMessage .= "The ../../" . ltrim(APP_DATA_DIRECTORY, "/") . "/temp directory does not exist. This folder needs to exist and PHP needs write access to it. ";
}
//good so far...
if($bolPassed){
//packageURL comes form the buzztouch API
$packageURL = fnGetBuzztouchPackageUsingAPI($appGuid, $projectName, $appName, $appIconURL, $whatPlatform, $appVersion);
if(is_array($packageURL)){
//flag as no good
$bolPassed = false;
//show the errors...
for($e = 0; $e < count($packageURL); $e++){
$strMessage .= $packageURL[$e];
}
}else{
//all good, download and save the file from the packageURL...
if(!fnDownloadAndSaveZip($packageURL, $saveToPath)){
$bolPassed = false;
$strMessage .= "<br>An error occurred trying to download a package from the buzztouch API";
}else{
//extract the .zip to the /temp directory..
if(is_file($saveToPath)){
$archive = new PclZip($saveToPath);
$list = $archive->extract(PCLZIP_OPT_PATH, $rootFolder);
if(count($list) < 5 || !is_dir($rootFolder)){
$bolPassed = false;
$strMessage .= "There was a problem unzipping the package delivered by the buzztouch API. This can be caused by a few things. Is it possible that this is a Windows Server? This software does not run on Windows powered servers.";
}
}else{
$bolPassed = false;
$strMessage .= "<br>There was a problem finding the downloaded package";
}
}
}//is_array errors
}//bolPassed
//at this point we should have a folder to use to create our new project...It may already be full of the
//contents from the project returned by the buzztouch API...
if($bolPassed){
if(is_dir($rootFolder)){
//array holds all the files we've already added to the project - no duplicates allowed!
$existingFiles = array();
//get the BT_config.txt data from this server's API...
$configDataString = fnGetConfigData($appGuid, $appAPIKey, $appAPISecret);
if(strlen($configDataString) > 10){
////////////////////////////////////////////////////////////////////////////////////
//iOS project...
if(strtoupper($whatPlatform) == "IOS"){
$originalDelegateName = "BT_appDelegate";
$newDelegateName = $projectName . "_appDelegate";
//build directories if they don't exist already...
$makeFolders = array("BT_Config", "BT_Art", "BT_Video", "BT_Sound", "BT_Images", "BT_Docs", "BT_Plugins");
for($d = 0; $d < count($makeFolders); $d++){
if(!is_dir($rootFolder . "/" . $makeFolders[$d])){
#mkdir($rootFolder . "/" . $makeFolders[$d]);
}
}
//over-write the config data...
if($fh = fopen($rootFolder . "/BT_Config/BT_config.txt", 'w')){
fwrite($fh, $configDataString);
fclose($fh);
}
//download app icon from remote server...Could be .jpg or .png
if(strtolower(substr($appIconURL, -4)) == ".jpg"){
$icon = #imagecreatefromjpeg($appIconURL);
}else{
if(strtolower(substr($appIconURL, -4)) == ".png"){
$icon = #imagecreatefrompng($appIconURL);
}
}
if($icon){
//get icons original size...
list($width_orig, $height_orig) = #getimagesize($appIconURL);
if($width_orig > 0 && $height_orig > 0){
//create a few new sizes...
$sizes = array(57, 72, 114);
for($s = 0; $s < count($sizes); $s++){
$thisSize = $sizes[$s];
$width = $thisSize;
$height = $thisSize;
$ratio_orig = $width_orig / $height_orig;
if($width / $height > $ratio_orig){
$width = $height * $ratio_orig;
}else{
$height = $width / $ratio_orig;
}
//resample
$icon_scaled = #imagecreatetruecolor($width, $height);
#imagecopyresampled($icon_scaled, $icon, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
//output
#imagepng($icon_scaled, $rootFolder . "/BT_Art/Icon_" . $thisSize . ".png");
}//end for each size
}//if original width / height > 0
}//if icon...
//process plugins...
$strSql = " SELECT webDirectoryName FROM " . TBL_BT_PLUGINS;
$res = fnDbGetResult($strSql, APP_DB_HOST, APP_DB_NAME, APP_DB_USER, APP_DB_PASS);
while($row = mysql_fetch_array($res)){
$tmpPath = APP_PHYSICAL_PATH . APP_DATA_DIRECTORY . "/plugins" . $row["webDirectoryName"];
if(is_dir($tmpPath)){
if(is_readable($tmpPath)){
//copy all the files from the source-ios directory into the BT_plugins folder...
$iosFolder = $tmpPath . "/source-ios";
if(is_dir($iosFolder)){
$newFolder = $rootFolder . "/BT_Plugins/" . ltrim($row["webDirectoryName"], "/");
#mkdir($newFolder, 0755);
//copy / merge every file in the /source-ios folder to this newly created folder...
if($handle = opendir($iosFolder)){
while(false !== ($file = readdir($handle))){
if(strlen($file) > 5){
if(is_file($iosFolder . "/" . $file)){
if($file != ".DS_Store" && $file != "__MACOSX"){
//don't include if it's already been added
if(!in_array($file, $existingFiles)){
//copy the file...
copy($iosFolder . "/". $file, $newFolder . "/" . $file);
//if this is a .m or .h file, replace the app delegate name...
$lastTwoChars = substr($file, strlen($file) - 2, 2);
if(strtoupper($lastTwoChars) == ".H" || strtoupper($lastTwoChars) == ".M"){
fnReplaceText($newFolder . "/" . $file, $originalDelegateName, $newDelegateName);
}
}//existing files
//remember file...
$existingFiles[] = $file;
}//not .DS_Store
}
}
}//end while
}//if open source-ios
}//is_dir /source-ios
}//is_readable for this plugin...
}//is_dir for this plugin...
}//end while plugins..
}
//end iOS
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
//Android project...
if(strtoupper($whatPlatform) == "ANDROID"){
$originalDelegateName = "BT_appDelegate";
$newDelegateName = $projectName . "_appDelegate";
$originalPackageName = "com.buzzTouch";
$newPackageName = "com." . $projectName;
//build directories if they don't exist already...
$makeFolders = array("assets", "bin", "gen", "jar", "res", "src");
for($d = 0; $d < count($makeFolders); $d++){
if(!is_dir($rootFolder . "/" . $makeFolders[$d])){
#mkdir($rootFolder . "/" . $makeFolders[$d]);
}
}
//make /assets sub-directories if they don't exist already...
$makeFolders = array("BT_Video", "BT_Audio", "BT_Docs");
for($d = 0; $d < count($makeFolders); $d++){
if(!is_dir($rootFolder . "/assets/" . $makeFolders[$d])){
#mkdir($rootFolder . "/assets/" . $makeFolders[$d]);
}
}
//make /res sub-directories if they don't exist already...
$makeFolders = array("anim", "drawable", "drawable-hdpi", "drawable-ldpi", "drawable-mdpi", "layout", "values");
for($d = 0; $d < count($makeFolders); $d++){
if(!is_dir($rootFolder . "/res/" . $makeFolders[$d])){
#mkdir($rootFolder . "/res/" . $makeFolders[$d]);
}
}
//make /src sub-directories if they don't exist already...
if(!is_dir($rootFolder . "/src/com")) #mkdir($rootFolder . "/src/com");
if(!is_dir($rootFolder . "/src/com/" . str_replace("com.", "", $newPackageName))) #mkdir($rootFolder . "/src/com/" . str_replace("com.", "", $newPackageName));
//over-write (or create) the config data...
if($fh = fopen($rootFolder . "/assets/BT_config.txt", 'w')){
fwrite($fh, $configDataString);
fclose($fh);
}
//get app's icon, could be .jpg or .png
if(strtolower(substr($appIconURL, -4)) == ".jpg"){
$icon = #imagecreatefromjpeg($appIconURL);
}else{
if(strtolower(substr($appIconURL, -4)) == ".png"){
$icon = #imagecreatefrompng($appIconURL);
}
}
if($icon){
//get icons original size...
list($width_orig, $height_orig) = #getimagesize($appIconURL);
if($width_orig > 0 && $height_orig > 0){
//create a few new sizes...
$sizes = array(36, 48, 57, 72);
//save them here...
$drawableFolders = array("drawable-ldpi", "drawable-mdpi", "drawable", "drawable-hdpi");
for($s = 0; $s < count($sizes); $s++){
$thisSize = $sizes[$s];
$width = $thisSize;
$height = $thisSize;
$ratio_orig = $width_orig / $height_orig;
if($width / $height > $ratio_orig){
$width = $height * $ratio_orig;
}else{
$height = $width / $ratio_orig;
}
//resample
$icon_scaled = #imagecreatetruecolor($width, $height);
#imagecopyresampled($icon_scaled, $icon, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
//output
#imagepng($icon_scaled, $rootFolder . "/res/" . $drawableFolders[$s] . "/icon.png");
}//end for each size
}//width / height
}//if icon...
/*
Android Activitites: The AndroidManifest.xml file has a line that reads:
<!-- replace this with list of activity includes -->
We'll end up replacing that line with a list of activity files included in
the project. It's important that each .java class in the Plugin be an Android Activity.
If another .java class is needed to support the plugin it needs to be a child-class
within the main activity class. In other words, it's assumed that all .java class
files found in the source-android folder are Android Activities.
*/
$activitiesList = "";
/*
Using Maps: The AndroidManifest.xml file has a line that reads:
<!-- <uses-library android:name="com.google.android.maps"/> -->
We'll end up replacing that line with an uncommented version like this:
<uses-library android:name="com.google.android.maps"/>
if the application is using a BT_screen_map plugin.
*/
$bolUsingMaps = false;
//process all the plugins...
$strSql = " SELECT webDirectoryName FROM " . TBL_BT_PLUGINS;
$res = fnDbGetResult($strSql, APP_DB_HOST, APP_DB_NAME, APP_DB_USER, APP_DB_PASS);
if($res){
while($row = mysql_fetch_array($res)){
$tmpPath = APP_PHYSICAL_PATH . APP_DATA_DIRECTORY . "/plugins" . $row["webDirectoryName"];
if(is_dir($tmpPath)){
if(is_readable($tmpPath)){
//look for source code...For Android we don't make any folder, we just copy the
//contents of the source-android to the appropriate directory in the Android project
$audioDir = $rootFolder . "/assets/BT_Audio";
$videoDir = $rootFolder . "/assets/BT_Video";
$docsDir = $rootFolder . "/assets/BT_Docs";
$srcDir = $rootFolder . "/src/com/" . str_replace("com.", "", $newPackageName);
$layoutDir = $rootFolder . "/res/layout";
$drawableDir = $rootFolder . "/res/drawable";
$androidFolder = $tmpPath . "/source-android";
if(is_dir($androidFolder)){
//copy every file in the /source-android folder to the proper Android folder...
if($handle = opendir($androidFolder)){
while(false !== ($file = readdir($handle))){
if(strlen($file) > 5){
if(is_file($androidFolder . "/" . $file)){
if($file != ".DS_Store" && $file != "__MACOSX"){
Thank you
You PHP code is too big for anyone here to read.
maybe you're doing it wrong from here:
// delete pdf...
if($fh = fopen($rootFolder . "instructions.pdf", 'w')){
fclose($fh);
unlink('instructions.pdf');
}
change it to (use file_exists as you don't need to read the file):
// delete pdf...
if(file_exists($rootFolder . "instructions.pdf"){
unlink($rootFolder . "instructions.pdf");
}
you should have permissions on that file.