Beispiel #1
0
 public function testGetExtension()
 {
     $file = 'picture-of-kittens.jpg';
     $this->assertEquals('jpg', Library::getExtension($file));
     $empty = '/path/to/noext';
     $this->assertEquals('', Library::getExtension($empty));
 }
 public function patchTranslationPath()
 {
     # workaround for Bolt 2.2 - fix in master (3.0), see #3553 and #3800
     //        $app->before(function() use ($app) {
     //            $path = $app['resources']->getPath('root/app/resources/translations');
     //            $app['translator']->addResource('yml', $path.'/contenttypes.de_DE.yml', 'de_DE', 'contenttypes');
     //        });
     if ("Bolt\\Configuration\\Composer" != get_class($this->app['resources'])) {
         return;
     }
     //        $versionParser = new \Composer\Package\Version\VersionParser();
     //        $version = $versionParser->parseConstraints($app['bolt_version']);
     //        print_r($version);
     // Directory to look for translation file(s)
     $transDir = $this->app['resources']->getPath('root/app/resources/translations/' . $this->app['locale']);
     if (is_dir($transDir)) {
         $iterator = new \DirectoryIterator($transDir);
         /**
          * @var \SplFileInfo $fileInfo
          */
         foreach ($iterator as $fileInfo) {
             $ext = Lib::getExtension((string) $fileInfo);
             if (!$fileInfo->isFile() || !in_array($ext, array('yml', 'xlf'))) {
                 continue;
             }
             list($domain) = explode('.', $fileInfo->getFilename());
             $this->app['translator']->addResource($ext, $transDir . '/' . $fileInfo->getFilename(), $this->app['locale'], $domain);
         }
     }
 }
 /**
  * Adds all resources that belong to a locale.
  *
  * @param Application $app
  * @param string      $locale
  */
 public static function addResources(Application $app, $locale)
 {
     // Directories to look for translation file(s)
     $transDirs = array_unique([$app['resources']->getPath("app/resources/translations/{$locale}"), $app['resources']->getPath("root/app/resources/translations/{$locale}")]);
     $needsSecondPass = true;
     foreach ($transDirs as $transDir) {
         if (!is_dir($transDir) || !is_readable($transDir)) {
             continue;
         }
         $iterator = new \DirectoryIterator($transDir);
         /**
          * @var \SplFileInfo $fileInfo
          */
         foreach ($iterator as $fileInfo) {
             $ext = Lib::getExtension((string) $fileInfo);
             if (!$fileInfo->isFile() || !in_array($ext, ['yml', 'xlf'], true)) {
                 continue;
             }
             list($domain) = explode('.', $fileInfo->getFilename());
             $app['translator']->addResource($ext, $fileInfo->getRealPath(), $locale, $domain);
             $needsSecondPass = false;
         }
     }
     if ($needsSecondPass && strlen($locale) === 5) {
         static::addResources($app, substr($locale, 0, 2));
     }
 }
Beispiel #4
0
 /**
  * Checks if a given file is acceptable for upload.
  *
  * @param string $originalFilename
  *
  * @return bool
  */
 public function allowedUpload($originalFilename)
 {
     // no UNIX-hidden files
     if ($originalFilename[0] === '.') {
         return false;
     }
     // only whitelisted extensions
     $extension = strtolower(Lib::getExtension($originalFilename));
     $allowedExtensions = $this->getAllowedUploadExtensions();
     return in_array($extension, $allowedExtensions);
 }
Beispiel #5
0
 /**
  * Checks if a given file is acceptable for upload.
  *
  * @param string $originalFilename
  *
  * @throws IOException
  *
  * @return bool
  */
 public function allowedUpload($originalFilename)
 {
     // Check if file_uploads ini directive is true
     if (ini_get('file_uploads') != 1) {
         throw new IOException('File uploads are not allowed, check the file_uploads ini directive.');
     }
     // no UNIX-hidden files
     if ($originalFilename[0] === '.') {
         return false;
     }
     // only whitelisted extensions
     $extension = strtolower(Lib::getExtension($originalFilename));
     $allowedExtensions = $this->getAllowedUploadExtensions();
     return in_array($extension, $allowedExtensions);
 }
 /**
  * Adds all resources that belong to a locale.
  *
  * @param Application $app
  * @param string      $locale
  */
 public static function addResources(Application $app, $locale)
 {
     // Directory to look for translation file(s)
     $transDir = $app['resources']->getPath('app/resources/translations/' . $locale);
     if (is_dir($transDir)) {
         $iterator = new \DirectoryIterator($transDir);
         /**
          * @var \SplFileInfo $fileInfo
          */
         foreach ($iterator as $fileInfo) {
             $ext = Lib::getExtension((string) $fileInfo);
             if (!$fileInfo->isFile() || !in_array($ext, ['yml', 'xlf'])) {
                 continue;
             }
             list($domain) = explode('.', $fileInfo->getFilename());
             $app['translator']->addResource($ext, $fileInfo->getRealPath(), $locale, $domain);
         }
     } elseif (strlen($locale) == 5) {
         static::addResources($app, substr($locale, 0, 2));
     }
 }
