public static function backup($destination = null, callable $messager = null) { if (!$destination) { $destination = self::getGrav()['locator']->findResource('backup://', true); if (!$destination) { throw new \RuntimeException('The backup folder is missing.'); } Folder::mkdir($destination); } $name = self::getGrav()['config']->get('site.title', basename(GRAV_ROOT)); $inflector = new Inflector(); if (is_dir($destination)) { $date = date('YmdHis', time()); $filename = trim($inflector->hyphenize($name), '-') . '-' . $date . '.zip'; $destination = rtrim($destination, DS) . DS . $filename; } $messager && $messager(['type' => 'message', 'level' => 'info', 'message' => 'Creating new Backup "' . $destination . '"']); $messager && $messager(['type' => 'message', 'level' => 'info', 'message' => '']); $zip = new \ZipArchive(); $zip->open($destination, \ZipArchive::CREATE); $max_execution_time = ini_set('max_execution_time', 600); static::folderToZip(GRAV_ROOT, $zip, strlen(rtrim(GRAV_ROOT, DS) . DS), $messager); $messager && $messager(['type' => 'progress', 'percentage' => false, 'complete' => true]); $messager && $messager(['type' => 'message', 'level' => 'info', 'message' => '']); $messager && $messager(['type' => 'message', 'level' => 'info', 'message' => 'Saving and compressing archive...']); $zip->close(); if ($max_execution_time !== false) { ini_set('max_execution_time', $max_execution_time); } return $destination; }
/** * Installs a given package to a given destination. * * @param string $package The local path to the ZIP package * @param string $destination The local path to the Grav Instance * @param array $options Options to use for installing. ie, ['install_path' => 'user/themes/antimatter'] * * @return boolean True if everything went fine, False otherwise. */ public static function install($package, $destination, $options = []) { $destination = rtrim($destination, DS); $options = array_merge(self::$options, $options); $install_path = rtrim($destination . DS . ltrim($options['install_path'], DS), DS); if (!self::isGravInstance($destination) || !self::isValidDestination($install_path, $options['exclude_checks'])) { return false; } if (self::lastErrorCode() == self::IS_LINK && $options['ignore_symlinks'] || self::lastErrorCode() == self::EXISTS && !$options['overwrite']) { return false; } $zip = new \ZipArchive(); $archive = $zip->open($package); $tmp = CACHE_DIR . DS . 'tmp/Grav-' . uniqid(); if ($archive !== true) { self::$error = self::ZIP_OPEN_ERROR; return false; } Folder::mkdir($tmp); $unzip = $zip->extractTo($tmp); if (!$unzip) { self::$error = self::ZIP_EXTRACT_ERROR; $zip->close(); Folder::delete($tmp); return false; } if (!$options['sophisticated']) { self::nonSophisticatedInstall($zip, $install_path, $tmp); } else { self::sophisticatedInstall($zip, $install_path, $tmp); } Folder::delete($tmp); $zip->close(); self::$error = self::OK; return true; }
/** * @param $package * * @return string */ private function downloadPackage($package) { $this->tmp = CACHE_DIR . DS . 'tmp/Grav-' . uniqid(); $filename = $package->slug . basename($package->zipball_url); $output = Response::get($package->zipball_url, [], [$this, 'progress']); Folder::mkdir($this->tmp); $this->output->write("\r"); $this->output->write(" |- Downloading package... 100%"); $this->output->writeln(''); file_put_contents($this->tmp . DS . $filename, $output); return $this->tmp . DS . $filename; }
private static function download($package) { $contents = Response::get($package->zipball_url, []); $cache_dir = self::getGrav()['locator']->findResource('cache://', true); $cache_dir = $cache_dir . DS . 'tmp/Grav-' . uniqid(); Folder::mkdir($cache_dir); $filename = $package->slug . basename($package->zipball_url); file_put_contents($cache_dir . DS . $filename, $contents); return $cache_dir . DS . $filename; }
private function cleanFilesData($key, $file) { $config = $this->grav['config']; $blueprint = isset($this->items['fields'][$key]['files']) ? $this->items['fields'][$key]['files'] : []; /** @var Page $page */ $page = null; $cleanFiles[$key] = []; if (!isset($blueprint)) { return false; } $type = trim("{$this->view}/{$this->admin->route}", '/'); $data = $this->admin->data($type, $this->post); $fields = $data->blueprints()->fields(); $blueprint = isset($fields[$key]) ? $fields[$key] : []; $cleanFiles = [$key => []]; foreach ((array) $file['error'] as $index => $error) { if ($error == UPLOAD_ERR_OK) { $tmp_name = $file['tmp_name'][$index]; $name = $file['name'][$index]; $type = $file['type'][$index]; $destination = Folder::getRelativePath(rtrim($blueprint['destination'], '/')); if (!$this->match_in_array($type, $blueprint['accept'])) { throw new \RuntimeException('File "' . $name . '" is not an accepted MIME type.'); } if (Utils::startsWith($destination, '@page:')) { $parts = explode(':', $destination); $route = $parts[1]; $page = $this->grav['page']->find($route); if (!$page) { throw new \RuntimeException('Unable to upload file to destination. Page route not found.'); } $destination = $page->relativePagePath(); } else { if ($destination == '@self') { $page = $this->admin->page(true); $destination = $page->relativePagePath(); } else { Folder::mkdir($destination); } } if (move_uploaded_file($tmp_name, "{$destination}/{$name}")) { $path = $page ? $this->grav['uri']->convertUrl($page, $page->route() . '/' . $name) : $destination . '/' . $name; $cleanFiles[$key][] = $path; } else { throw new \RuntimeException("Unable to upload file(s) to {$destination}/{$name}"); } } } return $cleanFiles[$key]; }
private function cleanFilesData($key, $file) { /** @var Page $page */ $page = null; $blueprint = $this->items['fields'][$key]['files']; $cleanFiles[$key] = []; if (!isset($blueprint)) { return false; } $cleanFiles = [$key => []]; foreach ((array) $file['error'] as $index => $error) { if ($error == UPLOAD_ERR_OK) { $tmp_name = $file['tmp_name'][$index]; $name = $file['name'][$index]; $type = $file['type'][$index]; $destination = Folder::getRelativePath(rtrim($blueprint['destination'], '/')); if (!$this->match_in_array($type, $blueprint['accept'])) { throw new \RuntimeException('File "' . $name . '" is not an accepted MIME type.'); } if (Utils::startsWith($destination, '@page:')) { $parts = explode(':', $destination); $route = $parts[1]; $page = self::getGrav()['page']->find($route); if (!$page) { throw new \RuntimeException('Unable to upload file to destination. Page route not found.'); } $destination = $page->relativePagePath(); } else { if ($destination == '@self') { $page = self::getGrav()['page']; $destination = $page->relativePagePath(); } else { Folder::mkdir($destination); } } if (move_uploaded_file($tmp_name, "{$destination}/{$name}")) { $path = $page ? self::getGrav()['uri']->convertUrl($page, $page->route() . '/' . $name) : $destination . '/' . $name; $cleanFiles[$key][$path] = ['name' => $file['name'][$index], 'type' => $file['type'][$index], 'size' => $file['size'][$index], 'file' => $destination . '/' . $name, 'route' => $page ? $path : null]; } else { throw new \RuntimeException('Unable to upload file(s). Error Code: ' . $error); } } } return $cleanFiles[$key]; }
private function getFilesOrderedByModifiedDate($path = '') { $files = []; if (!$path) { $path = DATA_DIR . 'comments'; } if (!file_exists($path)) { Folder::mkdir($path); } $dirItr = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS); $filterItr = new RecursiveFolderFilterIterator($dirItr); $itr = new \RecursiveIteratorIterator($filterItr, \RecursiveIteratorIterator::SELF_FIRST); $itrItr = new \RecursiveIteratorIterator($dirItr, \RecursiveIteratorIterator::SELF_FIRST); $filesItr = new \RegexIterator($itrItr, '/^.+\\.yaml$/i'); // Collect files if modified in the last 7 days foreach ($filesItr as $filepath => $file) { $modifiedDate = $file->getMTime(); $sevenDaysAgo = time() - 7 * 24 * 60 * 60; if ($modifiedDate < $sevenDaysAgo) { continue; } $files[] = (object) array("modifiedDate" => $modifiedDate, "fileName" => $file->getFilename(), "filePath" => $filepath, "data" => Yaml::parse(file_get_contents($filepath))); } // Traverse folders and recurse foreach ($itr as $file) { if ($file->isDir()) { $this->getFilesOrderedByModifiedDate($file->getPath() . '/' . $file->getFilename()); } } // Order files by last modified date usort($files, function ($a, $b) { return !($a->modifiedDate > $b->modifiedDate); }); return $files; }
/** * Recursive copy of one directory to another * * @param $src * @param $dest * * @return bool */ public static function rcopy($src, $dest) { // If the src is not a directory do a simple file copy if (!is_dir($src)) { copy($src, $dest); return true; } // If the destination directory does not exist create it if (!is_dir($dest)) { Folder::mkdir($dest); } // Open the source directory to read in files $i = new \DirectoryIterator($src); /** @var \DirectoryIterator $f */ foreach ($i as $f) { if ($f->isFile()) { copy($f->getRealPath(), "{$dest}/" . $f->getFilename()); } else { if (!$f->isDot() && $f->isDir()) { static::rcopy($f->getRealPath(), "{$dest}/{$f}"); } } } return true; }
/** * @param $package * * @return string */ private function download($package) { $this->tmp = CACHE_DIR . DS . 'tmp/Grav-' . uniqid(); $output = Response::get($package['download'], [], [$this, 'progress']); Folder::mkdir($this->tmp); $this->output->write("\r"); $this->output->write(" |- Downloading upgrade [" . $this->formatBytes($package['size']) . "]... 100%"); $this->output->writeln(''); file_put_contents($this->tmp . DS . $package['name'], $output); return $this->tmp . DS . $package['name']; }
/** * @param $package * * @return string */ private function download($package) { $cache_dir = Grav::instance()['locator']->findResource('cache://', true); $this->tmp = $cache_dir . DS . 'tmp/Grav-' . uniqid(); $output = Response::get($package['download'], [], [$this, 'progress']); Folder::mkdir($this->tmp); $this->output->write("\r"); $this->output->write(" |- Downloading upgrade [" . $this->formatBytes($package['size']) . "]... 100%"); $this->output->writeln(''); file_put_contents($this->tmp . DS . $package['name'], $output); return $this->tmp . DS . $package['name']; }
/** * Handles ajax upload for files. * Stores in a flash object the temporary file and deals with potential file errors. * * @return mixed True if the action was performed. */ public function uploadFiles() { $post = $_POST; $grav = Grav::instance(); $uri = $grav['uri']->url; $config = $grav['config']; $session = $grav['session']; $settings = $this->data->blueprints()->schema()->getProperty($post['name']); $settings = (object) array_merge(['destination' => $config->get('plugins.form.files.destination', 'self@'), 'avoid_overwriting' => $config->get('plugins.form.files.avoid_overwriting', false), 'random_name' => $config->get('plugins.form.files.random_name', false), 'accept' => $config->get('plugins.form.files.accept', ['image/*']), 'limit' => $config->get('plugins.form.files.limit', 10), 'filesize' => $config->get('plugins.form.files.filesize', 5242880)], (array) $settings, ['name' => $post['name']]); $upload = $this->normalizeFiles($_FILES['data'], $settings->name); // Handle errors and breaks without proceeding further if ($upload->file->error != UPLOAD_ERR_OK) { // json_response return ['status' => 'error', 'message' => sprintf($grav['language']->translate('PLUGIN_FORM.FILEUPLOAD_UNABLE_TO_UPLOAD', null, true), $upload->file->name, $this->upload_errors[$upload->file->error])]; } else { // Remove the error object to avoid storing it unset($upload->file->error); // we need to move the file at this stage or else // it won't be available upon save later on // since php removes it from the upload location $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); $tmp_file = $upload->file->tmp_name; $tmp = $tmp_dir . '/uploaded-files/' . basename($tmp_file); Folder::create(dirname($tmp)); if (!move_uploaded_file($tmp_file, $tmp)) { // json_response return ['status' => 'error', 'message' => sprintf($grav['language']->translate('PLUGIN_FORM.FILEUPLOAD_UNABLE_TO_MOVE', null, true), '', $tmp)]; } $upload->file->tmp_name = $tmp; } // Handle file size limits $settings->filesize *= 1048576; // 2^20 [MB in Bytes] if ($settings->filesize > 0 && $upload->file->size > $settings->filesize) { // json_response return ['status' => 'error', 'message' => $grav['language']->translate('PLUGIN_FORM.EXCEEDED_GRAV_FILESIZE_LIMIT')]; } // Handle Accepted file types // Accept can only be mime types (image/png | image/*) or file extensions (.pdf|.jpg) $accepted = false; $errors = []; foreach ((array) $settings->accept as $type) { // Force acceptance of any file when star notation if ($type == '*') { $accepted = true; break; } $isMime = strstr($type, '/'); $find = str_replace('*', '.*', $type); $match = preg_match('#' . $find . '$#', $isMime ? $upload->file->type : $upload->file->name); if (!$match) { $message = $isMime ? 'The MIME type "' . $upload->file->type . '"' : 'The File Extension'; $errors[] = $message . ' for the file "' . $upload->file->name . '" is not an accepted.'; $accepted |= false; } else { $accepted |= true; } } if (!$accepted) { // json_response return ['status' => 'error', 'message' => implode('<br />', $errors)]; } // Retrieve the current session of the uploaded files for the field // and initialize it if it doesn't exist $sessionField = base64_encode($uri); $flash = $session->getFlashObject('files-upload'); if (!$flash) { $flash = []; } if (!isset($flash[$sessionField])) { $flash[$sessionField] = []; } if (!isset($flash[$sessionField][$upload->field])) { $flash[$sessionField][$upload->field] = []; } // Set destination $destination = Folder::getRelativePath(rtrim($settings->destination, '/')); $destination = $this->getPagePathFromToken($destination); // Create destination if needed if (!is_dir($destination)) { Folder::mkdir($destination); } // Generate random name if required if ($settings->random_name) { $extension = pathinfo($upload->file->name)['extension']; $upload->file->name = Utils::generateRandomString(15) . '.' . $extension; } // Handle conflicting name if needed if ($settings->avoid_overwriting) { if (file_exists($destination . '/' . $upload->file->name)) { $upload->file->name = date('YmdHis') . '-' . $upload->file->name; } } // Prepare object for later save $path = $destination . '/' . $upload->file->name; $upload->file->path = $path; // $upload->file->route = $page ? $path : null; // Prepare data to be saved later $flash[$sessionField][$upload->field][$path] = (array) $upload->file; // Finally store the new uploaded file in the field session $session->setFlashObject('files-upload', $flash); // json_response return ['status' => 'success', 'session' => \json_encode(['sessionField' => base64_encode($uri), 'path' => $upload->file->path, 'field' => $settings->name])]; }
/** * Copy the local zip package to tmp * * @param $package_file * @param $tmp * @return null|string */ private function copyPackage($package_file, $tmp) { $this->output->write(" |- Copying package... 0%"); $package_file = realpath($package_file); if (file_exists($package_file)) { $filename = basename($package_file); Folder::mkdir($tmp); $this->output->write("\r"); $this->output->write(" |- Copying package... 100%"); $this->output->writeln(''); copy(realpath($package_file), $tmp . DS . $filename); return $tmp . DS . $filename; } return null; }
/** * Handles ajax upload for files. * Stores in a flash object the temporary file and deals with potential file errors. * * @return bool True if the action was performed. */ public function taskFilesUpload() { if (!$this->authorizeTask('save', $this->dataPermissions()) || !isset($_FILES)) { return false; } /** @var Config $config */ $config = $this->grav['config']; $data = $this->view == 'pages' ? $this->admin->page(true) : $this->prepareData([]); $settings = $data->blueprints()->schema()->getProperty($this->post['name']); $settings = (object) array_merge(['avoid_overwriting' => false, 'random_name' => false, 'accept' => ['image/*'], 'limit' => 10, 'filesize' => $config->get('system.media.upload_limit', 5242880)], (array) $settings, ['name' => $this->post['name']]); $upload = $this->normalizeFiles($_FILES['data'], $settings->name); if (!isset($settings->destination)) { $this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.DESTINATION_NOT_SPECIFIED', null, true)]; return false; } // Do not use self@ outside of pages if ($this->view != 'pages' && in_array($settings->destination, ['@self', 'self@'])) { $this->admin->json_response = ['status' => 'error', 'message' => sprintf($this->admin->translate('PLUGIN_ADMIN.FILEUPLOAD_PREVENT_SELF', null, true), $settings->destination)]; return false; } // Handle errors and breaks without proceeding further if ($upload->file->error != UPLOAD_ERR_OK) { $this->admin->json_response = ['status' => 'error', 'message' => sprintf($this->admin->translate('PLUGIN_ADMIN.FILEUPLOAD_UNABLE_TO_UPLOAD', null, true), $upload->file->name, $this->upload_errors[$upload->file->error])]; return false; } else { // Remove the error object to avoid storing it unset($upload->file->error); // we need to move the file at this stage or else // it won't be available upon save later on // since php removes it from the upload location $tmp_dir = Admin::getTempDir(); $tmp_file = $upload->file->tmp_name; $tmp = $tmp_dir . '/uploaded-files/' . basename($tmp_file); Folder::create(dirname($tmp)); if (!move_uploaded_file($tmp_file, $tmp)) { $this->admin->json_response = ['status' => 'error', 'message' => sprintf($this->admin->translate('PLUGIN_ADMIN.FILEUPLOAD_UNABLE_TO_MOVE', null, true), '', $tmp)]; return false; } $upload->file->tmp_name = $tmp; } // Handle file size limits $settings->filesize *= 1048576; // 2^20 [MB in Bytes] if ($settings->filesize > 0 && $upload->file->size > $settings->filesize) { $this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.EXCEEDED_GRAV_FILESIZE_LIMIT')]; return false; } // Handle Accepted file types // Accept can only be mime types (image/png | image/*) or file extensions (.pdf|.jpg) $accepted = false; $errors = []; foreach ((array) $settings->accept as $type) { // Force acceptance of any file when star notation if ($type == '*') { $accepted = true; break; } $isMime = strstr($type, '/'); $find = str_replace('*', '.*', $type); $match = preg_match('#' . $find . '$#', $isMime ? $upload->file->type : $upload->file->name); if (!$match) { $message = $isMime ? 'The MIME type "' . $upload->file->type . '"' : 'The File Extension'; $errors[] = $message . ' for the file "' . $upload->file->name . '" is not an accepted.'; $accepted |= false; } else { $accepted |= true; } } if (!$accepted) { $this->admin->json_response = ['status' => 'error', 'message' => implode('<br />', $errors)]; return false; } // Retrieve the current session of the uploaded files for the field // and initialize it if it doesn't exist $sessionField = base64_encode($this->uri); $flash = $this->admin->session()->getFlashObject('files-upload'); if (!$flash) { $flash = []; } if (!isset($flash[$sessionField])) { $flash[$sessionField] = []; } if (!isset($flash[$sessionField][$upload->field])) { $flash[$sessionField][$upload->field] = []; } // Set destination $destination = Folder::getRelativePath(rtrim($settings->destination, '/')); $destination = $this->admin->getPagePathFromToken($destination); // Create destination if needed if (!is_dir($destination)) { Folder::mkdir($destination); } // Generate random name if required if ($settings->random_name) { // TODO: document $extension = pathinfo($upload->file->name)['extension']; $upload->file->name = Utils::generateRandomString(15) . '.' . $extension; } // Handle conflicting name if needed if ($settings->avoid_overwriting) { // TODO: document if (file_exists($destination . '/' . $upload->file->name)) { $upload->file->name = date('YmdHis') . '-' . $upload->file->name; } } // Prepare object for later save $path = $destination . '/' . $upload->file->name; $upload->file->path = $path; // $upload->file->route = $page ? $path : null; // Prepare data to be saved later $flash[$sessionField][$upload->field][$path] = (array) $upload->file; // Finally store the new uploaded file in the field session $this->admin->session()->setFlashObject('files-upload', $flash); $this->admin->json_response = ['status' => 'success', 'session' => \json_encode(['sessionField' => base64_encode($this->uri), 'path' => $upload->file->path, 'field' => $settings->name])]; return true; }
/** * Unzip a file to somewhere * * @param $zip_file * @param $destination * @return bool|string */ public static function unZip($zip_file, $destination) { $zip = new \ZipArchive(); $archive = $zip->open($zip_file); if ($archive === true) { Folder::mkdir($destination); $unzip = $zip->extractTo($destination); if (!$unzip) { self::$error = self::ZIP_EXTRACT_ERROR; Folder::delete($destination); $zip->close(); return false; } $package_folder_name = $zip->getNameIndex(0); $zip->close(); $extracted_folder = $destination . '/' . $package_folder_name; return $extracted_folder; } self::$error = self::ZIP_EXTRACT_ERROR; return false; }
/** * @param Package $package * * @return string */ private function downloadPackage($package) { $cache_dir = Grav::instance()['locator']->findResource('cache://', true); $this->tmp = $cache_dir . DS . 'tmp/Grav-' . uniqid(); $filename = $package->slug . basename($package->zipball_url); $output = Response::get($package->zipball_url, [], [$this, 'progress']); Folder::mkdir($this->tmp); $this->output->write("\r"); $this->output->write(" |- Downloading package... 100%"); $this->output->writeln(''); file_put_contents($this->tmp . DS . $filename, $output); return $this->tmp . DS . $filename; }
/** * Handles creating an empty page folder (without markdown file) * * @return bool True if the action was performed. */ public function taskSaveNewFolder() { if (!$this->authorizeTask('save', $this->dataPermissions())) { return; } $data = $this->post; if ($data['route'] == '/') { $path = $this->grav['locator']->findResource('page://'); } else { $path = $page = $this->grav['page']->find($data['route'])->path(); } $files = Folder::all($path, ['recursive' => false]); $highestOrder = 0; foreach ($files as $file) { preg_match(PAGE_ORDER_PREFIX_REGEX, $file, $order); if (isset($order[0])) { $theOrder = intval(trim($order[0], '.')); } else { $theOrder = 0; } if ($theOrder >= $highestOrder) { $highestOrder = $theOrder; } } $orderOfNewFolder = $highestOrder + 1; if ($orderOfNewFolder < 10) { $orderOfNewFolder = '0' . $orderOfNewFolder; } Folder::mkdir($path . '/' . $orderOfNewFolder . '.' . $data['folder']); $this->admin->setMessage($this->admin->translate('PLUGIN_ADMIN.SUCCESSFULLY_SAVED'), 'info'); $multilang = $this->isMultilang(); $admin_route = $this->grav['config']->get('plugins.admin.route'); $redirect_url = '/' . ($multilang ? $this->grav['session']->admin_lang : '') . $admin_route . '/' . $this->view; $this->setRedirect($redirect_url); return true; }
/** * @param $state * @param $install_path */ protected static function flightProcessing($state, $install_path) { $blueprints_path = $install_path . DS . 'blueprints.yaml'; if (file_exists($blueprints_path)) { $package_yaml = Yaml::parse(file_get_contents($blueprints_path)); if (isset($package_yaml['install'][$state]['create'])) { foreach ((array) $package_yaml['install']['pre_install']['create'] as $file) { Folder::mkdir($install_path . '/' . ltrim($file, '/')); } } if (isset($package_yaml['install'][$state]['remove'])) { foreach ((array) $package_yaml['install']['pre_install']['remove'] as $file) { Folder::delete($install_path . '/' . ltrim($file, '/')); } } } }
/** * @param Package $package * * @param string $license * * @return string */ private function downloadPackage($package, $license = null) { $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); $this->tmp = $tmp_dir . '/Grav-' . uniqid(); $filename = $package->slug . basename($package->zipball_url); $query = ''; if ($package->premium) { $query = \json_encode(array_merge($package->premium, ['slug' => $package->slug, 'filename' => $package->premium['filename'], 'license_key' => $license])); $query = '?d=' . base64_encode($query); } try { $output = Response::get($package->zipball_url . $query, [], [$this, 'progress']); } catch (\Exception $e) { $error = str_replace("\n", "\n | '- ", $e->getMessage()); $this->output->write("\r"); // extra white spaces to clear out the buffer properly $this->output->writeln(" |- Downloading package... <red>error</red> "); $this->output->writeln(" | '- " . $error); return false; } Folder::mkdir($this->tmp); $this->output->write("\r"); $this->output->write(" |- Downloading package... 100%"); $this->output->writeln(''); file_put_contents($this->tmp . DS . $filename, $output); return $this->tmp . DS . $filename; }
private static function _downloadSelfupgrade($package, $tmp) { $output = Response::get($package['download'], []); Folder::mkdir($tmp); file_put_contents($tmp . DS . $package['name'], $output); return $tmp . DS . $package['name']; }
/** * Installs a given package to a given destination. * * @param string $package The local path to the ZIP package * @param string $destination The local path to the Grav Instance * @param array $options Options to use for installing. ie, ['install_path' => 'user/themes/antimatter'] * * @return boolean True if everything went fine, False otherwise. */ public static function install($package, $destination, $options = []) { $destination = rtrim($destination, DS); $options = array_merge(self::$options, $options); $install_path = rtrim($destination . DS . ltrim($options['install_path'], DS), DS); if (!self::isGravInstance($destination) || !self::isValidDestination($install_path, $options['exclude_checks'])) { return false; } if (self::lastErrorCode() == self::IS_LINK && $options['ignore_symlinks'] || self::lastErrorCode() == self::EXISTS && !$options['overwrite']) { return false; } $zip = new \ZipArchive(); $archive = $zip->open($package); $cache_dir = Grav::instance()['locator']->findResource('cache://', true); $tmp = $cache_dir . DS . 'tmp/Grav-' . uniqid(); if ($archive !== true) { self::$error = self::ZIP_OPEN_ERROR; return false; } Folder::mkdir($tmp); $unzip = $zip->extractTo($tmp); if (!$unzip) { self::$error = self::ZIP_EXTRACT_ERROR; $zip->close(); Folder::delete($tmp); return false; } $package_folder_name = $zip->getNameIndex(0); $installer_file_folder = $tmp . '/' . $package_folder_name; $is_install = true; $installer = self::loadInstaller($installer_file_folder, $is_install); if (isset($options['is_update']) && $options['is_update'] === true) { $method = 'preUpdate'; } else { $method = 'preInstall'; } if ($installer && method_exists($installer, $method)) { $method_result = $installer::$method(); if ($method_result !== true) { self::$error = 'An error occurred'; if (is_string($method_result)) { self::$error = $method_result; } return false; } } if (!$options['sophisticated']) { if ($options['theme']) { self::copyInstall($zip, $install_path, $tmp); } else { self::moveInstall($zip, $install_path, $tmp); } } else { self::sophisticatedInstall($zip, $install_path, $tmp); } Folder::delete($tmp); $zip->close(); if (isset($options['is_update']) && $options['is_update'] === true) { $method = 'postUpdate'; } else { $method = 'postInstall'; } self::$message = ''; if ($installer && method_exists($installer, $method)) { self::$message = $installer::$method(); } self::$error = self::OK; return true; }