Пример #1
0
 /**
  * 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])];
 }
Пример #2
0
 /**
  * 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 false;
     }
     $data = (array) $this->data;
     if ($data['route'] == '/') {
         $path = $this->grav['locator']->findResource('page://');
     } else {
         $path = $this->grav['page']->find($data['route'])->path();
     }
     $orderOfNewFolder = $this->getNextOrderInFolder($path);
     $new_path = $path . '/' . $orderOfNewFolder . '.' . $data['folder'];
     Folder::create($new_path);
     Cache::clearCache('standard');
     $this->grav->fireEvent('onAdminAfterSaveAs', new Event(['path' => $new_path]));
     $this->admin->setMessage($this->admin->translate('PLUGIN_ADMIN.SUCCESSFULLY_SAVED'), 'info');
     $multilang = $this->isMultilang();
     $admin_route = $this->admin->base;
     $redirect_url = '/' . ($multilang ? $this->grav['session']->admin_lang : '') . $admin_route . '/' . $this->view;
     $this->setRedirect($redirect_url);
     return true;
 }
Пример #3
0
 /**
  * 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;
 }