Beispiel #7
0
 /**
  * File editor.
  *
  * @param Request $request   The Symfony Request
  * @param string  $namespace The filesystem namespace
  * @param string  $file      The file path
  *
  * @return \Bolt\Response\BoltResponse|\Symfony\Component\HttpFoundation\RedirectResponse
  */
 public function edit(Request $request, $namespace, $file)
 {
     if ($namespace === 'app' && dirname($file) === 'config') {
         // Special case: If requesting one of the major config files, like contenttypes.yml, set the path to the
         // correct dir, which might be 'app/config', but it might be something else.
         $namespace = 'config';
     }
     /** @var FilesystemInterface $filesystem */
     $filesystem = $this->filesystem()->getFilesystem($namespace);
     if (!$filesystem->authorized($file)) {
         $error = Trans::__('general.phrase.access-denied-permissions-edit-file', ['%s' => $file]);
         $this->abort(Response::HTTP_FORBIDDEN, $error);
     }
     try {
         /** @var File $file */
         $file = $filesystem->get($file);
         $type = Lib::getExtension($file->getPath());
         $data = ['contents' => $file->read()];
     } catch (FileNotFoundException $e) {
         $error = Trans::__('general.phrase.file-not-exist', ['%s' => $file->getPath()]);
         $this->abort(Response::HTTP_NOT_FOUND, $error);
     } catch (IOException $e) {
         $error = Trans::__('general.phrase.file-not-readable', ['%s' => $file->getPath()]);
         $this->abort(Response::HTTP_NOT_FOUND, $error);
     }
     /** @var Form $form */
     $form = $this->createFormBuilder(FormType::class, $data)->add('contents', TextareaType::class)->getForm();
     // Handle the POST and check if it's valid.
     if ($request->isMethod('POST')) {
         return $this->handleEdit($request, $form, $file, $type);
     }
     // For 'related' files we might need to keep track of the current dirname on top of the namespace.
     if (dirname($file->getPath()) !== '') {
         $additionalpath = dirname($file->getPath()) . '/';
     } else {
         $additionalpath = '';
     }
     $context = ['form' => $form->createView(), 'filetype' => $type, 'file' => $file->getPath(), 'basename' => basename($file->getPath()), 'pathsegments' => $this->getPathSegments(dirname($file->getPath())), 'additionalpath' => $additionalpath, 'namespace' => $namespace, 'write_allowed' => true, 'filegroup' => $this->getFileGroup($filesystem, $file), 'datechanged' => date_format(new \DateTime('@' . $file->getTimestamp()), 'c')];
     return $this->render('@bolt/editfile/editfile.twig', $context);
 }
Beispiel #8
0
 /**
  * File editor.
  *
  * @param Request $request   The Symfony Request
  * @param string  $namespace The filesystem namespace
  * @param string  $file      The file path
  *
  * @return \Bolt\Response\BoltResponse|\Symfony\Component\HttpFoundation\RedirectResponse
  */
 public function edit(Request $request, $namespace, $file)
 {
     if ($namespace === 'app' && dirname($file) === 'config') {
         // Special case: If requesting one of the major config files, like contenttypes.yml, set the path to the
         // correct dir, which might be 'app/config', but it might be something else.
         $namespace = 'config';
     }
     /** @var FilesystemInterface $filesystem */
     $filesystem = $this->filesystem()->getFilesystem($namespace);
     if (!$filesystem->authorized($file)) {
         $error = Trans::__("You don't have correct permissions to edit the file '%s'.", ['%s' => $file]);
         $this->abort(Response::HTTP_FORBIDDEN, $error);
     }
     /** @var File $file */
     $file = $filesystem->get($file);
     $type = Lib::getExtension($file->getPath());
     $contents = null;
     if (!$file->exists() || !($contents = $file->read())) {
         $error = Trans::__("The file '%s' doesn't exist, or is not readable.", ['%s' => $file->getPath()]);
         $this->abort(Response::HTTP_NOT_FOUND, $error);
     }
     $writeallowed = $this->isWriteable($file);
     $data = ['contents' => $contents];
     /** @var Form $form */
     $form = $this->createFormBuilder('form', $data)->add('contents', 'textarea')->getForm();
     // Handle the POST and check if it's valid.
     if ($request->isMethod('POST')) {
         return $this->handleEdit($request, $form, $file, $type);
     }
     // For 'related' files we might need to keep track of the current dirname on top of the namespace.
     if (dirname($file->getPath()) !== '') {
         $additionalpath = dirname($file->getPath()) . '/';
     } else {
         $additionalpath = '';
     }
     $context = ['form' => $form->createView(), 'filetype' => $type, 'file' => $file->getPath(), 'basename' => basename($file->getPath()), 'pathsegments' => $this->getPathSegments(dirname($file->getPath())), 'additionalpath' => $additionalpath, 'namespace' => $namespace, 'write_allowed' => $writeallowed, 'filegroup' => $this->getFileGroup($filesystem, $file), 'datechanged' => date_format(new \DateTime('@' . $file->getTimestamp()), 'c')];
     return $this->render('@bolt/editfile/editfile.twig', $context);
 }
