// Import Field Types foreach ($json["components"]["field_types"] as $type) { if ($type) { sqlquery("DELETE FROM bigtree_field_types WHERE id = '" . sqlescape($type["id"]) . "'"); // Backwards compatibility with field types packaged for 4.1 if (!isset($type["use_cases"])) { $type["use_cases"] = array("templates" => $type["pages"], "modules" => $type["modules"], "callouts" => $type["callouts"], "settings" => $type["settings"]); } $use_cases = is_array($type["use_cases"]) ? sqlescape(json_encode($type["use_cases"])) : sqlescape($type["use_cases"]); $self_draw = $type["self_draw"] ? "'on'" : "NULL"; sqlquery("INSERT INTO bigtree_field_types (`id`,`name`,`use_cases`,`self_draw`) VALUES ('" . sqlescape($type["id"]) . "','" . sqlescape($type["name"]) . "','{$use_cases}',{$self_draw})"); } } // Import files foreach ($json["files"] as $file) { BigTree::copyFile(SERVER_ROOT . "cache/package/{$file}", SERVER_ROOT . $file); } // Run SQL foreach ($json["sql"] as $sql) { sqlquery($sql); } // Empty view cache sqlquery("DELETE FROM bigtree_module_view_cache"); // Remove the package directory, we do it backwards because the "deepest" files are last $contents = @array_reverse(BigTree::directoryContents(SERVER_ROOT . "cache/package/")); foreach ($contents as $file) { @unlink($file); @rmdir($file); } @rmdir(SERVER_ROOT . "cache/package/"); // Clear module class cache and field type cache.
static function processImageUpload($field) { global $bigtree; $failed = false; $name = $field["file_input"]["name"]; $temp_name = $field["file_input"]["tmp_name"]; $error = $field["file_input"]["error"]; // If a file upload error occurred, return the old image and set errors if ($error == 1 || $error == 2) { $bigtree["errors"][] = array("field" => $field["title"], "error" => "The file you uploaded ({$name}) was too large — <strong>Max file size: " . ini_get("upload_max_filesize") . "</strong>"); return false; } elseif ($error == 3) { $bigtree["errors"][] = array("field" => $field["title"], "error" => "The file upload failed ({$name})."); return false; } // We're going to tell BigTreeStorage to handle forcing images into JPEGs instead of writing the code 20x $storage = new BigTreeStorage(); $storage->AutoJPEG = $bigtree["config"]["image_force_jpeg"]; // Let's check the minimum requirements for the image first before we store it anywhere. $image_info = @getimagesize($temp_name); $iwidth = $image_info[0]; $iheight = $image_info[1]; $itype = $image_info[2]; $channels = $image_info["channels"]; // See if we're using image presets if ($field["options"]["preset"]) { $media_settings = BigTreeCMS::getSetting("bigtree-internal-media-settings"); $preset = $media_settings["presets"][$field["options"]["preset"]]; // If the preset still exists, copy its properties over to our options if ($preset) { foreach ($preset as $key => $val) { $field["options"][$key] = $val; } } } // If the minimum height or width is not meant, do NOT let the image through. Erase the change or update from the database. if (isset($field["options"]["min_height"]) && $iheight < $field["options"]["min_height"] || isset($field["options"]["min_width"]) && $iwidth < $field["options"]["min_width"]) { $error = "Image uploaded (" . htmlspecialchars($name) . ") did not meet the minimum size of "; if ($field["options"]["min_height"] && $field["options"]["min_width"]) { $error .= $field["options"]["min_width"] . "x" . $field["options"]["min_height"] . " pixels."; } elseif ($field["options"]["min_height"]) { $error .= $field["options"]["min_height"] . " pixels tall."; } elseif ($field["options"]["min_width"]) { $error .= $field["options"]["min_width"] . " pixels wide."; } $bigtree["errors"][] = array("field" => $field["title"], "error" => $error); $failed = true; } // If it's not a valid image, throw it out! if ($itype != IMAGETYPE_GIF && $itype != IMAGETYPE_JPEG && $itype != IMAGETYPE_PNG) { $bigtree["errors"][] = array("field" => $field["title"], "error" => "An invalid file was uploaded. Valid file types: JPG, GIF, PNG."); $failed = true; } // See if it's CMYK if ($channels == 4) { $bigtree["errors"][] = array("field" => $field["title"], "error" => "A CMYK encoded file was uploaded. Please upload an RBG image."); $failed = true; } // See if we have enough memory for all our crops and thumbnails if (!$failed && (is_array($field["options"]["crops"]) && count($field["options"]["crops"]) || is_array($field["options"]["thumbs"]) && count($field["options"]["thumbs"]))) { if (is_array($field["options"]["crops"])) { foreach ($field["options"]["crops"] as $crop) { if (!$failed && is_array($crop) && array_filter($crop)) { if ($field["options"]["retina"]) { $crop["width"] *= 2; $crop["height"] *= 2; } // We don't want to add multiple errors so we check if we've already failed if (!BigTree::imageManipulationMemoryAvailable($temp_name, $crop["width"], $crop["height"], $iwidth, $iheight)) { $bigtree["errors"][] = array("field" => $field["title"], "error" => "Image uploaded is too large for the server to manipulate. Please upload a smaller version of this image."); $failed = true; } } } } if (is_array($field["options"]["thumbs"])) { foreach ($field["options"]["thumbs"] as $thumb) { // We don't want to add multiple errors and we also don't want to waste effort getting thumbnail sizes if we already failed. if (!$failed && is_array($thumb) && array_filter($thumb)) { if ($field["options"]["retina"]) { $thumb["width"] *= 2; $thumb["height"] *= 2; } $sizes = BigTree::getThumbnailSizes($temp_name, $thumb["width"], $thumb["height"]); if (!BigTree::imageManipulationMemoryAvailable($temp_name, $sizes[3], $sizes[4], $iwidth, $iheight)) { $bigtree["errors"][] = array("field" => $field["title"], "error" => "Image uploaded is too large for the server to manipulate. Please upload a smaller version of this image."); $failed = true; } } } } if (is_array($field["options"]["center_crops"])) { foreach ($field["options"]["center_crops"] as $crop) { // We don't want to add multiple errors and we also don't want to waste effort getting thumbnail sizes if we already failed. if (!$failed && is_array($crop) && array_filter($crop)) { list($w, $h) = getimagesize($temp_name); if (!BigTree::imageManipulationMemoryAvailable($temp_name, $w, $h, $crop["width"], $crop["height"])) { $bigtree["errors"][] = array("field" => $field["title"], "error" => "Image uploaded is too large for the server to manipulate. Please upload a smaller version of this image."); $failed = true; } } } } } if (!$failed) { // Make a temporary copy to be used for thumbnails and crops. $itype_exts = array(IMAGETYPE_PNG => ".png", IMAGETYPE_JPEG => ".jpg", IMAGETYPE_GIF => ".gif"); // Make a first copy $first_copy = SITE_ROOT . "files/" . uniqid("temp-") . $itype_exts[$itype]; BigTree::moveFile($temp_name, $first_copy); // Do EXIF Image Rotation if ($itype == IMAGETYPE_JPEG && function_exists("exif_read_data")) { $exif = @exif_read_data($first_copy); $o = $exif['Orientation']; if ($o == 3 || $o == 6 || $o == 8) { $source = imagecreatefromjpeg($first_copy); if ($o == 3) { $source = imagerotate($source, 180, 0); } elseif ($o == 6) { $source = imagerotate($source, 270, 0); } else { $source = imagerotate($source, 90, 0); } // We're going to create a PNG so that we don't lose quality when we resave imagepng($source, $first_copy); rename($first_copy, substr($first_copy, 0, -3) . "png"); $first_copy = substr($first_copy, 0, -3) . "png"; // Force JPEG since we made the first copy a PNG $storage->AutoJPEG = true; // Clean up memory imagedestroy($source); // Get new width/height/type list($iwidth, $iheight, $itype, $iattr) = getimagesize($first_copy); } } // Create a temporary copy that we will use later for crops and thumbnails $temp_copy = SITE_ROOT . "files/" . uniqid("temp-") . $itype_exts[$itype]; BigTree::copyFile($first_copy, $temp_copy); // Gather up an array of file prefixes $prefixes = array(); if (is_array($field["options"]["thumbs"])) { foreach ($field["options"]["thumbs"] as $thumb) { if (!empty($thumb["prefix"])) { $prefixes[] = $thumb["prefix"]; } } } if (is_array($field["options"]["center_crops"])) { foreach ($field["options"]["center_crops"] as $crop) { if (!empty($crop["prefix"])) { $prefixes[] = $crop["prefix"]; } } } if (is_array($field["options"]["crops"])) { foreach ($field["options"]["crops"] as $crop) { if (is_array($crop)) { if (!empty($crop["prefix"])) { $prefixes[] = $crop["prefix"]; } if (is_array($crop["thumbs"])) { foreach ($crop["thumbs"] as $thumb) { if (!empty($thumb["prefix"])) { $prefixes[] = $thumb["prefix"]; } } } if (is_array($crop["center_crops"])) { foreach ($crop["center_crops"] as $center_crop) { if (!empty($center_crop["prefix"])) { $prefixes[] = $center_crop["prefix"]; } } } } } } // Upload the original to the proper place. $field["output"] = $storage->store($first_copy, $name, $field["options"]["directory"], true, $prefixes); // If the upload service didn't return a value, we failed to upload it for one reason or another. if (!$field["output"]) { if ($storage->DisabledFileError) { $bigtree["errors"][] = array("field" => $field["title"], "error" => "Could not upload file. The file extension is not allowed."); } else { $bigtree["errors"][] = array("field" => $field["title"], "error" => "Could not upload file. The destination is not writable."); } unlink($temp_copy); unlink($first_copy); // Failed, we keep the current value return false; // If we did upload it successfully, check on thumbs and crops. } else { // Get path info on the file. $pinfo = BigTree::pathInfo($field["output"]); // Handle Crops if (is_array($field["options"]["crops"])) { foreach ($field["options"]["crops"] as $crop) { if (is_array($crop)) { // Make sure the crops have a width/height and it's numeric if ($crop["width"] && $crop["height"] && is_numeric($crop["width"]) && is_numeric($crop["height"])) { $cwidth = $crop["width"]; $cheight = $crop["height"]; // Check to make sure each dimension is greater then or equal to, but not both equal to the crop. if ($iheight >= $cheight && $iwidth > $cwidth || $iwidth >= $cwidth && $iheight > $cheight) { // Make a square if for some reason someone only entered one dimension for a crop. if (!$cwidth) { $cwidth = $cheight; } elseif (!$cheight) { $cheight = $cwidth; } $bigtree["crops"][] = array("image" => $temp_copy, "directory" => $field["options"]["directory"], "retina" => $field["options"]["retina"], "name" => $pinfo["basename"], "width" => $cwidth, "height" => $cheight, "prefix" => $crop["prefix"], "thumbs" => $crop["thumbs"], "center_crops" => $crop["center_crops"], "grayscale" => $crop["grayscale"]); // If it's the same dimensions, let's see if they're looking for a prefix for whatever reason... } elseif ($iheight == $cheight && $iwidth == $cwidth) { // See if we want thumbnails if (is_array($crop["thumbs"])) { foreach ($crop["thumbs"] as $thumb) { // Make sure the thumbnail has a width or height and it's numeric if ($thumb["width"] && is_numeric($thumb["width"]) || $thumb["height"] && is_numeric($thumb["height"])) { // Create a temporary thumbnail of the image on the server before moving it to it's destination. $temp_thumb = SITE_ROOT . "files/" . uniqid("temp-") . $itype_exts[$itype]; BigTree::createThumbnail($temp_copy, $temp_thumb, $thumb["width"], $thumb["height"], $field["options"]["retina"], $thumb["grayscale"]); // We use replace here instead of upload because we want to be 100% sure that this file name doesn't change. $storage->replace($temp_thumb, $thumb["prefix"] . $pinfo["basename"], $field["options"]["directory"]); } } } // See if we want center crops if (is_array($crop["center_crops"])) { foreach ($crop["center_crops"] as $center_crop) { // Make sure the crop has a width and height and it's numeric if ($center_crop["width"] && is_numeric($center_crop["width"]) && $center_crop["height"] && is_numeric($center_crop["height"])) { // Create a temporary crop of the image on the server before moving it to it's destination. $temp_crop = SITE_ROOT . "files/" . uniqid("temp-") . $itype_exts[$itype]; BigTree::centerCrop($temp_copy, $temp_crop, $center_crop["width"], $center_crop["height"], $field["options"]["retina"], $center_crop["grayscale"]); // We use replace here instead of upload because we want to be 100% sure that this file name doesn't change. $storage->replace($temp_crop, $center_crop["prefix"] . $pinfo["basename"], $field["options"]["directory"]); } } } $storage->store($temp_copy, $crop["prefix"] . $pinfo["basename"], $field["options"]["directory"], false); } } } } } // Handle thumbnailing if (is_array($field["options"]["thumbs"])) { foreach ($field["options"]["thumbs"] as $thumb) { // Make sure the thumbnail has a width or height and it's numeric if ($thumb["width"] && is_numeric($thumb["width"]) || $thumb["height"] && is_numeric($thumb["height"])) { $temp_thumb = SITE_ROOT . "files/" . uniqid("temp-") . $itype_exts[$itype]; BigTree::createThumbnail($temp_copy, $temp_thumb, $thumb["width"], $thumb["height"], $field["options"]["retina"], $thumb["grayscale"]); // We use replace here instead of upload because we want to be 100% sure that this file name doesn't change. $storage->replace($temp_thumb, $thumb["prefix"] . $pinfo["basename"], $field["options"]["directory"]); } } } // Handle center crops if (is_array($field["options"]["center_crops"])) { foreach ($field["options"]["center_crops"] as $crop) { // Make sure the crop has a width and height and it's numeric if ($crop["width"] && is_numeric($crop["width"]) && $crop["height"] && is_numeric($crop["height"])) { $temp_crop = SITE_ROOT . "files/" . uniqid("temp-") . $itype_exts[$itype]; BigTree::centerCrop($temp_copy, $temp_crop, $crop["width"], $crop["height"], $field["options"]["retina"], $crop["grayscale"]); // We use replace here instead of upload because we want to be 100% sure that this file name doesn't change. $storage->replace($temp_crop, $crop["prefix"] . $pinfo["basename"], $field["options"]["directory"]); } } } // If we don't have any crops, get rid of the temporary image we made. if (!count($bigtree["crops"])) { unlink($temp_copy); } } // We failed, keep the current value. } else { return false; } return $field["output"]; }
} elseif (substr($file, 0, 20) == "custom/admin/images/") { $d = "images/" . substr($file, 20); } elseif (substr($file, 0, 21) == "custom/admin/modules/") { $d = "modules/" . substr($file, 21); } elseif (substr($file, 0, 19) == "custom/inc/modules/") { $d = "classes/" . substr($file, 19); } elseif (substr($file, 0, 10) == "templates/") { $d = $file; } elseif (substr($file, 0, 5) == "site/") { // Already in the proper directory, should be copied to public, not moved if (strpos($file, "site/extensions/{$id}/") === 0) { BigTree::copyFile(SERVER_ROOT . $file, SERVER_ROOT . "extensions/{$id}/public/" . str_replace("site/extensions/{$id}/", "", $file)); // Move into the site/extensions/ folder and then copy into /public/ } else { BigTree::moveFile(SERVER_ROOT . $file, SITE_ROOT . "extensions/{$id}/" . substr($file, 5)); BigTree::copyFile(SITE_ROOT . "extensions/{$id}/" . substr($file, 5), SERVER_ROOT . "extensions/{$id}/public/" . substr($file, 5)); } } // If we have a place to move it to, move it. if ($d) { BigTree::moveFile(SERVER_ROOT . $file, SERVER_ROOT . "extensions/{$id}/" . $d); } } } // If this package already exists, we need to do a diff of the tables, increment revision numbers, and add SQL statements. $existing = sqlfetch(sqlquery("SELECT * FROM bigtree_extensions WHERE id = '" . sqlescape($id) . "' AND type = 'extension'")); if ($existing) { $existing_json = json_decode($existing["manifest"], true); // Increment revision numbers $revision = $package["revision"] = intval($existing_json["revision"]) + 1; $package["sql_revisions"] = (array) $existing_json["sql_revisions"];
function store($local_file, $file_name, $relative_path, $remove_original = true, $prefixes = array()) { // If the file name ends in a disabled extension, fail. if (preg_match($this->DisabledExtensionRegEx, $file_name)) { $this->DisabledFileError = true; return false; } // If we're auto converting images to JPG from PNG $file_name = $this->convertJPEG($local_file, $file_name); // Enforce trailing slashe on relative_path $relative_path = $relative_path ? rtrim($relative_path, "/") . "/" : "files/"; if ($this->Cloud) { // Clean up the file name global $cms; $parts = BigTree::pathInfo($file_name); $clean_name = $cms->urlify($parts["filename"]); if (strlen($clean_name) > 50) { $clean_name = substr($clean_name, 0, 50); } // Best case name $file_name = $clean_name . "." . strtolower($parts["extension"]); $x = 2; // Make sure we have a unique name while (!$file_name || sqlrows(sqlquery("SELECT `timestamp` FROM bigtree_caches WHERE `identifier` = 'org.bigtreecms.cloudfiles' AND `key` = '" . sqlescape($relative_path . $file_name) . "'"))) { $file_name = $clean_name . "-{$x}." . strtolower($parts["extension"]); $x++; // Check all the prefixes, make sure they don't exist either if (is_array($prefixes) && count($prefixes)) { $prefix_query = array(); foreach ($prefixes as $prefix) { $prefix_query[] = "`key` = '" . sqlescape($relative_path . $prefix . $file_name) . "'"; } if (sqlrows(sqlquery("SELECT `timestamp` FROM bigtree_caches WHERE identifier = 'org.bigtreecms.cloudfiles' AND (" . implode(" OR ", $prefix_query) . ")"))) { $file_name = false; } } } // Upload it $success = $this->Cloud->uploadFile($local_file, $this->Settings->Container, $relative_path . $file_name, true); if ($success) { sqlquery("INSERT INTO bigtree_caches (`identifier`,`key`,`value`) VALUES ('org.bigtreecms.cloudfiles','" . sqlescape($relative_path . $file_name) . "','" . sqlescape(json_encode(array("name" => $file_name, "path" => $relative_path . $file_name, "size" => filesize($local_file)))) . "')"); } if ($remove_original) { unlink($local_file); } return $success; } else { $safe_name = BigTree::getAvailableFileName(SITE_ROOT . $relative_path, $file_name, $prefixes); if ($remove_original) { $success = BigTree::moveFile($local_file, SITE_ROOT . $relative_path . $safe_name); } else { $success = BigTree::copyFile($local_file, SITE_ROOT . $relative_path . $safe_name); } if ($success) { return "{staticroot}" . $relative_path . $safe_name; } else { return false; } } }
$photo_gallery = array(); if (is_array($field["input"])) { foreach ($field["input"] as $photo_count => $data) { // Existing Data if ($data["image"]) { $data["caption"] = BigTree::safeEncode($data["caption"]); $photo_gallery[] = $data; // Uploaded File } elseif ($field["file_input"][$photo_count]["image"]["name"]) { $field_copy = $field; $field_copy["file_input"] = $field["file_input"][$photo_count]["image"]; $file = $admin->processImageUpload($field_copy); if ($file) { $photo_gallery[] = array("caption" => BigTree::safeEncode($data["caption"]), "image" => $file); } // File From Image Manager } elseif ($data["existing"]) { $data["existing"] = str_replace(WWW_ROOT, SITE_ROOT, $data["existing"]); $pinfo = BigTree::pathInfo($data["existing"]); $field_copy = $field; $field_copy["file_input"] = array("name" => $pinfo["basename"], "tmp_name" => SITE_ROOT . "files/" . uniqid("temp-") . ".img", "error" => false); BigTree::copyFile($data["existing"], $field_copy["file_input"]["tmp_name"]); $file = $admin->processImageUpload($field_copy); if ($file) { $photo_gallery[] = array("caption" => BigTree::safeEncode($data["caption"]), "image" => $file); } } } } $field["output"] = $photo_gallery;
} else { $bigtree["errors"][] = array("field" => $field["options"]["title"], "error" => "Could not upload file. The destination is not writable."); } } } else { $field["output"] = $field["input"]; } // We're processing an image. } else { // We uploaded a new image. if (is_uploaded_file($field["file_input"]["tmp_name"])) { $file = $admin->processImageUpload($field); $field["output"] = $file ? $file : $field["input"]; // Using an existing image or one from the Image Browser } else { $field["output"] = $field["input"]; // We're trying to use an image from the Image Browser. if (substr($field["output"], 0, 11) == "resource://") { // It's technically a new file now, but we pulled it from resources so we might need to crop it. $resource = $admin->getResourceByFile(str_replace(array(STATIC_ROOT, WWW_ROOT), array("{staticroot}", "{wwwroot}"), substr($field["output"], 11))); $resource_location = str_replace(array("{wwwroot}", WWW_ROOT, "{staticroot}", STATIC_ROOT), SITE_ROOT, $resource["file"]); $pinfo = BigTree::pathInfo($resource_location); // Emulate a newly uploaded file $field["file_input"] = array("name" => $pinfo["basename"], "tmp_name" => SITE_ROOT . "files/" . uniqid("temp-") . ".img", "error" => false); BigTree::copyFile($resource_location, $field["file_input"]["tmp_name"]); $file = $admin->processImageUpload($field); $field["output"] = $file ? $file : $field["input"]; } } } }