Beispiel #9
0
 /**
  * Return a list with the current stacked items. Add some relevant info to each item,
  * and also check if the item is present and readable.
  *
  * @param integer $count
  * @param string  $typefilter
  *
  * @return array
  */
 public function listitems($count = 100, $typefilter = '')
 {
     $this->initialize();
     // Make sure typefilter is an array, if passed something like "image, document"
     if (!empty($typefilter)) {
         $typefilter = array_map('trim', explode(',', $typefilter));
     }
     // Our basepaths for all files that can be on the stack: 'files' and 'theme'.
     $filespath = $this->app['resources']->getPath('filespath');
     $themepath = $this->app['resources']->getPath('themebasepath');
     $items = $this->items;
     $list = [];
     foreach ($items as $item) {
         $extension = strtolower(Lib::getExtension($item));
         if (in_array($extension, $this->imageTypes)) {
             $type = 'image';
         } elseif (in_array($extension, $this->documentTypes)) {
             $type = 'document';
         } else {
             $type = 'other';
         }
         // Skip this one, if it doesn't match the type.
         if (!empty($typefilter) && !in_array($type, $typefilter)) {
             continue;
         }
         // Figure out the full path, based on the two possible locations.
         $fullpath = '';
         if (is_readable(str_replace('files/files/', 'files/', $filespath . '/' . $item))) {
             $fullpath = str_replace('files/files/', 'files/', $filespath . '/' . $item);
         } elseif (is_readable($themepath . '/' . $item)) {
             $fullpath = $themepath . '/' . $item;
         }
         // No dice! skip this one.
         if (empty($fullpath)) {
             continue;
         }
         $thisitem = ['basename' => basename($item), 'extension' => $extension, 'filepath' => str_replace('files/', '', $item), 'type' => $type, 'writable' => is_writable($fullpath), 'readable' => is_readable($fullpath), 'filesize' => Lib::formatFilesize(filesize($fullpath)), 'modified' => date('Y/m/d H:i:s', filemtime($fullpath)), 'permissions' => util::full_permissions($fullpath)];
         $thisitem['info'] = sprintf('%s: <code>%s</code><br>%s: %s<br>%s: %s<br>%s: <code>%s</code>', Trans::__('Path'), $thisitem['filepath'], Trans::__('Filesize'), $thisitem['filesize'], Trans::__('Modified'), $thisitem['modified'], Trans::__('Permissions'), $thisitem['permissions']);
         if ($type == 'image') {
             $size = getimagesize($fullpath);
             $thisitem['imagesize'] = sprintf('%s × %s', $size[0], $size[1]);
             $thisitem['info'] .= sprintf('<br>%s: %s × %s px', Trans::__('Size'), $size[0], $size[1]);
         }
         //add it to our list.
         $list[] = $thisitem;
     }
     $list = array_slice($list, 0, $count);
     return $list;
 }
Beispiel #10
0
 /**
  * File editor.
  *
  * @param string      $namespace The filesystem namespace
  * @param string      $file      The file path
  * @param Application $app       The application/container
  * @param Request     $request   The Symfony Request
  *
  * @return \Twig_Markup|\Symfony\Component\HttpFoundation\RedirectResponse
  */
 public function fileEdit($namespace, $file, Application $app, Request $request)
 {
     if ($namespace == 'app' && dirname($file) == 'config') {
         // Special case: If requesting one of the major config files, like contenttypes.yml, set the path to the
         // correct dir, which might be 'app/config', but it might be something else.
         $namespace = 'config';
     }
     /** @var \League\Flysystem\FilesystemInterface $filesystem */
     $filesystem = $app['filesystem']->getFilesystem($namespace);
     if (!$filesystem->authorized($file)) {
         $error = Trans::__("You don't have correct permissions to edit the file '%s'.", array('%s' => $file));
         $app->abort(Response::HTTP_FORBIDDEN, $error);
     }
     /** @var \League\Flysystem\File $file */
     $file = $filesystem->get($file);
     $datechanged = date_format(new \DateTime('@' . $file->getTimestamp()), 'c');
     $type = Lib::getExtension($file->getPath());
     // Get the pathsegments, so we can show the path.
     $path = dirname($file->getPath());
     $pathsegments = array();
     $cumulative = '';
     if (!empty($path)) {
         foreach (explode('/', $path) as $segment) {
             $cumulative .= $segment . '/';
             $pathsegments[$cumulative] = $segment;
         }
     }
     $contents = null;
     if (!$file->exists() || !($contents = $file->read())) {
         $error = Trans::__("The file '%s' doesn't exist, or is not readable.", array('%s' => $file->getPath()));
         $app->abort(Response::HTTP_NOT_FOUND, $error);
     }
     if (!$file->update($contents)) {
         $app['session']->getFlashBag()->add('info', Trans::__("The file '%s' is not writable. You will have to use your own editor to make modifications to this file.", array('%s' => $file->getPath())));
         $writeallowed = false;
     } else {
         $writeallowed = true;
     }
     // Gather the 'similar' files, if present.. i.e., if we're editing config.yml, we also want to check for
     // config.yml.dist and config_local.yml
     $basename = str_replace('.yml', '', str_replace('_local', '', $file->getPath()));
     $filegroup = array();
     if ($filesystem->has($basename . '.yml')) {
         $filegroup[] = basename($basename . '.yml');
     }
     if ($filesystem->has($basename . '_local.yml')) {
         $filegroup[] = basename($basename . '_local.yml');
     }
     $data = array('contents' => $contents);
     /** @var Form $form */
     $form = $app['form.factory']->createBuilder('form', $data)->add('contents', 'textarea')->getForm();
     // Check if the form was POST-ed, and valid. If so, store the user.
     if ($request->isMethod('POST')) {
         $form->submit($app['request']->get($form->getName()));
         if ($form->isValid()) {
             $data = $form->getData();
             $contents = Input::cleanPostedData($data['contents']) . "\n";
             $result = array('ok' => true, 'msg' => 'Unhandled state.');
             // Before trying to save a yaml file, check if it's valid.
             if ($type === 'yml') {
                 $yamlparser = new Yaml\Parser();
                 try {
                     $yamlparser->parse($contents);
                 } catch (ParseException $e) {
                     $result['ok'] = false;
                     $result['msg'] = Trans::__("File '%s' could not be saved:", array('%s' => $file->getPath())) . $e->getMessage();
                 }
             }
             if ($result['ok']) {
                 // Remove ^M (or \r) characters from the file.
                 $contents = str_ireplace("\r", '', $contents);
                 if ($file->update($contents)) {
                     $result['msg'] = Trans::__("File '%s' has been saved.", array('%s' => $file->getPath()));
                     $result['datechanged'] = date_format(new \DateTime('@' . $file->getTimestamp()), 'c');
                 } else {
                     $result['msg'] = Trans::__("File '%s' could not be saved, for some reason.", array('%s' => $file->getPath()));
                 }
             }
         } else {
             $result = array('ok' => false, 'msg' => Trans::__("File '%s' could not be saved, because the form wasn't valid.", array('%s' => $file->getPath())));
         }
         return new JsonResponse($result);
     }
     // For 'related' files we might need to keep track of the current dirname on top of the namespace.
     if (dirname($file->getPath()) != '') {
         $additionalpath = dirname($file->getPath()) . '/';
     } else {
         $additionalpath = '';
     }
     $context = array('form' => $form->createView(), 'filetype' => $type, 'file' => $file->getPath(), 'basename' => basename($file->getPath()), 'pathsegments' => $pathsegments, 'additionalpath' => $additionalpath, 'namespace' => $namespace, 'write_allowed' => $writeallowed, 'filegroup' => $filegroup, 'datechanged' => $datechanged);
     return $app['render']->render('editfile/editfile.twig', array('context' => $context));
 }